/* Shared component layer. Values come from tokens.css only (DESIGN_SYSTEM.md §16). */
/* Inline SVG reserves descender space like text by default, nudging icons a few px below their visual centre
   inside anything that centres them (grid place-items, flex align-items) — block removes that reserved space. */
.ce-icon { display: block; flex: none; }
.ce-muted { color: var(--text-secondary); }
/** Truncates one line of text with an ellipsis; put on the flexible/long sibling in a tight row (e.g. next to a fixed badge) so it shrinks instead of wrapping or pushing the row wider than its container. */
.ce-truncate { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ce-stack { display: grid; gap: var(--space-4); min-width: 0; }
.ce-row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ce-row > * { flex: 1 1 140px; }
/* A compact, centered row for a quantity stepper (Marketplace product cards): no per-child growth, unlike .ce-row. */
.ce-qty-stepper { display: flex; align-items: center; gap: var(--space-2); flex: none; }
.ce-qty-stepper strong { min-width: 1.5em; text-align: center; }
.ce-inline-notice { margin-bottom: var(--space-3); padding: var(--space-3); color: var(--status-info); border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--status-info-soft); font-size: var(--text-small); }
.ce-inline-notice[hidden] { display: none; }
/* Global correctness net: any author rule that sets `display` on an element beats the UA [hidden] rule at equal
   specificity (CSS cascade: author normal declarations always win over user-agent ones, regardless of source
   order). Without this, toggling `.hidden = true` silently does nothing on elements whose class also sets
   `display` (.ce-field, .ce-card, .ce-stack, etc.) — a bug found and fixed per-class below for .ce-btn only; this
   rule makes every element's `hidden` toggle work everywhere, present and future. */
[hidden] { display: none !important; }
@media (prefers-reduced-motion: reduce) { * { animation-duration: .01ms !important; transition-duration: .01ms !important; scroll-behavior: auto !important; } }

/* Every page/menu change — Admin/Driver/Merchant's router.ts and Marketplace's mountPage() both apply this to the
   freshly mounted page root, so every portal's navigation (and whatever a form submit leads to) gets the same
   soft entrance instead of the old instant, jarring swap. prefers-reduced-motion above collapses it to ~0ms. */
.ce-route-enter { animation: ce-route-fade-in var(--motion-page) ease-out; }
@keyframes ce-route-fade-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

/* Buttons */
.ce-btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); min-height: var(--control-height); padding: 0 var(--space-4); color: var(--brand-primary); border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-card); font-size: var(--text-small); font-weight: 700; text-decoration: none; transition: background var(--motion-fast), border-color var(--motion-fast), transform var(--motion-fast), color var(--motion-fast); }
/* An author rule of equal specificity to the UA [hidden] rule always wins, so .ce-btn's own display would otherwise show a button whose .hidden was set true anywhere in the app (pagination "Muat berikutnya", conditional actions, etc.). */
.ce-btn[hidden] { display: none; }
.ce-btn:hover { border-color: var(--brand-primary); background: var(--brand-primary-soft); }
.ce-btn:active { transform: translateY(1px); }
.ce-btn:disabled { color: var(--text-disabled); border-color: var(--border-default); background: var(--surface-disabled); cursor: not-allowed; }
.ce-btn-primary { color: var(--brand-on-primary); border-color: transparent; background: var(--brand-primary); }
.ce-btn-primary:hover { background: var(--brand-primary-hover); border-color: transparent; }
.ce-btn-ghost { border-color: transparent; background: transparent; }
.ce-btn-danger { color: var(--status-danger); border-color: var(--status-danger); background: var(--status-danger-soft); }
.ce-btn-danger:hover { background: var(--status-danger-soft); border-color: var(--status-danger); }
.ce-btn-full { width: 100%; }
.ce-btn-lg { min-height: 52px; font-size: var(--text-body); }
.ce-btn-sm { min-height: 36px; padding: 0 var(--space-3); font-size: var(--text-small); }
.ce-btn.is-busy { position: relative; color: transparent; }
.ce-btn > * { transition: opacity var(--motion-fast); }
.ce-btn.is-busy > * { opacity: 0; }
.ce-btn.is-busy::after { position: absolute; width: 18px; height: 18px; content: ''; border: 2px solid var(--brand-primary); border-top-color: transparent; border-radius: 50%; animation: ce-spin .7s linear infinite; }
.ce-btn-primary.is-busy::after { border-color: var(--brand-on-primary); border-top-color: transparent; }
@keyframes ce-spin { to { transform: rotate(360deg); } }
.ce-icon-btn { display: inline-grid; place-items: center; width: var(--control-height); height: var(--control-height); color: var(--text-secondary); border: 0; border-radius: var(--radius-control); background: transparent; }
.ce-icon-btn:hover { background: var(--surface-section); }

/* Badges and tones */
.ce-badge { display: inline-flex; flex: none; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); font-size: var(--text-caption); font-weight: 700; white-space: nowrap; }
.ce-tone-success { color: var(--status-success); background: var(--status-success-soft); }
.ce-tone-warning { color: var(--status-warning); background: var(--status-warning-soft); }
.ce-tone-danger { color: var(--status-danger); background: var(--status-danger-soft); }
.ce-tone-info { color: var(--status-info); background: var(--status-info-soft); }
.ce-tone-neutral { color: var(--status-neutral); background: var(--surface-section); }
.ce-tone-brand { color: var(--brand-primary); background: var(--brand-primary-soft); }

/* Forms */
.ce-form { display: grid; gap: var(--space-3); }
.ce-field { display: grid; gap: var(--space-2); min-width: 0; }
.ce-field label { margin: 0; font-size: var(--text-small); font-weight: 700; }
.ce-required { color: var(--text-tertiary); font-weight: 500; }
.ce-field input, .ce-field select, .ce-field textarea { width: 100%; min-height: var(--control-height); padding: var(--space-3); color: var(--text-primary); border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-card); font: inherit; }
.ce-field textarea { resize: vertical; }
/* input[type=date]'s native WebKit widget keeps its own intrinsic width for the day/month/year
   segments and can render narrower than width:100% would suggest; appearance:none makes it use
   the same box model as every other field above. */
.ce-field input[type="date"] { -webkit-appearance: none; appearance: none; }
.ce-field input:focus, .ce-field select:focus, .ce-field textarea:focus { border-color: var(--border-strong); box-shadow: 0 0 0 3px var(--brand-primary-soft); outline: 0; }
.ce-field [aria-invalid='true'] { border-color: var(--status-danger); }
.ce-hint { color: var(--text-tertiary); }
.ce-hint-success { color: var(--status-success); font-weight: 600; }
.ce-hint-info { color: var(--status-info); font-weight: 600; }
.ce-hint-danger { color: var(--status-danger); font-weight: 600; }
.ce-field-error { min-height: 0; color: var(--status-danger); font-weight: 600; }
.ce-field-consent label { display: flex; align-items: flex-start; gap: var(--space-2); font-weight: 500; }
.ce-field-consent input { width: auto; min-height: 0; margin-top: 0.2em; flex: none; }

/* Cards and data */
.ce-card { min-width: 0; border: 1px solid var(--border-default); border-radius: var(--radius-card); background: var(--surface-card); box-shadow: var(--shadow-subtle); }
.ce-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-4) var(--space-4) 0; }
.ce-card-head h3 { margin: 0; font-size: var(--heading-card); letter-spacing: -.02em; }
.ce-card-body { display: grid; gap: var(--space-3); padding: var(--space-4); }
.ce-card-foot { padding: 0 var(--space-4) var(--space-4); }
.ce-kv { display: grid; gap: var(--space-2); margin: 0; }
.ce-kv > div { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2); padding-bottom: var(--space-2); border-bottom: 1px solid var(--border-default); }
.ce-kv > div:last-child { padding-bottom: 0; border-bottom: 0; }
.ce-kv dt { color: var(--text-secondary); }
.ce-kv dd { margin: 0; font-weight: 700; text-align: right; overflow-wrap: anywhere; }
.ce-stat { display: grid; gap: var(--space-1); }
.ce-stat-label { color: var(--text-tertiary); font-size: var(--text-caption); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.ce-stat-value { font-size: var(--heading-card); letter-spacing: -.02em; }
/* Owner, 11 Okt 2026: as a flex item (a mobile-card <td>, see .ce-data td below) a block div with no width shrinks to its
   content instead of filling the row, collapsing to 0px and hiding the whole bar — explicit width keeps it visible there too. */
.ce-progress { width: 100%; height: 8px; overflow: hidden; border-radius: var(--radius-pill); background: var(--surface-section); }
.ce-progress > span { display: block; height: 100%; border-radius: inherit; background: var(--brand-accent); transition: width var(--motion-fast); }
.ce-list { display: grid; gap: var(--space-2); }
.ce-list-item { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-2) var(--space-3); padding: var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-control); }
.ce-list-item > div { display: grid; gap: 4px; min-width: 0; flex: 1 1 200px; overflow-wrap: anywhere; }
/* A <button> that should look and lay out exactly like a .ce-list-item row (Owner, 11 Okt 2026: Dashboard document-expiry list). */
button.ce-list-item { width: 100%; background: var(--surface-card); font: inherit; text-align: left; cursor: pointer; }
button.ce-list-item:hover { background: var(--surface-section); }
.ce-skeleton { display: grid; gap: var(--space-2); }
.ce-skeleton-line { height: 14px; border-radius: var(--radius-control); background: linear-gradient(90deg, var(--surface-section), var(--surface-disabled), var(--surface-section)); background-size: 200% 100%; animation: ce-shimmer 1.2s linear infinite; }
@keyframes ce-shimmer { to { background-position: -200% 0; } }
.ce-empty { display: grid; justify-items: center; gap: var(--space-2); padding: var(--space-6) var(--space-4); color: var(--text-secondary); text-align: center; }
.ce-empty strong { color: var(--text-primary); }
.ce-empty p { max-width: 36ch; margin: 0; }
.ce-empty-error { color: var(--status-danger); }

/* Toasts and dialogs */
.ce-toasts { position: fixed; z-index: 60; right: var(--space-4); bottom: calc(var(--bottom-nav-height) + var(--space-4)); left: var(--space-4); display: grid; justify-items: end; gap: var(--space-2); pointer-events: none; }
.ce-toast { display: flex; align-items: center; gap: var(--space-2); max-width: 420px; padding: var(--space-3) var(--space-4); border-radius: var(--radius-control); box-shadow: var(--shadow-overlay); font-weight: 600; pointer-events: auto; }
.ce-dialog { width: min(92vw, 480px); max-height: 90vh; padding: 0; color: var(--text-primary); border: 0; border-radius: var(--radius-container); background: var(--surface-overlay); box-shadow: var(--shadow-overlay); }
.ce-dialog::backdrop { background: var(--backdrop); }
.ce-dialog-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-4) var(--space-4) 0; }
.ce-dialog-head h2 { margin: 0; font-size: var(--heading-card); }
.ce-dialog-body { display: grid; gap: var(--space-3); max-height: 66vh; padding: var(--space-4); overflow-y: auto; }
.ce-dialog-foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-2); padding: 0 var(--space-4) var(--space-4); }
.ce-dialog-sheet { position: fixed; inset: auto 0 0; width: 100%; max-width: none; margin: 0; border-radius: var(--radius-container) var(--radius-container) 0 0; }
.ce-dialog-drawer { position: fixed; inset: 0 0 0 auto; width: min(100vw, 480px); max-height: none; height: 100%; margin: 0; border-radius: var(--radius-container) 0 0 var(--radius-container); }
.ce-dialog-drawer[open], .ce-dialog-sheet[open] { display: flex; flex-direction: column; }
.ce-dialog-drawer .ce-dialog-body { flex: 1; max-height: none; }
.ce-dialog-sheet .ce-dialog-body { max-height: 70vh; }

/* Auth pages (login, registration): centered card, legacy layout with Cak Ed tokens */
.ce-auth { display: grid; align-content: start; justify-items: center; gap: var(--space-4); min-height: 100vh; padding: var(--space-6) var(--space-4); background: var(--surface-page); }
.ce-auth-card { width: min(100%, 440px); overflow: hidden; border: 1px solid var(--border-default); border-radius: var(--radius-container); background: var(--surface-card); box-shadow: var(--shadow-subtle); }
.ce-auth-head { display: grid; justify-items: center; gap: var(--space-2); padding: var(--space-6) var(--space-4) var(--space-4); text-align: center; border-bottom: 1px solid var(--border-default); }
.ce-auth-head h1 { margin: var(--space-2) 0 0; color: var(--brand-primary); font-size: var(--heading-card); letter-spacing: -.01em; }
.ce-auth-head p { max-width: 34ch; margin: 0; color: var(--text-secondary); font-size: var(--text-small); }
.ce-auth-body { display: grid; gap: var(--space-4); padding: var(--space-6) var(--space-4); background: var(--surface-page); }
.ce-auth-foot { display: grid; gap: var(--space-2); padding-top: var(--space-4); border-top: 1px solid var(--border-default); text-align: center; }
.ce-auth-foot p { margin: 0; color: var(--text-secondary); font-size: var(--text-small); }
.ce-auth-note { max-width: 440px; margin: 0; color: var(--text-tertiary); font-size: var(--text-caption); text-align: center; }
.ce-brand { display: inline-flex; align-items: center; gap: var(--space-2); }
.ce-brand-mark { display: block; flex: none; width: 44px; height: 44px; color: transparent; font-size: 0; background: var(--brand-primary) url('/brand/logo-mark.png') center / cover no-repeat; border-radius: var(--radius-card); }
.ce-brand-name { display: grid; color: var(--brand-primary); font-size: 1.25rem; font-weight: 800; letter-spacing: -.04em; line-height: 1; }
.ce-brand-name small { color: var(--text-tertiary); font-size: 10px; font-weight: 600; letter-spacing: .32em; }

/* Driver shell: mobile-first, bottom navigation */
.ce-shell-driver { max-width: 480px; min-height: 100vh; margin: 0 auto; background: var(--surface-page); }
/* Marketplace (Customer) is the same mobile-first shape as Driver but had no container constraint at all — on a
   wide screen its content sat flush against the left edge instead of centered under the already-centered
   .ce-bottom-nav (max-width:480px/margin:auto below), leaving most of the viewport empty (audit, 12 Okt 2026). */
.ce-marketplace { max-width: 480px; min-height: 100vh; margin: 0 auto; }
.ce-driver-content { display: grid; align-content: start; gap: var(--space-4); padding: var(--space-4) var(--space-4) calc(var(--bottom-nav-height) + var(--space-6)); }
.ce-bottom-nav { position: fixed; z-index: var(--layer-sticky); right: 0; bottom: 0; left: 0; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; height: var(--bottom-nav-height); max-width: 480px; margin: 0 auto; padding-bottom: env(safe-area-inset-bottom); border-top: 1px solid var(--border-default); background: var(--surface-card); }
.ce-nav-item { display: grid; place-items: center; align-content: center; gap: var(--space-1); min-height: 56px; min-width: 0; padding: 0 var(--space-1); color: var(--text-tertiary); border: 0; background: transparent; font-size: var(--text-caption); font-weight: 600; }
.ce-nav-item span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ce-nav-item:hover { color: var(--brand-primary); }
.ce-nav-item.is-active { color: var(--brand-primary); font-weight: 800; }

/* Admin shell: sidebar on wide screens, bottom navigation on phones */
.ce-shell-admin { display: grid; grid-template-columns: var(--sidebar-width) minmax(0, 1fr); min-height: 100vh; background: var(--surface-page); }
.ce-sidebar { position: sticky; top: 0; align-self: start; display: flex; flex-direction: column; gap: var(--space-4); height: 100vh; padding: var(--space-4); overflow-y: auto; border-right: 1px solid var(--border-default); background: var(--surface-card); }
.ce-sidebar.is-collapsed { width: var(--sidebar-collapsed); }
.ce-sidebar.is-collapsed .ce-sidebar-item span, .ce-sidebar.is-collapsed .ce-sidebar-label, .ce-sidebar.is-collapsed .ce-brand-name { display: none; }
.ce-sidebar-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.ce-sidebar-nav { display: grid; gap: var(--space-1); }
.ce-sidebar-label { margin: var(--space-3) 0 var(--space-1); color: var(--text-tertiary); font-size: var(--text-caption); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.ce-sidebar-item { display: flex; align-items: center; gap: var(--space-3); min-height: var(--control-height); padding: 0 var(--space-3); color: var(--text-secondary); border: 0; border-radius: var(--radius-control); background: transparent; font-size: var(--text-body); font-weight: 600; text-align: left; }
.ce-sidebar-item span { overflow: hidden; min-width: 0; white-space: nowrap; text-overflow: ellipsis; }
.ce-sidebar-group-toggle { display: flex; align-items: center; justify-content: space-between; width: 100%; border: 0; background: transparent; cursor: pointer; }
.ce-sidebar-group-toggle .ce-icon { transition: transform var(--motion-fast); }
.ce-sidebar-group-toggle.is-open .ce-icon { transform: rotate(180deg); }
.ce-sidebar-group-items[hidden] { display: none; }
.ce-sidebar-item:hover { background: var(--surface-section); }
.ce-sidebar-item.is-active { color: var(--brand-primary); background: var(--brand-primary-soft); font-weight: 800; }
.ce-admin-content { display: grid; align-content: start; gap: var(--space-4); min-width: 0; padding: var(--space-6); }
.ce-bottom-nav-admin { display: none; }
.ce-admin-body { display: grid; align-content: start; gap: var(--space-4); min-width: 0; }
.ce-breadcrumb { display: flex; align-items: center; gap: var(--space-2); color: var(--text-secondary); font-size: var(--text-small); }
.ce-breadcrumb strong { color: var(--text-primary); font-weight: 700; }
.ce-breadcrumb-sep { opacity: .6; }
.ce-breadcrumb:empty { display: none; }
@media (max-width: 767px) {
  .ce-shell-admin { display: block; }
  .ce-sidebar { display: none; }
  .ce-breadcrumb { display: none; }
  .ce-admin-content { padding: var(--space-4) var(--space-4) calc(var(--bottom-nav-height) + var(--space-6)); }
  .ce-bottom-nav-admin { display: grid; max-width: none; }
}

/* Page furniture and tabs */
.ce-page-title { margin: 0; font-size: var(--heading-section); letter-spacing: -.03em; }
.ce-section-title { margin: var(--space-2) 0 0; font-size: var(--heading-card); letter-spacing: -.02em; }
.ce-tabs { display: flex; flex-wrap: wrap; gap: var(--space-1); padding: var(--space-1); border-radius: var(--radius-control); background: var(--surface-section); }
.ce-tab { flex: 1 1 auto; min-height: var(--control-height); padding: 0 var(--space-3); color: var(--text-secondary); border: 0; border-radius: var(--radius-control); background: transparent; font-size: var(--text-small); font-weight: 700; }
.ce-tab[aria-pressed='true'] { color: var(--brand-primary); background: var(--surface-card); box-shadow: var(--shadow-subtle); }
.ce-profile-head { display: flex; align-items: center; gap: var(--space-4); }
.ce-driver-card { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.ce-driver-card-info { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
.ce-driver-card-info strong { font-size: var(--text-large); }
.ce-driver-card-info small { color: var(--text-secondary); }
.ce-driver-card-actions { display: flex; align-items: flex-start; gap: var(--space-4); flex: none; }
.ce-icon-action { display: grid; justify-items: center; gap: 4px; border: 0; background: transparent; padding: 0; color: inherit; text-decoration: none; font: inherit; cursor: pointer; }
.ce-icon-action-icon { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; }
.ce-icon-action-icon.is-chat { color: var(--status-info); background: var(--status-info-soft); }
.ce-icon-action-icon.is-whatsapp { color: #25d366; background: rgb(37 211 102 / 12%); }
.ce-icon-action-label { max-width: 72px; color: var(--text-secondary); font-size: 11px; text-align: center; }
.ce-avatar { display: grid; flex: none; place-items: center; width: 56px; height: 56px; overflow: hidden; color: var(--brand-on-primary); border-radius: 50%; background: var(--brand-primary); font-weight: 800; }
.ce-avatar-photo { width: 100%; height: 100%; object-fit: cover; }
.ce-auth-wide .ce-auth-card { width: min(100%, 560px); }
.ce-auth-body .ce-card { box-shadow: none; }
.ce-photo-preview { max-width: 100%; max-height: 180px; border: 1px solid var(--border-default); border-radius: var(--radius-control); object-fit: cover; }
.ce-doc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--space-3); }
.ce-doc { display: grid; gap: var(--space-2); margin: 0; }
.ce-doc figcaption { color: var(--text-secondary); font-size: var(--text-caption); font-weight: 600; }
.ce-doc-frame { display: grid; place-items: center; align-content: center; gap: 4px; aspect-ratio: 4 / 3; overflow: hidden; border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-section); }
.ce-doc-frame img { width: 100%; height: 100%; object-fit: cover; }
.ce-doc-frame a { display: block; width: 100%; height: 100%; }
.ce-doc-missing { color: var(--status-danger); font-size: var(--text-caption); text-align: center; }

.ce-badges { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ce-menu-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: var(--space-3); }
.ce-menu-card { display: grid; justify-items: center; gap: var(--space-2); padding: var(--space-4) var(--space-2); border: 1px solid var(--border-default); border-radius: var(--radius-card); background: var(--surface-card); color: var(--text-secondary); font-size: var(--text-small); font-weight: 600; text-align: center; }
.ce-menu-card:hover { border-color: var(--brand-primary); color: var(--brand-primary); }

/* Driver Beranda: hero with the BID switch */
.ce-hero { display: grid; gap: var(--space-4); padding: var(--space-4); color: var(--text-inverse); border-radius: var(--radius-container); background: var(--brand-hero); box-shadow: var(--shadow-subtle); }
.ce-hero-top { display: flex; align-items: center; gap: var(--space-3); }
.ce-hero-name { margin: 0; font-size: var(--heading-card); letter-spacing: -.02em; }
.ce-hero-code { display: inline-block; flex: none; margin-left: var(--space-2); padding: var(--space-1) var(--space-2); color: var(--brand-on-accent); border-radius: var(--radius-pill); background: var(--brand-accent); font-size: var(--text-caption); font-weight: 800; white-space: nowrap; }
.ce-hero small { display: block; opacity: .85; }
.ce-avatar-onbrand { color: var(--brand-primary); background: var(--surface-card); }
.ce-hero-stats { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2); padding-top: var(--space-3); border-top: 1px solid rgb(255 255 255 / 22%); font-size: var(--text-small); font-weight: 700; }
.ce-hero-stats span { display: inline-flex; align-items: center; gap: var(--space-2); }
.ce-hero-panel { display: grid; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-radius: var(--radius-card); background: rgb(255 255 255 / 12%); }
.ce-hero-label { font-size: var(--text-caption); font-weight: 800; letter-spacing: .12em; opacity: .75; }
.ce-hero-switch { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); font-size: var(--text-body); font-weight: 600; }
.ce-hero-status { display: grid; gap: 2px; text-align: left; }
.ce-hero-note, .ce-hero-orders { margin: 0; font-size: var(--text-caption); }
.ce-hero-note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ce-hero-note { display: inline-flex; align-items: center; gap: var(--space-2); }
.ce-hero-orders { margin-left: var(--space-2); }
.ce-switch { position: relative; flex: none; width: 44px; height: 24px; border: 0; border-radius: var(--radius-pill); background: rgb(255 255 255 / 30%); transition: background var(--motion-fast); }
.ce-switch[aria-checked='true'] { background: var(--brand-accent); }
.ce-switch-knob { position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: var(--surface-card); box-shadow: var(--shadow-subtle); transition: transform var(--motion-fast); }
.ce-switch[aria-checked='true'] .ce-switch-knob { transform: translateX(20px); }
.ce-switch:focus-visible { outline: 3px solid var(--text-inverse); outline-offset: 3px; }
.ce-switch-light { background: var(--surface-section); border: 1px solid var(--border-default); }
.ce-switch-light[aria-checked='true'] { background: var(--brand-primary); border-color: var(--brand-primary); }
.ce-switch-light:focus-visible { outline: 3px solid var(--brand-accent); outline-offset: 3px; }
.ce-switch-group { display: flex; flex-wrap: wrap; gap: var(--space-4); }
.ce-switch-item { display: grid; justify-items: center; gap: var(--space-2); text-align: center; min-width: 84px; }
.ce-switch-item-label { font-size: var(--text-small); font-weight: 600; }
.ce-switch-item-amount { font-size: var(--text-caption); color: var(--text-tertiary); }
.ce-stepper { display: flex; align-items: center; gap: var(--space-2); }
.ce-stepper input { flex: 1 1 auto; min-width: 0; padding: 0 6px; text-align: center; -moz-appearance: textfield; }
.ce-stepper input::-webkit-outer-spin-button, .ce-stepper input::-webkit-inner-spin-button { margin: 0; -webkit-appearance: none; }
.ce-stepper button { flex: none; width: var(--control-height); padding: 0; }
.ce-stepper-prefix { flex: none; color: var(--text-tertiary); font-weight: 700; }
.ce-row-between { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); }
.ce-tappable-row { cursor: pointer; }
.ce-tappable-row:focus-visible { outline: 3px solid var(--brand-accent); outline-offset: 2px; }
.ce-hero-stat-link { display: inline-flex; align-items: center; gap: var(--space-2); padding: 0; color: inherit; border: 0; background: transparent; font: inherit; font-weight: 700; cursor: pointer; }
.ce-hero-stat-link:hover, .ce-hero-stat-link:focus-visible { text-decoration: underline; }
.ce-combo-wrap { position: relative; }
.ce-combo-dropdown { position: absolute; z-index: 20; top: 100%; right: 0; left: 0; display: grid; margin-top: 4px; max-height: 132px; overflow-y: auto; border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-card); box-shadow: var(--shadow-overlay); }
.ce-combo-dropdown[hidden] { display: none; }
.ce-combo-option { width: 100%; padding: var(--space-2) var(--space-3); color: var(--text-primary); border: 0; background: transparent; text-align: left; font: inherit; }
.ce-combo-option:hover, .ce-combo-option:focus-visible { background: var(--surface-section); }
.ce-combo-status { padding: var(--space-2) var(--space-3); font-size: var(--text-small); }
.ce-combo-status-new { color: var(--status-success); font-weight: 700; }
.ce-sticky-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-1) var(--space-2); padding-bottom: var(--space-2); border-bottom: 1px solid var(--border-default); }
.ce-sticky-stats .ce-stat-label { overflow: hidden; font-size: 9px; text-overflow: ellipsis; white-space: nowrap; }
.ce-sticky-stats .ce-stat-value { overflow: hidden; font-size: var(--text-small); text-overflow: ellipsis; white-space: nowrap; }
.ce-sticky-stats .ce-stat-tagihan .ce-stat-value { font-size: var(--text-body); font-weight: 800; }
.ce-times { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); padding: var(--space-3); text-align: center; border-radius: var(--radius-control); background: var(--surface-section); }
.ce-times small { display: block; color: var(--text-tertiary); font-size: var(--text-caption); font-weight: 800; letter-spacing: .06em; }
.ce-times strong { font-size: var(--heading-card); }
.ce-quick { display: flex; gap: var(--space-2); }
.ce-quick-item { display: flex; flex: 1; align-items: center; justify-content: center; gap: var(--space-2); min-width: 0; height: var(--control-height); color: var(--brand-primary); border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-card); font-size: var(--text-small); font-weight: 700; }
.ce-quick-item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ce-quick-item:hover { background: var(--brand-primary-soft); }
.ce-summary-order { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); width: 100%; padding: var(--space-2) var(--space-3); border: 0; border-radius: var(--radius-control); background: var(--surface-section); color: inherit; font: inherit; text-align: left; }
.ce-summary-order span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-small); }
.ce-summary-divider { height: 1px; background: var(--border-default); }
.ce-camera-frame { display: grid; place-items: center; width: 100%; max-width: 320px; justify-self: center; align-self: start; aspect-ratio: 9 / 16; overflow: hidden; border-radius: var(--radius-control); background: var(--surface-inverse); }
.ce-camera { width: 100%; height: 100%; object-fit: cover; transform: scaleX(-1); }
img.ce-camera { transform: none; }
.ce-location { display: flex; align-items: flex-start; gap: var(--space-2); margin: 0; color: var(--text-secondary); font-size: var(--text-small); }
.ce-thumb { flex: 0 0 96px; }
.ce-btn small { display: block; font-weight: 500; }

.ce-hero small, .ce-btn small { color: inherit; }
.ce-btn-primary small { opacity: .9; }

.ce-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ce-filter-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-3); }
.ce-list-item .ce-kv { margin-top: var(--space-2); }

/* Driver bottom navigation with centre action, order screens */
.ce-bottom-nav-driver { grid-template-columns: 1fr 1fr 84px 1fr 1fr; }
.ce-fab-slot { position: relative; display: grid; place-items: center; }
.ce-fab { position: absolute; top: -22px; display: grid; place-items: center; width: 58px; height: 58px; color: var(--brand-on-primary); border: 4px solid var(--surface-card); border-radius: 50%; background: var(--brand-primary); box-shadow: var(--shadow-overlay); }
.ce-fab:hover, .ce-fab.is-active { background: var(--brand-primary-hover); }
.ce-fab:focus-visible { outline: 3px solid var(--brand-accent); outline-offset: 2px; }
.ce-money { font-size: var(--heading-card); letter-spacing: -.02em; }
.ce-order-card .ce-row-between { align-items: flex-start; }
.ce-two { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
.ce-checks { display: grid; gap: var(--space-2); }
.ce-check { display: flex; align-items: center; gap: var(--space-3); min-height: var(--control-height); padding: 0 var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-control); font-weight: 600; }
.ce-check input { width: 20px; min-height: 20px; margin: 0; accent-color: var(--brand-primary); }
.ce-quote { display: grid; gap: var(--space-2); }
.ce-quote-line, .ce-quote-total { display: flex; justify-content: space-between; gap: var(--space-3); }
.ce-quote-total { padding-top: var(--space-2); border-top: 1px solid var(--border-default); font-size: var(--heading-card); }
.ce-quote-error { display: flex; align-items: flex-start; gap: var(--space-2); color: var(--status-danger); font-weight: 600; }
.ce-success { display: grid; justify-items: center; gap: var(--space-2); padding: var(--space-4); color: var(--status-success); text-align: center; }
.ce-share { display: grid; gap: var(--space-3); }
.ce-link { display: block; padding: var(--space-3); overflow-wrap: anywhere; white-space: pre-wrap; border: 1px dashed var(--border-strong); border-radius: var(--radius-control); background: var(--brand-primary-soft); font-size: var(--text-small); }
.ce-steps { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
.ce-step { position: relative; display: flex; gap: var(--space-3); padding-bottom: var(--space-4); }
.ce-step:last-child { padding-bottom: 0; }
.ce-step::before { position: absolute; top: 20px; bottom: 0; left: 9px; width: 2px; content: ''; background: var(--border-default); }
.ce-step:last-child::before { display: none; }
.ce-step-dot { display: grid; flex: none; place-items: center; width: 20px; height: 20px; color: var(--brand-on-primary); border: 2px solid var(--border-default); border-radius: 50%; background: var(--surface-card); }
.ce-step.is-done .ce-step-dot { border-color: var(--status-success); background: var(--status-success); }
.ce-step.is-done::before { background: var(--status-success); }
.ce-step.is-current .ce-step-dot { border-color: var(--brand-primary); box-shadow: 0 0 0 4px var(--brand-primary-soft); }
.ce-step.is-idle { color: var(--text-tertiary); }
.ce-step small { display: block; color: var(--text-secondary); }
.ce-has-sticky { padding-bottom: 96px; }
.ce-sticky-action { position: fixed; z-index: calc(var(--layer-sticky) + 1); right: 0; bottom: calc(var(--bottom-nav-height) + env(safe-area-inset-bottom)); left: 0; display: grid; gap: var(--space-2); max-width: 480px; margin: 0 auto; padding: var(--space-3) var(--space-4); border-top: 1px solid var(--border-default); border-radius: var(--radius-container) var(--radius-container) 0 0; background: var(--surface-card); box-shadow: var(--shadow-overlay); }
.ce-sticky-action-row { display: grid; grid-template-columns: 1fr 3fr; gap: var(--space-2); align-items: stretch; }
.ce-sticky-action-row > .ce-btn { height: 100%; }
/* The order form keeps its last buttons clear of the sticky totals bar (poin 4, 6 Okt 2026). 150px left only a
   ~4px margin against the real measured sticky-bar height (133.6px) — any small growth (a wrapped stats label,
   an extra stop) would overlap "Tambah tempat" (audit, 12 Okt 2026); 190px keeps a real safety margin. */
.ce-order-form { padding-bottom: 190px; }
/* A page that hides the bottom nav (order detail) needs its sticky bar to sit at the true bottom instead of
 * leaving the space the (now invisible) nav would have occupied. */
.ce-shell-driver.is-nav-hidden .ce-sticky-action { bottom: env(safe-area-inset-bottom); }
.ce-shell-driver.is-nav-hidden .ce-driver-content { padding-bottom: var(--space-6); }
/* Cart/checkout/merchant/service-order screens never show the bottom nav (Owner decision, 4 Okt 2026 added one only
 * to the four top-level tabs: Beranda, Kategori, Pesanan, Profil), so their sticky cart bar always sits at the true bottom. */
.ce-marketplace .ce-sticky-action { bottom: env(safe-area-inset-bottom); }
.ce-marketplace.ce-has-bottom-nav { padding-bottom: calc(var(--bottom-nav-height) + var(--space-6)); }
/* Owner decision, 4 Okt 2026: the partner-registration footer reads as secondary — muted text, soft-outlined
 * pills (not solid full-width buttons) so it never competes visually with the shopping CTAs above it. */
.ce-marketplace-footer { padding-top: var(--space-4); border-top: 1px solid var(--border-default); text-align: center; }
.ce-link-pill-row { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2); }
.ce-link-pill { padding: var(--space-2) var(--space-4); border: 1px solid var(--border-default); border-radius: var(--radius-pill); color: var(--text-secondary); font-size: var(--text-small); font-weight: 700; text-decoration: none; }
.ce-link-pill:hover { border-color: var(--brand-primary); color: var(--brand-primary); }
/* Paid banner ads (Owner decision, 27 Sep 2026): a horizontal-scroll strip, hidden entirely when there are none. */
.ce-banner-strip { display: flex; gap: var(--space-2); overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: var(--space-1); }
.ce-banner-item { flex: 0 0 auto; scroll-snap-align: start; width: min(280px, 80vw); padding: 0; border: none; border-radius: var(--radius-card); overflow: hidden; background: var(--surface-section); cursor: pointer; }
.ce-banner-item img { display: block; width: 100%; height: 120px; object-fit: cover; }
.ce-banner-carousel { display: grid; gap: var(--space-2); }
.ce-banner-dots { display: flex; justify-content: center; gap: 6px; }
.ce-banner-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--border-default); }
.ce-banner-dot.is-on { background: var(--brand-primary); }

/* Beranda service grid (Owner decision, 27 Sep 2026: all Cak Ed services in one grid, ala Gojek). */
.ce-service-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-3); padding: var(--space-2) 0; }
.ce-service-tile { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); border: none; background: none; padding: 0; font: inherit; color: var(--text-primary); cursor: pointer; }
.ce-service-icon { width: 48px; height: 48px; border-radius: var(--radius-card); display: grid; place-items: center; background: var(--brand-primary-soft); color: var(--brand-primary); }
.ce-service-icon[data-service="food"] { background: #fdecd8; color: #b5651d; }
.ce-service-icon[data-service="bike"] { background: #e1f2e7; color: #2f7a4f; }
.ce-service-icon[data-service="send"] { background: var(--brand-primary-soft); color: var(--brand-primary); }
.ce-service-icon[data-service="shop"] { background: #fdf6da; color: #96751a; }
.ce-service-icon[data-service="car"] { background: #e6eef2; color: #4a6a76; }
.ce-service-tile span:last-child { font-size: var(--text-small); font-weight: 600; text-align: center; }

.ce-rating-badge { color: var(--text-secondary); }

/* Horizontal-scroll teaser row (Resto Top Rating on Beranda). */
.ce-list-row { display: flex; gap: var(--space-3); overflow-x: auto; padding-bottom: var(--space-1); }
/* Resto Top Rating thumbnail: shows the merchant's logo when uploaded, initials otherwise. */
.ce-card-row { flex: 0 0 168px; display: flex; flex-direction: column; gap: 4px; border: 1px solid var(--border-default); border-radius: var(--radius-card); padding: var(--space-2); }
.ce-card-row-thumb { width: 100%; height: 120px; border-radius: var(--radius-control); background: var(--surface-section); position: relative; overflow: hidden; display: grid; place-items: center; }
.ce-card-row-thumb-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ce-card-row-thumb-initials { font-weight: 700; font-size: var(--text-large); color: var(--brand-primary); }
.ce-store-logo { flex: none; width: 48px; height: 48px; border-radius: var(--radius-control); background: var(--surface-section); display: grid; place-items: center; overflow: hidden; }
.ce-store-logo-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ce-store-logo-initials { font-weight: 700; color: var(--brand-primary); }
.ce-btn-danger-solid { color: var(--brand-on-primary); border-color: transparent; background: var(--status-danger); }
.ce-btn-danger-solid:hover { background: var(--status-danger); opacity: .92; }
.ce-actions-row { flex-wrap: nowrap; }
.ce-actions-row > .ce-btn { flex: 1 1 0; min-width: 0; padding: 0 var(--space-2); }
a.ce-btn { text-decoration: none; }

/* Customer portal (public page, mobile first) */
.ce-portal-head { display: flex; justify-content: flex-start; padding: var(--space-4); background: var(--surface-card); border-bottom: 1px solid var(--border-default); }
.ce-portal { width: min(100%, 560px); margin: 0 auto; padding: var(--space-4) var(--space-4) var(--space-8); }
.ce-hero-fold { margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px solid rgb(255 255 255 / 22%); }
/* Beats the generic `.ce-fold > summary` (brand-purple text) at equal class specificity via the extra tag qualifier. */
details.ce-hero-fold > summary { color: var(--text-inverse); font-weight: 700; cursor: pointer; }
.ce-hero-fold dl { margin-top: var(--space-3); padding: var(--space-3); border-radius: var(--radius-control); background: rgb(255 255 255 / 12%); }
.ce-hero-fold dt { color: rgb(255 255 255 / 75%); }
.ce-hero-fold dd { color: var(--text-inverse); }
.ce-invoice-table { display: grid; gap: var(--space-3); }
.ce-invoice-rows { display: grid; border: 1px solid var(--border-default); border-radius: var(--radius-control); overflow: hidden; }
.ce-invoice-row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2) var(--space-3); padding: var(--space-2) var(--space-3); }
.ce-invoice-row:nth-child(even) { background: var(--surface-section); }
.ce-invoice-row + .ce-invoice-row { border-top: 1px solid var(--border-default); }
.ce-invoice-total-box { justify-self: end; display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--radius-control); background: var(--brand-primary-soft); }
.ce-invoice-total-box strong { font-size: var(--heading-card); color: var(--brand-primary); }
.ce-reward-promo { overflow: hidden; border-color: #51159b; background: #51159b; color: var(--text-inverse); }
.ce-reward-promo .ce-card-body, .ce-reward-promo .ce-muted, .ce-reward-promo .ce-hint { color: var(--text-inverse); }
.ce-reward-promo-head { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4); color: var(--text-inverse); }
.ce-reward-promo-head strong { display: block; font-size: var(--text-large); letter-spacing: .02em; text-transform: uppercase; }
.ce-reward-promo-head small { opacity: .9; }
.ce-reward-promo-star { color: #ffd23f; }
.ce-reward-promo .ce-progress { background: rgb(255 255 255 / 25%); }
.ce-reward-promo .ce-progress > span { background: #ffd23f; }
.ce-reward-promo .ce-btn-primary { color: #51159b; border-color: transparent; background: #ffd23f; }
.ce-reward-promo .ce-btn-primary:hover { background: #ffd23f; opacity: .92; }
.ce-stars { display: flex; gap: var(--space-1); }
.ce-star { display: grid; place-items: center; width: 48px; height: 48px; color: var(--text-tertiary); border: 0; border-radius: var(--radius-control); background: transparent; }
.ce-star.is-on { color: var(--brand-accent); }
.ce-star:focus-visible { outline: 3px solid var(--brand-accent); outline-offset: 2px; }
.ce-review { width: 100%; padding: var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-control); font: inherit; resize: vertical; }
/* align-content: start — CSS grid's default stretches rows into any leftover space in the container (visible once
   .ce-chat-list-full below sets a min-height), which swells individual bubbles instead of leaving empty space after
   the last one. */
.ce-chat-list { max-height: 320px; align-content: start; overflow-y: auto; }
.ce-chat-bubble { display: grid; gap: 2px; max-width: 80%; min-width: 0; padding: var(--space-2) var(--space-3); border-radius: var(--radius-control); }
.ce-chat-bubble p { margin: 0; overflow-wrap: anywhere; }
.ce-chat-bubble small { color: var(--text-tertiary); }
.ce-chat-bubble.is-theirs { justify-self: start; background: var(--surface-section); }
.ce-chat-bubble.is-mine { justify-self: end; background: var(--brand-primary-soft); }
.ce-chat-bubble-foot { display: flex; align-items: center; gap: 4px; }
.ce-msg-ticks { display: inline-flex; align-items: center; gap: 4px; color: var(--text-tertiary); }
.ce-msg-ticks.is-read { color: #51159b; }
.ce-msg-ticks small { color: inherit; }
.ce-chat-badge { position: relative; }
.ce-chat-badge.has-unread::after { content: attr(data-count); position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px; padding: 0 4px; display: grid; place-items: center; border-radius: 999px; background: var(--status-danger); color: #fff; font-size: 10px; font-weight: 800; line-height: 1; }
.ce-chat-suggestions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ce-chat-suggestions .ce-btn { flex: 0 0 auto; width: fit-content; }
/* Purchase per outlet: quantity, satuan, and total on one row (Owner, 6 Okt 2026). */
.ce-purchase-block { display: grid; gap: var(--space-2); padding-bottom: var(--space-3); border-bottom: 1px solid var(--border-default); }
.ce-purchase-block:last-child { border-bottom: 0; }
.ce-purchase-line { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.4fr); gap: var(--space-2); }
.ce-purchase-line .ce-field { min-width: 0; }
.ce-money-input { display: flex; align-items: center; gap: var(--space-1); min-width: 0; }
.ce-money-input input { flex: 1 1 auto; min-width: 0; }
.ce-purchase-line-read { display: flex; justify-content: space-between; gap: var(--space-2); }
.ce-purchase-outlet { overflow-wrap: anywhere; }
.ce-purchase-parking { margin-top: 4px; padding-top: var(--space-2); border-top: 1px dashed var(--border-default); }
/* Chat time: lighter so it does not compete with the message (Owner, 6 Okt 2026). */
.ce-msg-ticks small { opacity: 0.55; }
/* Progress card can be folded (Owner, 6 Okt 2026). */
.ce-fold > summary { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); cursor: pointer; list-style: none; }
.ce-fold > summary::-webkit-details-marker { display: none; }
.ce-fold-summary { display: flex; align-items: baseline; gap: var(--space-2); }
/* Order form: the back row stays at the top while scrolling (Owner, 6 Okt 2026). */
.ce-form-head { position: sticky; top: env(safe-area-inset-top, 0px); z-index: 6; padding-block: var(--space-2); background: var(--surface-page); }
/* The shutter inside the camera frame (Owner, 6 Okt 2026). */
.ce-camera-take { position: absolute; bottom: 12px; left: 50%; transform: translateX(-50%); background: #ffffff; color: #51159b; border-color: #ffffff; }
/* The share-location request is a full-width button, not a bare text link (Owner, 6 Okt 2026). */
.ce-chat-suggestions-end { justify-content: flex-end; }
/* Full-page chat (driver order detail, customer portal): the list fills the space between the header and the
 * sticky composer instead of being capped like the old inline-card version. */
.ce-chat-page { min-height: calc(100vh - 160px); padding-bottom: 96px; }
.ce-chat-page .ce-chat-list-full { max-height: none; min-height: 40vh; }
.ce-chat-composer { position: fixed; z-index: calc(var(--layer-sticky) + 1); right: 0; bottom: 0; left: 0; display: grid; gap: var(--space-2); max-width: 560px; margin: 0 auto; padding: var(--space-3) var(--space-4) calc(var(--space-3) + env(safe-area-inset-bottom)); border-top: 1px solid var(--border-default); background: var(--surface-card); box-shadow: var(--shadow-overlay); }

/* Driver balance and finance (M6) */
.ce-balance { justify-items: start; }
.ce-balance-value { font-size: 2.25rem; line-height: 1.1; letter-spacing: -.03em; }
.ce-balance-plain { display: block; margin-bottom: var(--space-3); color: var(--text-primary); }
.ce-amount-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ce-amount-chips .ce-btn { min-height: 36px; padding: 0 var(--space-3); font-size: var(--text-small); white-space: nowrap; }
.ce-amount-chips .ce-btn:hover, .ce-amount-chips .ce-btn:focus-visible, .ce-amount-chips .ce-btn[aria-pressed="true"] { color: var(--brand-on-primary); border-color: var(--brand-primary); background: var(--brand-primary); }
.ce-qris { display: grid; justify-items: center; gap: var(--space-2); padding: var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-container); background: var(--surface-card); text-align: center; }
.ce-qris[hidden] { display: none; }
.ce-qris-image { width: min(240px, 100%); height: auto; border-radius: var(--radius-control); }
.ce-ledger-row { align-items: center; }
.ce-ledger-amount { display: grid; gap: 4px; justify-items: end; text-align: right; }
/* One thin line per mutation (Owner decision, 4 Okt 2026), instead of the taller ce-ledger-row card. */
.ce-ledger-line { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--border-default); font-size: var(--text-small); }
.ce-ledger-line:last-child { border-bottom: none; }
.ce-money-in { color: var(--status-success); }
.ce-money-out { color: var(--status-danger); }
.ce-wallet-strip { display: flex; align-items: center; gap: var(--space-3); width: 100%; padding: var(--space-3) var(--space-4); color: var(--text-primary); text-align: left; border: 1px solid var(--border-default); border-radius: var(--radius-container); background: var(--surface-card); font: inherit; }
.ce-wallet-info { display: grid; flex: 1; min-width: 0; }
.ce-wallet-strip small { color: var(--text-tertiary); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.ce-wallet-strip.is-low { border-color: var(--status-warning); }

/* Admin dashboard, comparisons, branding (M7+) */
.ce-queue-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--space-3); }
.ce-queue { display: grid; justify-items: start; gap: var(--space-1); padding: var(--space-3); color: var(--text-primary); text-align: left; border: 1px solid var(--border-default); border-radius: var(--radius-container); background: var(--surface-card); font: inherit; }
.ce-queue strong { font-size: var(--heading-card); }
.ce-queue span { color: var(--text-secondary); font-size: var(--text-small); }
.ce-queue.is-pending { border-color: var(--status-warning); background: var(--status-warning-soft); }
.ce-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: var(--space-4); }
.ce-trend-row { display: grid; grid-template-columns: 64px 1fr auto; align-items: center; gap: var(--space-3); font-size: var(--text-small); }
.ce-compare { display: grid; gap: var(--space-1); padding: var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-control); overflow-wrap: anywhere; }
.ce-compare small { color: var(--text-tertiary); text-decoration: line-through; }
.ce-compare span { color: var(--status-success); font-weight: 700; }
.ce-brand-logo { width: 40px; height: 40px; object-fit: contain; border-radius: var(--radius-control); }
.ce-portal-footer { margin-top: var(--space-4); text-align: center; }

/* Offline banner (PWA) */
.ce-offline { position: fixed; inset: 0 0 auto 0; z-index: 60; padding: var(--space-2) var(--space-4); color: var(--text-inverse); text-align: center; background: var(--surface-inverse); font-size: var(--text-small); font-weight: 700; }
.ce-offline-queue { position: fixed; right: var(--space-3); bottom: calc(var(--space-3) + 64px); z-index: 60; padding: var(--space-2) var(--space-3); border: none; border-radius: var(--radius-pill); background: var(--status-info); color: var(--text-inverse); font-size: var(--text-small); font-weight: 700; box-shadow: var(--shadow-overlay); }
.ce-offline-queue.is-conflict { background: var(--status-danger); }

/* Type scale: <small> would otherwise fall back to the browser's 11px, below the caption token. */
small { font-size: var(--text-small); }

/* Bulk import */
.ce-visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.ce-import-card { align-items: center; }
.ce-import-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ce-import-summary { margin: 0; font-weight: 700; }
.ce-import-error { color: var(--status-danger); }
.ce-inline-notice-danger { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); color: var(--status-danger); background: var(--status-danger-soft); }
.ce-dialog-wide { width: min(94vw, 760px); }
@media (max-width: 767px) { .ce-import-actions { width: 100%; } .ce-import-actions .ce-btn { flex: 1 1 140px; } }

/* Operations: Live Tracking and Dashboard Operasional */
.ce-filters { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--space-4); }
.ce-split { display: grid; grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); gap: var(--space-4); align-items: start; }
.ce-split-even { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--space-4); align-items: start; }
.ce-inline-notice-warning { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); color: var(--status-warning); background: var(--status-warning-soft); }
a.ce-btn { text-decoration: none; }
.ce-map { display: block; width: 100%; height: auto; border-radius: var(--radius-control); }
.ce-map-bg { fill: var(--brand-primary-soft); }
.ce-map-ring { fill: none; stroke: var(--border-default); stroke-width: 1.5; stroke-dasharray: 4 4; }
.ce-map-fence { fill: none; stroke: var(--brand-primary); stroke-width: 2; stroke-dasharray: 8 5; opacity: .7; }
.ce-map-center { fill: var(--brand-primary); }
.ce-map-label { fill: var(--text-secondary); font-size: 11px; font-weight: 700; }
.ce-chart { display: block; width: 100%; height: auto; }
.ce-chart-axis { stroke: var(--border-default); stroke-width: 1; }
.ce-chart-bar { fill: var(--brand-primary); }
.ce-chart-bar.is-negative { fill: var(--status-danger); }
.ce-chart-label { fill: var(--text-secondary); font-size: 10px; }
.ce-map-empty { fill: var(--text-secondary); font-size: 14px; font-weight: 700; text-anchor: middle; }
.ce-pin circle { stroke: var(--surface-card); stroke-width: 3; }
.ce-pin text { fill: var(--brand-on-primary); font-size: 12px; font-weight: 800; text-anchor: middle; pointer-events: none; }
.ce-pin-stay circle { fill: var(--status-success); }
.ce-pin-progress circle { fill: var(--status-info); }
.ce-pin-break circle { fill: var(--status-warning); }
.ce-pin.is-stale { opacity: .45; }
.ce-queue-list { display: grid; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
.ce-queue-list li { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); padding: var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-card); }
.ce-queue-list li.is-first { border-color: var(--brand-primary); background: var(--brand-primary-soft); }
.ce-queue-no { display: grid; place-items: center; flex: none; width: 32px; height: 32px; border-radius: var(--radius-pill); background: var(--surface-section); font-weight: 800; }
.is-first .ce-queue-no { color: var(--brand-on-primary); background: var(--brand-primary); }
.ce-queue-list li.is-blocked { border-color: var(--status-danger); background: var(--status-danger-soft); color: var(--status-danger); }
.is-blocked .ce-queue-no { color: var(--status-danger); background: transparent; border: 1px solid var(--status-danger); }
.ce-queue-who { display: grid; flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.ce-queue-who span { color: var(--text-secondary); font-size: var(--text-small); }
@media (max-width: 1023px) { .ce-split { grid-template-columns: minmax(0, 1fr); } }

.ce-livemap-canvas { position: relative; width: 100%; height: 380px; overflow: hidden; border-radius: var(--radius-control); background: var(--brand-primary-soft); }
.ce-livemap-canvas[hidden] { display: none; }
.ce-map-pin { display: grid; place-items: center; width: 34px; height: 34px; padding: 0; color: var(--brand-on-primary); border: 3px solid var(--surface-card); border-radius: var(--radius-pill); font: inherit; font-size: var(--text-small); font-weight: 800; cursor: pointer; box-shadow: var(--shadow-overlay); }
.ce-map-pin-stay { background: var(--status-success); }
.ce-map-pin-progress { background: var(--status-info); }
.ce-map-pin-break { background: var(--status-warning); }
.ce-map-pin.is-stale { opacity: .5; }
.ce-map-pin:focus-visible { outline: 3px solid var(--brand-accent); outline-offset: 2px; }
.ce-map-popup { display: grid; gap: var(--space-1); font-size: var(--text-small); }
.ce-map-popup a { color: var(--brand-primary); font-weight: 700; }
@media (max-width: 767px) { .ce-livemap-canvas { height: 300px; } }

/* Folded sections */
.ce-fold > summary { display: flex; align-items: center; min-height: var(--control-height); color: var(--brand-primary); font-size: var(--text-small); font-weight: 700; cursor: pointer; }
.ce-fold > summary:focus-visible { outline: 3px solid var(--brand-accent); outline-offset: 2px; }
.ce-fold-card { padding: 0 var(--space-4); border: 1px solid var(--border-default); border-radius: var(--radius-card); background: var(--surface-card); }
.ce-fold-card[open] { padding-bottom: var(--space-4); }

/* Phones: denser, shorter pages. Touch targets stay at 44px. */
@media (max-width: 767px) {
  .ce-stack { gap: var(--space-3); }
  .ce-page-title { font-size: 1.25rem; }
  .ce-card-head { padding: var(--space-3) var(--space-3) 0; }
  .ce-card-head h3 { font-size: var(--text-large); }
  .ce-card-body { gap: var(--space-2); padding: var(--space-3); }
  .ce-list { gap: 6px; }
  .ce-list-item { align-items: center; gap: 6px var(--space-2); padding: 10px var(--space-3); }
  .ce-list-item > div { flex: 1 1 150px; gap: 2px; }
  .ce-list-item strong { font-size: var(--text-body); line-height: 1.3; }
  .ce-list-item small { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-height: 1.35; }
  .ce-list-item .ce-actions, .ce-list-item .ce-badges { flex-wrap: nowrap; gap: 6px; }
  .ce-list-item .ce-actions { width: 100%; }
  .ce-list-item .ce-actions > .ce-btn { flex: 1 1 0; min-width: 0; padding: 0 var(--space-2); }
  .ce-badges { gap: 4px; }
  .ce-stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
  .ce-stat-value { font-size: var(--text-large); }
  .ce-queue-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); }
  .ce-queue { padding: var(--space-2); }
  .ce-tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .ce-tabs::-webkit-scrollbar { display: none; }
  .ce-tab { flex: 0 0 auto; white-space: nowrap; }
  .ce-filter-row, .ce-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
  .ce-inline-notice { padding: var(--space-2) var(--space-3); }
}

/* Admin: the sidebar stays 248px wide down to 767px, so tablets and small laptops (768-1279px) need the same compacting phones already get below 768px, not just phones. */
@media (min-width: 768px) and (max-width: 1279px) {
  .ce-list-item .ce-actions { flex-wrap: nowrap; }
  .ce-list-item .ce-actions > .ce-btn { flex: 0 0 auto; }
  .ce-filter-row { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
  .ce-filters { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
}

/* Owner decision, 4 Okt 2026: on a genuinely wide desktop screen, filter fields and the solo search field stop
 * stretching to fill the whole row — each keeps a comfortable fixed width, left-aligned, instead of spreading
 * out to the page's full content width. */
@media (min-width: 1280px) {
  .ce-filter-row { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 280px); justify-content: start; }
}

.ce-import-item { border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-card); }
.ce-import-item > summary { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); min-height: var(--control-height); padding: var(--space-2) var(--space-3); cursor: pointer; list-style: none; }
.ce-import-item > summary::-webkit-details-marker { display: none; }
.ce-import-item > summary:focus-visible { outline: 3px solid var(--brand-accent); outline-offset: -3px; border-radius: var(--radius-control); }
.ce-import-item > summary strong { flex: 1 1 200px; min-width: 0; overflow-wrap: anywhere; }
.ce-import-body { display: grid; gap: var(--space-2); padding: 0 var(--space-3) var(--space-3); }
.ce-import-body p { margin: 0; font-size: var(--text-small); }
.ce-map-pin { position: relative; }
.ce-map-pin::after { position: absolute; inset: -6px; content: ''; }

/* ---- Order form revision, 28 Sep 2026 ------------------------------------------------------------ */
.ce-hint-warning { color: var(--status-warning); font-weight: 600; }
.ce-combo-detail { display: block; color: var(--text-secondary); font-size: var(--text-caption); }
.ce-stop { display: grid; gap: var(--space-3); padding: var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-container); background: var(--surface-section); }
.ce-stop-title { font-size: var(--text-small); }
.ce-purchase-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); align-items: start; gap: var(--space-3); padding-bottom: var(--space-3); border-bottom: 1px solid var(--border-default); }
.ce-purchase-total { padding-top: var(--space-2); font-size: var(--text-body); }
.ce-three { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); }
.ce-tabs-six, .ce-tabs.ce-tabs-six { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); overflow: visible; }
.ce-tabs-six .ce-tab { padding-inline: 2px; text-align: center; font-size: var(--text-caption); white-space: nowrap; }
.ce-switch-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); justify-items: center; justify-content: center; max-width: 420px; margin-inline: auto; row-gap: var(--space-4); column-gap: var(--space-4); }
.ce-switch-grid .ce-switch-item { min-width: 0; width: 100%; }

/* ---- Horizontal overflow guard (Owner request, 28 Sep 2026) ------------------------------------------
 * Grid and flex children default to min-width:auto, so one long unbroken line (an address, an order code) stretched
 * the whole card wider than the screen. Letting them shrink, and wrapping long words, keeps every page inside the viewport. */
.ce-stack, .ce-card, .ce-card-body, .ce-list, .ce-list-item, .ce-kv, .ce-hero, .ce-fold, .ce-field, .ce-form, .ce-summary-order { min-width: 0; }
.ce-stack > *, .ce-card-body > *, .ce-form > * { min-width: 0; }
.ce-summary-order > span:first-child { flex: 1 1 0; min-width: 0; }
.ce-summary-order > .ce-badge { flex: none; }
.ce-list-item > div:first-child, .ce-kv dd, .ce-kv dt { min-width: 0; overflow-wrap: anywhere; }
.ce-card h3, .ce-hero-name, .ce-page-title { overflow-wrap: anywhere; }
.ce-form .ce-tabs:not(.ce-tabs-six) { flex-wrap: wrap; overflow: visible; }
.ce-form .ce-tabs:not(.ce-tabs-six) .ce-tab { flex: 1 1 auto; white-space: normal; }
.ce-list-item.ce-tappable-row { text-align: left; }
.ce-summary-order > span:first-child { white-space: normal; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ce-inline-notice-warning > span, .ce-inline-notice-danger > span { flex: 1 1 200px; }

/* ---- Admin shell and dashboard, Opsi A "Lembut" + live operations (Owner choice, 28 Sep 2026) ------------- */
.ce-admin-top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); min-height: 44px; }
.ce-user-chip { display: inline-flex; align-items: center; gap: var(--space-3); margin-left: auto; padding: 4px 14px 4px 4px; border: 0; border-radius: var(--radius-pill); background: var(--surface-lavender-soft); color: var(--text-primary); font: inherit; cursor: pointer; }
.ce-user-chip:hover { background: var(--tint-purple); }
.ce-user-avatar { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--brand-hero); color: var(--brand-on-primary); font-size: var(--text-small); font-weight: 700; }
.ce-user-text { display: grid; text-align: left; line-height: 1.2; }
.ce-user-text strong { font-size: var(--text-small); }
.ce-user-text small { color: var(--text-secondary); font-size: var(--text-caption); }
@media (min-width: 768px) {
  .ce-shell-admin { padding: 16px; gap: 0; background: var(--surface-lavender); }
  .ce-shell-admin .ce-sidebar { top: 16px; height: calc(100vh - 32px); border: 0; border-radius: 28px 0 0 28px; background: var(--surface-lavender-soft); box-shadow: 0 10px 40px rgb(81 21 155 / 8%); }
  .ce-shell-admin .ce-admin-content { min-height: calc(100vh - 32px); border-radius: 0 28px 28px 0; background: var(--surface-card); box-shadow: 0 10px 40px rgb(81 21 155 / 8%); padding: var(--space-5) var(--space-6) var(--space-6); }
  .ce-sidebar-item { min-height: 44px; border-radius: 14px; }
  .ce-sidebar-item.is-active { background: var(--surface-card); color: var(--brand-hero); box-shadow: 0 4px 14px rgb(81 21 155 / 12%); }
  .ce-sidebar-item:hover:not(.is-active) { background: var(--tint-purple); }
}
@media (max-width: 767px) { .ce-user-text { display: none; } .ce-user-chip { padding: 0; background: transparent; } .ce-admin-top { justify-content: flex-end; } }

.ce-dash-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-3); }
.ce-dash-head p { margin: 2px 0 0; }
.ce-kpi-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4); }
/* Owner decision, 4 Okt 2026: one neutral card style for every KPI tile (was 4 pastel tints) — a minimalist grid
 * instead of a colorful one. The `tone` parameter still exists in admin-kpi.ts but no longer changes appearance;
 * status elsewhere (order state, etc.) keeps using color + icon + label as before, unaffected by this. */
.ce-kpi { display: flex; align-items: center; gap: var(--space-4); width: 100%; padding: var(--space-4); border: 1px solid var(--border-default); border-radius: 22px; background: var(--surface-card); color: var(--text-primary); font: inherit; text-align: left; }
button.ce-kpi { cursor: pointer; transition: transform var(--motion-fast); }
button.ce-kpi:hover { transform: translateY(-2px); }
.ce-kpi-icon { display: grid; place-items: center; flex: none; width: 56px; height: 56px; border-radius: 18px; background: var(--surface-section); color: var(--brand-primary); }
.ce-kpi-text { display: grid; min-width: 0; }
.ce-kpi-label { color: var(--text-secondary); font-size: var(--text-small); }
/* overflow-wrap/word-break here (not just in the ≤767px block below): Intl.NumberFormat joins "Rp" to the digits
   with a non-breaking space, so a big rupiah value is one unbreakable run — at the 768-1279px 2-column grid
   (max-width:1279px rule below) it was spilling past the card edge exactly like the mobile case this was first
   fixed for (Owner, 12 Okt 2026), just never guarded at this width. */
.ce-kpi-value { width: 100%; font-size: 30px; line-height: 36px; letter-spacing: -.02em; overflow-wrap: anywhere; word-break: break-word; }
.ce-kpi-text small { color: var(--text-secondary); font-size: var(--text-caption); }

.ce-dash-live { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: var(--space-4); align-items: start; }
.ce-progress-head { display: grid; gap: var(--space-2); }
.ce-progress-value { display: block; font-size: 40px; line-height: 44px; letter-spacing: -.02em; }
.ce-progress-bar { display: block; height: 8px; overflow: hidden; border-radius: var(--radius-pill); background: var(--tint-purple); }
.ce-progress-fill { display: block; height: 100%; border-radius: inherit; background: var(--brand-hero); transition: width var(--motion-fast); }
.ce-mini-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
.ce-mini { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); border: 1px solid var(--border-default); border-radius: 16px; }
.ce-mini > span:last-child { display: grid; line-height: 1.2; }
.ce-mini small { color: var(--text-secondary); font-size: var(--text-caption); }
.ce-mini strong { font-size: 20px; }
.ce-mini-icon { display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 12px; }
.ce-mini-mint { background: var(--tint-mint); color: var(--ink-mint); }
.ce-mini-purple { background: var(--tint-purple); color: var(--brand-hero); }
.ce-mini-red { background: var(--tint-red); color: var(--ink-red); }
.ce-dash-map { height: 300px; }
.ce-dash-plot[hidden] { display: none; }
.ce-alert-list { display: grid; gap: var(--space-2); }
.ce-alert { display: flex; align-items: center; gap: var(--space-3); width: 100%; padding: var(--space-3); border: 0; border-radius: 14px; color: var(--text-primary); font: inherit; text-align: left; }
button.ce-alert { cursor: pointer; }
button.ce-alert:hover { filter: brightness(.97); }
.ce-alert-icon { display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 12px; background: var(--surface-card); }
.ce-alert-text { display: grid; min-width: 0; line-height: 1.3; }
.ce-alert-text small { color: var(--text-secondary); font-size: var(--text-caption); }
.ce-alert-warning { background: var(--tint-orange); } .ce-alert-warning .ce-alert-icon { color: var(--ink-orange); }
.ce-alert-danger { background: var(--tint-red); } .ce-alert-danger .ce-alert-icon { color: var(--ink-red); }
.ce-alert-info { background: var(--tint-purple); } .ce-alert-info .ce-alert-icon { color: var(--brand-hero); }
.ce-alert-success { background: var(--tint-mint); } .ce-alert-success .ce-alert-icon { color: var(--ink-mint); }

.ce-dash-two { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: var(--space-4); align-items: start; }
.ce-dash-three { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); align-items: start; }
.ce-pills { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ce-pill { min-height: 32px; padding: 0 14px; border: 0; border-radius: var(--radius-pill); background: var(--surface-lavender-soft); color: var(--brand-hero); font: inherit; font-size: var(--text-small); font-weight: 600; cursor: pointer; }
.ce-pill[aria-pressed="true"] { background: var(--brand-hero); color: var(--brand-on-primary); }
.ce-dash-orders { display: grid; gap: var(--space-2); }
.ce-dash-order { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, .7fr) auto auto; align-items: center; gap: var(--space-3); width: 100%; padding: var(--space-3); border: 0; border-radius: 14px; background: var(--surface-lavender-soft); color: var(--text-primary); font: inherit; text-align: left; cursor: pointer; }
.ce-dash-order:hover { background: var(--tint-purple); }
.ce-dash-order-main { display: grid; min-width: 0; }
.ce-dash-order-main small { overflow: hidden; color: var(--text-secondary); text-overflow: ellipsis; white-space: nowrap; }
.ce-dash-order-service { color: var(--text-secondary); font-size: var(--text-small); }
.ce-dash-order-total { min-width: 88px; text-align: right; font-size: var(--text-small); }

.ce-chart { display: block; width: 100%; height: auto; }
.ce-chart-grid { stroke: var(--tint-purple); }
.ce-chart-area { fill: var(--brand-hero); fill-opacity: .1; }
.ce-chart-line { fill: none; stroke: var(--brand-hero); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.ce-chart-dot { fill: var(--surface-card); stroke: var(--brand-hero); stroke-width: 3; }
.ce-chart-dot.is-last { fill: var(--brand-hero); stroke: var(--surface-card); }
.ce-chart-label { fill: var(--text-secondary); font-size: 11px; }
.ce-chart-value { fill: var(--brand-hero); font-size: 12px; font-weight: 700; }
.ce-chart-bar.is-peak { fill: var(--brand-hero); }
.ce-donut-wrap { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.ce-donut { flex: none; width: 132px; height: 132px; }
.ce-donut-total { fill: var(--text-primary); font-size: 22px; font-weight: 700; }
.ce-donut-caption { fill: var(--text-secondary); font-size: 11px; }
.ce-legend { display: grid; flex: 1 1 120px; gap: var(--space-2); font-size: var(--text-small); }
.ce-legend-row { display: flex; align-items: center; gap: var(--space-2); }
.ce-legend-row span:nth-child(2) { flex: 1; }
.ce-legend-dot { width: 10px; height: 10px; border-radius: 50%; background: #51159b; }
.ce-legend-dot[data-color="1"] { background: #eb9436; }
.ce-legend-dot[data-color="2"] { background: #b2dcc3; }
.ce-legend-dot[data-color="3"] { background: #f6c62d; }
.ce-legend-dot[data-color="4"] { background: #7b999a; }
.ce-capacity { display: flex; align-items: baseline; gap: var(--space-2); }
.ce-capacity strong { font-size: 44px; line-height: 48px; letter-spacing: -.02em; }
.ce-capacity span { color: var(--text-secondary); font-size: var(--text-small); }
.ce-state-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); }
.ce-state { display: grid; padding: var(--space-3); border-radius: 14px; }
.ce-state small { color: var(--text-secondary); font-size: var(--text-caption); }
.ce-state strong { font-size: 20px; }
.ce-state-mint { background: var(--tint-mint); } .ce-state-mint strong { color: var(--ink-mint); }
.ce-state-purple { background: var(--tint-purple); } .ce-state-purple strong { color: var(--brand-hero); }
.ce-state-orange { background: var(--tint-orange); } .ce-state-orange strong { color: var(--ink-orange); }
@media (max-width: 1279px) { .ce-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .ce-dash-live, .ce-dash-two { grid-template-columns: minmax(0, 1fr); } .ce-dash-three { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px) {
  .ce-dash-three { grid-template-columns: minmax(0, 1fr); }
  /* Owner, 12 Okt 2026: 3 across instead of 2 — 6 cards reads as two full rows (3+3) and 5 as 3+2, instead of an
     uneven trailing row; CSS grid auto-flow does this on its own once the column count is 3. */
  .ce-kpi-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-2); }
  .ce-kpi { flex-direction: column; align-items: flex-start; gap: var(--space-2); padding: var(--space-3) var(--space-2); border-radius: 16px; width: 100%; min-width: 0; }
  .ce-kpi-icon { width: 36px; height: 36px; border-radius: 12px; }
  /* Intl.NumberFormat('id-ID', {currency:'IDR'}) joins "Rp" to the digits with a non-breaking space, so a big
     rupiah value is one unbreakable run of characters — at 3 cards across that run is wider than the card itself
     unless it's allowed to break mid-string (Owner, 12 Okt 2026: values were spilling past the card edge). */
  .ce-kpi-value { width: 100%; font-size: 18px; line-height: 22px; overflow-wrap: anywhere; word-break: break-word; }
  .ce-kpi-label { width: 100%; font-size: var(--text-caption); overflow-wrap: anywhere; }
  .ce-kpi-text small { display: none; }
  .ce-mini { padding: var(--space-2); gap: var(--space-2); }
  .ce-mini-icon { display: none; }
  .ce-dash-order { grid-template-columns: minmax(0, 1fr) auto; }
  .ce-dash-order-service { display: none; }
  .ce-dash-order-total { grid-column: 2; }
  .ce-mini-grid { gap: var(--space-2); }
}
.ce-mini > span:last-child, .ce-kpi-text { min-width: 0; }

/* ---- Admin top bar tools: search, order manual, bell (Owner request, 28 Sep 2026) --------------------------- */
.ce-admin-top { gap: var(--space-3); }
.ce-admin-top .ce-breadcrumb { flex: 0 1 auto; min-width: 0; }
.ce-topbar-tools { display: flex; flex: 1 1 auto; align-items: center; justify-content: flex-end; gap: var(--space-2); min-width: 0; }
.ce-user-chip { margin-left: 0; flex: none; }
.ce-search { position: relative; display: flex; flex: 1 1 280px; align-items: center; gap: var(--space-2); max-width: 460px; min-width: 0; height: 44px; box-sizing: border-box; padding: 0 14px; border-radius: 16px; background: var(--surface-lavender-soft); color: var(--text-secondary); }
.ce-search:focus-within { box-shadow: 0 0 0 2px var(--brand-hero); }
.ce-search-input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--text-primary); font: inherit; font-size: var(--text-small); }
.ce-search-input::-webkit-search-cancel-button { display: none; }
.ce-search-results { position: absolute; top: calc(100% + 6px); right: 0; left: 0; z-index: 60; display: grid; gap: 2px; max-height: 60vh; overflow-y: auto; padding: var(--space-2); border-radius: 18px; background: var(--surface-card); box-shadow: 0 16px 40px rgb(38 34 55 / 18%); }
.ce-search-results[hidden], .ce-bell-panel[hidden] { display: none; }
.ce-search-group { padding: var(--space-2) var(--space-2) 2px; color: var(--text-tertiary); font-size: var(--text-caption); font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.ce-search-hit { display: flex; align-items: center; gap: var(--space-3); width: 100%; padding: var(--space-2) var(--space-3); border: 0; border-radius: 12px; background: transparent; color: var(--text-primary); font: inherit; text-align: left; cursor: pointer; }
.ce-search-hit:hover, .ce-search-hit:focus-visible { background: var(--tint-purple); }
.ce-search-hit > span { display: grid; min-width: 0; }
.ce-search-hit small { overflow: hidden; color: var(--text-secondary); text-overflow: ellipsis; white-space: nowrap; }
.ce-search-empty { margin: 0; padding: var(--space-3); color: var(--text-secondary); font-size: var(--text-small); }
.ce-topbar-order { flex: none; min-height: 44px; border-radius: 14px; }
.ce-bell-wrap { position: relative; flex: none; }
.ce-bell { position: relative; display: grid; place-items: center; width: 44px; height: 44px; border: 0; border-radius: 16px; background: var(--surface-lavender-soft); color: var(--brand-hero); cursor: pointer; }
.ce-bell:hover { background: var(--tint-purple); }
.ce-bell-badge { position: absolute; top: -4px; right: -4px; display: grid; place-items: center; min-width: 20px; height: 20px; box-sizing: border-box; padding: 0 5px; border-radius: 10px; background: var(--brand-hero); color: var(--brand-on-primary); font-size: 11px; font-weight: 700; }
.ce-bell-badge[hidden] { display: none; }
.ce-bell-panel { position: absolute; top: calc(100% + 10px); right: 0; z-index: 60; display: flex; flex-direction: column; gap: var(--space-2); width: 420px; max-height: min(70vh, 640px); box-sizing: border-box; padding: var(--space-4); border-radius: 22px; background: var(--surface-card); box-shadow: 0 16px 48px rgb(38 34 55 / 22%); }
.ce-bell-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.ce-bell-list { display: grid; gap: var(--space-1); overflow-y: auto; }
.ce-bell-item { display: flex; align-items: flex-start; gap: var(--space-3); width: 100%; padding: var(--space-3); border: 0; border-radius: 14px; background: transparent; color: var(--text-primary); font: inherit; text-align: left; cursor: pointer; }
.ce-bell-item:hover { background: var(--surface-lavender-soft); }
.ce-bell-item.is-unread { background: var(--tint-purple); }
.ce-bell-icon { display: grid; place-items: center; flex: none; width: 36px; height: 36px; border-radius: 12px; }
.ce-bell-driver { background: var(--tint-mint); color: var(--ink-mint); }
.ce-bell-customer { background: var(--tint-purple); color: var(--brand-hero); }
.ce-bell-merchant { background: var(--tint-orange); color: var(--ink-orange); }
.ce-bell-sistem { background: var(--tint-skin); color: var(--ink-skin); }
.ce-bell-text { display: grid; min-width: 0; line-height: 1.35; }
.ce-bell-text > span { overflow-wrap: anywhere; color: var(--text-secondary); font-size: var(--text-small); }
.ce-bell-text small { color: var(--text-secondary); font-size: var(--text-caption); }
@media (max-width: 767px) {
  .ce-admin-top { position: sticky; top: 0; z-index: 40; margin: calc(var(--space-4) * -1) calc(var(--space-4) * -1) 0; padding: var(--space-3) var(--space-4); background: var(--surface-card); }
  .ce-admin-top .ce-breadcrumb { display: none; }
  .ce-topbar-tools { justify-content: stretch; }
  .ce-search { max-width: none; }
  .ce-topbar-label { display: none; }
  .ce-topbar-order { width: 44px; padding: 0; }
  .ce-bell-panel { position: fixed; top: 68px; right: var(--space-3); left: var(--space-3); width: auto; max-height: calc(100vh - 150px); }
  .ce-search-results { position: fixed; top: 68px; right: var(--space-3); left: var(--space-3); }
}

/* ---- Admin pages inside the new frame: shared look for cards, lists, tabs and stat tiles ------------------- */
.ce-shell-admin .ce-page-title { font-size: 28px; letter-spacing: -.02em; }
.ce-shell-admin .ce-card { border: 1px solid var(--tint-purple); border-radius: 22px; box-shadow: none; }
.ce-shell-admin .ce-card-head h3 { font-size: 18px; }
.ce-shell-admin .ce-list-item { border: 0; border-radius: 14px; background: var(--surface-lavender-soft); }
.ce-shell-admin .ce-tabs { gap: var(--space-2); padding: 0; background: transparent; }
.ce-shell-admin .ce-tab { min-height: 36px; border-radius: var(--radius-pill); background: var(--surface-lavender-soft); color: var(--brand-hero); }
.ce-shell-admin .ce-tab[aria-pressed="true"] { background: var(--brand-hero); color: var(--brand-on-primary); }
.ce-shell-admin .ce-btn { border-radius: 14px; }
.ce-shell-admin .ce-field input:not([type="checkbox"]):not([type="radio"]):not([type="file"]), .ce-shell-admin .ce-field select, .ce-shell-admin .ce-field textarea { border-radius: 14px; background: var(--surface-lavender-soft); }
.ce-shell-admin .ce-stat-grid > .ce-stat { border: 0; border-radius: 18px; }
.ce-shell-admin .ce-stat-grid > .ce-stat:nth-child(4n+1) { background: var(--tint-purple); }
.ce-shell-admin .ce-stat-grid > .ce-stat:nth-child(4n+2) { background: var(--tint-mint); }
.ce-shell-admin .ce-stat-grid > .ce-stat:nth-child(4n+3) { background: var(--tint-orange); }
.ce-shell-admin .ce-stat-grid > .ce-stat:nth-child(4n+4) { background: var(--tint-skin); }
.ce-shell-admin .ce-queue-grid > .ce-queue { border: 0; border-radius: 18px; background: var(--tint-purple); }
.ce-shell-admin .ce-queue-grid > .ce-queue.is-pending { background: var(--tint-orange); }
.ce-shell-admin .ce-fold-card { border-radius: 22px; }
.ce-page-head { display: flex; align-items: flex-end; justify-content: space-between; flex-wrap: wrap; gap: var(--space-3); }
.ce-page-head p { margin: 2px 0 0; }
.ce-page-head > .ce-btn { flex: none; }

/* Admin list pages (pola pratinjau 4 Okt 2026): segmented status control at its natural width, search beside it,
   one record per table row with Aksi last, and forms opened in a drawer instead of sitting on the page */
.ce-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.ce-toolbar-search { flex: 1 1 240px; max-width: 360px; min-width: 0; }
.ce-toolbar-search .ce-field { gap: 0; }
.ce-tabs.ce-seg { display: inline-flex; width: max-content; max-width: 100%; }
.ce-tabs.ce-seg .ce-tab { flex: 0 0 auto; }
.ce-btn-text-danger { border-color: transparent; background: transparent; color: var(--status-danger); }
.ce-btn-text-danger:hover { background: var(--status-danger-soft); border-color: transparent; }
/* At tablet width (e.g. 1024px, Admin sidebar still full-width) a row's trailing columns (Total/Aksi) are often
   scrolled out of view with no visual hint there is more to the right — this is the classic CSS "scroll shadow"
   trick (two gradients that scroll with the content to hide at each edge, two that stay fixed to the container to
   reveal a shadow only while that edge is scrolled past), so the hint appears/disappears with the real scroll
   position, pure CSS, no JS (audit, 12 Okt 2026). */
.ce-data-wrap {
  overflow-x: auto; border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-card);
  background-image: linear-gradient(to right, var(--surface-card) 30%, rgb(255 255 255 / 0%)), linear-gradient(to right, rgb(255 255 255 / 0%), var(--surface-card) 70%), linear-gradient(to right, rgb(0 0 0 / 12%), rgb(0 0 0 / 0%)), linear-gradient(to left, rgb(0 0 0 / 12%), rgb(0 0 0 / 0%));
  background-repeat: no-repeat; background-color: var(--surface-card); background-size: 24px 100%, 24px 100%, 10px 100%, 10px 100%;
  background-position: left center, right center, left center, right center; background-attachment: local, local, scroll, scroll;
}
.ce-data { width: 100%; min-width: 640px; border-collapse: collapse; font-size: var(--text-small); }
.ce-data th { padding: var(--space-3) var(--space-4); color: var(--text-tertiary); background: var(--surface-section); border-bottom: 1px solid var(--border-default); font-size: var(--text-caption); font-weight: 700; letter-spacing: .04em; text-align: left; text-transform: uppercase; white-space: nowrap; }
.ce-data td { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border-default); vertical-align: middle; }
.ce-data tbody tr:last-child td { border-bottom: 0; }
.ce-data tbody tr:hover { background: var(--surface-section); }
.ce-data .is-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ce-data .is-action { width: 1%; text-align: right; white-space: nowrap; }
.ce-data .ce-actions { flex-wrap: nowrap; justify-content: flex-end; }
.ce-data .ce-cell-clip { display: block; max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ce-dialog-drawer .ce-form { display: flex; flex-direction: column; gap: var(--space-4); min-height: 100%; }
.ce-dialog-drawer .ce-form > .ce-dialog-foot { margin-top: auto; }
@media (max-width: 767px) {
  .ce-data-wrap { overflow: visible; border: 0; background: transparent; background-image: none; }
  .ce-data { min-width: 0; }
  .ce-data thead { display: none; }
  .ce-data, .ce-data tbody, .ce-data tr { display: block; width: 100%; }
  /* Owner, 11 Okt 2026: a card per row still, but its fields sit two to a line (each with its own small label
     above the value) instead of one full-width line per field — shorter cards, less scrolling through a long list. */
  .ce-data tbody tr { display: grid; grid-template-columns: 1fr 1fr; gap: 2px var(--space-3); margin-bottom: var(--space-2); padding: var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-card); }
  .ce-data td { display: block; min-width: 0; padding: 4px 0; border: 0; text-align: left; }
  .ce-data td::before { display: block; content: attr(data-label); margin-bottom: 2px; color: var(--text-tertiary); font-size: var(--text-caption); font-weight: 700; text-align: left; }
  .ce-data .is-num { text-align: left; white-space: normal; }
  .ce-data td.is-title { grid-column: 1 / -1; padding: 0 0 var(--space-2); font-size: var(--text-body); }
  .ce-data td.is-title::before, .ce-data td.is-action::before { display: none; }
  /* The desktop rule above sets `.is-action` to `width: 1%` (a table-cell auto-width trick) and `white-space: nowrap` —
     both wrong for this grid item and, together with flex-end, pushed the button off the left edge (11 Okt 2026). */
  .ce-data td.is-action { grid-column: 1 / -1; width: auto; display: flex; justify-content: flex-end; padding-top: var(--space-2); white-space: normal; }
  /* The desktop rule forces a single nowrap row of action buttons (right-aligned) — fine for 2-3 buttons, but a
     row with 4 (e.g. Riwayat/Crosscheck/Ubah/Koreksi) overflowed the card edge on a phone (12 Okt 2026). */
  .ce-data .ce-actions { flex-wrap: wrap; }
  .ce-toolbar-search { max-width: none; flex-basis: 100%; }
}
.ce-shell-admin .ce-stat-grid > .ce-stat { padding: var(--space-3) var(--space-4); }

/* Admin hub: grouped section list beside the active section (wrapping pills on a phone) */
.ce-hub-body { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); align-items: start; }
.ce-hub-nav { display: flex; flex-wrap: wrap; gap: var(--space-2); min-width: 0; }
.ce-hub-group { display: contents; }
.ce-hub-group-label { display: none; }
.ce-hub-item { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--control-height); padding: 0 var(--space-3); color: var(--text-secondary); border: 1px solid var(--border-default); border-radius: var(--radius-pill); background: var(--surface-card); font-size: var(--text-small); font-weight: 700; }
.ce-hub-item:hover { color: var(--brand-primary); border-color: var(--brand-primary); }
.ce-hub-item.is-active { color: var(--brand-primary); border-color: var(--brand-primary); background: var(--brand-primary-soft); }
.ce-hub-item-label { min-width: 0; text-align: left; }
.ce-hub-panel { min-width: 0; }
@media (min-width: 900px) {
  .ce-hub-body { grid-template-columns: 220px minmax(0, 1fr); }
  .ce-hub-nav { position: sticky; top: var(--space-4); max-height: calc(100vh - var(--space-8)); overflow-y: auto; flex-direction: column; flex-wrap: nowrap; gap: var(--space-4); padding: var(--space-3); border: 1px solid var(--border-default); border-radius: 18px; background: var(--surface-card); }
  .ce-hub-group { display: flex; flex-direction: column; gap: var(--space-1); }
  .ce-hub-group-label { display: block; padding: 0 var(--space-3); color: var(--text-tertiary); font-size: var(--text-caption); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
  .ce-hub-item { width: 100%; border: 0; border-radius: var(--radius-control); background: transparent; }
  .ce-hub-item .ce-badge { margin-left: auto; }
  .ce-hub-item:hover { background: var(--surface-section); }
  .ce-hub-item.is-active { background: var(--brand-primary-soft); }
}

/* Desa/Kelurahan combobox: the list opens flush under the input so the two read as one control */
.ce-combo-wrap.is-open > input { border-color: var(--brand-primary); border-bottom-right-radius: 0; border-bottom-left-radius: 0; }
.ce-combo-dropdown.ce-combo-attached { margin-top: -1px; max-height: 248px; border-color: var(--brand-primary); border-top-color: var(--border-default); border-radius: 0 0 var(--radius-control) var(--radius-control); }
.ce-combo-attached .ce-combo-option { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); min-height: var(--control-height); }
.ce-combo-attached .ce-combo-option[aria-selected='true'] { background: var(--brand-primary-soft); }
.ce-combo-tag { flex: none; padding: 2px var(--space-2); color: var(--brand-primary); border-radius: var(--radius-pill); background: var(--brand-primary-soft); font-size: var(--text-caption); font-weight: 700; }
.ce-combo-tag-muted { color: var(--text-secondary); background: var(--surface-section); }
.ce-combo-empty { padding: var(--space-3); color: var(--text-secondary); font-size: var(--text-small); }

/* Owner Access (governance/RBAC) panel: a bespoke component (src/web/rbac.ts) that otherwise renders with zero
   styling — this keeps it compact and legible instead of stacking every field and every permission key on its own line. */
.rbac { font-size: var(--text-small); }
.rbac > .eyebrow { display: block; color: var(--text-tertiary); font-size: var(--text-caption); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.rbac h2 { margin: var(--space-1) 0; font-size: var(--heading-card); }
.rbac h3 { margin: var(--space-3) 0 var(--space-2); font-size: var(--text-body); }
.rbac .muted, .rbac .footnote, .rbac .guest-note { margin: var(--space-1) 0; color: var(--text-secondary); }
.rbac dl { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-1) var(--space-2); margin: var(--space-2) 0; }
.rbac dt { color: var(--text-tertiary); font-weight: 600; }
.rbac dd { margin: 0; word-break: break-word; }
.rbac-catalogs { display: grid; gap: var(--space-3); margin: var(--space-3) 0; }
.rbac-catalog { padding: var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-section); }
.rbac-catalog .records { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-2); }
.rbac-record { padding: var(--space-2) var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-card); }
.rbac-record > summary { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2); cursor: pointer; font-weight: 700; }
.rbac-record[open] > summary { margin-bottom: var(--space-2); }
.rbac-summary-meta { color: var(--text-secondary); font-weight: 400; font-size: var(--text-caption); }
.rbac-line { padding: 6px var(--space-2); border-bottom: 1px solid var(--border-default); font-family: monospace; font-size: var(--text-caption); }
.rbac-line:last-child { border-bottom: 0; }
.rbac-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.rbac-tag { padding: 2px var(--space-2); border-radius: var(--radius-pill); background: var(--surface-section); font-size: var(--text-caption); font-family: monospace; }
.rbac-tag-muted { color: var(--text-tertiary); }
.rbac-form { display: grid; gap: var(--space-2); margin: var(--space-3) 0; padding: var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-control); }
.rbac-form legend { padding: 0; font-weight: 700; }
.rbac-form label { display: block; margin-top: var(--space-2); font-size: var(--text-caption); color: var(--text-secondary); }
.rbac-form input, .rbac-form select, .rbac-form textarea { width: 100%; min-height: var(--control-height); margin-top: 2px; padding: var(--space-2); border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-card); font: inherit; }
.rbac .button { min-height: var(--control-height); margin-top: var(--space-2); padding: 0 var(--space-4); border: 1px solid var(--border-default); border-radius: var(--radius-control); background: var(--surface-card); color: var(--brand-primary); font-weight: 700; }
.rbac .button.primary { border-color: var(--brand-primary); background: var(--brand-primary); color: var(--brand-on-primary); }
.rbac .button.danger { border-color: var(--status-danger); color: var(--status-danger); }
.rbac .notice { margin: var(--space-2) 0; padding: var(--space-2) var(--space-3); border-radius: var(--radius-control); background: var(--surface-section); }
.rbac .notice.error { color: var(--status-danger); background: var(--status-danger-soft); }
.rbac .notice.success { color: var(--status-success); background: var(--status-success-soft); }
.rbac .field-error { color: var(--status-danger); }
.rbac pre { max-width: 100%; overflow-x: auto; padding: var(--space-2); border-radius: var(--radius-control); background: var(--surface-section); font-size: var(--text-caption); white-space: pre-wrap; word-break: break-word; }

/* ---- Admin monokrom (4 Okt 2026): Dashboard, Live Tracking, dan daftar Master Data memakai satu warna brand
   dan netral. Warna status tetap dipakai hanya pada badge bertulisan (Aktif, STAY, BREAK) dan pin peta, karena
   keduanya membawa arti status (AGENTS.md §9.18: warna + ikon + label). */
.ce-shell-admin .ce-card { border-color: var(--border-default); }
.ce-shell-admin .ce-stat-grid > .ce-stat,
.ce-shell-admin .ce-stat-grid > .ce-stat:nth-child(n) { background: var(--surface-card); border: 1px solid var(--border-default); }
.ce-shell-admin .ce-queue-grid > .ce-queue,
.ce-shell-admin .ce-queue-grid > .ce-queue.is-pending { background: var(--surface-card); border-color: var(--border-default); }
.ce-state-mint, .ce-state-purple, .ce-state-orange { background: var(--surface-section); }
.ce-state-mint strong, .ce-state-purple strong, .ce-state-orange strong { color: var(--text-primary); }
.ce-mini-mint, .ce-mini-purple, .ce-mini-red { background: var(--surface-section); color: var(--brand-primary); }
.ce-alert-warning, .ce-alert-danger, .ce-alert-info, .ce-alert-success { background: var(--surface-section); }
.ce-alert-warning .ce-alert-icon, .ce-alert-danger .ce-alert-icon, .ce-alert-info .ce-alert-icon, .ce-alert-success .ce-alert-icon { color: var(--brand-primary); }
.ce-dash-order:hover { background: var(--surface-card); box-shadow: inset 0 0 0 1px var(--brand-primary); }
.ce-dash-order { background: var(--surface-section); }
.ce-progress-bar { background: var(--surface-section); }
.ce-queue-list li.is-blocked { background: var(--surface-section); border-color: var(--border-default); color: var(--text-primary); }
.is-blocked .ce-queue-no { color: var(--text-primary); border-color: var(--border-default); }
.ce-legend-dot { background: #51159b; }
.ce-legend-dot[data-color="1"] { background: #7a4fb5; }
.ce-legend-dot[data-color="2"] { background: #a48bcf; }
.ce-legend-dot[data-color="3"] { background: #cbbde6; }
.ce-legend-dot[data-color="4"] { background: #6b6478; }

/* Pengaturan (form tunggal): lebar dibatasi agar tidak melebar penuh, field berpasangan dua kolom */
.ce-settings { max-width: 720px; }
.ce-settings .ce-btn:not(.ce-btn-full) { justify-self: start; align-self: flex-start; width: auto; }
.ce-form-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.ce-form-row > .ce-field { min-width: 0; }
@media (max-width: 767px) { .ce-form-row { grid-template-columns: minmax(0, 1fr); } }

.ce-block { display: block; }

/* Hub on a phone: sections as a grouped list of rows (not a wrapping run of pills). Tapping one opens it, with a
   back button to the list. Desktop keeps the side list and the open section side by side. */
.ce-hub-mobile, .ce-hub-back { display: none; }
@media (max-width: 767px) {
  .ce-hub-nav { display: none; }
  .ce-hub-mobile { display: grid; gap: var(--space-4); }
  .ce-hub-mobile-group { display: grid; overflow: hidden; border: 1px solid var(--border-default); border-radius: var(--radius-container); background: var(--surface-card); }
  .ce-hub-mobile-label { padding: var(--space-3) var(--space-4) var(--space-1); color: var(--text-tertiary); font-size: var(--text-caption); font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
  .ce-hub-row { display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: 52px; padding: 0 var(--space-4); border: 0; border-top: 1px solid var(--border-default); background: transparent; color: var(--text-primary); font: inherit; font-weight: 600; text-align: left; }
  .ce-hub-row:first-of-type { border-top: 0; }
  .ce-hub-row-label { flex: 1 1 auto; min-width: 0; }
  .ce-hub-row .ce-icon:last-child { color: var(--text-tertiary); }
  .ce-hub:not(.is-detail) .ce-hub-panel { display: none; }
  .ce-hub.is-detail .ce-hub-mobile { display: none; }
  .ce-hub.is-detail .ce-hub-back { display: inline-flex; align-items: center; gap: var(--space-2); min-height: 40px; padding: 0; border: 0; background: transparent; color: var(--brand-primary); font: inherit; font-weight: 700; }
  .ce-hub-back .ce-icon { transform: rotate(90deg); }
}

/* Driver portal: inputs at 16px so iOS does not zoom in on focus; touch-action stops double-tap zoom. */
.ce-shell-driver { touch-action: manipulation; }
.ce-shell-driver input, .ce-shell-driver select, .ce-shell-driver textarea { font-size: 16px; }

/* Camera frames: the picture (live video or the taken photo) fills its frame and never spills over the controls
   below it. The attendance frame is portrait 9:16 so the photo reaches the chest. */
.ce-camera-frame { position: relative; }
.ce-camera-frame > .ce-camera { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Fixed height, not aspect-ratio: a ratio-only box gave the grid row no height, so the photo spilled over the controls below. */
.ce-camera-frame-portrait { width: calc(46vh * 9 / 16); max-width: 100%; height: 46vh; justify-self: center; }

/* Profile header: name on the left, rating at the far right of the same row. */
.ce-profile-head { display: flex; align-items: center; gap: var(--space-3); }
.ce-profile-text { display: grid; min-width: 0; flex: 1 1 auto; }
.ce-profile-rating { flex: none; margin-left: auto; }
.ce-profile-rating-btn { display: inline-flex; align-items: center; gap: 4px; min-height: 36px; padding: 0 var(--space-3); border: 1px solid var(--border-default); border-radius: var(--radius-pill); background: var(--surface-card); color: var(--text-primary); font: inherit; }
.ce-profile-head { align-items: flex-start; }
.ce-profile-rating { align-self: flex-start; }

/* Chat header, WhatsApp-style: back, photo, name with the motor under it, WhatsApp icon on the far right. */
.ce-chat-head { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.ce-chat-head-info { display: grid; min-width: 0; flex: 1 1 auto; line-height: 1.25; }
.ce-chat-head-info strong, .ce-chat-head-info small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ce-chat-head-info small { color: var(--text-secondary); font-size: var(--text-caption); }
.ce-chat-head-avatar { width: 40px; height: 40px; font-size: 14px; }
.ce-chat-head .ce-icon-action { flex: none; margin-left: auto; }

/* ON BID popup: the switch sits centred on its own, sized for a light dialog (the Beranda switch is for the purple hero). */
.ce-bid-popup { justify-items: center; text-align: center; }
.ce-bid-toggle { display: flex; justify-content: center; }
.ce-bid-toggle .ce-switch { width: 76px; height: 42px; background: var(--border-default); }
.ce-bid-toggle .ce-switch[aria-checked='true'] { background: var(--brand-primary); }
.ce-bid-toggle .ce-switch-knob { top: 3px; left: 3px; width: 36px; height: 36px; }
.ce-bid-toggle .ce-switch[aria-checked='true'] .ce-switch-knob { transform: translateX(34px); }

/* "+" button: centred by an explicit offset, not by the grid's automatic position (which differs between browsers). */
.ce-fab { left: 50%; transform: translateX(-50%); padding: 0; margin: 0; }

/* Chat header back: an icon only, the arrow pointing out of the chat. */
.ce-chat-head > .ce-btn { padding: 0; width: 40px; min-width: 40px; }
/* Quantity/price stepper: one compact box, the buttons flush with the price, the price fully visible. */
.ce-stepper { gap: 0; border: 1px solid var(--border-default); border-radius: var(--radius-control); overflow: hidden; background: var(--surface-card); }
.ce-stepper input { flex: 1 1 0; min-width: 0; border: 0; border-radius: 0; }
.ce-stepper button { width: 40px; height: 40px; min-height: 40px; border: 0; border-radius: 0; background: var(--surface-section); }

/* Live map pin: photo, driver name and queue number in one tag. */
.ce-map-pin { display: flex; align-items: center; gap: 6px; max-width: 220px; padding: 3px 8px 3px 3px; border-radius: 999px; background: var(--surface-card); box-shadow: var(--shadow-overlay); font-size: 12px; font-weight: 700; color: var(--text-primary); cursor: pointer; }
.ce-map-pin-photo { display: grid; place-items: center; flex: none; width: 30px; height: 30px; overflow: hidden; border-radius: 50%; background: var(--brand-primary); color: var(--brand-on-primary); font-size: 11px; }
.ce-map-pin-photo img { width: 100%; height: 100%; object-fit: cover; }
.ce-map-pin-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* --brand-on-accent (not --text-inverse/white) is the token this brand-accent background was designed to pair
   with — .ce-hero-code already uses it correctly; this one and two more below didn't (white-on-accent measures
   ~2.17:1, well under WCAG AA; brand-on-accent measures ~4.75:1 — audit, 12 Okt 2026). */
.ce-map-pin-queue { flex: none; min-width: 22px; padding: 1px 6px; border-radius: 999px; background: var(--brand-accent); color: var(--brand-on-accent); text-align: center; }
/* Photo and queue number as one unit: the badge sits on the photo's bottom-right corner (6 Okt 2026). */
/* Product list: one compact row per product (Owner, 6 Okt 2026). */
.ce-product-item { display: grid; grid-template-columns: 56px minmax(0, 1fr) auto; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); }
.ce-product-item .ce-ledger-amount { display: grid; justify-items: end; gap: 4px; }
.ce-product-item .ce-product-text small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Photo grid in the product form: the nine photos fit in one view as small squares (Owner, 6 Okt 2026). */
.ce-photo-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.ce-photo-tile { position: relative; margin: 0; aspect-ratio: 1 / 1; min-width: 0; overflow: hidden; border-radius: var(--radius-control); border: 1px solid var(--border-default); background: var(--surface-section); }
.ce-photo-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ce-photo-index { position: absolute; top: 2px; left: 2px; padding: 0 4px; border-radius: 999px; background: var(--brand-accent); color: var(--brand-on-accent); font-size: 9px; font-weight: 800; }
.ce-photo-tile > .ce-btn { position: absolute; top: 2px; right: 2px; padding: 0; min-width: 22px; width: 22px; height: 22px; background: var(--surface-card); }
.ce-photo-grid + .ce-hint, .ce-photo-grid ~ small { display: block; }
.ce-product-thumb { flex: none; width: 56px; height: 56px; object-fit: cover; border-radius: var(--radius-control); background: var(--surface-section); }
.ce-product-thumb-empty { display: block; }
/* Live map pin (Owner, 6 Okt 2026): the photo in a #51159b ring, the queue number on top of the photo, the name below it, so the label never covers the face. */
.ce-map-pin { display: flex; flex-direction: column; align-items: center; gap: 2px; max-width: none; padding: 0; background: transparent; box-shadow: none; }
.ce-map-pin-photo { width: 40px; height: 40px; border: 3px solid #51159b; background: #ffffff; color: #51159b; }
.ce-map-pin-name { max-width: 120px; padding: 1px 6px; border-radius: 999px; background: var(--surface-card); box-shadow: var(--shadow-overlay); font-size: 11px; }
.ce-map-pin-stack { position: relative; flex: none; display: inline-block; }
/* Cek Ongkir (Owner, 6 Okt 2026): form left, result table right on desktop; on phones the result sits above the bottom navigation. */
.ce-shipping-split { display: grid; gap: var(--space-4); align-items: start; }
@media (min-width: 1024px) {
  .ce-shipping-split { grid-template-columns: minmax(0, 1fr) minmax(320px, 420px); }
  .ce-shipping-result-col { position: sticky; top: var(--space-4); }
}
@media (max-width: 1023px) {
  .ce-shipping-form-col { padding-bottom: 220px; }
  .ce-shipping-result-col { position: fixed; right: 0; left: 0; bottom: calc(var(--bottom-nav-height) + env(safe-area-inset-bottom)); z-index: var(--layer-sticky); max-height: 42vh; overflow-y: auto; padding: var(--space-3) var(--space-4); background: var(--surface-card); border-top: 1px solid var(--border-default); border-radius: var(--radius-container) var(--radius-container) 0 0; box-shadow: var(--shadow-overlay); }
}
.ce-map-pin-stack .ce-map-pin-queue { position: absolute; top: -10px; left: 50%; transform: translateX(-50%); border: 2px solid #ffffff; }
.ce-map-pin.is-stale { opacity: .55; }

/* Customer's own rating: big gold stars, centred, with the review text under them. */
.ce-rating-own { display: grid; justify-items: center; gap: var(--space-2); text-align: center; }
.ce-rating-own-stars { color: var(--status-warning); font-size: 40px; line-height: 1; letter-spacing: 4px; }
.ce-rating-own-review { margin: 0; max-width: 100%; padding: var(--space-3) var(--space-4); border-left: 3px solid var(--status-warning); background: var(--surface-section); border-radius: var(--radius-control); text-align: left; overflow-wrap: anywhere; }

/* Tap-to-open photo on the invoice (bukti transfer): looks like the plain frame, opens the popup on click. */
.ce-doc-open { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; }

/* Paste button sits on the right of the customer chat box in the order form. */
.ce-paste-field { position: relative; min-width: 0; }
.ce-paste-field textarea { padding-right: 52px; }
/* The paste icon sits inside the chat box, bottom right (Owner, 5 Okt 2026). */
.ce-paste-box { position: relative; }
.ce-paste-box textarea { padding-right: 56px; }
.ce-paste-inside { position: absolute; top: var(--space-2); right: var(--space-2); }
.ce-paste-inside .ce-btn { width: 36px; min-width: 36px; height: 36px; padding: 0; }
/* Saldo chip: icon and amount in one row, always (Owner, 6 Okt 2026). */
.ce-hero-balance { flex-direction: row; flex-wrap: nowrap; }

/* "Nominal lain" tab while it is picked: the same size as the other tabs, showing an amount input. */
.ce-tab-input { width: 100%; min-width: 0; border: 0; background: transparent; text-align: center; font: inherit; color: inherit; }

/* Chat header: a coloured bar pinned to the top of the page while the chat scrolls underneath. */
.ce-chat-head { position: sticky; top: 0; z-index: 5; margin: calc(var(--space-4) * -1) calc(var(--space-4) * -1) 0; padding: var(--space-3) var(--space-4); background: var(--brand-primary); color: var(--brand-on-primary); box-shadow: var(--shadow-overlay); }
.ce-chat-head .ce-btn, .ce-chat-head .ce-btn .ce-icon, .ce-chat-head small, .ce-chat-head strong { color: var(--brand-on-primary); }

/* Driver hero: balance in the top-right corner, icon and amount only. */
.ce-hero-who { min-width: 0; flex: 1 1 auto; }
/* Saldo chip: icon and amount on one line, softer shape (Owner, 6 Okt 2026). */
.ce-hero-balance > * { display: inline-block; vertical-align: middle; }
.ce-hero-balance { border-radius: 999px; background: rgba(255, 255, 255, 0.12); font-weight: 600; display: inline-flex; align-items: center; gap: var(--space-1); margin-left: auto; align-self: flex-start; flex: 0 0 auto; white-space: nowrap; padding: var(--space-1) var(--space-2); border: 0; border-radius: var(--radius-pill); background: rgba(255, 255, 255, 0.16); color: inherit; font: inherit; cursor: pointer; }
.ce-hero-balance strong { font-size: var(--text-body); white-space: nowrap; }
.ce-hero-balance.is-low { background: var(--status-warning-soft); color: var(--status-warning); }

/* Antrian Stay on the driver home: up to five rows, the caller's row highlighted. */
.ce-queue-list { display: grid; gap: var(--space-2); margin: 0; padding: 0; list-style: none; }
.ce-queue-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-3); border-radius: var(--radius-control); background: var(--surface-section); }
.ce-queue-row.is-me { background: var(--brand-primary); color: var(--brand-on-primary); }
.ce-queue-pos { min-width: 28px; font-weight: 700; text-align: center; font-variant-numeric: tabular-nums; }
.ce-queue-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ce-queue-you { flex: none; padding: 0 var(--space-2); border-radius: var(--radius-pill); background: var(--brand-accent); color: var(--brand-on-accent); font-size: var(--text-caption); font-weight: 700; }

/* Location pin for the Merchant registration: the map moves under a fixed centre pin. */
.ce-location-box { position: relative; min-width: 0; }
.ce-location-map { width: 100%; height: 260px; border-radius: var(--radius-card); overflow: hidden; background: var(--surface-section); }
.ce-location-center { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -100%); color: var(--status-danger); pointer-events: none; line-height: 0; }
.ce-location-numbers { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }

/* ---- Store page (Owner, 5 Okt 2026): Facebook-like top, grid or list products, one-box quantity, floating cart. ---- */
.ce-store { display: grid; gap: var(--space-2); }
.ce-store-cover { position: relative; aspect-ratio: 16 / 7; max-width: 100%; border-radius: var(--radius-card); overflow: hidden; background: var(--surface-section); }
.ce-store-cover-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ce-store-cover-fallback { width: 100%; height: 100%; background: linear-gradient(135deg, var(--brand-primary), var(--brand-accent)); }
.ce-store-id { display: flex; align-items: flex-end; gap: var(--space-3); margin-top: calc(var(--space-6) * -1); padding: 0 var(--space-3); min-width: 0; }
.ce-store-avatar { flex: none; width: 88px; height: 88px; border-radius: 50%; border: 4px solid var(--surface-card); background: var(--brand-primary); color: var(--brand-on-primary); display: grid; place-items: center; overflow: hidden; font-weight: 700; font-size: var(--text-large); }
.ce-store-avatar img { width: 100%; height: 100%; object-fit: cover; }
.ce-store-name { display: grid; min-width: 0; padding-bottom: var(--space-1); }
.ce-store-name h2 { margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ce-photo-row { display: flex; align-items: center; gap: var(--space-3); }
.ce-store-logo-lg { width: 64px; height: 64px; border-radius: var(--radius-control); }
.ce-photo-cover { width: 100%; aspect-ratio: 16 / 7; object-fit: cover; border-radius: var(--radius-control); display: block; border: 1px solid var(--border-default); }
.ce-photo-cover-fallback { display: grid; place-items: center; background: var(--surface-section); color: var(--text-tertiary); font-size: var(--text-small); }
.ce-product-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.ce-product-card { display: grid; gap: var(--space-2); min-width: 0; padding: var(--space-2); border-radius: var(--radius-card); background: var(--surface-card); box-shadow: var(--shadow-overlay); cursor: pointer; }
.ce-product-row { display: grid; grid-template-columns: 72px minmax(0, 1fr) auto; gap: var(--space-3); align-items: center; padding: var(--space-2); border-radius: var(--radius-card); background: var(--surface-card); }
.ce-product-photo { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: var(--radius-control); display: block; }
.ce-product-row .ce-product-photo { width: 72px; height: 72px; aspect-ratio: auto; }
.ce-product-photo-empty { display: grid; place-items: center; background: var(--surface-section); color: var(--text-tertiary); }
.ce-product-text { display: grid; gap: 2px; min-width: 0; }
.ce-product-text strong:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ce-product-action { display: flex; justify-content: stretch; }
.ce-qty-box { display: inline-flex; align-items: stretch; }
.ce-qty-box strong { min-width: 36px; display: grid; place-items: center; font-variant-numeric: tabular-nums; }
.ce-variant-group { display: grid; gap: var(--space-2); }
.ce-variant-group h3 { margin: 0; }
.ce-tab[data-option]:disabled, .ce-tab.is-soldout { text-decoration: line-through; opacity: 0.45; cursor: not-allowed; }
.ce-cart-float { position: fixed; left: 16px; right: 16px; bottom: calc(var(--bottom-nav-height, 64px) + env(safe-area-inset-bottom, 0px) + 8px); z-index: 20; border-radius: var(--radius-card); box-shadow: var(--shadow-overlay); background: var(--surface-card); }
@media (max-width: 380px) { .ce-product-grid { grid-template-columns: minmax(0, 1fr); } }
