:root{
  --ink:#12141c;
  --muted:#5b6472;
  --faint:#8991a3;
  --paper:#f4f6fb;
  --card:#ffffff;
  --line:#e5e8f0;
  --navy:#0b1020;
  --navy-2:#161c34;
  --gold:#c9a227;
  --accent:#1d4ed8;
  --accent-2:#3b63e0;
  --accent-ink:#ffffff;
  --accent-soft:#eaf0ff;
  --good:#0f9d58;
  --bad:#c53030;
  --radius:16px;
  --radius-sm:10px;
  --shadow:0 1px 2px rgba(15,18,30,.04),0 12px 28px -10px rgba(15,18,30,.10);
  --shadow-lg:0 20px 60px -18px rgba(11,16,32,.35);
  --sans:"Inter","Segoe UI",Arial,sans-serif;
  --heading:"Plus Jakarta Sans","Inter","Segoe UI",Arial,sans-serif;
  --topbar-h:67px;
  --sidebar-w:460px;
  --admin-sidebar-w:264px;
}
html[data-theme="dark"]{
  color-scheme:dark;
  --ink:#eef0f6;
  --muted:#a3acc2;
  --faint:#78819a;
  --paper:#0d0f16;
  --card:#171a24;
  --line:#2a2e3d;
  --shadow:0 1px 2px rgba(0,0,0,.4),0 12px 28px -10px rgba(0,0,0,.5);
  --shadow-lg:0 20px 60px -18px rgba(0,0,0,.65);
  --accent-soft:color-mix(in srgb, var(--accent) 20%, var(--card));
}
html[data-theme="dark"] body[data-accent]{
  --accent-soft:color-mix(in srgb, var(--accent) 22%, var(--card));
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);font-size:15px;line-height:1.55;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
button{font:inherit;cursor:pointer}
input,select,textarea{font:inherit;color:inherit}
h1,h2,h3{font-family:var(--heading)}
.container{width:min(1200px,calc(100% - 40px));margin:0 auto}
::selection{background:var(--accent);color:#fff}

/* Per-page accent themes (muted, professional jewel tones) */
body[data-accent="invoice"]{--accent:#1d4ed8;--accent-2:#3b63e0;--accent-soft:#eaf0ff}
body[data-accent="proforma-invoice"]{--accent:#4338ca;--accent-2:#5849e0;--accent-soft:#eceafe}
body[data-accent="sales-contract"]{--accent:#7c3aed;--accent-2:#8b5cf6;--accent-soft:#f2ecff}
body[data-accent="sales-confirmation"]{--accent:#0284c7;--accent-2:#0ea5e9;--accent-soft:#e0f2fe}
body[data-accent="delivery-confirmation"]{--accent:#16a34a;--accent-2:#22c55e;--accent-soft:#dcfce7}
body[data-accent="sales-order"]{--accent:#0e7490;--accent-2:#22a8c4;--accent-soft:#e0f7fa}
body[data-accent="purchase-requisition"]{--accent:#c2410c;--accent-2:#ea580c;--accent-soft:#ffedd5}
body[data-accent="rfq"]{--accent:#a16207;--accent-2:#ca8a04;--accent-soft:#fef9c3}
body[data-accent="supplier-agreement"]{--accent:#92400e;--accent-2:#b45309;--accent-soft:#fef3c7}
body[data-accent="quotation"]{--accent:#6d28d9;--accent-2:#8547e6;--accent-soft:#f2ecff}
body[data-accent="receipt"]{--accent:#047857;--accent-2:#0f9d6c;--accent-soft:#e8faf0}
body[data-accent="purchase-order"]{--accent:#b45309;--accent-2:#c96a12;--accent-soft:#fff1e6}
body[data-accent="quotation-comparison"]{--accent:#9a3412;--accent-2:#b06146;--accent-soft:#ffe8d9}
body[data-accent="purchase-agreement"]{--accent:#7c2d12;--accent-2:#995b46;--accent-soft:#fbe6dc}
body[data-accent="supplier-evaluation"]{--accent:#854d0e;--accent-2:#a07443;--accent-soft:#faf0da}
body[data-accent="purchase-return"]{--accent:#c2661a;--accent-2:#cf884c;--accent-soft:#ffedd9}
body[data-accent="supplier-statement"]{--accent:#78350f;--accent-2:#966144;--accent-soft:#f6e6da}
body[data-accent="delivery-note"]{--accent:#0f766e;--accent-2:#158f85;--accent-soft:#e6faf7}
body[data-accent="certificate"]{--accent:#a16207;--accent-2:#b8790f;--accent-soft:#fdf5e2}
body[data-accent="business-letter"]{--accent:#3730a3;--accent-2:#4a3fc2;--accent-soft:#eeeeff}
body[data-accent="payslip"]{--accent:#be123c;--accent-2:#d3264f;--accent-soft:#fde8ec}
body[data-accent="credit-note"]{--accent:#0369a1;--accent-2:#0c86c9;--accent-soft:#e0f2fe}
body[data-accent="handover-report"]{--accent:#4d7c0f;--accent-2:#65a30d;--accent-soft:#ecfccb}
body[data-accent="power-of-attorney"]{--accent:#1e3a8a;--accent-2:#2c4fb0;--accent-soft:#dbeafe}
body[data-accent="mou"]{--accent:#86198f;--accent-2:#a321ad;--accent-soft:#fae8ff}
body[data-accent="nda"]{--accent:#5b21b6;--accent-2:#7c3aed;--accent-soft:#f2ecff}
body[data-accent="goods-receipt"]{--accent:#0d9488;--accent-2:#14b8a6;--accent-soft:#e6faf7}
body[data-accent="packing-list"]{--accent:#059669;--accent-2:#10b981;--accent-soft:#e6faf7}
body[data-accent="stock-transfer"]{--accent:#0891b2;--accent-2:#22c3dc;--accent-soft:#e0f7fa}
body[data-accent="stock-opname"]{--accent:#115e59;--accent-2:#0f766e;--accent-soft:#e6faf7}
body[data-accent="material-requisition"]{--accent:#14b8a6;--accent-2:#2dd4bf;--accent-soft:#e6faf7}
body[data-accent="goods-issue"]{--accent:#06b6d4;--accent-2:#22d3ee;--accent-soft:#e0f7fa}
body[data-accent="inventory-adjustment"]{--accent:#10b981;--accent-2:#34d399;--accent-soft:#d1fae5}
body[data-accent="warehouse-return"]{--accent:#065f46;--accent-2:#059669;--accent-soft:#d1fae5}
body[data-accent="warehouse-handover"]{--accent:#155e75;--accent-2:#0e7490;--accent-soft:#e0f7fa}
body[data-accent="payment-voucher"]{--accent:#0369a1;--accent-2:#0c86c9;--accent-soft:#e0f2fe}
body[data-accent="expense-report"]{--accent:#2563eb;--accent-2:#3b82f6;--accent-soft:#eaf0ff}
body[data-accent="statement-of-account"]{--accent:#0c4a6e;--accent-2:#0e7490;--accent-soft:#e0f2fe}
body[data-accent="payment-request"]{--accent:#075985;--accent-2:#0369a1;--accent-soft:#e0f2fe}
body[data-accent="receipt-voucher"]{--accent:#1e40af;--accent-2:#2f5bc4;--accent-soft:#dbeafe}
body[data-accent="cash-payment"]{--accent:#3b82f6;--accent-2:#60a5fa;--accent-soft:#dbeafe}
body[data-accent="cash-receipt"]{--accent:#0ea5e9;--accent-2:#38bdf8;--accent-soft:#e0f2fe}
body[data-accent="expense-claim"]{--accent:#6366f1;--accent-2:#818cf8;--accent-soft:#e0e7ff}
body[data-accent="financial-report"]{--accent:#164e63;--accent-2:#0e7490;--accent-soft:#e0f2fe}
body[data-accent="cash-flow-report"]{--accent:#312e81;--accent-2:#4338ca;--accent-soft:#e0e7ff}
body[data-accent="budget-request"]{--accent:#172554;--accent-2:#1e3a8a;--accent-soft:#dbeafe}
body[data-accent="employment-contract"]{--accent:#9f1239;--accent-2:#be123c;--accent-soft:#fde8ec}
body[data-accent="offer-letter"]{--accent:#e11d48;--accent-2:#f43f5e;--accent-soft:#fde8ec}
body[data-accent="warning-letter"]{--accent:#b91c1c;--accent-2:#dc2626;--accent-soft:#fee2e2}
body[data-accent="appointment-letter"]{--accent:#881337;--accent-2:#9f1239;--accent-soft:#fde8ec}
body[data-accent="promotion-letter"]{--accent:#dc2626;--accent-2:#ef4444;--accent-soft:#fee2e2}
body[data-accent="salary-adjustment-letter"]{--accent:#9d174d;--accent-2:#be185d;--accent-soft:#fce7f3}
body[data-accent="termination-letter"]{--accent:#7f1d1d;--accent-2:#991b1b;--accent-soft:#fee2e2}
body[data-accent="resignation-letter"]{--accent:#db2777;--accent-2:#ec4899;--accent-soft:#fce7f3}
body[data-accent="employee-handover"]{--accent:#991b1b;--accent-2:#b91c1c;--accent-soft:#fee2e2}
body[data-accent="experience-certificate"]{--accent:#831843;--accent-2:#a5386a;--accent-soft:#fce7f3}
body[data-accent="employment-certificate"]{--accent:#9d2235;--accent-2:#c33a4c;--accent-soft:#fde2e6}
body[data-accent="leave-application"]{--accent:#4c0519;--accent-2:#7d0e30;--accent-soft:#fde8ec}
body[data-accent="overtime-request"]{--accent:#500724;--accent-2:#82113f;--accent-soft:#fce7f3}
body[data-accent="attendance-report"]{--accent:#450a0a;--accent-2:#7a1717;--accent-soft:#fee2e2}
body[data-accent="performance-evaluation"]{--accent:#a11d33;--accent-2:#c93350;--accent-soft:#fde2e6}
body[data-accent="business-report"]{--accent:#3f6212;--accent-2:#4d7c0f;--accent-soft:#ecfccb}
body[data-accent="project-report"]{--accent:#65a30d;--accent-2:#84cc16;--accent-soft:#ecfccb}
body[data-accent="meeting-minutes"]{--accent:#15803d;--accent-2:#16a34a;--accent-soft:#dcfce7}
body[data-accent="sales-report"]{--accent:#3d8b1f;--accent-2:#5aab35;--accent-soft:#e6f5d9}
body[data-accent="purchasing-report"]{--accent:#2f6b1a;--accent-2:#4d8c2e;--accent-soft:#dbeecb}
body[data-accent="inventory-report"]{--accent:#6b9e1f;--accent-2:#8bc23e;--accent-soft:#eef7d5}
body[data-accent="hr-report"]{--accent:#1f7a4d;--accent-2:#3d9c6c;--accent-soft:#dff5ea}
body[data-accent="management-report"]{--accent:#3f6b3f;--accent-2:#5c8f5c;--accent-soft:#e2f0e2}
body[data-accent="partnership-agreement"]{--accent:#7e22ce;--accent-2:#9333ea;--accent-soft:#f5e8ff}
body[data-accent="service-agreement"]{--accent:#a21caf;--accent-2:#c026d3;--accent-soft:#fdf0ff}
body[data-accent="vendor-agreement"]{--accent:#6b21a8;--accent-2:#8b2fc9;--accent-soft:#f1e5ff}
body[data-accent="rental-agreement"]{--accent:#701a75;--accent-2:#9d3a9f;--accent-soft:#fbe9ff}
body[data-accent="freelance-agreement"]{--accent:#581c87;--accent-2:#7928ca;--accent-soft:#f4e9ff}
body[data-accent="consultancy-agreement"]{--accent:#3b0764;--accent-2:#6d28d9;--accent-soft:#f3e8ff}
body[data-accent="authorization-letter"]{--accent:#2e1065;--accent-2:#7c3aed;--accent-soft:#efe6fe}
body[data-accent="declaration-letter"]{--accent:#4a044e;--accent-2:#c026d3;--accent-soft:#fce7f8}
body[data-accent="statement-of-responsibility"]{--accent:#6b2fb3;--accent-2:#9d4edd;--accent-soft:#f2e6fb}
body[data-accent="work-order"]{--accent:#a3410f;--accent-2:#c96b2e;--accent-soft:#ffe4d1}
body[data-accent="job-order"]{--accent:#ad4a0f;--accent-2:#d1662e;--accent-soft:#ffdec2}
body[data-accent="service-report"]{--accent:#c94f0e;--accent-2:#e2703a;--accent-soft:#fff0e0}
body[data-accent="work-completion-report"]{--accent:#d2540d;--accent-2:#e87a42;--accent-soft:#ffe4d1}
body[data-accent="inspection-report"]{--accent:#dc5510;--accent-2:#f08a4e;--accent-soft:#ffdec2}
body[data-accent="maintenance-report"]{--accent:#e35d12;--accent-2:#ec7a34;--accent-soft:#fff0e0}
body[data-accent="installation-report"]{--accent:#ef6a1f;--accent-2:#f28b4a;--accent-soft:#ffe4d1}
body[data-accent="incident-report"]{--accent:#7c2d0e;--accent-2:#a84f20;--accent-soft:#ffdec2}
body[data-accent="daily-activity-report"]{--accent:#f2740f;--accent-2:#f59660;--accent-soft:#fff0e0}
body[data-accent="site-visit-report"]{--accent:#c75b12;--accent-2:#d97a3a;--accent-soft:#ffe4d1}
body[data-accent="checklist"]{--accent:#b9540f;--accent-2:#b85824;--accent-soft:#ffdec2}
body[data-accent="project-proposal"]{--accent:#1c4e80;--accent-2:#3570ab;--accent-soft:#eaf1fb}
body[data-accent="project-plan"]{--accent:#2563a6;--accent-2:#4a86c9;--accent-soft:#e8f0fb}
body[data-accent="project-schedule"]{--accent:#17395e;--accent-2:#2f5e8f;--accent-soft:#dde9fa}
body[data-accent="project-progress-report"]{--accent:#2f6fb0;--accent-2:#5490cf;--accent-soft:#f0f5fc}
body[data-accent="project-status-report"]{--accent:#3d5a99;--accent-2:#6280bd;--accent-soft:#e3ecf9}
body[data-accent="project-completion-report"]{--accent:#204878;--accent-2:#3d6ba3;--accent-soft:#dae7f7}
body[data-accent="project-handover"]{--accent:#4a6fa5;--accent-2:#7093c4;--accent-soft:#ecf3fb}
body[data-accent="risk-register"]{--accent:#1a2f52;--accent-2:#345480;--accent-soft:#d7e3f5}
body[data-accent="issue-report"]{--accent:#375d8a;--accent-2:#5c7fac;--accent-soft:#e6eefa}
body[data-accent="change-request"]{--accent:#2a4d7c;--accent-2:#4d72a3;--accent-soft:#e0eaf8}
body[data-accent="customer-registration"]{--accent:#d6336c;--accent-2:#e8578f;--accent-soft:#ffe9f0}
body[data-accent="customer-complaint"]{--accent:#c2255c;--accent-2:#db4d82;--accent-soft:#ffe0ea}
body[data-accent="customer-feedback"]{--accent:#a61e4d;--accent-2:#c94270;--accent-soft:#fbdde6}
body[data-accent="service-request"]{--accent:#ae3ec9;--accent-2:#c363da;--accent-soft:#f6e0fa}
body[data-accent="warranty-claim"]{--accent:#9c36b5;--accent-2:#b658cc;--accent-soft:#f2dbf7}
body[data-accent="return-request"]{--accent:#862e9c;--accent-2:#a352b8;--accent-soft:#ecd6f2}
body[data-accent="refund-request"]{--accent:#be4bdb;--accent-2:#d06fe8;--accent-soft:#f8e3fc}
body[data-accent="customer-satisfaction-report"]{--accent:#cc5de8;--accent-2:#dd82ee;--accent-soft:#fbe6fd}
body[data-accent="quality-inspection"]{--accent:#0f9b6e;--accent-2:#2bb98c;--accent-soft:#e2f7ef}
body[data-accent="inspection-checklist"]{--accent:#12a67a;--accent-2:#34c398;--accent-soft:#e3f8f1}
body[data-accent="non-conformance-report"]{--accent:#0c8a63;--accent-2:#2aa47f;--accent-soft:#ddf5ec}
body[data-accent="corrective-action-report"]{--accent:#16b085;--accent-2:#3ecba3;--accent-soft:#e0f9f1}
body[data-accent="preventive-action-report"]{--accent:#1abd8e;--accent-2:#43d3a8;--accent-soft:#e2fbf3}
body[data-accent="quality-audit-report"]{--accent:#0a7a58;--accent-2:#279b76;--accent-soft:#d9f2e9}
body[data-accent="quality-certificate"]{--accent:#1ec89a;--accent-2:#4fdcb4;--accent-soft:#e5fbf4}
body[data-accent="internal-memo"]{--accent:#334155;--accent-2:#4c5f78;--accent-soft:#e6e9ee}
body[data-accent="announcement"]{--accent:#475569;--accent-2:#64748b;--accent-soft:#e9ecf1}
body[data-accent="circular-letter"]{--accent:#3c4858;--accent-2:#57697d;--accent-soft:#e4e8ec}
body[data-accent="meeting-invitation"]{--accent:#52616b;--accent-2:#71828d;--accent-soft:#e7ebed}
body[data-accent="visitor-form"]{--accent:#5c6b73;--accent-2:#7c8d96;--accent-soft:#e9edef}
body[data-accent="asset-handover"]{--accent:#405366;--accent-2:#5c7286;--accent-soft:#e5eaee}
body[data-accent="certificate-of-completion"]{--accent:#b8860b;--accent-2:#d4a017;--accent-soft:#fdf3d9}
body[data-accent="certificate-of-achievement"]{--accent:#c9971c;--accent-2:#e0b23a;--accent-soft:#fdf0d6}
body[data-accent="certificate-of-appreciation"]{--accent:#bf8f0e;--accent-2:#dba829;--accent-soft:#fcefd2}
body[data-accent="certificate-of-attendance"]{--accent:#a8790a;--accent-2:#cc9a2e;--accent-soft:#faecd0}
body[data-accent="training-certificate"]{--accent:#9c7209;--accent-2:#c19425;--accent-soft:#f8ead0}
body[data-accent="warranty-certificate"]{--accent:#8a6d1f;--accent-2:#ab8a3a;--accent-soft:#f0e8d2}

/* Topbar */
.topbar{position:sticky;top:0;z-index:40;background:rgba(255,255,255,.86);backdrop-filter:blur(12px);border-bottom:1px solid var(--line)}
.topbar-inner{display:flex;align-items:center;justify-content:space-between;height:66px;width:min(1200px,calc(100% - 40px));margin:0 auto}
.brand{display:flex;align-items:center;gap:10px;font-family:var(--heading);font-weight:700;font-size:17px;letter-spacing:-.01em;color:var(--ink)}
.brand .brand-mark{display:block;width:32px;height:32px;border-radius:50%;box-shadow:0 4px 12px rgba(11,16,32,.25);flex:none}
.brand em{color:var(--muted);font-style:normal;font-weight:600}
.topbar-back{display:inline-flex;align-items:center;gap:8px;padding:9px 14px;border-radius:var(--radius-sm);border:1px solid var(--line);color:var(--muted);font-size:13px;font-weight:600;background:var(--card);transition:.15s}
.topbar-back:hover{border-color:var(--accent);color:var(--accent);transform:translateX(-2px)}
.topbar-back span{max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.topbar-title{display:flex;flex-direction:column;line-height:1.25}
.topbar-title span{font-size:10.5px;color:var(--faint);text-transform:uppercase;letter-spacing:.1em}
.topbar-title strong{font-family:var(--heading);font-size:14.5px;position:relative;padding-left:13px}
.topbar-title strong:before{content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);width:6px;height:6px;border-radius:50%;background:var(--accent)}
.topbar-right{display:flex;align-items:center;gap:12px}
.topbar-user{display:flex;align-items:center;gap:10px;justify-content:flex-end}
.topbar-user-dropdown{position:relative}
.topbar-user-name{display:flex;align-items:center;gap:7px;font-size:13px;font-weight:600;color:var(--ink);white-space:nowrap;background:none;border:none;padding:7px 8px;border-radius:9px;cursor:pointer;font-family:inherit;transition:.15s}
.topbar-user-name:hover{background:var(--paper)}
.topbar-user-name i:first-child{color:var(--faint);font-size:17px}
.topbar-user-name .caret{font-size:9px;color:var(--faint);transition:transform .15s}
.topbar-user-name[aria-expanded="true"] .caret{transform:rotate(180deg)}
.topbar-user-menu{position:absolute;top:calc(100% + 8px);right:0;min-width:210px;background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);box-shadow:var(--shadow-lg);padding:6px;z-index:60}
.topbar-user-menu a{display:flex;align-items:center;gap:10px;padding:9px 11px;border-radius:8px;font-size:13px;font-weight:600;color:var(--ink);transition:.12s}
.topbar-user-menu a:hover{background:var(--accent-soft);color:var(--accent)}
.topbar-user-menu a i{width:16px;color:var(--faint);font-size:13px}
.topbar-user-menu a:hover i{color:var(--accent)}
.topbar-logout{display:grid;place-items:center;width:34px;height:34px;flex:none;border-radius:9px;border:1px solid var(--line);background:var(--card);color:var(--muted);transition:.15s}
.topbar-logout:hover{border-color:var(--bad);color:var(--bad)}
.topbar-user-menu-divider{height:1px;background:var(--line);margin:6px 4px}
.topbar-theme-toggle{display:flex;gap:4px;padding:4px;background:var(--paper);border-radius:8px;margin:2px 2px 4px}
.topbar-theme-toggle button{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:7px 0;border:none;background:transparent;border-radius:6px;font-size:12px;font-weight:700;color:var(--muted);cursor:pointer;transition:.15s;font-family:inherit}
.topbar-theme-toggle button.active{background:var(--card);color:var(--ink);box-shadow:var(--shadow)}
/* The same .lang-toggle used elsewhere (navbar, admin topbar) as a compact
   pill — restyled here, scoped to just the user-menu dropdown, to match the
   full-width segmented look of the theme toggle immediately above it. */
.topbar-user-menu .lang-toggle{display:flex;gap:4px;padding:4px;border:none;border-radius:8px;margin:0 2px 2px;width:auto}
.topbar-user-menu .lang-toggle button{flex:1;padding:7px 0;border-radius:6px;font-size:12px;font-weight:700}
.topbar-user-menu .lang-toggle button.active{background:var(--card);color:var(--ink);box-shadow:var(--shadow)}
/* The menu laid out wide rather than long: who is signed in, two labelled
   columns of links, theme and language side by side. It scrolls inside
   itself on a short screen, and is one column across the width on a phone. */
.topbar-user-menu{width:min(470px,calc(100vw - 24px));min-width:0;padding:0;overflow:hidden auto;max-height:calc(100vh - 80px);max-height:calc(100dvh - 80px)}
.tum-head{display:flex;align-items:center;gap:11px;padding:14px 16px;border-bottom:1px solid var(--line);background:var(--paper)}
.tum-avatar{width:38px;height:38px;flex:none;border-radius:50%;display:grid;place-items:center;overflow:hidden;background:var(--card);border:1px solid var(--line);color:var(--faint);font-size:22px}
.tum-avatar img{width:100%;height:100%;object-fit:cover}
.tum-who{display:flex;flex-direction:column;min-width:0;flex:1}
.tum-who b{font-size:14px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tum-who small{font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tum-plan{flex:none;font-size:11px;font-weight:700;letter-spacing:.03em;padding:4px 9px;border-radius:999px;background:var(--accent-soft);color:var(--accent);text-transform:uppercase}
.tum-plan[data-plan="free"]{background:var(--paper);color:var(--muted);border:1px solid var(--line)}
.tum-cols{display:grid;grid-template-columns:1fr 1fr;gap:4px 8px;padding:10px 8px 6px}
.tum-col{display:flex;flex-direction:column;min-width:0}
.tum-label{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--faint);padding:4px 11px 6px}
.topbar-user-menu .tum-col a{padding:8px 11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.topbar-user-menu .tum-col a.tum-upgrade i{color:#d97706}
.tum-foot{display:grid;grid-template-columns:1fr auto;gap:8px;align-items:center;padding:8px 10px 10px;border-top:1px solid var(--line)}
.tum-foot .topbar-theme-toggle{margin:0}
.tum-foot .lang-toggle{margin:0;background:var(--paper);min-width:110px}
@media(max-width:560px){
  /* Across the phone, over the chat button (chatWidget.js sits at 99998). */
  .topbar-user-menu{position:fixed;top:64px;left:12px;right:12px;width:auto;z-index:100000}
  .tum-head{padding:12px 14px}
  .tum-cols{gap:0 4px;padding:8px 4px 4px}
  .topbar-user-menu .tum-col a{padding:8px 8px;gap:8px;font-size:12.5px}
  .tum-label{padding:4px 8px 4px}
  .tum-foot .lang-toggle{min-width:96px}
}
@media(max-width:340px){
  .tum-cols{grid-template-columns:1fr}
  .tum-col + .tum-col{border-top:1px solid var(--line);padding-top:6px;margin-top:2px}
  .tum-foot{grid-template-columns:1fr}
}
.navbar-links{display:flex;align-items:center;gap:30px}
.navbar-links a{font-size:13.5px;font-weight:600;color:var(--muted);transition:.15s}
.navbar-links a:hover{color:var(--accent)}
.navbar-auth{display:flex;align-items:center;gap:10px}
.btn-sm{padding:9px 16px;font-size:12.5px}
.nav-toggle{display:none;width:38px;height:38px;border-radius:9px;border:1px solid var(--line);background:var(--card);color:var(--ink);align-items:center;justify-content:center;font-size:15px;flex:none}
.mobile-nav{display:none}

.lang-toggle{display:flex;align-items:center;gap:2px;border:1px solid var(--line);border-radius:100px;padding:3px;background:var(--paper);flex:none}
.lang-toggle button{border:none;background:transparent;padding:6px 12px;border-radius:100px;font-size:11.5px;font-weight:800;letter-spacing:.02em;color:var(--muted);cursor:pointer;transition:background-color .15s ease,color .15s ease}
.lang-toggle button:hover{color:var(--ink)}
.lang-toggle button.active{background:var(--navy);color:#fff}
.mobile-nav-auth .lang-toggle{align-self:center;margin-top:2px}

@media(max-width:900px){
  .navbar-links{display:none}
  .nav-toggle{display:inline-flex}
  /* Both auth buttons already live inside the mobile-nav dropdown below —
     showing them again in the collapsed topbar just crowds the brand and
     hamburger onto one cramped row on phone/tablet widths. */
  .navbar-auth .btn{display:none}
  .navbar-auth .lang-toggle{display:none}
  .mobile-nav{position:fixed;inset:66px 0 0 0;z-index:39;background:var(--paper);transform:translateY(-8px);opacity:0;pointer-events:none;transition:opacity .18s ease,transform .18s ease;overflow-y:auto}
  .mobile-nav.is-open{opacity:1;transform:none;pointer-events:auto;display:block}
  .mobile-nav-inner{width:min(1200px,calc(100% - 40px));margin:0 auto;padding:22px 0 32px;display:flex;flex-direction:column;gap:4px}
  .mobile-nav a{padding:14px 4px;border-bottom:1px solid var(--line);font-size:15px;font-weight:600;color:var(--ink)}
  .mobile-nav .mobile-nav-auth{display:flex;flex-direction:column;gap:10px;margin-top:18px}
  .mobile-nav .mobile-nav-auth .btn{width:100%}
}

/* Dashboard hero (full-bleed dark) */
.hero-band{position:relative;background:linear-gradient(175deg,var(--navy) 0%,var(--navy-2) 62%,#1b2140 100%);overflow:hidden;padding:74px 0 96px}
.hero-grid-bg{position:absolute;inset:0;opacity:.5;background-image:linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);background-size:44px 44px;mask-image:radial-gradient(ellipse 80% 60% at 50% 0%,#000 40%,transparent 100%)}
.hero-band:before{content:"";position:absolute;width:520px;height:520px;border-radius:50%;right:-160px;top:-200px;background:radial-gradient(circle,rgba(60,99,224,.35),transparent 70%);filter:blur(10px)}
.hero-band:after{content:"";position:absolute;width:380px;height:380px;border-radius:50%;left:-140px;bottom:-180px;background:radial-gradient(circle,rgba(201,162,39,.18),transparent 70%);filter:blur(10px)}
.hero-inner{position:relative;z-index:1;display:grid;grid-template-columns:1.05fr .95fr;gap:40px;align-items:center}
.hero-badge{display:inline-flex;align-items:center;gap:8px;padding:7px 14px;border-radius:100px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.16);backdrop-filter:blur(6px);font-size:12px;font-weight:700;color:#e8ecff;margin-bottom:22px}
.hero-badge i{font-size:10px;color:var(--gold)}
.hero-band h1{font-family:var(--heading);font-size:clamp(32px,3.6vw,46px);margin:0 0 16px;letter-spacing:-.03em;line-height:1.12;color:#fff;font-weight:800;max-width:14ch}
.hero-band h1 em{font-style:normal;background:linear-gradient(100deg,#e7c866 10%,#fff 45%,#e7c866 80%);background-size:200% auto;-webkit-background-clip:text;background-clip:text;color:transparent;animation:heroShine 7s linear infinite}
@keyframes heroShine{to{background-position:200% center}}
.hero-band p{color:#aab2cc;max-width:480px;margin:0;font-size:15px;line-height:1.65}
.hero-cta{display:flex;align-items:center;gap:20px;margin-top:28px;flex-wrap:wrap}
.btn-ghost-light{color:#dfe3f5;font-size:13.5px;font-weight:600;padding:12px 4px}
.btn-ghost-light:hover{color:#fff}
.hero-trust{display:flex;flex-wrap:wrap;gap:18px;margin-top:18px;padding:0}
.hero-trust span{display:flex;align-items:center;gap:7px;font-size:12.5px;color:#9aa2c2;font-weight:600}
.hero-trust i{color:#3ddc84;font-size:11px}
.hero-stats{display:flex;gap:0;margin-top:34px;flex-wrap:wrap}
.hero-stats div{display:flex;flex-direction:column;padding:0 28px;border-left:1px solid rgba(255,255,255,.14)}
.hero-stats div:first-child{padding-left:0;border-left:0}
.hero-stats strong{font-family:var(--heading);font-size:22px;letter-spacing:-.02em;color:#fff}
.hero-stats span{font-size:10.5px;color:#8891b3;text-transform:uppercase;letter-spacing:.08em;margin-top:2px}

/* Same stat-row treatment as the hero, scaled down for the narrower
   auth-page brand panel (login/register/forgot/reset password). */
.auth-stats{display:flex;gap:0;margin-top:28px;flex-wrap:wrap}
.auth-stats div{display:flex;flex-direction:column;padding:0 20px;border-left:1px solid rgba(255,255,255,.14)}
.auth-stats div:first-child{padding-left:0;border-left:0}
.auth-stats strong{font-family:var(--heading);font-size:19px;letter-spacing:-.02em;color:#fff}
.auth-stats span{font-size:9.5px;color:#8891b3;text-transform:uppercase;letter-spacing:.07em;margin-top:2px}

/* Hero product mockup */
.hero-visual{position:relative;height:380px;display:flex;align-items:center;justify-content:center}
.hero-visual-inner{position:relative;will-change:transform;transition:transform .25s ease-out}
.mock-card-peek{position:absolute;width:280px;height:210px;left:26px;top:38px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.14);border-radius:14px;transform:rotate(-9deg);z-index:0}
.mock-card{position:relative;z-index:1;width:320px;background:#fff;border-radius:14px;box-shadow:0 40px 80px -20px rgba(0,0,0,.5);padding:22px 22px 18px;transform:rotate(4deg);animation:mockFloat 6s ease-in-out infinite}
.mock-card-head{display:flex;justify-content:space-between;align-items:flex-start;padding-bottom:12px;border-bottom:2px solid #171b23;gap:10px}
.mock-brand{font-family:var(--heading);font-weight:800;font-size:13px;color:var(--ink)}
.mock-sub{font-size:9.5px;color:var(--faint);margin-top:2px}
.mock-type{text-align:right;font-family:var(--heading);font-weight:800;font-size:12px;color:var(--accent);line-height:1.4}
.mock-type span{display:block;font-size:8.5px;color:var(--faint);font-weight:600}
.mock-lines{margin-top:14px;display:flex;flex-direction:column;gap:9px}
.mock-line{display:flex;justify-content:space-between;font-size:11px;color:#3a3f49}
.mock-line b{font-weight:700;color:var(--ink)}
.mock-total{display:flex;justify-content:space-between;align-items:center;margin-top:14px;padding-top:12px;border-top:1px dashed var(--line);font-family:var(--heading);font-weight:800;font-size:13px}
.mock-total b{color:var(--accent);font-size:15px}
.mock-chip{position:absolute;display:flex;align-items:center;gap:8px;padding:9px 14px;border-radius:10px;background:#fff;box-shadow:0 16px 32px -10px rgba(0,0,0,.4);font-size:11px;font-weight:700;color:var(--ink);animation:mockFloat 5s ease-in-out infinite}
.mock-chip i{color:var(--good)}
.chip-a{left:-18px;bottom:56px;animation-delay:-1.5s}
.chip-b{right:-14px;top:34px;animation-delay:-3s}
.chip-b i{color:var(--gold)}
@keyframes mockFloat{0%,100%{transform:rotate(4deg) translateY(0)}50%{transform:rotate(2deg) translateY(-10px)}}
@media(max-width:960px){.hero-inner{grid-template-columns:1fr}.hero-visual{height:280px;margin-top:10px}.hero-band h1{max-width:none}}
@media(max-width:640px){.hero-visual{display:none}}

/* Dashboard hero (dark banner, mirrors the auth pages' navy/gold identity) */
.dash-hero{position:relative;overflow:hidden;margin-top:28px;padding:34px 32px;border-radius:20px;background:linear-gradient(155deg,var(--navy) 0%,var(--navy-2) 65%,#1b2140 100%);display:flex;align-items:center;justify-content:space-between;gap:24px;flex-wrap:wrap}
.dash-hero:before{content:"";position:absolute;width:360px;height:360px;border-radius:50%;right:-120px;top:-150px;background:radial-gradient(circle,rgba(60,99,224,.35),transparent 70%);filter:blur(10px)}
.dash-hero:after{content:"";position:absolute;width:260px;height:260px;border-radius:50%;left:-100px;bottom:-150px;background:radial-gradient(circle,rgba(201,162,39,.18),transparent 70%);filter:blur(10px)}
.dash-hero-inner{position:relative;z-index:1;max-width:560px}
.dash-hero-eyebrow{display:flex;align-items:center;gap:8px;margin:0 0 10px;font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:#aab2cc}
.dash-hero-eyebrow i{color:var(--gold)}
.dash-hero h1{font-family:var(--heading);font-size:27px;margin:0 0 10px;letter-spacing:-.02em;font-weight:800;color:#fff}
.dash-hero p{margin:0;color:#c3c9de;font-size:14px;max-width:480px;line-height:1.6}
.dash-hero-actions{position:relative;z-index:1;display:flex;gap:10px;flex-wrap:wrap}
.btn-ghost-light{background:rgba(255,255,255,.08);color:#fff;border:1px solid rgba(255,255,255,.22)}
.btn-ghost-light:hover{background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.4)}

/* Stat cards below the hero */
.dash-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:20px 0}
.stat-card{display:flex;align-items:flex-start;gap:14px;padding:18px 20px;background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow)}
.stat-icon{display:grid;place-items:center;width:42px;height:42px;border-radius:11px;flex:none;font-size:17px}
.stat-icon.plan{background:#fdf5e2;color:#a16207}
.stat-icon.usage{background:var(--accent-soft);color:var(--accent)}
.stat-icon.history{background:#e6faf7;color:#0f766e}
.stat-icon.crm{background:#f2ecff;color:#6d28d9}
.admin-section{margin-top:20px;scroll-margin-top:90px}

/* Admin dashboard shell — fixed dark navy/gold sidebar + topbar, TailAdmin-
   style layout applied to TH Business's own brand colors rather than
   TailAdmin's blue palette (kept consistent with the auth pages/landing
   page's navy+gold identity). Scoped entirely to admin.html; every other
   authenticated page keeps the plain .topbar + .container layout. */
.admin-shell{display:flex;min-height:100vh;background:var(--paper)}
.admin-sidebar{position:fixed;top:0;left:0;bottom:0;width:var(--admin-sidebar-w);background:linear-gradient(185deg,var(--navy) 0%,var(--navy-2) 70%,#1b2140 100%);display:flex;flex-direction:column;z-index:50;overflow-y:auto;overflow-x:hidden;transition:transform .22s ease,width .2s ease}
.admin-sidebar-brand{display:flex;align-items:center;gap:10px;padding:22px 22px 18px;font-family:var(--heading);font-weight:700;font-size:16px;color:#fff;letter-spacing:-.01em;white-space:nowrap;position:relative}
.admin-sidebar-brand .brand-mark{width:30px;height:30px;border-radius:50%;flex:none;box-shadow:0 0 0 3px rgba(201,162,39,.18),0 4px 14px rgba(11,16,32,.35)}
.admin-sidebar-brand em{color:#aab2cc;font-style:normal;font-weight:600}
.admin-sidebar-badge{margin:0 18px 18px;padding:7px 12px;border-radius:10px;background:linear-gradient(115deg,rgba(201,162,39,.2),rgba(201,162,39,.08));border:1px solid rgba(201,162,39,.32);color:var(--gold);font-size:11px;font-weight:700;display:flex;align-items:center;gap:8px;white-space:nowrap}
.admin-sidebar-badge i{animation:adminBadgePulse 2.6s ease-in-out infinite}
@keyframes adminBadgePulse{0%,100%{opacity:1}50%{opacity:.55}}
.admin-sidebar-nav{flex:1;padding:4px 14px 18px;display:flex;flex-direction:column;gap:18px}
.admin-nav-group-label{padding:0 10px;margin-bottom:6px;font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.1em;color:#7981a3;white-space:nowrap}
.admin-nav-group{display:flex;flex-direction:column;gap:2px;position:relative}
.admin-nav-group:not(:last-child):after{content:"";display:block;height:1px;margin:12px 10px 0;background:linear-gradient(90deg,rgba(255,255,255,.1),transparent)}
.admin-nav-link{display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:10px;color:#c3c9de;font-size:13.3px;font-weight:600;transition:background-color .15s,color .15s;cursor:pointer;white-space:nowrap;position:relative}
.admin-nav-link i{width:16px;text-align:center;font-size:13px;color:#8891b3;transition:.15s;flex:none}
.admin-nav-link:hover{background:rgba(255,255,255,.07);color:#fff}
.admin-nav-link:hover i{color:#dfe3f5}
.admin-nav-link.active{background:linear-gradient(90deg,rgba(201,162,39,.18),rgba(201,162,39,.06));color:#fff}
/* Count of items waiting in the "Perlu Tindakan" queue (admin-attention.html)
   — pushed to the right of its own nav row, and in the collapsed icon rail it
   shrinks to a dot pinned to the icon's corner, since there's no room for
   digits there but "something is waiting" still has to be visible. */
.admin-nav-badge{margin-left:auto;min-width:19px;padding:1px 6px;border-radius:999px;background:var(--bad,#d64545);color:#fff;font-size:11px;font-weight:700;line-height:1.5;text-align:center;flex:none}
html.sidebar-collapsed .admin-nav-badge{position:absolute;top:5px;right:5px;margin:0;min-width:8px;width:8px;height:8px;padding:0;font-size:0;line-height:0}
.admin-nav-link.active i{color:var(--gold)}
.admin-nav-link.active:before{content:"";position:absolute;left:-14px;top:50%;transform:translateY(-50%);width:3px;height:58%;border-radius:0 4px 4px 0;background:linear-gradient(180deg,#e7c866,var(--gold))}
.admin-sidebar-footer{padding:14px 14px 20px;border-top:1px solid rgba(255,255,255,.08);display:flex;flex-direction:column;gap:2px}
.admin-main{flex:1;min-width:0;margin-left:var(--admin-sidebar-w);display:flex;flex-direction:column;transition:margin-left .2s ease}

/* Desktop collapse-to-icon-rail toggle. Persisted in localStorage and
   applied to <html> (not <body>) via an inline script at the top of <head>
   on every admin page — since each sidebar link is a full page navigation
   rather than an SPA route, applying the class any later would flash the
   full-width sidebar for a moment on every single page load. */
.admin-sidebar-collapse-btn{position:fixed;top:26px;left:calc(var(--admin-sidebar-w) - 13px);width:26px;height:26px;border-radius:50%;background:var(--card);border:1px solid var(--line);color:var(--muted);display:grid;place-items:center;font-size:10px;cursor:pointer;z-index:51;box-shadow:var(--shadow);padding:0;transition:left .2s ease}
.admin-sidebar-collapse-btn:hover{color:var(--accent);border-color:var(--accent)}
html.sidebar-collapsed{--admin-sidebar-w:80px}
html.sidebar-collapsed .admin-nav-group-label,
html.sidebar-collapsed .admin-sidebar-brand-text,
html.sidebar-collapsed .admin-sidebar-badge-text,
html.sidebar-collapsed .admin-nav-label{display:none}
html.sidebar-collapsed .admin-nav-link{justify-content:center;padding:10px 0}
html.sidebar-collapsed .admin-sidebar-brand{justify-content:center;padding:22px 0 18px}
html.sidebar-collapsed .admin-sidebar-badge{justify-content:center;padding:9px;margin:0 18px 18px}
@media(max-width:900px){.admin-sidebar-collapse-btn{display:none}}
.admin-topbar{position:sticky;top:0;z-index:40;display:flex;align-items:center;justify-content:space-between;gap:16px;padding:16px 28px;background:rgba(255,255,255,.88);backdrop-filter:blur(12px);border-bottom:1px solid var(--line)}
.admin-topbar-left{display:flex;align-items:center;gap:14px;min-width:0}
.admin-topbar-title{display:flex;flex-direction:column;gap:2px;min-width:0}
.admin-topbar-title strong{font-family:var(--heading);font-size:16.5px;font-weight:800;color:var(--ink);letter-spacing:-.01em}
.admin-topbar-title span{font-size:12px;color:var(--muted)}
.admin-sidebar-toggle{display:none;width:38px;height:38px;flex:none;border-radius:9px;border:1px solid var(--line);background:var(--card);color:var(--ink);align-items:center;justify-content:center;font-size:15px}
.admin-sidebar-overlay{display:none}
.admin-content{padding:24px 28px 64px;max-width:1580px;width:100%}
/* The sidebar stays permanently visible (like a normal dashboard) on any
   typical laptop/desktop width — it only collapses into a toggleable
   overlay drawer on genuinely narrow tablet/phone widths. Every sidebar
   link is a real page navigation (separate .html file, not an SPA route),
   so if this collapsed the sidebar at a wider breakpoint, it would default
   to hidden again on every single page it navigates to. */
.kasir-pay-toggle{display:flex;gap:4px;padding:4px;background:var(--paper);border:1px solid var(--line);border-radius:10px}
.kasir-pay-toggle button{flex:1;padding:9px 0;border:none;background:transparent;border-radius:7px;font-size:12.5px;font-weight:700;color:var(--muted);cursor:pointer;transition:.15s;font-family:inherit}
.kasir-pay-toggle button.active{background:var(--card);color:var(--ink);box-shadow:var(--shadow)}
@media(max-width:900px){.kasir-pos-grid{grid-template-columns:1fr !important}}
@media(max-width:900px){
  /* The collapse-to-icon-rail feature is desktop-only — on the mobile
     off-canvas drawer, always show the full-width sidebar regardless of
     the desktop collapsed preference stored in localStorage. */
  html.sidebar-collapsed{--admin-sidebar-w:264px}
  html.sidebar-collapsed .admin-nav-group-label{display:block}
  html.sidebar-collapsed .admin-sidebar-brand-text,
  html.sidebar-collapsed .admin-sidebar-badge-text,
  html.sidebar-collapsed .admin-nav-label{display:inline}
  html.sidebar-collapsed .admin-nav-link{justify-content:flex-start;padding:10px 12px}
  html.sidebar-collapsed .admin-sidebar-brand{justify-content:flex-start;padding:22px 22px 18px}
  html.sidebar-collapsed .admin-sidebar-badge{justify-content:flex-start;padding:7px 12px;margin:0 18px 18px}
  .admin-sidebar{transform:translateX(-100%)}
  .admin-sidebar.is-open{transform:none;box-shadow:var(--shadow-lg)}
  .admin-main{margin-left:0}
  .admin-sidebar-toggle{display:inline-flex}
  .admin-sidebar-overlay{display:block;position:fixed;inset:0;background:rgba(11,16,32,.45);z-index:45;opacity:0;pointer-events:none;transition:opacity .2s}
  .admin-sidebar-overlay.is-open{opacity:1;pointer-events:auto}
  .admin-content{padding:20px 18px 50px}
  .admin-topbar{padding:14px 18px}
}

/* KPI cards (TailAdmin-style: icon square, trend badge top-right, big value).
   A colored top accent (via the same --kpi-accent set by the .plan/.usage/
   .history/.crm icon variant, so no extra markup is needed) plus a hover
   lift gives each card a bit more life than a flat bordered box. */
.kpi-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin:0 0 20px}
.kpi-card{position:relative;overflow:hidden;padding:20px 20px 18px;background:var(--card);border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:12px;transition:transform .18s ease,box-shadow .18s ease;--kpi-accent:var(--accent);--kpi-accent-2:var(--accent-2);opacity:0;transform:translateY(10px);animation:cardIn .4s ease forwards}
.kpi-card:nth-child(2){animation-delay:.05s}.kpi-card:nth-child(3){animation-delay:.1s}.kpi-card:nth-child(4){animation-delay:.15s}
.kpi-card:before{content:"";position:absolute;left:0;top:0;right:0;height:3px;background:linear-gradient(90deg,var(--kpi-accent),var(--kpi-accent-2))}
.kpi-card:hover{transform:translateY(-3px);box-shadow:0 20px 40px -16px rgba(15,18,30,.2)}
.kpi-card-clickable{cursor:pointer}
.kpi-card-clickable:hover{border-color:var(--accent)}
.kpi-card-clickable.active{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft),var(--shadow)}
.kpi-card:has(.kpi-icon.plan){--kpi-accent:#c9a227;--kpi-accent-2:#e7c866}
.kpi-card:has(.kpi-icon.history){--kpi-accent:#0f766e;--kpi-accent-2:#2dd4bf}
.kpi-card:has(.kpi-icon.crm){--kpi-accent:#6d28d9;--kpi-accent-2:#a78bfa}
.kpi-card-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.kpi-icon{display:grid;place-items:center;width:44px;height:44px;border-radius:12px;font-size:18px;flex:none}
.kpi-icon.plan{background:linear-gradient(155deg,#fdf5e2,#fbe8bd);color:#a16207}
.kpi-icon.usage{background:linear-gradient(155deg,var(--accent-soft),#d7e2ff);color:var(--accent)}
.kpi-icon.history{background:linear-gradient(155deg,#e6faf7,#c7f3ea);color:#0f766e}
.kpi-icon.crm{background:linear-gradient(155deg,#f2ecff,#e2d4ff);color:#6d28d9}
.kpi-trend{display:inline-flex;align-items:center;gap:5px;padding:4px 9px;border-radius:100px;font-size:11px;font-weight:800;flex:none}
.kpi-trend.up{background:#e8faf0;color:var(--good)}
.kpi-trend.down{background:#fdeeee;color:var(--bad)}
.kpi-trend.new{background:var(--accent-soft);color:var(--accent)}
.kpi-body{display:flex;flex-direction:column;gap:4px}
.kpi-label{font-size:12px;font-weight:700;color:var(--muted)}
.kpi-value{font-size:22px;font-weight:800;font-family:var(--heading);color:var(--ink);letter-spacing:-.01em}
.kpi-sub{font-size:11.5px;color:var(--faint)}
@media(max-width:1200px){.kpi-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.kpi-grid{grid-template-columns:1fr}}

/* Simpler label/value/hint stat tile (no icon) used by the platform-wide
   Kasir admin pages (admin-kasir-transactions.html, admin-ppob.html,
   admin-attention.html) — same card/grid language as .kpi-card above, just
   without the icon row those pages' 2-3 tile rows don't need. */
.admin-stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:16px;margin:0 0 20px}
.admin-stat-card{padding:18px 20px;background:var(--card);border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:4px}
.admin-stat-label{font-size:12px;font-weight:700;color:var(--muted)}
.admin-stat-value{font-size:22px;font-weight:800;font-family:var(--heading);color:var(--ink);letter-spacing:-.01em}
.admin-stat-hint{font-size:11.5px;color:var(--faint)}

/* Finance dashboard: a distinguished "hero" overview card plus labeled
   dividers that group several .card blocks into named sections — used on
   admin-finance.html to separate the Kasir tenant wallet system from the
   older manual Midtrans withdrawal bookkeeping, so the two aren't mistaken
   for the same balance. */
.finance-hero-card{position:relative;overflow:hidden;border-color:color-mix(in srgb, var(--accent) 22%, var(--line))}
.finance-hero-card:before{content:"";position:absolute;left:0;top:0;right:0;height:4px;background:linear-gradient(90deg,var(--accent),var(--accent-2))}
/* A full colored bar per section (not just small text + a thin line) so
   scrolling from one finance section into the next (Saldo Kasir Tenant / H2H
   / Midtrans) is unmistakable even at a glance — each gets its own accent
   via the .tenant/.h2h/.midtrans modifier class, not just varying icons. */
.finance-section-divider{display:flex;align-items:center;gap:10px;margin:32px 0 16px;padding:11px 16px;border-radius:12px;font-family:var(--heading);font-size:13px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;--fsd-accent:var(--accent);background:color-mix(in srgb, var(--fsd-accent) 13%, var(--card));border:1px solid color-mix(in srgb, var(--fsd-accent) 32%, var(--line));color:var(--ink)}
.finance-section-divider i{color:#fff;font-size:12px;width:26px;height:26px;flex:none;display:inline-flex;align-items:center;justify-content:center;background:var(--fsd-accent);border-radius:8px}
.finance-section-divider.tenant{--fsd-accent:#6d28d9}
.finance-section-divider.h2h{--fsd-accent:#b45309}
.finance-section-divider.midtrans{--fsd-accent:#0f766e}
.admin-section h2{font-family:var(--heading);font-size:14px;margin:0 0 16px;display:flex;align-items:center;gap:9px;font-weight:800;color:var(--ink)}
.admin-section h2 i{color:var(--accent);width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;background:var(--accent-soft);border-radius:6px;font-size:11px}
.admin-content .card{transition:box-shadow .18s ease,border-color .18s ease}
.admin-content .card:hover{box-shadow:0 16px 34px -18px rgba(15,18,30,.18);border-color:color-mix(in srgb, var(--accent) 22%, var(--line))}
.admin-content .card h2 i,
.admin-content .admin-section h2 i{background:linear-gradient(155deg,var(--accent-soft),color-mix(in srgb, var(--accent) 30%, white))}
.admin-chart{display:flex;align-items:flex-end;gap:4px;height:140px;padding:16px 12px 0;background:linear-gradient(180deg,color-mix(in srgb, var(--accent) 5%, transparent),transparent 70%);border-radius:12px}
.admin-chart-bar{flex:1;background:linear-gradient(180deg,var(--accent-2),var(--accent));border-radius:6px 6px 2px 2px;min-height:5px;transition:transform .15s ease,filter .15s ease;cursor:default;transform-origin:bottom}
.admin-chart-bar:hover{filter:brightness(1.08);transform:scaleY(1.02)}
.admin-chart-bar.is-peak{background:linear-gradient(180deg,#e7c866,var(--gold))}
.admin-price-subhead{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:700;color:var(--ink);margin:0 0 12px}
.admin-price-subhead i{color:var(--accent)}
.admin-price-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.admin-price-field label{display:block;font-size:12px;font-weight:700;color:var(--muted);margin-bottom:8px;text-transform:uppercase;letter-spacing:.05em}
.admin-price-input-row{display:flex;align-items:center;gap:8px;border:1px solid var(--line);border-radius:var(--radius-sm);padding:6px 10px}
.admin-price-input-row span{color:var(--muted);font-size:13px;font-weight:700}
.admin-price-input-row input{border:none;flex:1;font-size:14px;font-weight:700;padding:6px 0;width:0;min-width:0}
.admin-price-input-row input:focus{outline:none}
@media(max-width:760px){.admin-price-grid{grid-template-columns:1fr}}
.admin-feature-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
.admin-feature-col label{display:block;font-size:12px;font-weight:700;color:var(--muted);margin-bottom:8px;text-transform:uppercase;letter-spacing:.05em}
.admin-feature-list{list-style:none;margin:0 0 10px;padding:0;display:flex;flex-direction:column;gap:6px;min-height:20px}
.admin-feature-list li{display:flex;align-items:center;gap:8px;padding:7px 9px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--paper);transition:opacity .15s ease,border-color .15s ease}
.admin-feature-list li[draggable="true"]{cursor:grab}
.admin-feature-list li.is-dragging{opacity:.4}
.admin-feature-list li.drag-over{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft) inset}
.admin-feature-grip{color:var(--faint);font-size:11px;cursor:grab;flex:none}
.admin-feature-text{flex:1;font-size:12.5px;line-height:1.4}
.admin-feature-actions{display:flex;gap:2px;flex:none}
.admin-feature-actions button{width:22px;height:22px;border:none;background:none;border-radius:5px;color:var(--muted);cursor:pointer;font-size:10px;display:grid;place-items:center;transition:.15s}
.admin-feature-actions button:hover{background:var(--accent-soft);color:var(--accent)}
.admin-feature-actions [data-delete]:hover{background:#fdeeee;color:var(--bad)}
.admin-feature-add{display:flex;gap:6px}
.admin-feature-add input{flex:1;min-width:0;padding:8px 10px;border:1px solid var(--line);border-radius:var(--radius-sm);font-size:12.5px}
@media(max-width:1080px){.admin-feature-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.admin-feature-grid{grid-template-columns:1fr}}
.stat-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.stat-label{font-size:11px;font-weight:700;color:var(--faint);text-transform:uppercase;letter-spacing:.06em}
.stat-value{font-size:15px;font-weight:800;font-family:var(--heading);color:var(--ink)}
.stat-sub{font-size:11.5px;color:var(--muted)}
.usage-bar{margin-top:7px;height:6px;border-radius:100px;background:var(--paper);overflow:hidden}
.usage-bar-fill{height:100%;border-radius:100px;background:var(--accent);transition:width .3s ease}
.usage-bar-fill.warn{background:var(--gold)}
.usage-bar-fill.danger{background:var(--bad)}
.stat-cta{align-self:center;font-size:12px;font-weight:700;color:var(--accent);white-space:nowrap;display:inline-flex;align-items:center;gap:4px;flex:none}
.plan-pill{display:inline-flex;align-items:center;gap:7px;padding:6px 13px;border-radius:100px;font-size:12px;font-weight:800;font-family:var(--heading);letter-spacing:.02em}
.plan-pill.plan-free{background:#eef0f5;color:#5b6472}
.plan-pill.plan-basic{background:var(--accent-soft);color:var(--accent)}
.plan-pill.plan-pro{background:#fdf5e2;color:#a16207}
.plan-pill.plan-business{background:#eeeeff;color:#3730a3}
/* Quick-access shortcut row on the user dashboard */
.quick-actions{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;margin:0 0 20px}
.quick-action{display:flex;flex-direction:column;align-items:flex-start;gap:10px;padding:16px 16px 15px;background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);font-size:12.8px;font-weight:700;color:var(--ink);transition:transform .15s ease,box-shadow .15s ease,border-color .15s ease}
.quick-action:hover{transform:translateY(-2px);box-shadow:0 18px 36px -14px rgba(15,18,30,.18);border-color:var(--accent)}
.quick-action-icon{display:grid;place-items:center;width:34px;height:34px;border-radius:10px;background:var(--accent-soft);color:var(--accent);font-size:14px}
@media(max-width:900px){.dash-stats{grid-template-columns:1fr}}
@media(max-width:760px){.dash-hero{flex-direction:column;align-items:flex-start}}

/* Smaller hero for single-purpose interior pages (account, security,
   upgrade) — same navy/gold language as the dashboard hero, lighter touch. */
.settings-hero{position:relative;overflow:hidden;margin-top:28px;padding:26px 30px;border-radius:18px;background:linear-gradient(155deg,var(--navy) 0%,var(--navy-2) 65%,#1b2140 100%);display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.settings-hero:before{content:"";position:absolute;width:280px;height:280px;border-radius:50%;right:-100px;top:-120px;background:radial-gradient(circle,rgba(60,99,224,.35),transparent 70%);filter:blur(10px)}
.settings-hero:after{content:"";position:absolute;width:200px;height:200px;border-radius:50%;left:-80px;bottom:-120px;background:radial-gradient(circle,rgba(201,162,39,.16),transparent 70%);filter:blur(10px)}
.settings-hero-icon{position:relative;z-index:1;display:grid;place-items:center;width:50px;height:50px;border-radius:14px;background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.18);color:var(--gold);font-size:21px;flex:none}
.settings-hero-text{position:relative;z-index:1}
.settings-hero-text h1{font-family:var(--heading);font-size:22px;margin:0 0 4px;color:#fff;font-weight:800;letter-spacing:-.01em}
.settings-hero-text p{margin:0;color:#c3c9de;font-size:13.5px;max-width:480px}
.settings-hero-badge{position:relative;z-index:1;margin-left:auto;padding:10px 18px;border-radius:100px;background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.22);color:#fff;font-size:12.5px;font-weight:700;white-space:nowrap}
.settings-hero-badge b{color:var(--gold);font-family:var(--heading)}
@media(max-width:760px){.settings-hero{flex-direction:column;align-items:flex-start}.settings-hero-badge{margin-left:0}}

.history-toolbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-top:18px}
/* All 126 document types grouped into the same product categories used on
   the dashboard, collapsed behind one chip per category — clicking a chip
   reveals just that category's generator list below it. Replaces the old
   flat single-row-of-126-pills layout (originally a flat-list-of-~30 that
   already needed a scrollable row; at 126 it stopped being usable at all). */
.history-filters{margin:18px 0 16px}
.history-cat-row{display:flex;gap:8px;flex-wrap:wrap}
.history-cat-btn{display:flex;align-items:center;gap:7px;padding:9px 14px;border-radius:100px;border:1px solid var(--line);background:var(--card);font-size:12.5px;font-weight:700;color:var(--muted);cursor:pointer;transition:.15s}
.history-cat-btn i.history-cat-icon{color:var(--accent);font-size:12.5px}
.history-cat-btn .history-cat-count{padding:1px 7px;border-radius:100px;background:var(--paper);color:var(--faint);font-size:10.5px;font-weight:700}
.history-cat-btn .history-cat-caret{font-size:9px;color:var(--faint);transition:transform .15s ease}
.history-cat-btn:hover{border-color:var(--accent);color:var(--ink)}
.history-cat-btn.open{background:var(--accent-soft);border-color:var(--accent);color:var(--ink)}
.history-cat-btn.open .history-cat-caret{transform:rotate(180deg)}
.history-cat-btn.has-active{border-color:var(--accent)}
.history-cat-btn.has-active .history-cat-count{background:var(--accent);color:#fff}
.history-cat-panel{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;padding:12px;border-radius:var(--radius-sm);background:var(--paper);border:1px solid var(--line)}
.history-cat-panel[hidden]{display:none}
.history-filter-btn{flex:none;padding:8px 14px;border-radius:100px;border:1px solid var(--line);background:var(--card);font-size:12.5px;font-weight:600;color:var(--muted);cursor:pointer;transition:.15s;white-space:nowrap}
.history-filter-btn:hover{border-color:var(--accent);color:var(--accent)}
.history-filter-btn.active{background:var(--navy);color:#fff;border-color:var(--navy)}
.history-table{width:100%;border-collapse:collapse;font-size:13px}
.history-table th{text-align:left;padding:12px;font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--faint);border-bottom:1px solid var(--line)}
.history-table td{padding:12px;border-bottom:1px solid var(--line);vertical-align:middle;color:var(--ink)}
.history-table tr:last-child td{border-bottom:none}
/* The bell in the top bar (app.js's mountNotifications). */
.topbar-bell-wrap{position:relative;display:inline-flex}
.topbar-bell{position:relative;width:38px;height:38px;display:inline-grid;place-items:center;border:1px solid var(--line);border-radius:12px;background:var(--card);color:var(--ink);cursor:pointer;font-size:15px}
.topbar-bell:hover{border-color:var(--accent);color:var(--accent)}
.topbar-bell.has-unread i{color:var(--accent)}
.topbar-bell-count{position:absolute;top:-5px;right:-5px;min-width:18px;height:18px;padding:0 4px;border-radius:9px;background:#ef4444;color:#fff;font:700 10px/18px Inter,system-ui,sans-serif;text-align:center;box-shadow:0 0 0 2px var(--card)}
.topbar-bell-count[hidden],.topbar-bell-menu[hidden]{display:none}
.topbar-bell-menu{position:absolute;top:calc(100% + 8px);right:0;z-index:120;width:340px;max-width:calc(100vw - 24px);border:1px solid var(--line);border-radius:14px;background:var(--card);box-shadow:var(--shadow-lg);overflow:hidden}
.tbn-head{display:flex;justify-content:space-between;align-items:center;padding:10px 14px;border-bottom:1px solid var(--line);font-size:13px}
.tbn-head button{border:0;background:none;color:var(--accent);font-size:12px;font-weight:600;cursor:pointer}
.tbn-list{max-height:60vh;overflow:auto}
.tbn-item{display:flex;gap:10px;padding:10px 14px;border-bottom:1px solid var(--line);text-decoration:none;color:var(--ink);font-size:12.5px}
.tbn-item:hover{background:var(--paper)}
.tbn-item.unread{background:var(--accent-soft)}
.tbn-item i{margin-top:2px;color:var(--accent)}
.tbn-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.tbn-text span{color:var(--muted);overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.tbn-text small{color:var(--faint);font-size:11px}
.tbn-empty{padding:18px 14px;color:var(--muted);font-size:12.5px;text-align:center}
.history-type-badge{display:inline-flex;align-items:center;padding:4px 10px;border-radius:100px;background:var(--accent-soft);color:var(--accent);font-size:11px;font-weight:700}
/* Edited in the Document Editor (history.html's decorateEditorLinks). */
.history-edited-badge{display:inline-flex;align-items:center;gap:4px;margin-left:6px;padding:3px 8px;border-radius:100px;background:#fef3c7;color:#92400e;font-size:10.5px;font-weight:700;text-decoration:none;white-space:nowrap}
.history-edited-badge:hover{background:#fde68a}
.history-edited-badge[data-approval="approved"],.history-edited-badge[data-approval="signed"]{background:#dcfce7;color:#166534}
.history-edited-badge[data-approval="changes"]{background:#fee2e2;color:#991b1b}
.history-table .btn.is-edited{color:#b45309;border-color:#fcd34d;background:#fffbeb}
html[data-theme="dark"] .history-edited-badge{background:rgba(245,158,11,.18);color:#fbbf24}
html[data-theme="dark"] .history-table .btn.is-edited{background:rgba(245,158,11,.12);color:#fbbf24;border-color:rgba(245,158,11,.4)}
.history-table tbody tr{transition:background-color .12s ease}
.history-table tbody tr:hover{background:var(--paper)}

/* Opt-in checklists: "Tampilkan di Dokumen" on the From/To cards and the
   invoice's "Opsi Pajak". These used to be bare checkboxes laid out with
   ad-hoc inline styles, so the box and its text sat on different baselines
   and the rows wrapped unevenly. Styling them as toggle chips instead makes
   the tick target the whole label and makes what is on vs off readable at a
   glance. Shared by all three so they can't drift apart again. */
.thb-checklist{margin-top:16px;padding-top:16px;border-top:1px solid var(--line)}
.thb-checklist-title{display:flex;align-items:center;gap:7px;font-size:11px;font-weight:700;color:var(--faint);text-transform:uppercase;letter-spacing:.07em}
.thb-checklist-title::before{content:"";width:3px;height:11px;border-radius:2px;background:var(--accent)}
.thb-checklist-hint{margin:6px 0 0;font-size:11.5px;line-height:1.55;color:var(--muted);max-width:52ch}
.thb-checklist-items{display:flex;flex-wrap:wrap;gap:9px;margin-top:12px}
.thb-checklist-items label{display:inline-flex;align-items:center;gap:8px;margin:0;padding:7px 14px 7px 10px;border:1px solid var(--line);border-radius:100px;background:var(--card);font-size:12.5px;font-weight:600;color:var(--muted);line-height:1.2;cursor:pointer;user-select:none;transition:border-color .15s ease,background .15s ease,color .15s ease,box-shadow .15s ease}
.thb-checklist-items label:hover{border-color:color-mix(in srgb, var(--accent) 45%, var(--line));color:var(--ink);box-shadow:0 2px 8px -3px color-mix(in srgb, var(--accent) 35%, transparent)}
.thb-checklist-items input[type="checkbox"]{appearance:none;-webkit-appearance:none;flex:none;width:16px;height:16px;margin:0;border:1.5px solid color-mix(in srgb, var(--muted) 55%, transparent);border-radius:5px;background:var(--card) center/10px no-repeat;cursor:pointer;transition:background-color .15s ease,border-color .15s ease}
.thb-checklist-items label:hover input[type="checkbox"]{border-color:var(--accent)}
.thb-checklist-items input[type="checkbox"]:checked{border-color:var(--accent);background-color:var(--accent);background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='3.5 8.5 6.5 11.5 12.5 4.5'/%3E%3C/svg%3E")}
/* :has() is the only part that needs a modern engine; without it the chips
   simply stay in their resting colour, which is still perfectly usable. */
.thb-checklist-items label:has(input:checked){border-color:transparent;background:var(--accent-soft);color:var(--accent);box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent)}
html[data-theme="dark"] .thb-checklist-items label{background:color-mix(in srgb, var(--card) 88%, transparent)}
html[data-theme="dark"] .thb-checklist-items label:has(input:checked){background:color-mix(in srgb, var(--accent) 22%, var(--card))}
html[data-theme="dark"] .thb-checklist-items input[type="checkbox"]{background-color:color-mix(in srgb, var(--card) 70%, transparent)}

/* Kasir module's own table polish — scoped to .kasir-content (every
   kasir-*.html wraps its <main class="admin-content"> in this) rather than
   changing .history-table globally, since that same class is also used by
   admin/, dashboard, history, customers, etc. pages nobody asked to change.
   Tinted header, zebra rows, an accent-tinted hover, and rounded corners on
   the outer cells so the table reads as one polished card element instead
   of a bare grid of lines. */
.kasir-content .history-table{border-radius:var(--radius-sm);overflow:hidden}
.kasir-content .history-table th,
.kasir-content .history-table td{text-align:center}
.kasir-content .history-table thead th{background:var(--paper);font-weight:800;padding:13px 14px;border-bottom:2px solid var(--line)}
.kasir-content .history-table thead th:first-child{border-top-left-radius:var(--radius-sm)}
.kasir-content .history-table thead th:last-child{border-top-right-radius:var(--radius-sm)}
.kasir-content .history-table td{padding:13px 14px}
.kasir-content .history-table tbody tr:nth-child(even){background:color-mix(in srgb, var(--paper) 60%, transparent)}

/* Any .history-table rendered inside a SweetAlert2 popup (e.g. admin-
   finance.html's KPI-tile drill-down modals, the Saldo Kasir ledger modal)
   gets the same centered header/cell treatment as .kasir-content — a modal
   reads as a focused, self-contained table, so it should look like one
   regardless of which page opened it. Scoped to .swal2-popup rather than
   changing .history-table globally so ordinary in-page admin tables (the
   ones this rule doesn't apply to) keep their existing left-aligned layout. */
.swal2-popup .history-table th,
.swal2-popup .history-table td{text-align:center}
.kasir-content .history-table tbody tr:hover{background:var(--accent-soft)}
.kasir-content .history-table tbody tr td:first-child{font-weight:600;color:var(--ink)}
.kasir-content .history-table tbody tr:last-child td:first-child{border-bottom-left-radius:var(--radius-sm)}
.kasir-content .history-table tbody tr:last-child td:last-child{border-bottom-right-radius:var(--radius-sm)}
.kasir-content .history-table tfoot td{background:var(--paper);font-weight:700;border-top:2px solid var(--line)}
.kasir-content .history-table tfoot tr:last-child td:first-child{border-bottom-left-radius:var(--radius-sm)}
.kasir-content .history-table tfoot tr:last-child td:last-child{border-bottom-right-radius:var(--radius-sm)}

/* grid-column:1/-1 only takes effect when the element actually sits inside
   a display:grid container (harmless no-op otherwise) — needed because a
   lone .history-empty/.admin-loading dropped into a multi-column grid (e.g.
   .admin-price-grid, .admin-feature-grid) would otherwise only fill the
   grid's first column instead of the card's full width, landing off-center. */
.history-empty,.admin-loading{grid-column:1/-1;width:100%}
.history-empty{padding:48px 20px;text-align:center;color:var(--faint);font-size:13.5px}
.history-empty i{display:block;font-size:24px;margin-bottom:10px;color:var(--faint)}
.history-empty b{display:block;color:var(--muted);font-size:13.5px;margin-bottom:3px;font-weight:700}
.history-pagination{display:flex;justify-content:center;align-items:center;gap:12px;margin:20px 0 40px}

/* Section header row (h2 + right-aligned actions like an export/add button
   or a result-count chip) — an opt-in upgrade to the plain .card h2 used
   wherever a card needs more than just a title. */
.card-head{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:14px}
.card-head h2{margin:0 !important}
.card-head-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.card-head-count{font-size:12px;font-weight:700;color:var(--muted);background:var(--paper);padding:5px 11px;border-radius:100px}

/* Inline loading state — replaces bare "Memuat..." text with a small spinner. */
.admin-loading{display:flex;align-items:center;justify-content:center;gap:10px;padding:48px 20px;color:var(--faint);font-size:13px}
.admin-spinner{width:15px;height:15px;border-radius:50%;border:2px solid var(--line);border-top-color:var(--accent);animation:adminSpin .7s linear infinite;flex:none}
@keyframes adminSpin{to{transform:rotate(360deg)}}

/* Status pills (payment/withdrawal/etc. state) — reusable so pages stop
   hand-rolling inline background/color per status. */
.status-badge{display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border-radius:100px;font-size:11px;font-weight:800}
.status-badge:before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}
.status-badge.good{background:#e8faf0;color:var(--good)}
.status-badge.warn{background:#fdf5e2;color:#a16207}
.status-badge.bad{background:#fdeeee;color:var(--bad)}
.status-badge.neutral{background:var(--paper);color:var(--muted)}

/* Unsaved-changes affordance — a small dot appended next to a section's
   title (only shown while .is-dirty is on an ancestor) plus, where a section
   has one, a "Batalkan perubahan" ghost button that restores the last-saved
   snapshot. Used by the plan price editor and the landing-page content
   editor, both of which let several fields drift from their saved value
   before the admin hits Save. */
.dirty-dot{display:none;width:7px;height:7px;border-radius:50%;background:var(--gold);margin-left:8px;flex:none;box-shadow:0 0 0 3px color-mix(in srgb, var(--gold) 25%, transparent);vertical-align:middle}
.is-dirty .dirty-dot{display:inline-block}

.admin-toolbar-search{position:relative;flex:1;min-width:200px}
.admin-toolbar-search i{position:absolute;left:12px;top:50%;transform:translateY(-50%);color:var(--faint);font-size:12.5px}
.admin-toolbar-search input{width:100%;padding:10px 12px 10px 32px;border:1px solid var(--line);border-radius:var(--radius-sm);font-size:13px}

/* Landing-page content editor: search + jump-to-section toolbar, a two-
   column layout (form left, sticky live-preview mockup right), and a
   scaled-down reproduction of the real landing sections using the same
   navy/gold visual language as .hero-band/.dash-hero rather than the actual
   full-size components (which are sized for a full page width, not a 340px
   sidebar). Search highlights matching field labels/values and auto-opens
   any section containing a match. */
.content-editor-toolbar{position:sticky;top:0;z-index:15;display:flex;gap:10px;flex-wrap:wrap;align-items:center;background:var(--paper);padding:10px 0;margin-bottom:4px}
.content-jump-nav{display:flex;gap:6px;flex-wrap:wrap}
.content-jump-nav button{padding:8px 13px;border-radius:100px;border:1px solid var(--line);background:var(--card);font-size:12px;font-weight:700;color:var(--muted);cursor:pointer;transition:.15s;white-space:nowrap}
.content-jump-nav button:hover{border-color:var(--accent);color:var(--accent)}
.content-jump-nav button.active{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.content-field-match{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}

.content-editor-layout{display:grid;grid-template-columns:1fr 340px;gap:20px;align-items:start}
@media(max-width:1100px){.content-editor-layout{grid-template-columns:1fr}}

.content-preview{position:sticky;top:70px;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);overflow:hidden}
@media(max-width:1100px){.content-preview{position:static}}
.content-preview-label{display:flex;align-items:center;gap:8px;padding:12px 16px;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);border-bottom:1px solid var(--line)}
.content-preview-label i{color:var(--accent)}
.content-preview-body{max-height:calc(100vh - 150px);overflow-y:auto;padding:14px}
.content-preview-hero{position:relative;overflow:hidden;padding:22px 18px;border-radius:14px;background:linear-gradient(165deg,var(--navy) 0%,var(--navy-2) 65%,#1b2140 100%)}
.content-preview-hero-badge{display:inline-flex;align-items:center;gap:6px;padding:5px 10px;border-radius:100px;background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.18);font-size:10px;font-weight:700;color:#e8ecff;margin-bottom:10px}
.content-preview-hero h3{font-family:var(--heading);font-size:16px;line-height:1.3;margin:0 0 8px;color:#fff;font-weight:800}
.content-preview-hero h3 em{font-style:normal;color:var(--gold)}
.content-preview-hero p{margin:0 0 12px;font-size:11.5px;line-height:1.55;color:#c3c9de}
.content-preview-hero-promo{color:var(--gold)!important;padding-left:8px;border-left:2px solid var(--gold)}
.content-preview-hero-cta{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px}
.content-preview-hero-cta span{padding:6px 11px;border-radius:100px;font-size:10.5px;font-weight:700}
.content-preview-hero-cta span:first-child{background:var(--gold);color:#171100}
.content-preview-hero-cta span:last-child{background:rgba(255,255,255,.1);color:#fff;border:1px solid rgba(255,255,255,.22)}
.content-preview-hero-trust{display:flex;flex-direction:column;gap:5px;margin-bottom:12px}
.content-preview-hero-trust span{font-size:10px;color:#9aa2c2;font-weight:600;display:flex;align-items:center;gap:6px}
.content-preview-hero-trust i{color:#3ddc84;font-size:9px}
.content-preview-hero-stats{display:flex;gap:14px;padding-top:10px;border-top:1px solid rgba(255,255,255,.14)}
.content-preview-hero-stats div{display:flex;flex-direction:column}
.content-preview-hero-stats strong{font-family:var(--heading);font-size:13px;color:#fff}
.content-preview-hero-stats span{font-size:8.5px;color:#8891b3;text-transform:uppercase;letter-spacing:.06em}
.content-preview-section{margin-top:16px}
.content-preview-section h4{display:flex;align-items:center;gap:7px;font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin:0 0 8px}
.content-preview-step{display:flex;gap:9px;padding:8px 0;border-bottom:1px dashed var(--line);font-size:12px}
.content-preview-step:last-child{border-bottom:none}
.content-preview-step b{flex:none;width:20px;height:20px;border-radius:50%;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;font-size:10px;font-family:var(--heading)}
.content-preview-step div b{margin:0 0 2px;display:block;width:auto;height:auto;background:none;color:var(--ink);font-size:12px}
.content-preview-step div span{color:var(--muted);font-size:11px;line-height:1.4}
.content-preview-feature{padding:9px 10px;border:1px solid var(--line);border-radius:9px;margin-bottom:7px;font-size:12px}
.content-preview-feature b{display:block;color:var(--ink);margin-bottom:2px}
.content-preview-feature span{color:var(--muted);font-size:11px;line-height:1.4}
.content-preview-faq{padding:9px 10px;border:1px solid var(--line);border-radius:9px;margin-bottom:7px}
.content-preview-faq b{display:block;color:var(--ink);font-size:12px;margin-bottom:3px}
.content-preview-faq span{color:var(--muted);font-size:11px;line-height:1.4}
.content-preview-cta{padding:16px;border-radius:12px;background:linear-gradient(165deg,var(--navy) 0%,var(--navy-2) 100%);text-align:center}
.content-preview-cta b{display:block;color:#fff;font-family:var(--heading);font-size:13px;margin-bottom:5px}
.content-preview-cta span{color:#c3c9de;font-size:11px;line-height:1.5}
.content-preview-footer{margin-top:10px;padding-top:10px;border-top:1px solid var(--line);font-size:10.5px;color:var(--faint);line-height:1.5}

/* Floating profile card (overlaps hero on landing, normal spacing on dashboard) */
.profile-card{position:relative;z-index:2;margin:24px 0 8px;padding:22px 24px;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow-lg)}
.profile-card summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;font-weight:700;font-size:14px;font-family:var(--heading)}
.profile-card summary::-webkit-details-marker{display:none}
.profile-card summary i:last-child{color:var(--faint);transition:.2s}
.profile-card[open] summary i:last-child{transform:rotate(180deg)}
.profile-card .hint{font-weight:400;color:var(--faint);font-size:12px;margin-left:8px;font-family:var(--sans)}
.profile-switcher{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:16px}
.profile-switcher:empty{margin-top:0}
.profile-chip{padding:8px 14px;border-radius:100px;border:1px solid var(--line);background:var(--card);font-size:12.5px;font-weight:600;color:var(--muted);cursor:pointer;transition:.15s}
.profile-chip:hover{border-color:var(--accent);color:var(--accent)}
.profile-chip.active{background:var(--navy);color:#fff;border-color:var(--navy)}
.profile-logo-row{display:flex;align-items:center;gap:16px;margin-top:18px;padding-bottom:18px;border-bottom:1px dashed var(--line)}
.profile-logo-row[hidden]{display:none}
.profile-logo-row.compact{margin-top:0;margin-bottom:14px}
.profile-logo-transparent-toggle{display:flex;align-items:center;gap:8px;margin-top:8px;font-size:13px;color:var(--muted);cursor:pointer;user-select:none}
.profile-logo-transparent-toggle input{width:15px;height:15px;accent-color:var(--accent);cursor:pointer}
/* Certificate template picker: ready-made designs or the account's own upload. */
.cert-tpl-tabs{display:flex;gap:6px;margin-bottom:12px}
.cert-tpl-tab{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:9px 10px;border:1px solid var(--line);background:var(--card);border-radius:10px;font-family:var(--sans);font-size:12.5px;font-weight:700;color:var(--muted);cursor:pointer;transition:.15s}
.cert-tpl-tab:hover{color:var(--ink)}
.cert-tpl-tab.active{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
.cert-tpl-panel[hidden]{display:none}
.cert-tpl-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin-bottom:10px;max-height:480px;overflow-y:auto;padding:3px 5px 3px 3px;scrollbar-width:thin}
.cert-tpl-tile{padding:6px;border:2px solid var(--line);border-radius:10px;background:var(--card);cursor:pointer;text-align:left;font-family:var(--sans);transition:.15s}
.cert-tpl-tile:hover{border-color:color-mix(in srgb, var(--accent) 45%, var(--line))}
.cert-tpl-tile img{display:block;width:100%;aspect-ratio:297/210;object-fit:cover;border:1px solid var(--line);border-radius:5px;background:#fff}
.cert-tpl-tile span{display:block;margin-top:6px;font-size:11.5px;font-weight:700;color:var(--ink)}
.cert-tpl-tile.selected{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.cert-bg-size-field{margin-top:14px}
.doc-appearance-section .cert-bg-size-field{padding-top:14px;border-top:1px dashed var(--line)}
.cert-bg-size-row{display:flex;align-items:center;gap:8px}
.cert-bg-size-row .cert-bg-size-input{width:52px;padding:6px 4px;text-align:center;font-weight:700;font-size:13px;color:var(--ink);-moz-appearance:textfield}
.cert-bg-size-input::-webkit-outer-spin-button,.cert-bg-size-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}

/* API & Integrasi settings page (api-settings.html) */
.api-code-block{background:var(--paper);border:1px solid var(--line);border-radius:var(--radius-sm);padding:14px 16px;font-family:var(--mono,monospace);font-size:12.5px;color:var(--ink);overflow-x:auto;white-space:pre;line-height:1.6}
.api-endpoint-table{width:100%;border-collapse:collapse;font-size:12.5px}
.api-endpoint-table th{text-align:left;padding:8px 10px;font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--faint);border-bottom:1px solid var(--line)}
.api-endpoint-table td{padding:8px 10px;border-bottom:1px solid var(--line);color:var(--ink);vertical-align:top}
.api-endpoint-table code{font-family:var(--mono,monospace);font-size:12px;background:var(--paper);padding:2px 6px;border-radius:4px}
.api-key-secret-box{display:flex;align-items:center;gap:10px;padding:12px 14px;background:var(--accent-soft);border:1px dashed color-mix(in srgb, var(--accent) 40%, var(--line));border-radius:var(--radius-sm);font-size:12.5px;color:var(--ink)}
.api-key-secret-box code{font-family:var(--mono,monospace);font-size:12px}
.api-generator-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:6px;max-height:420px;overflow-y:auto;padding:6px;border:1px solid var(--line);border-radius:var(--radius-sm)}
.api-generator-item{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:6px;font-size:12.5px;color:var(--ink);cursor:pointer}
.api-generator-item:hover{background:var(--paper)}
.api-generator-item input{width:15px;height:15px;accent-color:var(--accent);cursor:pointer;flex:none}
.logo-preview{display:grid;place-items:center;width:72px;height:72px;flex:none;border-radius:14px;background:var(--paper);border:1px solid var(--line);color:var(--faint);font-size:20px;overflow:hidden}
.logo-preview img{width:100%;height:100%;object-fit:contain}
.avatar-preview{display:grid;place-items:center;width:72px;height:72px;flex:none;border-radius:50%;background:var(--paper);border:1px solid var(--line);color:var(--faint);font-size:24px;overflow:hidden}
.avatar-preview img{width:100%;height:100%;object-fit:cover}
.topbar-user-avatar{width:22px;height:22px;border-radius:50%;object-fit:cover;flex:none}
@media(max-width:640px){.topbar-user-name-text{display:none}}
/* flex:1;min-width:0 — without it this had no flex-grow at all, so as a flex
   item of .profile-logo-row (used on 129 pages: every generator's logo AND
   signature uploader) it only ever sized to its own content's natural width
   (~150-240px) rather than filling the row's remaining space. The checkbox
   label "Jadikan latar belakang transparan" and the hint paragraph then
   wrapped into a cramped multi-line column while the rest of the row sat
   empty — same shrink-to-fit oversight as .wallet-hero-body/.ppob-hero-body
   elsewhere in this file, just never noticed here since nothing overlapped,
   it just looked unbalanced. min-width:0 lets it size down too, for the
   narrow phones where .logo-preview's fixed 72px already claims most of a
   very tight row. */
.profile-logo-actions{display:flex;flex-direction:column;gap:6px;flex:1;min-width:0}
.profile-logo-buttons{display:flex;align-items:center;flex-wrap:wrap;gap:8px}
.profile-logo-hint{margin:0;font-size:11.5px;color:var(--faint)}
/* --- Documentation pages (/panduan, /kasir/panduan) --- */
.doc-layout{display:grid;grid-template-columns:220px 1fr;gap:24px;align-items:start}
@media(max-width:900px){.doc-layout{grid-template-columns:1fr}}
.doc-toc{position:sticky;top:16px;padding:14px;background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);box-shadow:var(--shadow)}
@media(max-width:900px){.doc-toc{position:static}}
.doc-toc-title{font-size:11px;font-weight:800;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;margin:0 0 8px}
.doc-toc a{display:block;padding:6px 9px;border-radius:7px;font-size:12.5px;color:var(--muted);text-decoration:none;transition:background-color .12s ease,color .12s ease}
.doc-toc a:hover{background:var(--paper);color:var(--ink)}
.doc-toc a.active{background:var(--accent-soft);color:var(--accent);font-weight:700}
.doc-section{scroll-margin-top:16px}
.doc-section+.doc-section{margin-top:18px}
.doc-section h2{display:flex;align-items:center;gap:9px;margin:0 0 4px;font-family:var(--heading);font-size:17px;font-weight:800;color:var(--ink)}
.doc-section h2 i{color:var(--accent);font-size:15px}
.doc-section h3{margin:18px 0 6px;font-family:var(--heading);font-size:14px;font-weight:800;color:var(--ink)}
.doc-section p{margin:0 0 10px;font-size:13.5px;line-height:1.7;color:var(--ink)}
.doc-section ul,.doc-section ol{margin:0 0 10px;padding-left:20px;font-size:13.5px;line-height:1.75;color:var(--ink)}
.doc-section li{margin:4px 0}
.doc-lede{font-size:13px;color:var(--muted);margin:0 0 14px !important}
.doc-step{display:flex;gap:11px;padding:11px 0;border-bottom:1px solid var(--line)}
.doc-step:last-child{border-bottom:none}
.doc-step-num{width:24px;height:24px;flex:none;border-radius:50%;background:var(--accent-soft);color:var(--accent);font-size:12px;font-weight:800;display:grid;place-items:center}
.doc-step-body{font-size:13.5px;line-height:1.65;color:var(--ink)}
.doc-step-body b{color:var(--ink)}
.doc-code{position:relative;margin:0 0 12px;padding:13px 15px;background:#0f172a;color:#e2e8f0;border-radius:10px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;line-height:1.65;overflow-x:auto;white-space:pre}
html[data-theme="dark"] .doc-code{background:#020617;border:1px solid var(--line)}
.doc-code .tok-key{color:#7dd3fc}
.doc-code .tok-str{color:#bef264}
.doc-code .tok-com{color:#94a3b8;font-style:italic}
.doc-copy{position:absolute;top:8px;right:8px;padding:4px 9px;border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.08);color:#e2e8f0;border-radius:6px;font-size:11px;font-weight:600;cursor:pointer}
.doc-copy:hover{background:rgba(255,255,255,.16)}
.doc-endpoint{display:flex;align-items:center;gap:9px;flex-wrap:wrap;padding:9px 0;border-bottom:1px solid var(--line);font-size:13px}
.doc-endpoint:last-child{border-bottom:none}
.doc-method{flex:none;min-width:54px;text-align:center;padding:3px 8px;border-radius:6px;font-size:10.5px;font-weight:800;letter-spacing:.03em;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.doc-method.get{background:#e6f4ff;color:#0369a1}
.doc-method.post{background:#e8faf0;color:#15803d}
.doc-method.put{background:#fef6e7;color:#b45309}
.doc-method.delete{background:#fdeeee;color:#b91c1c}
html[data-theme="dark"] .doc-method.get{background:rgba(3,105,161,.22);color:#7dd3fc}
html[data-theme="dark"] .doc-method.post{background:rgba(21,128,61,.22);color:#86efac}
html[data-theme="dark"] .doc-method.put{background:rgba(180,83,9,.22);color:#fcd34d}
html[data-theme="dark"] .doc-method.delete{background:rgba(185,28,28,.22);color:#fca5a5}
.doc-path{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;font-weight:600;color:var(--ink)}
.doc-endpoint span:last-child{color:var(--muted);font-size:12.5px}
code.doc-inline{padding:2px 6px;border-radius:5px;background:var(--paper);border:1px solid var(--line);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;color:var(--ink)}

/* Neutral explanatory note for admin pages — the "what am I actually
   looking at" box that sits above a stat row or a card's contents. Same
   shape as .finance-warning-banner below, but informational rather than a
   warning, so the two read as clearly different weights. */
.admin-note{display:flex;align-items:flex-start;gap:9px;padding:11px 14px;margin:0 0 16px;border-radius:10px;background:color-mix(in srgb, var(--accent) 7%, var(--card));border:1px solid color-mix(in srgb, var(--accent) 20%, var(--line));font-size:12.5px;line-height:1.65;color:var(--ink)}
.admin-note i{color:var(--accent);margin-top:2px;flex:none}
.admin-note b{color:var(--ink)}
.admin-note ul{margin:6px 0 0;padding-left:18px}
.admin-note li{margin:3px 0}

/* Money-safety callout — Midtrans is ONE shared merchant account behind
   both the platform's own plan-upgrade revenue AND every Kasir tenant's
   Non-Tunai sales (see admin-finance.html), so nothing in this app can stop
   an admin from over-withdrawing on Midtrans's OWN dashboard. This is the
   loud, hard-to-miss reminder of exactly how much of that shared real
   balance belongs to tenants and must be left alone. */
.finance-warning-banner{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:var(--radius-sm);background:color-mix(in srgb, var(--bad) 10%, var(--card));border:1px solid color-mix(in srgb, var(--bad) 35%, var(--line));font-size:12.5px;color:var(--ink);margin:0 0 16px}
.finance-warning-banner i{color:var(--bad);font-size:15px;margin-top:1px;flex:none}
.finance-warning-banner b{color:var(--bad)}
.profile-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:18px}
.profile-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:18px}

#fitur,#cara-kerja,#kenapa,#editor,#harga,#faq{scroll-margin-top:90px}

.eyebrow{display:flex;align-items:center;gap:8px;font-size:11.5px;font-weight:800;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);margin-bottom:10px}
.eyebrow:before{content:"";width:18px;height:2px;border-radius:2px;background:var(--accent);flex:none}
.section-heading{padding:44px 0 20px}
.section-heading h2{font-size:24px;margin:0 0 8px;letter-spacing:-.02em}
.section-heading p{margin:0;color:var(--muted);font-size:13.5px}

/* Scroll-reveal */
.reveal{opacity:0;transform:translateY(22px);transition:opacity .65s ease,transform .65s ease}
.reveal.is-visible{opacity:1;transform:none}
.step-item.reveal:nth-child(3){transition-delay:.08s}
.step-item.reveal:nth-child(5){transition-delay:.16s}
.feature-strip-item.reveal:nth-child(2){transition-delay:.06s}
.feature-strip-item.reveal:nth-child(3){transition-delay:.12s}
.feature-strip-item.reveal:nth-child(4){transition-delay:.18s}
.pricing-card.reveal:nth-child(2){transition-delay:.06s}
.pricing-card.reveal:nth-child(3){transition-delay:.12s}
.pricing-card.reveal:nth-child(4){transition-delay:.18s}
@media(prefers-reduced-motion:reduce){.reveal{opacity:1;transform:none;transition:none}}

.tool-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;padding:0 0 48px}
.tool-card{position:relative;padding:22px 22px 20px 24px;background:var(--card);border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:12px;box-shadow:var(--shadow);transition:transform .18s ease,box-shadow .18s ease;display:flex;flex-direction:column;gap:9px;opacity:0;transform:translateY(10px);animation:cardIn .45s ease forwards}
.tool-card:nth-child(1){animation-delay:.02s}.tool-card:nth-child(2){animation-delay:.06s}.tool-card:nth-child(3){animation-delay:.10s}.tool-card:nth-child(4){animation-delay:.14s}.tool-card:nth-child(5){animation-delay:.18s}.tool-card:nth-child(6){animation-delay:.22s}.tool-card:nth-child(7){animation-delay:.26s}
@keyframes cardIn{to{opacity:1;transform:none}}
.tool-card:hover{transform:translateY(-3px);box-shadow:0 18px 36px -14px rgba(15,18,30,.18)}
.tool-card .tool-icon{display:grid;place-items:center;width:38px;height:38px;border-radius:10px;background:var(--accent-soft);color:var(--accent);font-size:15px;transition:transform .18s ease}
.tool-card:hover .tool-icon{transform:scale(1.08) rotate(-4deg)}
.tool-card h3{margin:2px 0 0;font-size:16px;letter-spacing:-.01em;font-weight:700}
.tool-card p{margin:0;color:var(--muted);font-size:12.8px;flex:1;line-height:1.55}
.tool-card .tool-go{font-size:12px;font-weight:700;color:var(--accent);display:inline-flex;align-items:center;gap:6px;transition:gap .2s}
.tool-card:hover .tool-go{gap:10px}
.tool-badge{position:absolute;top:16px;right:16px;padding:4px 10px;border-radius:100px;background:var(--accent-soft);color:var(--accent);font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;display:inline-flex;align-items:center;gap:5px}
.tool-badge.locked{background:#fdf5e2;color:#a16207}
@media(max-width:1080px){.tool-grid{grid-template-columns:repeat(2,1fr)}.profile-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.tool-grid{grid-template-columns:1fr}.profile-grid{grid-template-columns:1fr}}

/* Carousel mode — applied by JS to any .tool-grid with more than 4 cards,
   so categories with 5+ tools scroll horizontally instead of wrapping. */
.tool-carousel-wrap{position:relative;padding:0 0 48px}
.tool-carousel-wrap .tool-grid{padding-bottom:0}
.tool-grid.is-carousel{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;-webkit-overflow-scrolling:touch;scrollbar-width:none}
.tool-grid.is-carousel::-webkit-scrollbar{display:none}
.tool-grid.is-carousel .tool-card{scroll-snap-align:start;flex:0 0 calc(25% - 12px)}
@media(max-width:1080px){.tool-grid.is-carousel .tool-card{flex:0 0 calc(50% - 8px)}}
@media(max-width:640px){.tool-grid.is-carousel .tool-card{flex:0 0 86%}}
.tool-carousel-btn{position:absolute;top:calc(50% - 30px);width:36px;height:36px;border-radius:50%;background:var(--card);border:1px solid var(--line);box-shadow:var(--shadow);display:grid;place-items:center;color:var(--ink);font-size:13px;cursor:pointer;z-index:5;transition:background .15s ease,color .15s ease,opacity .15s ease}
.tool-carousel-btn:hover{background:var(--accent-soft);color:var(--accent)}
.tool-carousel-btn.prev{left:-16px}
.tool-carousel-btn.next{right:-16px}
.tool-carousel-btn[disabled]{opacity:.3;cursor:default;pointer-events:none}
@media(max-width:900px){.tool-carousel-btn{display:none}}

/* Document categories (Sales/Purchasing/Warehouse/Finance/HR/Legal/Reports) */
.tool-category{margin-bottom:40px}
.tool-category:last-child{margin-bottom:0}
.tool-category-title{display:flex;align-items:center;gap:10px;font-size:16px;font-weight:800;margin:0 0 14px;color:var(--ink);font-family:var(--heading);letter-spacing:-.01em}
.tool-category-title:after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--line),transparent);margin-left:4px}
.tool-category-title i{width:30px;height:30px;border-radius:9px;background:var(--accent-soft);color:var(--accent);display:inline-flex;align-items:center;justify-content:center;font-size:13px;flex:none}
.tool-category-count{margin-left:auto;font-size:11px;font-weight:700;color:var(--faint);text-transform:uppercase;letter-spacing:.05em}

/* "Segera Hadir" placeholder cards for not-yet-built document types —
   same grid/sizing as .tool-card but dashed border and no link, so a
   category can list its full roadmap without implying a broken link. */
.tool-card-soon{position:relative;padding:22px 22px 20px 24px;background:var(--paper);border:1px dashed var(--line);border-left:3px dashed var(--faint);border-radius:12px;display:flex;flex-direction:column;gap:9px}
.tool-card-soon .tool-icon{display:grid;place-items:center;width:38px;height:38px;border-radius:10px;background:#eef0f5;color:var(--faint);font-size:15px}
.tool-card-soon h3{margin:2px 0 0;font-size:16px;letter-spacing:-.01em;font-weight:700;color:var(--muted)}
.tool-card-soon p{margin:0;color:var(--faint);font-size:12.8px;flex:1;line-height:1.55}
.soon-badge{position:absolute;top:16px;right:16px;padding:4px 10px;border-radius:100px;background:#eef0f5;color:var(--faint);font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.06em}

.feature-strip-section{padding:8px 0 52px}
.feature-strip{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-top:6px}
.feature-strip-item{position:relative;padding:24px 20px 22px;background:var(--card);border:1px solid var(--line);border-top:3px solid var(--accent);border-radius:12px;box-shadow:var(--shadow);transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease}
.feature-strip-item:hover{transform:translateY(-3px);box-shadow:0 18px 36px -14px rgba(15,18,30,.18)}
.feature-strip-icon{display:grid;place-items:center;width:40px;height:40px;border-radius:10px;background:var(--accent-soft);color:var(--accent);font-size:16px;margin-bottom:14px}
.feature-strip-item h3{margin:0 0 6px;font-size:14.5px;letter-spacing:-.01em}
.feature-strip-item p{margin:0;color:var(--muted);font-size:12.5px;line-height:1.55}
@media(max-width:1080px){.feature-strip{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.feature-strip{grid-template-columns:1fr}}

.site-footer{border-top:1px solid var(--line);padding:26px 0 44px;color:var(--faint);font-size:12.5px;display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px}

/* Generator layout: form-panel docks as a fixed full-height sidebar; the
   header + preview-panel form the main content area, offset by the
   sidebar's width so they fill the rest of the viewport (no more 1200px
   centered container on generator pages). */
.gen-shell{width:100%}
.gen-header{padding:28px 40px 6px;margin-left:var(--sidebar-w);transition:margin-left .2s ease}
.gen-header h1{font-family:var(--heading);font-size:23px;margin:0 0 4px;letter-spacing:-.015em;display:flex;align-items:center;gap:10px;font-weight:800}
.gen-header h1 i{color:var(--accent);font-size:19px}
.gen-header p{margin:0;color:var(--muted);font-size:13.5px}
/* Non-generator settings pages (profile.html, api-settings.html, ...) reuse
   .gen-header for their title block but aren't generator pages (no sidebar
   form-panel), so the shared margin-left:var(--sidebar-w) would otherwise
   shove it ~460px off the left edge, out of line with the .container-width
   card below it. Scoped here instead of changing .gen-header itself, which
   every one of the 126 generator pages also relies on. */
.gen-header.gen-header-banner{margin-left:0;padding:26px 32px;border-radius:var(--radius);background:linear-gradient(135deg,var(--accent-soft),var(--card) 75%);border:1px solid var(--line);box-shadow:var(--shadow)}
.gen-progress{margin-top:16px;display:flex;align-items:center;gap:10px;max-width:420px}
.gen-progress-track{flex:1;height:6px;border-radius:100px;background:var(--line);overflow:hidden}
.gen-progress-fill{height:100%;border-radius:100px;background:var(--accent);transition:width .25s ease}
.gen-progress-pct{font-size:11.5px;font-weight:700;color:var(--muted);flex:none;min-width:84px;white-space:nowrap;font-variant-numeric:tabular-nums}
.gen-progress.is-complete .gen-progress-fill{background:var(--good)}
.gen-progress.is-complete .gen-progress-pct{color:var(--good)}
.draft-banner{display:flex;align-items:center;gap:10px;padding:10px 14px;background:var(--accent-soft);border:1px dashed color-mix(in srgb, var(--accent) 40%, var(--line));border-radius:var(--radius-sm);font-size:12.5px;color:var(--ink);margin-bottom:2px}
.draft-banner i{color:var(--accent);flex:none}
.draft-banner span{flex:1}
.draft-banner .btn{padding:6px 12px;font-size:12px}
.autosave-indicator{position:fixed;bottom:18px;left:calc(var(--sidebar-w) + 18px);display:flex;align-items:center;gap:6px;padding:7px 13px;background:var(--ink);color:#fff;border-radius:100px;font-size:11.5px;font-weight:600;box-shadow:var(--shadow-lg);opacity:0;transform:translateY(6px);transition:opacity .25s ease,transform .25s ease,left .2s ease;pointer-events:none;z-index:40}
.autosave-indicator.is-visible{opacity:1;transform:translateY(0)}
.autosave-indicator i{color:#3ddc84}
@media(max-width:900px){.autosave-indicator{left:18px}}
.gen-layout{padding:18px 40px 60px;margin-left:var(--sidebar-w);transition:margin-left .2s ease}
/* "Dokumen Terkait" — internal-linking footer added to every one of the 126
   generator pages (see routes/pages.js's category folders), pointing at a
   few sibling document types from the same category. Shares .gen-layout's
   own sidebar-offset margin (declared right here, BEFORE the responsive
   overrides below, so the cascade's source-order tiebreak — not just
   specificity — lets @media(max-width:900px) below actually win on a
   narrow screen instead of this rule re-winning the tie every time). */
.related-docs{margin:0 0 0 var(--sidebar-w);padding:20px 40px 40px;border-top:1px solid var(--line);transition:margin-left .2s ease}
.related-docs h2{font-size:12.5px;font-weight:700;color:var(--muted);margin:0 0 12px;text-transform:uppercase;letter-spacing:.04em}
.related-docs-grid{display:flex;flex-wrap:wrap;gap:8px}
.related-doc-link{padding:8px 14px;border:1px solid var(--line);border-radius:100px;background:var(--card);color:var(--ink);font-size:12.5px;font-weight:600;text-decoration:none;transition:.15s ease}
.related-doc-link:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
.form-panel{position:fixed;top:var(--topbar-h);left:0;bottom:0;width:var(--sidebar-w);display:flex;flex-direction:column;gap:14px;padding:22px;overflow-y:auto;background:var(--card);border-right:1px solid var(--line);z-index:30;transition:width .2s ease}
body.panel-resizing .form-panel,body.panel-resizing .gen-header,body.panel-resizing .gen-layout,body.panel-resizing .autosave-indicator,body.panel-resizing .panel-collapse-btn{transition:none}

/* Form-panel resize: drag the thin strip on the right edge to resize
   freely (width written to --sidebar-w on <html> — see
   THB.initPanelResizer in app.js — so .gen-header/.gen-layout/
   .autosave-indicator, all keyed off that variable, follow automatically).
   The collapse button is a separate, fixed-position toggle, styled and
   positioned the same way as .admin-sidebar-collapse-btn. */
/* Fixed to the viewport (not a child of .form-panel) and tracks
   --sidebar-w via `left`, because .form-panel's own overflow-y:auto
   forces its overflow-x to clip too (a CSS quirk: setting only one
   overflow axis makes the other compute to non-visible as well) — a
   handle placed just outside the panel's own box would get clipped and
   become unclickable for a real mouse, even though synthetic
   dispatchEvent() calls in automated tests don't notice since they skip
   hit-testing entirely. */
.panel-resizer{position:fixed;top:var(--topbar-h);left:calc(var(--sidebar-w) - 3px);bottom:0;width:6px;z-index:34;cursor:col-resize;touch-action:none}
.panel-resizer:before{content:"";position:absolute;top:0;bottom:0;left:50%;width:2px;transform:translateX(-50%);background:transparent;transition:background .15s}
.panel-resizer:hover:before,body.panel-resizing .panel-resizer:before{background:var(--accent)}
body.panel-resizing{cursor:col-resize!important;user-select:none}
body.panel-resizing *{cursor:col-resize!important}
@media(max-width:900px){.panel-resizer{display:none}}

/* Sits centered in the topbar band (not lower, inside .form-panel's own
   scrollable area) so it never collides with that panel's scrollbar —
   z-index above the topbar's own (40) since it visually overlaps it. */
.panel-collapse-btn{position:fixed;top:calc(var(--topbar-h) - 0px);left:calc(var(--sidebar-w) - 0px);width:26px;height:26px;border-radius:50%;background:var(--card);border:1px solid var(--line);color:var(--muted);display:grid;place-items:center;font-size:10px;cursor:pointer;z-index:41;box-shadow:var(--shadow);padding:0;transition:left .2s ease}
.panel-collapse-btn:hover{color:var(--accent);border-color:var(--accent)}
html.panel-collapsed .form-panel{width:0!important;padding:0;overflow:hidden;border-right:none}
html.panel-collapsed .panel-resizer{display:none}
html.panel-collapsed .panel-collapse-btn{left:7px}
html.panel-collapsed .gen-header,html.panel-collapsed .gen-layout,html.panel-collapsed .related-docs{margin-left:0}
html.panel-collapsed .autosave-indicator{left:18px}
@media(max-width:900px){.panel-collapse-btn{display:none}}
html.doc-view-only .form-panel{display:none!important}
html.doc-view-only .gen-header,html.doc-view-only .gen-layout,html.doc-view-only .related-docs{margin-left:0!important}
html.doc-view-only .related-docs{display:none}
html.doc-view-only .gen-header p{display:none}
.preview-panel{display:flex;flex-direction:column;gap:12px}
.preview-label{display:flex;align-items:center;gap:8px;font-size:11.5px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.08em;padding-left:2px}
.preview-label .dot{width:7px;height:7px;border-radius:50%;background:var(--good);box-shadow:0 0 0 0 rgba(15,157,88,.5);animation:pulseDot 2s infinite}
.zoom-toolbar{margin-left:auto;display:flex;align-items:center;gap:2px;background:var(--card);border:1px solid var(--line);border-radius:100px;padding:3px;box-shadow:var(--shadow)}
.zoom-toolbar button{border:none;background:none;width:24px;height:24px;border-radius:50%;display:grid;place-items:center;color:var(--muted);cursor:pointer;font-size:10.5px;transition:.15s}
.zoom-toolbar button:hover{background:var(--accent-soft);color:var(--accent)}
.zoom-toolbar .zoom-pct{font-size:11px;font-weight:700;color:var(--ink);width:38px;text-align:center;flex:none}
.zoom-toolbar .zoom-fit{width:auto;padding:0 9px;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.03em}
@keyframes pulseDot{0%{box-shadow:0 0 0 0 rgba(15,157,88,.45)}70%{box-shadow:0 0 0 7px rgba(15,157,88,0)}100%{box-shadow:0 0 0 0 rgba(15,157,88,0)}}
/* Stacks the form above the preview. Kept at 900px (tablet portrait) rather
   than 1080px: a 1024px laptop has ample room for the two-pane layout, and
   collapsing it there pushed the live document preview — the whole point of
   the generator — below the fold while stretching short fields like "No.
   Invoice" to ~900px wide. The panel width steps down with the viewport
   instead — capped in JS (initPanelResizer's viewportCap in
   public/assets/js/app.js), because --sidebar-w is written there as an
   inline style on <html> and would outrank any @media rule here. */
@media(max-width:900px){
  .gen-header{margin-left:0;padding:24px 20px 6px}
  .gen-layout{margin-left:0;padding:18px 20px 60px}
  .related-docs{margin-left:0;padding:16px 20px 32px}
  .form-panel{position:static;width:100%;height:auto;border-right:none;border-bottom:1px solid var(--line)}
  /* The panel stops being the scroll container here, so a sticky bar would
     latch onto the page scroll and slide under the fixed topbar. */
  .form-section-nav{position:static}
}

.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow);padding:18px 20px;transition:border-color .2s}
.card h2{font-family:var(--heading);font-size:12.5px;margin:0 0 14px;text-transform:uppercase;letter-spacing:.07em;color:var(--muted);display:flex;align-items:center;gap:9px;font-weight:700}
.card h2 i{color:var(--accent);width:20px;height:20px;display:inline-flex;align-items:center;justify-content:center;background:var(--accent-soft);border-radius:6px;font-size:10.5px}
/* Jump-to-section strip above the form panel (built by initCollapsibleCards
   in app.js) — sticky so it stays reachable while scrolling a nine-card form.
   Two things keep it from looking like it floats over the content:
   - It paints .form-panel's OWN background (var(--card)) and bleeds out over
     the panel's 22px side padding, so cards passing underneath are fully
     covered edge to edge. (var(--bg) does not exist in this stylesheet, so
     it resolved to transparent.)
   - .form-panel is the scroll container and has padding:22px, and Chromium
     resolves a sticky `top` against its CONTENT edge — top:0 would park the
     bar 22px below the panel's top and leave a gap for cards to scroll
     through. top:-22px cancels that padding and pins it flush. */
.form-section-nav{position:sticky;top:-22px;z-index:5;display:flex;align-items:center;gap:8px;margin:0 -22px 2px;padding:14px 22px 10px;background:var(--card);border-bottom:1px solid var(--line)}
.form-section-jump{flex:1;min-width:0;padding:6px 9px;border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--muted);font-size:11.5px;font-weight:600;cursor:pointer}
.form-section-jump:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.form-section-all{flex:none;padding:5px 10px;border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--muted);font-size:11.5px;font-weight:700;white-space:nowrap;cursor:pointer;transition:.15s}
.form-section-all:hover{border-color:var(--accent);color:var(--accent)}
.card h2.card-toggle{cursor:pointer;user-select:none}
.card-chevron{margin-left:auto;font-size:11px;color:var(--muted);transition:transform .2s ease}
.card.collapsed .card-chevron{transform:rotate(-90deg)}
.card.collapsed>*:not(h2){display:none}
.card.collapsed{padding-bottom:14px}

.field-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.field{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}
.field[hidden]{display:none}
.field:last-child{margin-bottom:0}
.field label{font-size:12px;font-weight:600;color:var(--muted)}
.field input,.field select,.field textarea{padding:10px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:#fbfcfe;font-size:13.5px;width:100%;transition:.15s}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--accent);background:#fff;box-shadow:0 0 0 3px var(--accent-soft)}
/* Date fields shown as dd/mm/yyyy (app.js enhanceDateInput): a text field
   with a calendar at its end; the native date input behind it is kept,
   hidden, for the browser's own picker (moved under the field to open). */
input.thb-date-text,.field input.thb-date-text{padding-right:34px !important;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cpath d='M16 2v4M8 2v4M3 10h18'/%3E%3C/svg%3E") !important;background-repeat:no-repeat !important;background-position:right 11px center !important;background-size:16px 16px !important;font-variant-numeric:tabular-nums}
input.thb-date-text:hover{cursor:text}
input.thb-date-native{position:fixed !important;width:1px !important;height:1px !important;min-width:0 !important;padding:0 !important;border:0 !important;margin:0 !important;opacity:0 !important;pointer-events:none !important;left:0;top:0}
.field textarea{resize:vertical;min-height:70px;font-family:var(--sans)}

/* Every input[type="password"] on the site gets wrapped in this by
   THB.initPasswordToggles() (app.js) — a show/hide eye button, added once
   globally instead of by hand on each of the 5 password forms (login,
   register, reset-password, accept-invite, account's change-password). */
.password-field-wrap{position:relative;display:flex}
.password-field-wrap input{padding-right:38px!important}
.password-toggle-btn{position:absolute;top:50%;right:4px;transform:translateY(-50%);width:30px;height:30px;display:flex;align-items:center;justify-content:center;background:none;border:none;color:var(--muted);cursor:pointer;border-radius:8px;font-size:14px}
.password-toggle-btn:hover{color:var(--ink);background:var(--paper)}
.password-toggle-btn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--accent-soft)}

.bank-picker{display:grid;gap:8px}

.doc-theme-row{display:flex;flex-wrap:wrap;gap:9px;align-items:center}
.doc-color-swatch{width:26px;height:26px;border-radius:50%;border:2px solid #fff;box-shadow:0 0 0 1px var(--line);cursor:pointer;flex:none;padding:0;transition:.15s}
.doc-color-swatch:hover{transform:scale(1.1)}
.doc-color-swatch.active{box-shadow:0 0 0 2px var(--ink)}
.doc-color-custom{width:26px;height:26px;border-radius:50%;border:none;padding:0;cursor:pointer;background:none;flex:none}
.doc-color-custom::-webkit-color-swatch-wrapper{padding:0}
.doc-color-custom::-webkit-color-swatch{border-radius:50%;border:2px solid #fff;box-shadow:0 0 0 1px var(--line)}
.doc-theme-locked{display:flex;align-items:center;gap:10px;width:100%;box-sizing:border-box;padding:12px 14px;background:var(--accent-soft);border:1px dashed color-mix(in srgb, var(--accent) 40%, var(--line));border-radius:var(--radius-sm);font-size:12.5px;color:var(--muted)}
.doc-theme-locked[hidden]{display:none}
.doc-theme-locked i{color:var(--accent);flex:none}
.doc-theme-locked span{flex:1}

/* "Latar Dokumen" (THB.initDocBackground) — the uploaded background layer
   inside .doc-page, and its controls in the Tampilan Dokumen card.
   .has-doc-bg isolates the page so the layer's z-index:-1 sits just above the
   page's own white fill (on screen AND in print), under all of its content. */
.doc-page.has-doc-bg{isolation:isolate}
.doc-bg-layer{position:absolute;inset:0;z-index:-1;pointer-events:none;background-position:center;background-size:cover;background-repeat:no-repeat}
.doc-bg-section{margin-top:18px;padding-top:16px;border-top:1px solid var(--line);display:flex;flex-direction:column;gap:10px}
.doc-bg-title{display:flex;align-items:center;gap:7px;font-size:11px;font-weight:700;color:var(--faint);text-transform:uppercase;letter-spacing:.07em}
.doc-bg-title::before{content:"";width:3px;height:11px;border-radius:2px;background:var(--accent)}
.doc-bg-hint{margin:-4px 0 0;font-size:11.5px;line-height:1.55;color:var(--muted)}
.doc-bg-section .profile-logo-row{margin:0}
.doc-bg-controls{display:flex;flex-direction:column;gap:14px;padding-top:12px;border-top:1px dashed var(--line)}
.doc-bg-controls[hidden]{display:none}
.doc-bg-opacity-field,.doc-bg-size-field{margin:0}
.doc-bg-size-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.doc-bg-size-input{display:inline-flex;align-items:center;gap:4px;padding:0 10px;height:34px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card)}
.doc-bg-size-input:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent)}
.doc-bg-size-input input{width:44px;border:0;padding:0;margin:0;background:transparent;text-align:right;font-weight:700;font-size:13px;color:var(--ink);font-variant-numeric:tabular-nums;box-shadow:none;outline:none;-moz-appearance:textfield}
.doc-bg-size-input input::-webkit-outer-spin-button,.doc-bg-size-input input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.doc-bg-size-input span{font-size:12.5px;font-weight:600;color:var(--muted)}
.doc-bg-opacity-row{display:flex;align-items:center;gap:12px}
.doc-bg-opacity-row input[type="range"]{flex:1;min-width:0;height:6px;margin:0;appearance:none;-webkit-appearance:none;border-radius:100px;background:linear-gradient(to right,var(--accent) var(--fill,0%),var(--line) var(--fill,0%));cursor:pointer}
.doc-bg-opacity-row input[type="range"]::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:var(--card);border:2px solid var(--accent);box-shadow:0 1px 4px rgba(15,18,30,.2)}
.doc-bg-opacity-row input[type="range"]::-moz-range-thumb{width:14px;height:14px;border-radius:50%;background:var(--card);border:2px solid var(--accent);box-shadow:0 1px 4px rgba(15,18,30,.2)}
.doc-bg-opacity-row input[type="range"]:focus-visible{outline:2px solid color-mix(in srgb, var(--accent) 45%, transparent);outline-offset:4px}
.doc-bg-opacity-row output{min-width:44px;padding:4px 8px;border-radius:var(--radius-sm);background:var(--accent-soft);color:var(--accent);font-size:12px;font-weight:700;text-align:center;font-variant-numeric:tabular-nums}

/* Guest-mode banner (THB.mountGuestBanner) — appended to .gen-header on any
   generator page opened without logging in, explaining that every field and
   plan-gated control on the page is unlocked to try (see /api/plan's guest
   branch), and that saving/downloading needs a free account. */
.guest-trial-banner{margin-top:14px;display:flex;align-items:center;gap:12px;padding:12px 16px;background:linear-gradient(135deg,var(--accent-soft),var(--card) 80%);border:1px solid var(--line);border-radius:var(--radius-sm);box-shadow:var(--shadow);flex-wrap:wrap}
.guest-trial-banner i{color:var(--accent);font-size:16px;flex:none}
.guest-trial-banner span{flex:1;min-width:240px;font-size:12.5px;color:var(--muted);line-height:1.5}
.guest-trial-banner .btn{flex:none}
@media(max-width:640px){.guest-trial-banner{padding:10px 12px}.guest-trial-banner span{font-size:12px}}

/* Document design template picker — free for every plan, unlike the
   color/font customizer above. See THB.initDocTemplate in app.js and the
   .doc-page[data-template] rules further below.
//
   A flat wrap of chips stopped working once this grew past a couple of
   dozen options: 29 same-looking pills in one block is a wall to read, and
   a name like "Tabel Lebar" says nothing about WHERE anything actually
   moves. So each option is a card carrying a small wireframe of its own
   layout (see .tpl-mini below), and the cards are split into "style"
   (same skeleton, different skin) and "layout" (things that genuinely move
   sections around) so the two kinds of choice aren't mixed together. */
/* .doc-template-row is the CONTAINER element itself, hardcoded into all 126
   generator pages (<div class="doc-template-row" id="docTemplateCard">), so
   it stays a plain block and the actual grid lives on .doc-template-grid
   inside each group — giving the container the grid would have laid the two
   group blocks out as 86px columns. */
.doc-template-row{display:block}
.legal-topbar{border-bottom:1px solid var(--line);background:var(--card)}
.legal-topbar-inner{display:flex;align-items:center;justify-content:space-between;gap:16px;padding-top:14px;padding-bottom:14px;font-size:13.5px}
.legal-page{max-width:760px;padding-top:36px;padding-bottom:48px;line-height:1.7;color:var(--ink);font-size:15px}
.legal-page h1{font-size:30px;margin:0 0 4px;text-wrap:balance}
.legal-page h2{font-size:18px;margin:30px 0 8px}
.legal-page ul{padding-left:22px}
.legal-page li{margin:4px 0}
.legal-updated{color:var(--muted);font-size:13px;margin:0 0 22px}
.verify-banner{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:10px 20px;background:var(--accent-soft);border-bottom:1px solid color-mix(in srgb, var(--accent) 30%, var(--line));color:var(--ink);font-size:13px;line-height:1.5}
.verify-banner > i{color:var(--accent);font-size:16px;flex:none}
.verify-banner > span{flex:1;min-width:200px}
.verify-banner--gen{margin-left:var(--sidebar-w)}
@media(max-width:900px){.verify-banner--gen{margin-left:0}}
.doc-template-group + .doc-template-group{margin-top:16px}
.doc-template-group[hidden],.doc-template-btn[hidden],.doc-template-empty[hidden]{display:none}
.doc-template-toolbar{display:flex;flex-direction:column;gap:9px;margin-bottom:14px}
.doc-template-search{width:100%;box-sizing:border-box;padding:9px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);color:var(--ink);font-size:13px}
.doc-template-search:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.doc-template-chips{display:flex;flex-wrap:wrap;gap:6px}
.doc-template-chip{padding:5px 11px;border:1px solid var(--line);border-radius:999px;background:var(--card);color:var(--muted);font-size:11.5px;font-weight:700;cursor:pointer;transition:.15s}
.doc-template-chip:hover{border-color:var(--accent);color:var(--accent)}
.doc-template-chip.active{background:var(--accent);border-color:var(--accent);color:#fff}
.doc-template-note{margin:0;font-size:11px;line-height:1.5;color:var(--faint)}
.doc-template-empty{margin:4px 0 0;font-size:12.5px;color:var(--muted)}
.doc-template-btn{position:relative}
.doc-template-plain{position:absolute;top:6px;right:8px;font-size:11px;color:var(--faint)}
.doc-template-group-label{display:flex;align-items:center;gap:8px;font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--faint);margin-bottom:9px}
.doc-template-group-label:after{content:"";flex:1;height:1px;background:var(--line)}
/* Pro-gated group (Tata Letak): shown, not hidden, so a Basic account can
   see what upgrading buys. order:2 puts the badge after the label's divider
   rule, which is a ::after and therefore order:0. */
.doc-template-group-lock{order:2;display:inline-flex;align-items:center;gap:5px;flex:none;padding:2px 7px;border-radius:999px;background:var(--accent-soft);color:var(--accent);font-size:9.5px;font-weight:800;letter-spacing:.03em;text-decoration:none;white-space:nowrap}
.doc-template-group-lock:hover{background:var(--accent);color:#fff}
.doc-template-group.is-locked .doc-template-btn{opacity:.5;cursor:not-allowed}
.doc-template-group.is-locked .doc-template-btn:hover{opacity:.72;border-color:var(--line);transform:none;box-shadow:none}
.doc-template-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(124px,1fr));gap:12px}
.doc-template-btn{display:flex;flex-direction:column;align-items:center;gap:9px;padding:14px 8px 12px;border-radius:var(--radius-sm);border:1px solid var(--line);background:var(--card);font-size:12px;font-weight:700;line-height:1.25;text-align:center;color:var(--muted);cursor:pointer;transition:.15s}
.doc-template-btn:hover{border-color:var(--accent);color:var(--accent);transform:translateY(-1px)}
.doc-template-btn.active{border-color:var(--accent);color:var(--accent);background:var(--accent-soft);box-shadow:0 0 0 1px var(--accent) inset}

/* The wireframe. One fixed set of child bars (letterhead, two info lines,
   a content block, a signature mark) that every variant below repositions
   — the same trick the real templates use on .doc-page's own children, at
   1/12th the size. Purely decorative: aria-hidden in the markup, so a
   screen reader gets only the label. */
/* .tpl-mini-frame reserves the enlarged footprint; .tpl-mini inside it stays
   its original 52px-wide design, scaled up to fill the frame. Every one of
   the ~30 [data-mini="..."] variant rules below was hand-tuned in px against
   that original size (absolute-positioned ribbons, corner badges, sidebars,
   stamps...) — scaling the whole box up with `transform` instead of resizing
   it means all of them stay in proportion for free, nothing to rescale one
   by one when this changes again. */
.tpl-mini-frame{position:relative;width:100%;max-width:78px;aspect-ratio:46/60;flex:none;overflow:hidden}
.tpl-mini{position:absolute;top:0;left:0;width:52px;transform:scale(1.5);transform-origin:top left;border:1px solid var(--line);border-radius:4px;background:#fff;display:flex;flex-direction:column;gap:3px;padding:4px;overflow:hidden;flex:none}
.tpl-mini i{display:block;border-radius:1.5px;background:#dfe3ec;flex:none}
.tpl-mini .m-head{height:9px;background:color-mix(in srgb, var(--accent) 40%, #dfe3ec)}
.tpl-mini .m-line{height:3px}
.tpl-mini .m-block{height:15px;background:#eceff5}
.tpl-mini .m-sign{height:4px;width:17px;margin-top:auto;align-self:flex-end;background:#cdd4e0}
.doc-template-btn.active .tpl-mini{border-color:color-mix(in srgb, var(--accent) 45%, var(--line))}

.tpl-mini[data-mini="filledHead"] .m-head{background:var(--accent)}
.tpl-mini[data-mini="compact"]{gap:2px}
.tpl-mini[data-mini="compact"] .m-line{height:2px}
.tpl-mini[data-mini="compact"] .m-block{height:11px}
.tpl-mini[data-mini="framed"]{box-shadow:inset 0 0 0 2px color-mix(in srgb, var(--accent) 30%, #fff)}
.tpl-mini[data-mini="framed"] .m-head,
.tpl-mini[data-mini="framed"] .m-sign{align-self:center}
.tpl-mini[data-mini="framed"] .m-head{width:70%}

.tpl-mini[data-mini="sidebarLeft"]{padding-left:20px}
.tpl-mini[data-mini="sidebarLeft"] .m-head{position:absolute;left:0;top:0;bottom:0;width:16px;height:auto;border-radius:0}
.tpl-mini[data-mini="sidebarRight"]{padding-right:20px}
.tpl-mini[data-mini="sidebarRight"] .m-head{position:absolute;right:0;top:0;bottom:0;width:16px;height:auto;border-radius:0}
.tpl-mini[data-mini="sidebarRight"] .m-sign{align-self:flex-start}

.tpl-mini[data-mini="mirrored"] .m-head{background:linear-gradient(270deg,color-mix(in srgb, var(--accent) 55%, #dfe3ec),#dfe3ec)}
.tpl-mini[data-mini="mirrored"] .m-line{width:78%;align-self:flex-end}
.tpl-mini[data-mini="mirrored"] .m-sign{align-self:flex-start}

/* "Isi Dahulu" moves the content block above the info lines; "Total di
   Atas" instead lifts a filled totals bar up under the letterhead and
   leaves the block where it was. They'd read as the same picture if both
   just reordered the block, so each shows the piece that actually moves. */
.tpl-mini[data-mini="contentFirst"] .m-block{order:-1;margin-top:1px}
.tpl-mini[data-mini="contentFirst"] .m-head{order:-2}
.tpl-mini[data-mini="totalsFirst"] .m-head{order:-2}
.tpl-mini[data-mini="totalsFirst"] .m-line:first-of-type{order:-1;height:8px;border-radius:2px;background:color-mix(in srgb, var(--accent) 28%, #dfe3ec)}

.tpl-mini[data-mini="boxed"]{background:#f4f6fb;gap:2px}
.tpl-mini[data-mini="boxed"] i{border:1px solid #dfe3ec;background:#fff}
.tpl-mini[data-mini="boxed"] .m-head{background:#fff}

.tpl-mini[data-mini="centeredHead"] .m-head{width:64%;align-self:center;height:6px}
.tpl-mini[data-mini="centeredHead"] .m-line:first-of-type{width:46%;align-self:center;height:4px;background:color-mix(in srgb, var(--accent) 45%, #dfe3ec)}

.tpl-mini[data-mini="splitHead"] .m-head{height:5px}
.tpl-mini[data-mini="splitHead"] .m-line:first-of-type{height:5px;width:60%;align-self:flex-end;background:color-mix(in srgb, var(--accent) 40%, #dfe3ec)}

.tpl-mini[data-mini="slimHead"] .m-head{height:4px}
.tpl-mini[data-mini="slimHead"] .m-block{height:22px}

.tpl-mini[data-mini="cardHead"]{background:#eef1f7}
.tpl-mini[data-mini="cardHead"] .m-head{background:#fff;border:1px solid #dfe3ec;border-radius:3px;height:11px;box-shadow:0 2px 4px -2px rgba(15,18,30,.35)}

.tpl-mini[data-mini="edgeAccent"]{padding-left:9px}
.tpl-mini[data-mini="edgeAccent"]:before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--accent)}

.tpl-mini[data-mini="wideBlock"] .m-block{margin-left:-4px;margin-right:-4px;border-radius:0}

.tpl-mini[data-mini="metaBoxed"] .m-line{height:9px;border:1px solid #dfe3ec;background:#fff}
.tpl-mini[data-mini="metaBoxed"] .m-line + .m-line{display:none}

.tpl-mini[data-mini="metaStacked"] .m-line{border-left:2px solid var(--accent);height:5px;border-radius:0}

.tpl-mini[data-mini="cornerBadge"] .m-head{width:58%}
.tpl-mini[data-mini="cornerBadge"]:after{content:"";position:absolute;right:4px;top:4px;width:13px;height:9px;border-radius:2px;background:var(--accent)}

.tpl-mini[data-mini="stampCorner"] .m-sign{width:14px;height:11px;border-radius:2px;border:1px dashed color-mix(in srgb, var(--accent) 55%, #cdd4e0);background:transparent}

.tpl-mini[data-mini="stackedSign"] .m-sign{height:3px;width:15px}
.tpl-mini[data-mini="stackedSign"]:after{content:"";position:absolute;right:4px;bottom:4px;width:15px;height:3px;border-radius:1.5px;background:#cdd4e0}
.tpl-mini[data-mini="stackedSign"] .m-sign{margin-bottom:5px}

.tpl-mini[data-mini="footerBand"]{padding-bottom:13px}
.tpl-mini[data-mini="footerBand"] .m-sign{position:absolute;left:0;right:0;bottom:0;width:auto;height:11px;margin:0;border-radius:0;background:color-mix(in srgb, var(--accent) 22%, #fff);border-top:2px solid var(--accent)}

.tpl-mini[data-mini="twoCol"] .m-block{background:transparent;border-left:1px solid #dfe3ec;border-right:1px solid #dfe3ec;position:relative}
.tpl-mini[data-mini="twoCol"] .m-block:after{content:"";position:absolute;left:50%;top:0;bottom:0;width:1px;background:#dfe3ec}

/* Ribbon: the header is a full-bleed accent band the title sits reversed
   out of, so the mini shows a solid bar running edge to edge. */
.tpl-mini[data-mini="ribbon"]{padding-top:15px}
.tpl-mini[data-mini="ribbon"] .m-head{position:absolute;left:0;right:0;top:0;width:auto;height:13px;border-radius:0;background:var(--accent)}

/* Ruled form: every element boxed on a hairline grid. */
.tpl-mini[data-mini="ruled"]{gap:0}
.tpl-mini[data-mini="ruled"] i{border-radius:0;border-bottom:1px solid #cdd4e0;background:transparent}
.tpl-mini[data-mini="ruled"] .m-head{background:color-mix(in srgb, var(--accent) 20%, #fff);height:7px;border-bottom:1px solid var(--accent)}
.tpl-mini[data-mini="ruled"] .m-block{border:1px solid #cdd4e0;background:repeating-linear-gradient(#fff 0 4px,#eef1f7 4px 5px)}

/* Highlighted total: the totals band is the loudest thing on the page. */
.tpl-mini[data-mini="grandTotal"] .m-sign{width:auto;align-self:stretch;height:9px;border-radius:2px;background:var(--accent)}

/* Dark letterhead: near-black header block instead of an accent one. */
.tpl-mini[data-mini="darkHead"] .m-head{background:#20242c;height:11px}
.tpl-mini[data-mini="darkHead"] .m-line:first-of-type{background:var(--accent);width:40%}

/* Ten more templates (see the matching .doc-page[data-template="..."] rules
   further down for what each actually changes on the real document). */
.tpl-mini[data-mini="outlined"]{border:1.5px solid #20242c}
.tpl-mini[data-mini="outlined"] .m-head{background:none;border:1.5px solid #20242c}
.tpl-mini[data-mini="outlined"] .m-block{background:none;border:1px solid #cdd4e0}

.tpl-mini[data-mini="gradientHead"] .m-head,
.tpl-mini[data-mini="gradientHead"] .m-sign{background:linear-gradient(90deg,var(--accent),var(--navy))}

.tpl-mini[data-mini="roundedCard"]{border-radius:10px}
.tpl-mini[data-mini="roundedCard"] .m-head,
.tpl-mini[data-mini="roundedCard"] .m-block,
.tpl-mini[data-mini="roundedCard"] .m-sign{border-radius:6px}

.tpl-mini[data-mini="splitHeadColor"] .m-head{background:linear-gradient(90deg,var(--accent) 50%,var(--navy) 50%)}

.tpl-mini[data-mini="markerLine"] .m-head{background:color-mix(in srgb, var(--accent) 35%, #dfe3ec);transform:skewX(-8deg)}

.tpl-mini[data-mini="narrowCenter"]{align-items:center}
.tpl-mini[data-mini="narrowCenter"] .m-head,
.tpl-mini[data-mini="narrowCenter"] .m-line,
.tpl-mini[data-mini="narrowCenter"] .m-block{width:70%}
.tpl-mini[data-mini="narrowCenter"] .m-sign{align-self:center}

.tpl-mini[data-mini="chipRow"] .m-line{background:#f4f6fb;border:1px solid #dfe3ec;border-radius:2px}

.tpl-mini[data-mini="tintedCanvas"]{background:#eef1f7}
.tpl-mini[data-mini="tintedCanvas"] .m-head{background:transparent}
.tpl-mini[data-mini="tintedCanvas"] .m-block{background:#fff;box-shadow:0 2px 4px -2px rgba(15,18,30,.3)}

.tpl-mini[data-mini="centeredSign"] .m-sign{align-self:center}

.tpl-mini[data-mini="titleBand"] .m-line:first-of-type{height:7px;width:100%;border-radius:2px;background:var(--accent)}

/* Ten more mini previews (see the matching .doc-page[data-template="..."]
   rules further down for what each actually changes on the real document). */

.tpl-mini[data-mini="spaced"]{gap:5px}
.tpl-mini[data-mini="spaced"] .m-line{width:55%}

.tpl-mini[data-mini="zebraRows"] .m-block{background:repeating-linear-gradient(180deg,#eceff5 0 3px,color-mix(in srgb, var(--accent) 25%, #eceff5) 3px 6px)}

.tpl-mini[data-mini="underlineAccent"] .m-head{background:none;border-radius:0;border-bottom:2px solid var(--accent)}

.tpl-mini[data-mini="thinFrame"]{box-shadow:inset 0 0 0 1px var(--accent)}

.tpl-mini[data-mini="numberedDots"]{padding-left:11px}
.tpl-mini[data-mini="numberedDots"]:before{content:"";position:absolute;left:2px;top:4px;width:6px;height:6px;border-radius:50%;background:var(--accent)}

.tpl-mini[data-mini="hairlines"] .m-block{border-top:1px solid #dfe3ec;background:none;padding-top:2px;height:13px}

.tpl-mini[data-mini="notesFirst"] .m-line:first-of-type{order:-1}

.tpl-mini[data-mini="signFirstMini"] .m-sign{order:-1;margin-top:0;margin-bottom:auto}

.tpl-mini[data-mini="logoTopMini"]{align-items:center}
.tpl-mini[data-mini="logoTopMini"] .m-head{width:40%;height:14px}

/* Six shape-changing mini previews (see the matching .doc-page rules further
   down for what each looks like on the real document). */
.tpl-mini[data-mini="angledCut"] .m-head{clip-path:polygon(0 0,100% 0,100% 70%,0 100%)}

.tpl-mini[data-mini="waveCut"] .m-head{clip-path:polygon(0 0,100% 0,100% 55%,75% 85%,50% 60%,25% 85%,0 60%)}

.tpl-mini[data-mini="ribbonCorner"]{overflow:hidden}
.tpl-mini[data-mini="ribbonCorner"]:after{content:"";position:absolute;top:9px;right:-15px;width:38px;height:7px;background:var(--accent);transform:rotate(45deg)}

.tpl-mini[data-mini="circleBadge"] .m-sign{width:14px;height:14px;border-radius:50%;align-self:flex-end;background:var(--accent)}

.tpl-mini[data-mini="perforated"] .m-sign{background:none;border-top:1.5px dashed #b9c0cc;height:0;margin-top:5px}

.tpl-mini[data-mini="polaroidMini"] .m-sign{background:#fff;border:1px solid #dfe3ec;border-bottom-width:4px;width:20px;height:8px}

/* Six more shape mini previews. */
.tpl-mini[data-mini="cutCornerMini"]{clip-path:polygon(0 0,70% 0,100% 30%,100% 100%,0 100%)}

.tpl-mini[data-mini="hexLogoMini"]{padding-left:14px}
.tpl-mini[data-mini="hexLogoMini"]:before{content:"";position:absolute;left:2px;top:3px;width:9px;height:9px;background:var(--accent);clip-path:polygon(25% 0,75% 0,100% 50%,75% 100%,25% 100%,0 50%)}

.tpl-mini[data-mini="chevronMini"] .m-sign{clip-path:polygon(0 0,80% 0,100% 50%,80% 100%,0 100%);background:var(--accent);width:auto;align-self:stretch}

.tpl-mini[data-mini="bubbleMini"] .m-sign{background:var(--accent-soft);border-radius:4px 4px 4px 0;width:auto;align-self:stretch;height:10px}

.tpl-mini[data-mini="scallopMini"] .m-sign{border-top:2px dotted var(--accent);background:none;height:0}

.tpl-mini[data-mini="stripedMini"] .m-head{background:repeating-linear-gradient(45deg,var(--accent),var(--accent) 3px,color-mix(in srgb, var(--accent) 70%, #000) 3px,color-mix(in srgb, var(--accent) 70%, #000) 6px)}

/* Six more shape mini previews. */
.tpl-mini[data-mini="tornMini"] .m-head{position:relative}
.tpl-mini[data-mini="tornMini"] .m-head:after{content:"";position:absolute;left:0;right:0;bottom:-3px;height:3px;background-image:linear-gradient(135deg,#fff 50%,transparent 50%),linear-gradient(45deg,#fff 50%,transparent 50%);background-size:4px 3px;background-repeat:repeat-x}

.tpl-mini[data-mini="bracketsMini"]{border:none}
.tpl-mini[data-mini="bracketsMini"]:before{content:"";position:absolute;top:0;left:0;width:10px;height:10px;background:none;border-top:1.5px solid var(--accent);border-left:1.5px solid var(--accent)}
.tpl-mini[data-mini="bracketsMini"]:after{content:"";position:absolute;bottom:0;right:0;width:10px;height:10px;background:none;border-bottom:1.5px solid var(--accent);border-right:1.5px solid var(--accent)}

.tpl-mini[data-mini="envelopeMini"] .m-head{clip-path:polygon(0 0,50% 60%,100% 0,100% 100%,0 100%)}

.tpl-mini[data-mini="bookmarkMini"]{padding-top:8px}
.tpl-mini[data-mini="bookmarkMini"]:before{content:"";position:absolute;top:0;left:14px;width:16px;height:8px;background:var(--accent);clip-path:polygon(0 0,100% 0,100% 60%,50% 100%,0 60%)}

.tpl-mini[data-mini="stackMini"] .m-sign{box-shadow:2px 2px 0 -0.5px #fff,2px 2px 0 0 #cdd4e0}

.tpl-mini[data-mini="waveDividerMini"] .m-sign{clip-path:polygon(0 30%,15% 70%,30% 30%,45% 70%,60% 30%,75% 70%,90% 30%,100% 50%,100% 100%,0 100%);background:var(--accent);width:auto;align-self:stretch;height:6px}

.tpl-mini[data-mini="decoFrameMini"]{border:none;box-shadow:inset 0 0 0 2px var(--accent),inset 0 0 0 4px #fff,inset 0 0 0 5px var(--accent)}

.tpl-mini[data-mini="goldRuleMini"] .m-head{border-bottom:none;position:relative;margin-bottom:6px}
.tpl-mini[data-mini="goldRuleMini"] .m-head:after{content:"";position:absolute;left:0;right:0;bottom:-3px;height:1px;background:var(--accent)}
.tpl-mini[data-mini="goldRuleMini"] .m-head:before{content:"";position:absolute;left:50%;bottom:-5px;width:4px;height:4px;background:var(--accent);transform:translateX(-50%) rotate(45deg)}

.tpl-mini[data-mini="waxSealMini"] .m-sign{position:relative}
.tpl-mini[data-mini="waxSealMini"] .m-sign:before{content:"";position:absolute;top:-7px;left:8px;width:9px;height:9px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 1.5px #fff,0 0 0 2px var(--accent)}

.tpl-mini[data-mini="filigreeMini"]{border:none}
.tpl-mini[data-mini="filigreeMini"]:before{content:"";position:absolute;top:0;left:0;width:9px;height:9px;background:none;border-radius:0 0 9px 0;border-bottom:1.5px solid var(--accent);border-right:1.5px solid var(--accent)}
.tpl-mini[data-mini="filigreeMini"]:after{content:"";position:absolute;bottom:0;right:0;width:9px;height:9px;background:none;border-radius:9px 0 0 0;border-top:1.5px solid var(--accent);border-left:1.5px solid var(--accent)}

.tpl-mini[data-mini="medallionMini"] .m-head{position:relative;overflow:hidden}
.tpl-mini[data-mini="medallionMini"] .m-head:after{content:"";position:absolute;top:50%;right:4px;width:16px;height:16px;border-radius:50%;border:1px solid var(--accent);opacity:.35;transform:translateY(-50%)}

.tpl-mini[data-mini="pearlMini"] .m-sign{background-image:radial-gradient(circle,var(--accent) 35%,transparent 40%);background-size:5px 100%;background-repeat:repeat-x;background-position:left center;width:auto;align-self:stretch;height:4px}

.tpl-mini[data-mini="bgStripesMini"]{background-image:repeating-linear-gradient(45deg,var(--accent) 0,var(--accent) 3px,transparent 3px,transparent 6px);opacity:1}

.tpl-mini[data-mini="bgDotGridMini"]{background-image:radial-gradient(var(--accent) 1px,transparent 1.2px);background-size:5px 5px}

.tpl-mini[data-mini="bgSideBandMini"]{border:none}
.tpl-mini[data-mini="bgSideBandMini"]:before{content:"";position:absolute;top:0;left:0;bottom:0;width:6px;background:var(--accent)}

.tpl-mini[data-mini="bgTriangleMini"]{border:none}
.tpl-mini[data-mini="bgTriangleMini"]:before{content:"";position:absolute;top:0;right:0;width:16px;height:16px;background:var(--accent);clip-path:polygon(100% 0,100% 100%,0 0);opacity:.55}
.tpl-mini[data-mini="bgTriangleMini"]:after{content:"";position:absolute;bottom:0;left:0;width:16px;height:16px;background:var(--accent);clip-path:polygon(0 100%,0 0,100% 100%);opacity:.55}

.tpl-mini[data-mini="bgRingsMini"]:before{content:"";position:absolute;top:50%;left:50%;width:30px;height:30px;border-radius:50%;background:none;border:4px solid var(--accent);opacity:.45;transform:translate(-50%,-50%)}

.tpl-mini[data-mini="bgFrameMini"]{border:4px solid var(--accent)}

.tpl-mini[data-mini="bgGridMini"]{background:repeating-linear-gradient(0deg,var(--accent) 0,var(--accent) 1px,transparent 1px,transparent 7px),repeating-linear-gradient(90deg,var(--accent) 0,var(--accent) 1px,transparent 1px,transparent 7px);background-color:#fff}

.tpl-mini[data-mini="bgLatticeMini"]{background:repeating-linear-gradient(45deg,var(--accent) 0 2px,transparent 2px 6px),repeating-linear-gradient(-45deg,var(--accent) 0 2px,transparent 2px 6px);background-color:#fff}

.tpl-mini[data-mini="bgHalfSplitMini"]{border:none}
.tpl-mini[data-mini="bgHalfSplitMini"]:before{content:"";position:absolute;inset:0;background:var(--accent);opacity:.3;clip-path:polygon(0 0,100% 0,0 100%)}

.tpl-mini[data-mini="bgBigWaveMini"]{border:none}
.tpl-mini[data-mini="bgBigWaveMini"]:before{content:"";position:absolute;left:0;right:0;bottom:0;height:16px;background:var(--accent);opacity:.4;clip-path:polygon(0 50%,17% 30%,34% 50%,50% 30%,67% 50%,84% 30%,100% 50%,100% 100%,0 100%)}

.tpl-mini[data-mini="bgBandsMini"]{border:none}
.tpl-mini[data-mini="bgBandsMini"]:before{content:"";position:absolute;top:0;left:0;right:0;height:5px;background:var(--accent)}
.tpl-mini[data-mini="bgBandsMini"]:after{content:"";position:absolute;bottom:0;left:0;right:0;height:5px;background:var(--accent)}

.tpl-mini[data-mini="bgQuarterMini"]{border:none;overflow:hidden}
.tpl-mini[data-mini="bgQuarterMini"]:before{content:"";position:absolute;bottom:-14px;right:-14px;width:34px;height:34px;border-radius:50%;background:var(--accent);opacity:.4}

.tpl-mini[data-mini="bgFlowerLatticeMini"]{background:radial-gradient(circle at 6px 6px,transparent 4px,var(--accent) 5px,var(--accent) 5.5px,transparent 6px),radial-gradient(circle at 0 0,transparent 4px,var(--accent) 5px,var(--accent) 5.5px,transparent 6px),radial-gradient(circle at 12px 0,transparent 4px,var(--accent) 5px,var(--accent) 5.5px,transparent 6px),radial-gradient(circle at 0 12px,transparent 4px,var(--accent) 5px,var(--accent) 5.5px,transparent 6px),radial-gradient(circle at 12px 12px,transparent 4px,var(--accent) 5px,var(--accent) 5.5px,transparent 6px);background-size:12px 12px;background-color:#fff}

.tpl-mini[data-mini="bgBloomCornerMini"]{border:none}
.tpl-mini[data-mini="bgBloomCornerMini"]:before{content:"";position:absolute;bottom:2px;right:2px;width:22px;height:22px;background-image:radial-gradient(circle 5px at 15px 11px,var(--accent) 90%,transparent 100%),radial-gradient(circle 5px at 11px 4px,var(--accent) 90%,transparent 100%),radial-gradient(circle 5px at 4px 8px,var(--accent) 90%,transparent 100%),radial-gradient(circle 5px at 6px 16px,var(--accent) 90%,transparent 100%),radial-gradient(circle 3px at 10px 10px,var(--accent) 90%,transparent 100%);opacity:.6}

.tpl-mini[data-mini="bgLeafScatterMini"]{background:radial-gradient(ellipse 3px 5px at 6px 6px,var(--accent) 85%,transparent 100%),radial-gradient(ellipse 3px 5px at 18px 14px,var(--accent) 85%,transparent 100%);background-size:24px 24px;background-color:#fff}

.tpl-mini[data-mini="bgVineTopMini"]{border:none}
.tpl-mini[data-mini="bgVineTopMini"]:before{content:"";position:absolute;top:0;left:0;right:0;height:8px;background:var(--accent);opacity:.6;clip-path:polygon(0 60%,20% 30%,40% 60%,60% 30%,80% 60%,100% 30%,100% 0,0 0)}

.tpl-mini[data-mini="bgFlowerMandalaMini"]{border:none}
.tpl-mini[data-mini="bgFlowerMandalaMini"]:before{content:"";position:absolute;top:50%;left:50%;width:26px;height:26px;transform:translate(-50%,-50%);background-image:radial-gradient(circle 6px at 20px 13px,var(--accent) 90%,transparent 100%),radial-gradient(circle 6px at 15.5px 4.2px,var(--accent) 90%,transparent 100%),radial-gradient(circle 6px at 6.5px 4.2px,var(--accent) 90%,transparent 100%),radial-gradient(circle 6px at 2px 13px,var(--accent) 90%,transparent 100%),radial-gradient(circle 6px at 6.5px 21.8px,var(--accent) 90%,transparent 100%),radial-gradient(circle 6px at 15.5px 21.8px,var(--accent) 90%,transparent 100%),radial-gradient(circle 4px at 11px 13px,var(--accent) 90%,transparent 100%);opacity:.5}

.tpl-mini[data-mini="bgPetalBorderMini"]{border:none}
.tpl-mini[data-mini="bgPetalBorderMini"]:before{content:"";position:absolute;bottom:0;left:0;right:0;height:10px;background-image:radial-gradient(circle 3px at 8px 5px,var(--accent) 90%,transparent 100%),radial-gradient(circle 3px at 20px 5px,var(--accent) 90%,transparent 100%),radial-gradient(circle 3px at 32px 5px,var(--accent) 90%,transparent 100%),radial-gradient(circle 3px at 44px 5px,var(--accent) 90%,transparent 100%);opacity:.6}

.tpl-mini[data-mini="bgFloralFrameMini"]{border:none}
.tpl-mini[data-mini="bgFloralFrameMini"]:before{content:"";position:absolute;inset:0;background-image:radial-gradient(circle 4px at 6px 6px,var(--accent) 90%,transparent 100%),radial-gradient(circle 4px at 46px 6px,var(--accent) 90%,transparent 100%),radial-gradient(circle 4px at 6px 46px,var(--accent) 90%,transparent 100%),radial-gradient(circle 4px at 46px 46px,var(--accent) 90%,transparent 100%);opacity:.6}

.tpl-mini[data-mini="bgWildflowerPatchMini"]{border:none}
.tpl-mini[data-mini="bgWildflowerPatchMini"]:before{content:"";position:absolute;bottom:2px;left:2px;width:24px;height:24px;background-image:radial-gradient(circle 3px at 6px 18px,var(--accent) 90%,transparent 100%),radial-gradient(circle 4px at 15px 12px,var(--accent) 90%,transparent 100%),radial-gradient(circle 3px at 11px 4px,var(--accent) 90%,transparent 100%);opacity:.6}

.tpl-mini[data-mini="bgFernRowsMini"]:before{content:"";position:absolute;inset:-30%;background:radial-gradient(ellipse 2px 6px at 6px 6px,var(--accent) 85%,transparent 100%),radial-gradient(ellipse 2px 6px at 16px 13px,var(--accent) 85%,transparent 100%);background-size:20px 20px;transform:rotate(20deg);opacity:.7}

.tpl-mini[data-mini="bgBranchSashMini"]{border:none;overflow:hidden}
.tpl-mini[data-mini="bgBranchSashMini"]:before{content:"";position:absolute;top:23px;left:-10px;width:70px;height:6px;background:var(--accent);opacity:.5;transform:rotate(-20deg)}

.tpl-mini[data-mini="bgBigBloomSideMini"]{border:none;overflow:hidden}
.tpl-mini[data-mini="bgBigBloomSideMini"]:before{content:"";position:absolute;top:50%;left:-10px;width:28px;height:28px;transform:translateY(-50%);background-image:radial-gradient(circle 6px at 20px 14px,var(--accent) 90%,transparent 100%),radial-gradient(circle 6px at 15.5px 5.2px,var(--accent) 90%,transparent 100%),radial-gradient(circle 6px at 6.5px 5.2px,var(--accent) 90%,transparent 100%),radial-gradient(circle 6px at 2px 14px,var(--accent) 90%,transparent 100%),radial-gradient(circle 6px at 6.5px 22.8px,var(--accent) 90%,transparent 100%),radial-gradient(circle 6px at 15.5px 22.8px,var(--accent) 90%,transparent 100%),radial-gradient(circle 4px at 11px 14px,var(--accent) 90%,transparent 100%);opacity:.5}

/* Document design templates — "classic" is the plain default look (no
   attribute needed), applied via [data-template] on .doc-page so it works
   uniformly across every generator that shares these component classes
   (.doc-head/.doc-type/.receipt-title/.doc-table/.doc-totals/.doc-sign),
   without needing a separate hand-built layout per document type. Not
   applied to certificate, which already has its own template system (a
   custom uploadable background) and uses entirely different .cert-* markup
   these rules wouldn't reach anyway. */
.doc-page[data-template="modern"]{position:relative}
.doc-page[data-template="modern"]:before{height:10px}
.doc-page[data-template="modern"] .doc-head{background:linear-gradient(135deg,var(--accent-soft),transparent 75%);margin:-16mm -16mm 16px;padding:16mm 16mm 14px;border-bottom:none}
.doc-page[data-template="modern"] .doc-type h2,
.doc-page[data-template="modern"] .receipt-title h2{background:var(--accent);color:#fff;padding:7px 16px;border-radius:100px;display:inline-block}
.doc-page[data-template="modern"] .doc-totals .r.grand{background:var(--accent-soft);padding:10px 12px;border-radius:10px;border-top:none;margin-top:8px}
.doc-page[data-template="modern"] .receipt-amount-box{border-radius:14px;box-shadow:var(--shadow)}
.doc-page[data-template="modern"] .doc-sign .name{border-top-width:3px}
.doc-page[data-template="modern"] .doc-notes{background:var(--accent-soft);border-radius:10px;padding:10px 14px;border-left:none}

.doc-page[data-template="minimal"]:before{display:none}
.doc-page[data-template="minimal"] .doc-head{border-bottom:1px solid #d8dce6}
.doc-page[data-template="minimal"] .doc-type h2,
.doc-page[data-template="minimal"] .receipt-title h2{color:#20242c}
.doc-page[data-template="minimal"] .doc-table th{background:#f4f6fb;color:#20242c;border-bottom:2px solid #20242c}
.doc-page[data-template="minimal"] .doc-table tr:last-child td{border-bottom:2px solid #d8dce6}
.doc-page[data-template="minimal"] .doc-totals .r.grand{color:#20242c;border-top:2px solid #20242c}
.doc-page[data-template="minimal"] .receipt-amount-box{background:#fff;border:1px solid #d8dce6}
.doc-page[data-template="minimal"] .receipt-amount-box .amt{color:#20242c}
.doc-page[data-template="minimal"] .doc-sign .name{border-top-color:#20242c}

.doc-page[data-template="elegant"]:before{height:3px;background:linear-gradient(90deg,transparent,var(--accent),transparent)}
.doc-page[data-template="elegant"] .doc-head{border-bottom:3px double var(--accent);padding-bottom:18px}
.doc-page[data-template="elegant"] .doc-brand{font-family:"Playfair Display",var(--doc-font, var(--heading));font-style:italic}
.doc-page[data-template="elegant"] .doc-type h2,
.doc-page[data-template="elegant"] .receipt-title h2{letter-spacing:.22em;font-weight:700;color:#20242c;background:none}
.doc-page[data-template="elegant"] .doc-table th{background:none;color:#20242c;border-top:1px solid #20242c;border-bottom:1px solid #20242c}
.doc-page[data-template="elegant"] .doc-totals .r.grand{border-top:3px double var(--accent);color:#20242c}
.doc-page[data-template="elegant"] .receipt-amount-box{background:none;border:1px solid var(--accent)}
.doc-page[data-template="elegant"] .receipt-amount-box .amt{color:#20242c}
.doc-page[data-template="elegant"] .doc-sign .name{font-family:"Playfair Display",var(--doc-font, var(--heading));font-style:italic}
.doc-page[data-template="elegant"] .doc-notes{font-style:italic;border-top:1px solid #d8dce6;padding-top:12px}

.doc-page[data-template="bold"]{position:relative}
.doc-page[data-template="bold"]:before{height:14px}
.doc-page[data-template="bold"] .doc-head{background:var(--navy);margin:-16mm -16mm 16px;padding:16mm 16mm 14px;border-bottom:none}
.doc-page[data-template="bold"] .doc-brand{color:#fff}
.doc-page[data-template="bold"] .doc-brand-sub{color:#c3c9de}
.doc-page[data-template="bold"] .doc-type h2,
.doc-page[data-template="bold"] .receipt-title h2{color:var(--gold);font-weight:800;background:none}
.doc-page[data-template="bold"] .doc-type .doc-no{color:#c3c9de}
.doc-page[data-template="bold"] .doc-table th{background:#20242c;color:#fff}
.doc-page[data-template="bold"] .doc-totals .r.grand{background:var(--navy);color:#fff;padding:10px 12px;border-radius:8px;border-top:none;margin-top:8px}
.doc-page[data-template="bold"] .receipt-amount-box{background:var(--navy);border:none}
.doc-page[data-template="bold"] .receipt-amount-box .amt{color:var(--gold)}
.doc-page[data-template="bold"] .receipt-amount-box>div:last-child{color:#c3c9de}
.doc-page[data-template="bold"] .doc-sign .name{border-top-width:3px;border-top-color:#20242c}
.doc-page[data-template="bold"] .doc-notes{background:#f4f6fb;border-radius:8px;padding:10px 14px}

.doc-page[data-template="compact"] .doc-head{padding-bottom:8px}
.doc-page[data-template="compact"]:before{height:4px}
.doc-page[data-template="compact"] .doc-meta{margin-top:10px}
.doc-page[data-template="compact"] .doc-table{margin-top:10px;font-size:11px}
.doc-page[data-template="compact"] .doc-table th{padding:5px 8px}
.doc-page[data-template="compact"] .doc-table td{padding:5px 8px}
.doc-page[data-template="compact"] .doc-totals{margin-top:6px;padding-top:6px}
.doc-page[data-template="compact"] .doc-notes{margin-top:10px}
.doc-page[data-template="compact"] .doc-sign{margin-top:26px}
.doc-page[data-template="compact"] .receipt-amount-box{margin:10px 0;padding:10px 14px}

/* Four more design templates, same shared-component hooks as the six above
   (.doc-head/.doc-brand/.doc-type or .receipt-title/.doc-table/.doc-totals
   .r.grand/.receipt-amount-box/.doc-notes/.doc-sign .name) so they apply
   uniformly across every generator that already works with Classic/Modern/
   etc. — no per-document-type CSS needed. Fixed hex (#20242c, #d8dce6, #fff)
   rather than the --ink/--muted/--paper tokens throughout, same reason the
   six above do that: .doc-page is a print-preview surface that must look
   identical regardless of the site's light/dark theme (see the dark-mode
   overrides block further down, which deliberately never touches .doc-page). */
.doc-page[data-template="corporate"]{position:relative}
.doc-page[data-template="corporate"]:before{display:none}
.doc-page[data-template="corporate"] .doc-head{background:var(--accent);color:#fff;margin:-16mm -16mm 18px;padding:14mm 16mm 16px;border-bottom:none;align-items:center}
.doc-page[data-template="corporate"] .doc-brand{color:#fff}
.doc-page[data-template="corporate"] .doc-brand-sub{color:rgba(255,255,255,.75)}
.doc-page[data-template="corporate"] .doc-type h2,
.doc-page[data-template="corporate"] .receipt-title h2{color:#fff;background:none}
.doc-page[data-template="corporate"] .doc-type .doc-no{color:rgba(255,255,255,.75)}
.doc-page[data-template="corporate"] .doc-meta{padding:10px 14px;background:#f4f6fb;border-radius:8px;border:1px solid #e3e7ef}
.doc-page[data-template="corporate"] .doc-table th{background:#20242c;color:#fff}
.doc-page[data-template="corporate"] .doc-table tr:nth-child(even) td{background:#f7f8fb}
.doc-page[data-template="corporate"] .doc-totals .r.grand{background:#20242c;color:#fff;border-top:none;border-radius:6px;padding:10px 12px;margin-top:6px}
.doc-page[data-template="corporate"] .receipt-amount-box{background:#20242c;border:none}
.doc-page[data-template="corporate"] .receipt-amount-box .amt{color:#fff}
.doc-page[data-template="corporate"] .doc-notes{border-left:3px solid var(--accent);padding-left:10px}
.doc-page[data-template="corporate"] .doc-sign .name{border-top:2px solid #20242c}

.doc-page[data-template="creative"]{position:relative}
.doc-page[data-template="creative"]:before{height:8px;border-radius:0 0 8px 8px}
.doc-page[data-template="creative"] .doc-head{border-bottom:none;padding-bottom:10px}
.doc-page[data-template="creative"] .doc-brand{color:var(--accent)}
.doc-page[data-template="creative"] .doc-type h2,
.doc-page[data-template="creative"] .receipt-title h2{background:var(--accent-soft);color:var(--accent);padding:9px 18px;border-radius:100px 100px 100px 4px;display:inline-block;font-size:18px}
.doc-page[data-template="creative"] .doc-table th{background:var(--accent-soft);color:var(--accent)}
.doc-page[data-template="creative"] .doc-table th:first-child{border-radius:8px 0 0 0}
.doc-page[data-template="creative"] .doc-table th:last-child{border-radius:0 8px 0 0}
.doc-page[data-template="creative"] .doc-table td{border-bottom:1px dashed #d8dce6}
.doc-page[data-template="creative"] .doc-totals .r.grand{background:var(--accent);color:#fff;border-radius:100px;border-top:none;padding:9px 16px}
.doc-page[data-template="creative"] .receipt-amount-box{border-radius:100px;padding:14px 22px}
.doc-page[data-template="creative"] .doc-notes{background:var(--accent-soft);padding:10px 14px;border-radius:10px}
.doc-page[data-template="creative"] .doc-sign .name{border-top:none;background:var(--accent-soft);border-radius:8px;padding:8px 0}

.doc-page[data-template="framed"]{box-shadow:inset 0 0 0 2px var(--accent), inset 0 0 0 8px #fff, inset 0 0 0 9px var(--accent-soft)}
.doc-page[data-template="framed"]:before{display:none}
.doc-page[data-template="framed"] .doc-head{flex-direction:column;align-items:center;text-align:center;border-bottom:1px solid var(--accent);gap:6px;padding:6mm 6mm 14px}
.doc-page[data-template="framed"] .doc-type{text-align:center;margin-top:6px}
.doc-page[data-template="framed"] .doc-type h2,
.doc-page[data-template="framed"] .receipt-title h2{letter-spacing:.18em}
.doc-page[data-template="framed"] .doc-meta{justify-content:center;gap:60px;text-align:center;padding:0 6mm}
.doc-page[data-template="framed"] .doc-table{margin-left:6mm;width:calc(100% - 12mm)}
.doc-page[data-template="framed"] .doc-totals{margin-right:6mm}
.doc-page[data-template="framed"] .doc-table th{border-top:1px solid var(--accent);border-bottom:1px solid var(--accent);background:none;color:var(--accent)}
.doc-page[data-template="framed"] .doc-totals .r.grand{border-top:1px solid var(--accent);border-bottom:1px solid var(--accent);color:var(--accent)}
.doc-page[data-template="framed"] .doc-notes{margin-left:6mm;margin-right:6mm}
.doc-page[data-template="framed"] .doc-sign{justify-content:center;gap:60px;padding:0 6mm}
.doc-page[data-template="framed"] .doc-sign .name{border-top-color:var(--accent)}

.doc-page[data-template="mono"]{}
.doc-page[data-template="mono"] .doc-brand,
.doc-page[data-template="mono"] .doc-brand-sub,
.doc-page[data-template="mono"] .doc-type,
.doc-page[data-template="mono"] .receipt-title,
.doc-page[data-template="mono"] .doc-meta,
.doc-page[data-template="mono"] .doc-table,
.doc-page[data-template="mono"] .doc-totals,
.doc-page[data-template="mono"] .doc-notes,
.doc-page[data-template="mono"] .doc-sign{font-family:"Courier New",Courier,var(--doc-font, monospace)}
.doc-page[data-template="mono"] .doc-head{border-bottom:2px dashed #20242c}
.doc-page[data-template="mono"] .doc-type h2,
.doc-page[data-template="mono"] .receipt-title h2{color:#20242c;background:none;letter-spacing:.08em}
.doc-page[data-template="mono"] .doc-table th{background:none;color:#20242c;border-bottom:2px dashed #20242c;text-transform:uppercase}
.doc-page[data-template="mono"] .doc-table td{border-bottom:1px dashed #d8dce6}
.doc-page[data-template="mono"] .doc-totals .r.grand{border-top:2px dashed #20242c;color:#20242c}
.doc-page[data-template="mono"] .receipt-amount-box{background:none;border:2px dashed #20242c}
.doc-page[data-template="mono"] .receipt-amount-box .amt{color:#20242c}
.doc-page[data-template="mono"] .doc-sign .name{border-top:1px dashed #20242c}

/* Five more style templates (recolor/reshape only, same top-to-bottom flow
   as the ten above — see DOC_TEMPLATES in app.js). */

/* Outline: nothing filled — every accent becomes a solid dark border
   instead, for a "line drawing" look opposite of mono's dashes and
   minimal's plain text. */
.doc-page[data-template="outline"]:before{display:none}
.doc-page[data-template="outline"] .doc-head{border-bottom:1.5px solid #20242c}
.doc-page[data-template="outline"] .doc-type h2,
.doc-page[data-template="outline"] .receipt-title h2{background:none;color:#20242c;border:1.5px solid #20242c;padding:6px 14px;border-radius:0;display:inline-block}
.doc-page[data-template="outline"] .doc-table th{background:none;color:#20242c;border-top:1.5px solid #20242c;border-bottom:1.5px solid #20242c}
.doc-page[data-template="outline"] .doc-table td{border-bottom:1px solid #d8dce6}
.doc-page[data-template="outline"] .doc-totals .r.grand{background:none;color:#20242c;border-top:1.5px solid #20242c;border-bottom:1.5px solid #20242c}
.doc-page[data-template="outline"] .receipt-amount-box{background:none;border:1.5px solid #20242c}
.doc-page[data-template="outline"] .receipt-amount-box .amt{color:#20242c}
.doc-page[data-template="outline"] .doc-notes{border:1px solid #d8dce6;padding:10px 14px}
.doc-page[data-template="outline"] .doc-sign .name{border-top:1.5px solid #20242c}

/* Gradient: a diagonal two-colour band (accent -> navy) instead of any of
   the six above's single flat/soft fill. */
.doc-page[data-template="gradient"]{position:relative}
.doc-page[data-template="gradient"]:before{height:10px;background:linear-gradient(90deg,var(--accent),var(--navy))}
.doc-page[data-template="gradient"] .doc-head{background:linear-gradient(120deg,var(--accent),var(--navy));margin:-16mm -16mm 16px;padding:16mm 16mm 14px;border-bottom:none}
.doc-page[data-template="gradient"] .doc-brand,
.doc-page[data-template="gradient"] .doc-brand-sub{color:#fff}
.doc-page[data-template="gradient"] .doc-brand-sub{opacity:.85}
.doc-page[data-template="gradient"] .doc-type h2,
.doc-page[data-template="gradient"] .receipt-title h2{color:#fff;background:none}
.doc-page[data-template="gradient"] .doc-type div,
.doc-page[data-template="gradient"] .receipt-title div{color:#fff;opacity:.85}
.doc-page[data-template="gradient"] .doc-logo{background:#fff;padding:4px;box-sizing:border-box}
.doc-page[data-template="gradient"] .doc-totals .r.grand{background:linear-gradient(90deg,var(--accent),var(--navy));color:#fff;border-top:none;border-radius:10px;padding:10px 12px;margin-top:8px}
.doc-page[data-template="gradient"] .receipt-amount-box{background:linear-gradient(120deg,var(--accent),var(--navy));border:none}
.doc-page[data-template="gradient"] .receipt-amount-box .amt,
.doc-page[data-template="gradient"] .receipt-amount-box>div:last-child{color:#fff}

/* Rounded: big soft corners and floating shadows everywhere — a friendlier,
   app-like feel distinct from creative's pill shapes. overflow:hidden keeps
   the accent bar's square corners from poking past the page's own rounded
   ones. */
.doc-page[data-template="rounded"]{border-radius:18px;overflow:hidden}
.doc-page[data-template="rounded"] .doc-head{border-bottom:none;padding-bottom:14px}
.doc-page[data-template="rounded"] .doc-type h2,
.doc-page[data-template="rounded"] .receipt-title h2{background:var(--accent-soft);color:var(--accent);padding:8px 16px;border-radius:16px}
.doc-page[data-template="rounded"] .doc-meta{background:#f7f8fb;border-radius:14px;padding:12px 16px}
.doc-page[data-template="rounded"] .doc-table{border-radius:10px;overflow:hidden}
.doc-page[data-template="rounded"] .doc-totals .r.grand{background:var(--accent-soft);color:var(--accent);border-radius:14px;border-top:none;padding:10px 14px;margin-top:8px}
.doc-page[data-template="rounded"] .receipt-amount-box{border-radius:18px;box-shadow:0 10px 24px -16px rgba(15,18,30,.35)}
.doc-page[data-template="rounded"] .doc-notes{background:#f7f8fb;border-radius:12px;padding:10px 14px}
.doc-page[data-template="rounded"] .doc-sign .name{border-top:none;background:#f7f8fb;border-radius:10px;padding:8px 0}

/* Two-tone: the letterhead splits into two solid colour halves with a hard
   edge — different from gradient's smooth blend and twoColumnText's body
   columns (a different section entirely). */
.doc-page[data-template="twoTone"]:before{display:none}
.doc-page[data-template="twoTone"] .doc-head{background:linear-gradient(90deg,var(--accent) 50%,var(--navy) 50%);margin:-16mm -16mm 16px;padding:16mm 16mm 14px;border-bottom:none}
.doc-page[data-template="twoTone"] .doc-brand,
.doc-page[data-template="twoTone"] .doc-brand-sub{color:#fff}
.doc-page[data-template="twoTone"] .doc-brand-sub{opacity:.85}
.doc-page[data-template="twoTone"] .doc-type h2,
.doc-page[data-template="twoTone"] .receipt-title h2{color:#fff;background:none}
.doc-page[data-template="twoTone"] .doc-type div,
.doc-page[data-template="twoTone"] .receipt-title div{color:#fff;opacity:.85}
.doc-page[data-template="twoTone"] .doc-logo{background:#fff;padding:4px;box-sizing:border-box}
.doc-page[data-template="twoTone"] .doc-totals .r.grand{background:var(--navy);color:#fff;border-top:none;border-radius:8px;padding:10px 12px;margin-top:8px}

/* Highlight: the title and the headline figure get a skewed marker-style
   swipe of colour behind just the text, like a highlighter pen — nothing
   else on the page is recoloured. */
.doc-page[data-template="highlight"]:before{height:5px}
.doc-page[data-template="highlight"] .doc-type h2,
.doc-page[data-template="highlight"] .receipt-title h2{position:relative;z-index:0;background:none;color:#20242c;display:inline-block}
.doc-page[data-template="highlight"] .doc-type h2:before,
.doc-page[data-template="highlight"] .receipt-title h2:before{content:"";position:absolute;left:-4px;right:-4px;bottom:3px;height:40%;background:var(--accent-soft);z-index:-1;transform:skewX(-8deg)}
.doc-page[data-template="highlight"] .doc-table th{background:none;color:#20242c;border-bottom:2px solid var(--accent)}
.doc-page[data-template="highlight"] .doc-totals .r.grand{background:none;color:#20242c;border-top:2px solid var(--accent)}
.doc-page[data-template="highlight"] .receipt-amount-box{background:none;border:1px solid #d8dce6}
.doc-page[data-template="highlight"] .receipt-amount-box .amt{position:relative;z-index:0;color:#20242c}
.doc-page[data-template="highlight"] .receipt-amount-box .amt:before{content:"";position:absolute;left:-6px;right:-6px;bottom:2px;height:35%;background:var(--accent-soft);z-index:-1;transform:skewX(-8deg)}

/* Five more style templates. */

/* Letterspaced: an airy editorial typographic treatment — generous tracking
   on the title and table headers, hairline rules instead of any of the
   heavier borders/fills above, nothing recoloured. */
.doc-page[data-template="letterSpaced"]:before{height:3px}
.doc-page[data-template="letterSpaced"] .doc-head{border-bottom:1px solid #e3e7ef;padding-bottom:16px}
.doc-page[data-template="letterSpaced"] .doc-brand{letter-spacing:.08em;text-transform:uppercase;font-size:13px}
.doc-page[data-template="letterSpaced"] .doc-type h2,
.doc-page[data-template="letterSpaced"] .receipt-title h2{letter-spacing:.3em;font-weight:600;background:none;color:#20242c}
.doc-page[data-template="letterSpaced"] .doc-table th{letter-spacing:.12em;background:none;border-bottom:1px solid #20242c;color:#20242c}
.doc-page[data-template="letterSpaced"] .doc-totals .r.grand{letter-spacing:.05em;border-top:1px solid #20242c;color:#20242c;background:none}
.doc-page[data-template="letterSpaced"] .doc-sign .name{letter-spacing:.05em}

/* Zebra rows: alternating tinted item rows in the accent colour — a
   different rhythm from corporate's plain grey stripe, and from ruled's
   full cell borders. */
.doc-page[data-template="zebra"] .doc-table th{background:none;color:#20242c;border-bottom:2px solid #20242c}
.doc-page[data-template="zebra"] .doc-table tr:nth-child(even) td{background:var(--accent-soft)}
.doc-page[data-template="zebra"] .doc-totals .r.grand{border-top:2px solid #20242c;color:#20242c;background:none}

/* Underline accent: every highlight becomes a thick colour rule under the
   text instead of a filled pill/box or border-all box — the lightest-touch
   style template here, opposite of bold/corporate's heavy fills. */
.doc-page[data-template="underline"]:before{display:none}
.doc-page[data-template="underline"] .doc-head{border-bottom:2px solid var(--accent)}
.doc-page[data-template="underline"] .doc-type h2,
.doc-page[data-template="underline"] .receipt-title h2{background:none;color:#20242c;border-bottom:3px solid var(--accent);padding-bottom:4px;display:inline-block}
.doc-page[data-template="underline"] .doc-table th{background:none;color:#20242c;border-bottom:2px solid var(--accent)}
.doc-page[data-template="underline"] .doc-totals .r.grand{background:none;color:#20242c;border-top:none;border-bottom:3px solid var(--accent);padding-bottom:6px}
.doc-page[data-template="underline"] .receipt-amount-box{background:none;border:none;border-radius:0;border-bottom:3px solid var(--accent)}
.doc-page[data-template="underline"] .receipt-amount-box .amt{color:#20242c}

/* Thin frame: a single inset hairline around the whole page — a lighter,
   single-line alternative to "framed"'s ornate triple border (which also
   recentres the header/meta/sign); this touches nothing but the frame
   itself. .doc-page is already position:relative (see its base rule). */
.doc-page[data-template="cornerFrame"]:after{content:"";position:absolute;inset:8mm;border:1px solid var(--accent);pointer-events:none}

/* Six templates that change an element's actual SHAPE — a diagonal or
   scalloped cut (clip-path), a rotated ribbon, a circle, a dashed
   perforation, a tilted photo frame — instead of only its colour or
   spacing, which is all every template above this line ever touches. */

/* Angled header: the letterhead's bottom edge is a single diagonal cut
   instead of a straight rule. clip-path only reshapes .doc-head itself, so
   this carries no risk to anything below it (unlike the section-reordering
   templates, which had to be checked against every .doc-page direct-child
   shape). */
.doc-page[data-template="angledHeader"]:before{display:none}
.doc-page[data-template="angledHeader"] .doc-head{background:var(--accent);margin:-16mm -16mm 24px;padding:16mm 16mm 26px;border-bottom:none;clip-path:polygon(0 0,100% 0,100% 82%,0 100%)}
.doc-page[data-template="angledHeader"] .doc-brand,
.doc-page[data-template="angledHeader"] .doc-brand-sub{color:#fff}
.doc-page[data-template="angledHeader"] .doc-brand-sub{opacity:.85}
.doc-page[data-template="angledHeader"] .doc-type h2,
.doc-page[data-template="angledHeader"] .receipt-title h2{color:#fff;background:none}
.doc-page[data-template="angledHeader"] .doc-type div,
.doc-page[data-template="angledHeader"] .receipt-title div{color:#fff;opacity:.85}
.doc-page[data-template="angledHeader"] .doc-logo{background:#fff;padding:4px;box-sizing:border-box}

/* Wave header: the same idea with a scalloped bottom edge instead of one
   straight diagonal — clip-path polygon points approximate a wave. */
.doc-page[data-template="waveHeader"]:before{display:none}
.doc-page[data-template="waveHeader"] .doc-head{background:var(--accent);margin:-16mm -16mm 26px;padding:16mm 16mm 30px;border-bottom:none;clip-path:polygon(0 0,100% 0,100% 78%,88% 92%,75% 80%,62% 92%,50% 80%,38% 92%,25% 80%,12% 92%,0 80%)}
.doc-page[data-template="waveHeader"] .doc-brand,
.doc-page[data-template="waveHeader"] .doc-brand-sub{color:#fff}
.doc-page[data-template="waveHeader"] .doc-brand-sub{opacity:.85}
.doc-page[data-template="waveHeader"] .doc-type h2,
.doc-page[data-template="waveHeader"] .receipt-title h2{color:#fff;background:none}
.doc-page[data-template="waveHeader"] .doc-type div,
.doc-page[data-template="waveHeader"] .receipt-title div{color:#fff;opacity:.85}
.doc-page[data-template="waveHeader"] .doc-logo{background:#fff;padding:4px;box-sizing:border-box}

/* Corner ribbon: the document type/title rotates 45° into a banner
   crossing the top-right corner, like a "PAID"-style sticker — a shape no
   other template here uses. position:absolute takes it out of .doc-head's
   flex flow entirely (safe regardless of that flex container's direction —
   unlike flex-basis tricks, an absolutely positioned element isn't laid out
   by its parent's flex algorithm at all, see bannerTitle's own comment for
   the bug that taught this), so the header simply shows the brand alone
   underneath it. overflow:hidden on .doc-page trims the ribbon's tails at
   the page edge; .doc-page's own box-shadow still renders outside it
   (overflow only clips descendant content, never the box's own shadow). */
.doc-page[data-template="cornerRibbon"]{overflow:hidden}
.doc-page[data-template="cornerRibbon"]:before{display:none}
.doc-page[data-template="cornerRibbon"] .doc-type,
.doc-page[data-template="cornerRibbon"] .receipt-title{position:absolute;top:15mm;right:-16mm;width:64mm;transform:rotate(45deg);transform-origin:center;background:var(--accent);text-align:center;padding:5px 0;box-shadow:0 2px 6px rgba(15,18,30,.25);z-index:2}
.doc-page[data-template="cornerRibbon"] .doc-type h2,
.doc-page[data-template="cornerRibbon"] .receipt-title h2{color:#fff;background:none;margin:0;font-size:11px;letter-spacing:.06em}
.doc-page[data-template="cornerRibbon"] .doc-type div,
.doc-page[data-template="cornerRibbon"] .receipt-title div{color:#fff;opacity:.85;font-size:7px}

/* Circle seal: the grand total becomes a round badge instead of a
   rectangular row — only .r.grand itself is touched (margin-left:auto right-
   aligns the fixed-size circle within .doc-totals' existing column stack),
   so the "Subtotal" row(s) above it are completely unaffected. Not applied
   to receipt.html's .receipt-amount-box: that block also carries a
   "Terbilang" (amount in words) line, which can run to a long sentence no
   fixed-size circle could hold — left in its normal rectangular form there
   rather than risk the same kind of overflow bannerTitle's fix had to
   correct for. */
.doc-page[data-template="circleSeal"] .doc-totals .r.grand{width:104px;height:104px;border-radius:50%;background:var(--accent);color:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;border:none;margin:10px 0 0 auto;padding:8px;box-sizing:border-box;font-size:11.5px;line-height:1.3}

/* Ticket stub: a dashed perforation with two small "eyelet" circles sits
   above the totals, as if the amount were torn off a ticket. Only decorates
   the border above .doc-totals/.receipt-amount-box — nothing moves. */
.doc-page[data-template="ticketStub"] .doc-totals,
.doc-page[data-template="ticketStub"] .receipt-amount-box{position:relative;border-top:2px dashed #b9c0cc;padding-top:16px;margin-top:20px}
.doc-page[data-template="ticketStub"] .doc-totals:before,
.doc-page[data-template="ticketStub"] .receipt-amount-box:before{content:"";position:absolute;top:-9px;left:-2px;width:16px;height:16px;border-radius:50%;background:#fff;border:2px dashed #b9c0cc}
.doc-page[data-template="ticketStub"] .doc-totals:after,
.doc-page[data-template="ticketStub"] .receipt-amount-box:after{content:"";position:absolute;top:-9px;right:-2px;width:16px;height:16px;border-radius:50%;background:#fff;border:2px dashed #b9c0cc}

/* Polaroid frame: each signature block gets a thick-bottomed white photo
   frame, tilted a few degrees like a pinned instant photo — .sig is
   .doc-sign's own always-present per-signer child (see stackedSign's
   comment), so this needs no knowledge of how many signers a document has. */
.doc-page[data-template="polaroidSign"] .doc-sign{align-items:flex-start}
.doc-page[data-template="polaroidSign"] .doc-sign .sig{background:#fff;border:1px solid #e3e7ef;border-bottom-width:16px;box-shadow:0 6px 14px -8px rgba(15,18,30,.35);padding:10px 10px 2px;transform:rotate(-2deg)}
.doc-page[data-template="polaroidSign"] .doc-sign .sig:nth-child(2){transform:rotate(2deg)}

/* Six more shape templates. */

/* Cut corner: the whole PAGE's silhouette loses its top-right corner to a
   diagonal cut — every template above this line, including the other five
   "shape" ones, only ever reshapes an element INSIDE the page; this is the
   first to touch the page's own outline. A single property, so there is
   nothing inside it that can misalign the way a multi-section template
   could. */
.doc-page[data-template="cutCorner"]{clip-path:polygon(0 0, calc(100% - 20mm) 0, 100% 20mm, 100% 100%, 0 100%)}

/* Hexagon logo: the business logo sits in a hexagon instead of the plain
   square/circle every other template leaves it in. Only the logo's own box
   is clipped, so this is safe regardless of what image an account has
   uploaded — a non-square photo just gets cropped to the hexagon the same
   way it would otherwise be cropped to a square. */
.doc-page[data-template="hexLogo"] .doc-logo{clip-path:polygon(25% 0,75% 0,100% 50%,75% 100%,25% 100%,0 50%);border-radius:0}

/* Arrow total: the grand-total row becomes a chevron pointing right instead
   of a plain rectangle — generous right padding keeps the point clear of
   the actual number. Left off receipt.html's .receipt-amount-box for the
   same reason circleSeal is: that block's "Terbilang" (amount in words)
   line can run long, and a pointed clip-path gives it nowhere to overflow
   into without being visibly cut off. */
.doc-page[data-template="chevronTotal"] .doc-totals .r.grand{clip-path:polygon(0 0, 94% 0, 100% 50%, 94% 100%, 0 100%);background:var(--accent);color:#fff;border:none;padding:10px 30px 10px 14px;margin-top:8px}

/* Speech bubble notes: .doc-notes becomes a rounded comment bubble with a
   small triangular tail pointing up at whatever's above it — a shape
   nothing else here uses. :not(:empty) matters exactly as it does for
   "ruled": a business document has two .doc-notes blocks (notes and bank
   details) and either can be blank, which must not draw a bubble (tail
   included) around nothing. */
.doc-page[data-template="speechNote"] .doc-notes:not(:empty){position:relative;background:var(--accent-soft);border-radius:12px;padding:12px 16px;margin-top:22px}
.doc-page[data-template="speechNote"] .doc-notes:not(:empty):before{content:"";position:absolute;top:-8px;left:22px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid var(--accent-soft)}

/* Scalloped edge: a row of small half-circle notches above .doc-notes,
   like a decorative pinking-shears/ticket edge — a repeating radial-
   gradient rather than any of the solid/dashed borders every other
   template uses. Assumes a white page behind it, same as every other
   fixed-hex-colour template here. */
.doc-page[data-template="scallopEdge"] .doc-notes:not(:empty){position:relative;margin-top:22px}
.doc-page[data-template="scallopEdge"] .doc-notes:not(:empty):before{content:"";position:absolute;top:-9px;left:0;right:0;height:9px;background-image:radial-gradient(circle at 9px 0, transparent 9px, var(--accent-soft) 9px);background-size:18px 9px;background-repeat:repeat-x}

/* Striped header: a diagonal candy-stripe pattern instead of a solid or
   gradient fill — a texture, not just a colour, which nothing above this
   line uses either. */
.doc-page[data-template="stripedHeader"] .doc-head{background:repeating-linear-gradient(45deg,var(--accent),var(--accent) 10px,color-mix(in srgb, var(--accent) 80%, #000) 10px,color-mix(in srgb, var(--accent) 80%, #000) 20px);margin:-16mm -16mm 18px;padding:16mm 16mm 14px;border-bottom:none}
.doc-page[data-template="stripedHeader"] .doc-brand,
.doc-page[data-template="stripedHeader"] .doc-brand-sub{color:#fff}
.doc-page[data-template="stripedHeader"] .doc-brand-sub{opacity:.9}
.doc-page[data-template="stripedHeader"] .doc-type h2,
.doc-page[data-template="stripedHeader"] .receipt-title h2{color:#fff;background:none}
.doc-page[data-template="stripedHeader"] .doc-type div,
.doc-page[data-template="stripedHeader"] .receipt-title div{color:#fff;opacity:.9}
.doc-page[data-template="stripedHeader"] .doc-logo{background:#fff;padding:4px;box-sizing:border-box}

/* Six more shape templates. */

/* Torn edge: the header's bottom looks torn off rather than cut on a clean
   line — two diagonal gradients form a zigzag of little triangles, the
   classic CSS "torn paper" recipe. Assumes a white page behind it, same as
   every other fixed-hex-colour template here. */
.doc-page[data-template="tornEdge"]{position:relative}
.doc-page[data-template="tornEdge"] .doc-head{background:var(--accent);margin:-16mm -16mm 22px;padding:16mm 16mm 18px;border-bottom:none;position:relative}
.doc-page[data-template="tornEdge"] .doc-head:after{content:"";position:absolute;left:0;right:0;bottom:-10px;height:10px;background-image:linear-gradient(135deg,#fff 50%,transparent 50%),linear-gradient(45deg,#fff 50%,transparent 50%);background-size:14px 10px;background-repeat:repeat-x}
.doc-page[data-template="tornEdge"] .doc-brand,
.doc-page[data-template="tornEdge"] .doc-brand-sub{color:#fff}
.doc-page[data-template="tornEdge"] .doc-brand-sub{opacity:.85}
.doc-page[data-template="tornEdge"] .doc-type h2,
.doc-page[data-template="tornEdge"] .receipt-title h2{color:#fff;background:none}
.doc-page[data-template="tornEdge"] .doc-type div,
.doc-page[data-template="tornEdge"] .receipt-title div{color:#fff;opacity:.85}
.doc-page[data-template="tornEdge"] .doc-logo{background:#fff;padding:4px;box-sizing:border-box}

/* Corner brackets: viewfinder-style L marks at the top-left and bottom-
   right corners instead of a full frame (cornerFrame) or a filled shape —
   explicitly cancels the base accent bar's own :before properties
   (right/background) it would otherwise inherit, rather than only adding
   new ones. */
.doc-page[data-template="cornerBrackets"]{position:relative}
.doc-page[data-template="cornerBrackets"]:before{content:"";position:absolute;top:8mm;left:8mm;right:auto;width:14mm;height:14mm;background:none;border-top:2px solid var(--accent);border-left:2px solid var(--accent);pointer-events:none}
.doc-page[data-template="cornerBrackets"]:after{content:"";position:absolute;bottom:8mm;right:8mm;width:14mm;height:14mm;background:none;border-bottom:2px solid var(--accent);border-right:2px solid var(--accent);pointer-events:none}

/* Envelope flap: a V-notch cut INTO the top of the header, like an open
   envelope — the opposite move of angledHeader/waveHeader, which only ever
   cut the BOTTOM edge. Extra top padding keeps the brand row clear of the
   notch's lowest point. */
.doc-page[data-template="envelopeFlap"]:before{display:none}
.doc-page[data-template="envelopeFlap"] .doc-head{background:var(--accent);margin:-16mm -16mm 22px;padding:24mm 16mm 14px;border-bottom:none;clip-path:polygon(0 0,50% 32%,100% 0,100% 100%,0 100%)}
.doc-page[data-template="envelopeFlap"] .doc-brand,
.doc-page[data-template="envelopeFlap"] .doc-brand-sub{color:#fff}
.doc-page[data-template="envelopeFlap"] .doc-brand-sub{opacity:.85}
.doc-page[data-template="envelopeFlap"] .doc-type h2,
.doc-page[data-template="envelopeFlap"] .receipt-title h2{color:#fff;background:none}
.doc-page[data-template="envelopeFlap"] .doc-type div,
.doc-page[data-template="envelopeFlap"] .receipt-title div{color:#fff;opacity:.85}
.doc-page[data-template="envelopeFlap"] .doc-logo{background:#fff;padding:4px;box-sizing:border-box}

/* Bookmark tab: the document type/title hangs from the very top edge as a
   small pentagon tag (a flat top, pointed bottom) instead of sitting inline
   in the header — position:absolute against .doc-page (see cornerRibbon's
   own comment on why that's safe regardless of the parent's flex
   direction), placed to sit in the page's own top margin above where the
   letterhead's content starts, so nothing overlaps it. */
.doc-page[data-template="bookmarkTab"] .doc-type,
.doc-page[data-template="bookmarkTab"] .receipt-title{position:absolute;top:0;left:16mm;width:50mm;background:var(--accent);clip-path:polygon(0 0,100% 0,100% 72%,50% 100%,0 72%);padding:7px 10px 14px;text-align:center;z-index:2}
.doc-page[data-template="bookmarkTab"] .doc-type h2,
.doc-page[data-template="bookmarkTab"] .receipt-title h2{color:#fff;background:none;margin:0;font-size:11px}
.doc-page[data-template="bookmarkTab"] .doc-type div,
.doc-page[data-template="bookmarkTab"] .receipt-title div{color:#fff;opacity:.85;font-size:7px}

/* Layered stack: hard-edged offset box-shadows behind the total/amount box
   suggest a stack of sheets underneath it — a flat, paper-cutout depth cue,
   different from rounded's soft blurred elevation (the only other template
   using shadow for depth) and circleSeal's plain solid fill. */
.doc-page[data-template="layeredStack"] .receipt-amount-box{box-shadow:6px 6px 0 -2px #fff,6px 6px 0 0 #d8dce6,12px 12px 0 -2px #fff,12px 12px 0 0 #c3c9de}
.doc-page[data-template="layeredStack"] .doc-totals .r.grand{box-shadow:4px 4px 0 -1px #fff,4px 4px 0 0 #d8dce6;background:var(--accent-soft);color:#20242c;border:none;border-radius:6px;padding:8px 12px;margin-top:8px}

/* Wave divider: a small zigzag ribbon sits above the signature block — the
   same clip-path-polygon-as-wave idea as waveHeader, applied to a different,
   much smaller element instead of the whole letterhead. */
.doc-page[data-template="waveDivider"] .doc-sign{position:relative;padding-top:16px}
.doc-page[data-template="waveDivider"] .doc-sign:before{content:"";position:absolute;top:0;left:0;right:0;height:8px;background:var(--accent);clip-path:polygon(0 30%,8% 70%,16% 30%,24% 70%,32% 30%,40% 70%,48% 30%,56% 70%,64% 30%,72% 70%,80% 30%,88% 70%,96% 30%,100% 70%,100% 100%,0 100%)}

/* Six elegant/luxury-motif templates — jewellery-catalogue and invitation-card
   cues (a frame, a foil rule, a stamped seal, filigree, a faint medallion,
   a string of pearls) instead of the bolder graphic shapes above. */

/* Art Deco frame: a nested double border a little inside the page edge,
   replacing the default single top accent bar entirely (both properties the
   base .doc-page:before rule sets — background and height — are explicitly
   cancelled below, since the cascade only overrides what a rule redeclares). */
.doc-page[data-template="artDecoFrame"]:before{content:"";position:absolute;top:6mm;left:6mm;right:6mm;bottom:6mm;height:auto;background:none;border:2px solid var(--accent);pointer-events:none}
.doc-page[data-template="artDecoFrame"]:after{content:"";position:absolute;top:9mm;left:9mm;right:9mm;bottom:9mm;border:1px solid var(--accent);background:none;pointer-events:none}

/* Gold rule: the plain border-bottom under the letterhead and above the
   grand total is replaced with a thin rule plus a small centred diamond,
   the classic invitation-card divider — on both the invoice-style totals
   row and the receipt's amount box. */
.doc-page[data-template="goldRule"] .doc-head{border-bottom:none;position:relative;padding-bottom:20px}
.doc-page[data-template="goldRule"] .doc-head:after{content:"";position:absolute;left:0;right:0;bottom:6px;height:1px;background:var(--accent)}
.doc-page[data-template="goldRule"] .doc-head:before{content:"";position:absolute;left:50%;bottom:2px;width:7px;height:7px;background:var(--accent);transform:translateX(-50%) rotate(45deg)}
.doc-page[data-template="goldRule"] .doc-totals .r.grand{border-top:none;position:relative;padding-top:10px;margin-top:6px}
.doc-page[data-template="goldRule"] .doc-totals .r.grand:before{content:"";position:absolute;left:0;right:0;top:0;height:1px;background:var(--accent)}
.doc-page[data-template="goldRule"] .doc-totals .r.grand:after{content:"";position:absolute;left:50%;top:-4px;width:7px;height:7px;background:var(--accent);transform:translateX(-50%) rotate(45deg)}
.doc-page[data-template="goldRule"] .receipt-amount-box{border-top:none;position:relative;padding-top:14px;margin-top:6px}
.doc-page[data-template="goldRule"] .receipt-amount-box:before{content:"";position:absolute;left:0;right:0;top:0;height:1px;background:var(--accent)}
.doc-page[data-template="goldRule"] .receipt-amount-box:after{content:"";position:absolute;left:50%;top:-4px;width:7px;height:7px;background:var(--accent);transform:translateX(-50%) rotate(45deg)}

/* Wax seal: a small stamped medallion (solid disc + a white-then-accent
   double ring, no fill in the centre) sits above the business's own
   signature line, like a wax seal pressed onto a letter. .doc-sign's last
   .sig is the one prefilled with the business name (the first .sig is an
   empty slot left for the customer/recipient to sign) — targeting :last-
   child puts the seal over the actual filled-in signature rather than
   floating above blank space, on every generator that has two signers.
   A stamp over the signature, not circleSeal's earlier trick of turning
   the whole total box into a circle. */
.doc-page[data-template="waxSeal"] .doc-sign{position:relative;padding-top:28px}
.doc-page[data-template="waxSeal"] .sig:last-child{position:relative}
.doc-page[data-template="waxSeal"] .sig:last-child:before{content:"";position:absolute;top:-24px;left:50%;width:32px;height:32px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 3px #fff,0 0 0 4px var(--accent);transform:translateX(-50%)}
.doc-page[data-template="waxSeal"] .sig:last-child:after{content:"";position:absolute;top:-14px;left:50%;width:12px;height:12px;border:2px solid #fff;border-radius:50%;transform:translateX(-50%)}

/* Filigree corners: quarter-circle curled brackets (rounded, not the sharp
   right angles cornerBrackets uses) sit just inside the top-left and
   bottom-right page corners, a softer certificate-style flourish. */
.doc-page[data-template="filigreeCorners"]:before{content:"";position:absolute;top:6mm;left:6mm;right:auto;width:18px;height:18px;background:none;border-radius:0 0 18px 0;border-bottom:2px solid var(--accent);border-right:2px solid var(--accent);pointer-events:none}
.doc-page[data-template="filigreeCorners"]:after{content:"";position:absolute;bottom:6mm;right:6mm;left:auto;top:auto;width:18px;height:18px;background:none;border-radius:18px 0 0 0;border-top:2px solid var(--accent);border-left:2px solid var(--accent);pointer-events:none}

/* Medallion watermark: a faint, low-opacity double ring floats in the
   letterhead like an embossed seal seen through paper. Negative z-index
   keeps it behind the brand text instead of over it (doc-head is given
   position:relative here so that z-index applies against this element's
   own stacking context, not the page's). */
.doc-page[data-template="medallionWatermark"] .doc-head{position:relative}
.doc-page[data-template="medallionWatermark"] .doc-head:after{content:"";position:absolute;top:50%;right:10mm;width:64px;height:64px;border-radius:50%;border:1px solid var(--accent);box-shadow:0 0 0 6px #fff,0 0 0 7px var(--accent);opacity:.15;transform:translateY(-50%);z-index:-1}

/* Pearl divider: a delicate row of small dots (radial-gradient repeated as
   a background, not a border) sits above the signature block — a softer,
   jewellery-like texture next to waveDivider's bolder zigzag ribbon. */
.doc-page[data-template="pearlDivider"] .doc-sign{position:relative;padding-top:14px}
.doc-page[data-template="pearlDivider"] .doc-sign:before{content:"";position:absolute;top:0;left:0;right:0;height:5px;background-image:radial-gradient(circle,var(--accent) 40%,transparent 42%);background-size:11px 5px;background-repeat:repeat-x;opacity:.8}

/* Six bold full-page background templates — every one above this point only
   ever decorates the header, a divider or the signature block; these instead
   paint something behind the WHOLE page (meta, table, totals, notes, sign,
   the works), answering feedback that the set so far reads as "minor" —
   header/footer flourishes only. Each background layer is a page-covering
   :before/:after with negative z-index so it always sits behind the real
   content, never in front of it. .doc-page's default :before is the plain
   6px top accent bar (left:0;top:0;right:0;height:6px;background:accent) —
   every override below that reuses :before has to explicitly cancel
   whichever of those properties it doesn't already redeclare, the same
   cascade gotcha documented for cornerBrackets/artDecoFrame earlier; :after
   has no such default and is used wherever a second free layer is needed. */

/* Clip oversized/bleeding layers to the paper — otherwise print shrinks the whole page to fit them. */
.doc-page[data-template^="bg"]{overflow:hidden}

/* Diagonal stripe background: a soft repeating diagonal stripe fills the
   entire page (not just the letterhead, unlike stripedHeader), like faint
   security-paper texture running behind every section. */
.doc-page[data-template="bgDiagonalStripes"]:before{content:"";position:absolute;inset:0;height:auto;background:repeating-linear-gradient(45deg,var(--accent) 0,var(--accent) 12px,transparent 12px,transparent 24px);opacity:.12;z-index:-1;pointer-events:none}

/* Dot grid background: a faint blueprint/graph-paper dot grid covers the
   whole page behind the content, a technical texture rather than a line. */
.doc-page[data-template="bgDotGrid"]:before{content:"";position:absolute;inset:0;height:auto;background-color:transparent;background-image:radial-gradient(var(--accent) 2.6px,transparent 2.9px);background-size:24px 24px;opacity:.22;z-index:-1;pointer-events:none}

/* Side band background: a solid accent-colour band runs the full height of
   the page down the left margin. The page's own left padding is pushed out
   to make room so the band never sits under real text — a continuous
   full-height background element, not a corner or edge accent. */
.doc-page[data-template="bgSideBand"]{padding-left:28mm}
.doc-page[data-template="bgSideBand"]:before{content:"";position:absolute;top:0;left:0;bottom:0;right:auto;height:auto;width:12mm;background:var(--accent);pointer-events:none}

/* Corner triangle background: two large translucent triangles fill opposite
   corners of the page (clip-path over a big box, not the small border-mark
   corners cornerBrackets/filigreeCorners use), a bold graphic backdrop. */
.doc-page[data-template="bgCornerTriangle"]:after{content:"";position:absolute;top:0;right:0;width:70mm;height:70mm;background:var(--accent);clip-path:polygon(100% 0,100% 100%,0 0);opacity:.12;z-index:-1;pointer-events:none}
.doc-page[data-template="bgCornerTriangle"]:before{content:"";position:absolute;bottom:0;left:0;top:auto;right:auto;width:70mm;height:70mm;background:var(--accent);clip-path:polygon(0 100%,0 0,100% 100%);opacity:.12;z-index:-1;pointer-events:none}

/* Large ring background: two big concentric rings (hollow — background:none
   cancels the base fill so only the border ring shows) sit centred behind
   the whole page, a large medallion-like backdrop rather than
   medallionWatermark's small ring tucked into just the letterhead. */
.doc-page[data-template="bgRings"]:before{content:"";position:absolute;top:50%;left:50%;right:auto;bottom:auto;height:150mm;width:150mm;background:none;border-radius:50%;border:14mm solid var(--accent);opacity:.06;transform:translate(-50%,-50%);z-index:-1;pointer-events:none}
.doc-page[data-template="bgRings"]:after{content:"";position:absolute;top:50%;left:50%;width:80mm;height:80mm;background:none;border-radius:50%;border:8mm solid var(--accent);opacity:.08;transform:translate(-50%,-50%);z-index:-1;pointer-events:none}

/* Bold frame background: a solid accent-colour layer fills the entire page
   (z-index -2) with a white rectangle inset a fixed distance from every
   edge on top of it (z-index -1), leaving a thick solid colour border
   running around the whole page perimeter — done as two stacked layers
   instead of a real CSS border so the page's own box model/padding, and
   therefore print pagination, is never touched. */
.doc-page[data-template="bgFramedBorder"]:before{content:"";position:absolute;inset:0;height:auto;background:var(--accent);z-index:-2;pointer-events:none}
.doc-page[data-template="bgFramedBorder"]:after{content:"";position:absolute;top:10mm;right:10mm;bottom:10mm;left:10mm;background:#fff;z-index:-1;pointer-events:none}

/* Six more bold full-page background templates. Every one of these uses the
   'background' SHORTHAND (never the background-image longhand on its own)
   when overriding .doc-page's default :before, specifically because the
   shorthand always resets background-color to transparent as part of it —
   the fix bgDotGrid needed after its background-image-only rule left the
   base rule's solid background-color showing through behind the pattern,
   at the exact same colour as the pattern itself, erasing all contrast. */

/* Grid line background: a faint axis-aligned line grid (graph paper), two
   repeating-linear-gradients at 0deg/90deg layered in one background, behind
   the whole page — a grid of lines rather than bgDotGrid's grid of dots. */
.doc-page[data-template="bgGridLines"]:before{content:"";position:absolute;inset:0;height:auto;background:repeating-linear-gradient(0deg,var(--accent) 0,var(--accent) 1px,transparent 1px,transparent 24px),repeating-linear-gradient(90deg,var(--accent) 0,var(--accent) 1px,transparent 1px,transparent 24px);opacity:.18;z-index:-1;pointer-events:none}

/* Diamond lattice background: two diagonal repeating-linear-gradients
   crossing each other weave a criss-cross diamond texture across the whole
   page — busier and more jewel-like than the single-direction
   bgDiagonalStripes or the perpendicular bgGridLines. */
.doc-page[data-template="bgDiamondLattice"]:before{content:"";position:absolute;inset:0;height:auto;background:repeating-linear-gradient(45deg,var(--accent) 0 3px,transparent 3px 16px),repeating-linear-gradient(-45deg,var(--accent) 0 3px,transparent 3px 16px);opacity:.14;z-index:-1;pointer-events:none}

/* Diagonal half split background: one flat colour wash fills the entire
   upper-left triangular HALF of the page (corner to corner, not a small
   box in the corner like bgCornerTriangle) — the boldest-scale shape of
   the set, kept to a low opacity since it sits behind so much running text. */
.doc-page[data-template="bgHalfSplit"]:before{content:"";position:absolute;inset:0;height:auto;background:var(--accent);opacity:.08;clip-path:polygon(0 0,100% 0,0 100%);z-index:-1;pointer-events:none}

/* Big wave background: the same wave-point clip-path idea as waveDivider,
   scaled up into a tall band filling the bottom of the page as a background
   shape instead of a thin ribbon above the signature. */
.doc-page[data-template="bgBottomWave"]:before{content:"";position:absolute;bottom:0;left:0;right:0;top:auto;height:50mm;background:var(--accent);opacity:.10;clip-path:polygon(0 30%,10% 22%,20% 30%,30% 22%,40% 30%,50% 22%,60% 30%,70% 22%,80% 30%,90% 22%,100% 30%,100% 100%,0 100%);z-index:-1;pointer-events:none}

/* Top-bottom band background: solid bands sit in the page's own top and
   bottom margins (:before and :after — :after has no default rule to
   collide with, so it needs no cancellation). Full opacity is safe here
   since both bands stay inside the blank padding, never under real text. */
.doc-page[data-template="bgTopBottomBands"]:before{content:"";position:absolute;top:0;left:0;right:0;bottom:auto;height:12mm;background:var(--accent);z-index:-1;pointer-events:none}
.doc-page[data-template="bgTopBottomBands"]:after{content:"";position:absolute;bottom:0;left:0;right:0;height:12mm;background:var(--accent);z-index:-1;pointer-events:none}

/* Quarter circle background: a full circle positioned mostly off-page past
   the bottom-right corner, so only a large rounded quarter-arc shows inside
   the page — a soft curved bloom, unlike every hard-angled shape above it
   (bgCornerTriangle, bgHalfSplit). */
.doc-page[data-template="bgQuarterCircle"]:before{content:"";position:absolute;bottom:-40mm;right:-40mm;top:auto;left:auto;width:140mm;height:140mm;background:var(--accent);border-radius:50%;opacity:.10;z-index:-1;pointer-events:none}

/* Six floral/botanical full-page background templates. The "flower" and
   "petal" shapes here are all built from plain overlapping radial-gradient
   circles (a ring of petal-circles around a smaller centre circle) rather
   than an SVG/mask image, keeping every template in this file to the same
   plain-CSS techniques (gradients, clip-path, borders) instead of adding a
   new one this late. Every override below uses the 'background' SHORTHAND
   for the same reason documented at the top of the previous background
   batch: it always resets background-color to transparent, which is what
   keeps the base .doc-page:before rule's solid accent fill from showing
   through behind a pattern (the bug bgDotGrid had to be fixed for). */

/* Flower lattice: a ring centred on every grid intersection plus one at
   each cell's centre, tiled edge to edge — the classic "flower of life"
   interlocking-circles motif, where neighbouring rings overlap into
   lens-shaped petals. Covers the whole page, unlike bgDotGrid/bgGridLines'
   plain dots/lines or bgDiamondLattice's straight crossed stripes. */
.doc-page[data-template="bgFlowerLattice"]:before{content:"";position:absolute;inset:0;height:auto;background:radial-gradient(circle at 12px 12px,transparent 9px,var(--accent) 10px,var(--accent) 11px,transparent 12px),radial-gradient(circle at 0 0,transparent 9px,var(--accent) 10px,var(--accent) 11px,transparent 12px),radial-gradient(circle at 24px 0,transparent 9px,var(--accent) 10px,var(--accent) 11px,transparent 12px),radial-gradient(circle at 0 24px,transparent 9px,var(--accent) 10px,var(--accent) 11px,transparent 12px),radial-gradient(circle at 24px 24px,transparent 9px,var(--accent) 10px,var(--accent) 11px,transparent 12px);background-size:24px 24px;opacity:.15;z-index:-1;pointer-events:none}

/* Corner bloom: six petal-circles arranged in a hexagon around a smaller
   centre circle — a single stylised flower, not a repeating pattern —
   tucked into the bottom-right page corner margin like a pressed-flower
   sticker, the way filigreeCorners/cornerBrackets tuck a mark into a
   corner but with an actual flower shape instead of a line ornament. */
.doc-page[data-template="bgBloomCorner"]:before{content:"";position:absolute;bottom:6mm;right:6mm;top:auto;left:auto;width:50mm;height:50mm;background:radial-gradient(circle 9mm at 36mm 25mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 9mm at 30.5mm 15.5mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 9mm at 19.5mm 15.5mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 9mm at 14mm 25mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 9mm at 19.5mm 34.5mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 9mm at 30.5mm 34.5mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 6mm at 25mm 25mm,var(--accent) 97%,transparent 100%);opacity:.35;z-index:-1;pointer-events:none}

/* Leaf scatter: two small ellipses per tile, offset from each other, tile
   into a loose brick-like scatter across the whole page instead of a rigid
   grid — meant to read as scattered leaves/petals rather than a lattice. */
.doc-page[data-template="bgLeafScatter"]:before{content:"";position:absolute;inset:0;height:auto;background:radial-gradient(ellipse 5px 9px at 10px 10px,var(--accent) 90%,transparent 100%),radial-gradient(ellipse 5px 9px at 30px 24px,var(--accent) 90%,transparent 100%);background-size:40px 40px;opacity:.16;z-index:-1;pointer-events:none}

/* Top vine: a wavy ribbon (the same wave-point clip-path recipe as
   waveDivider/bgBottomWave) stands in for a vine stem along the top edge,
   with small round "buds" (a second, free-standing :after layer, so no
   base-rule cancellation is needed) scattered along it at alternating
   heights echoing the wave's rhythm. */
.doc-page[data-template="bgVineTop"]:before{content:"";position:absolute;top:0;left:0;right:0;bottom:auto;height:14mm;background:var(--accent);opacity:.35;clip-path:polygon(0 60%,10% 40%,20% 60%,30% 40%,40% 60%,50% 40%,60% 60%,70% 40%,80% 60%,90% 40%,100% 60%,100% 0,0 0);z-index:-1;pointer-events:none}
.doc-page[data-template="bgVineTop"]:after{content:"";position:absolute;top:2mm;left:0;right:0;height:6mm;background-image:radial-gradient(circle 3mm at 10% 30%,var(--accent) 90%,transparent 100%),radial-gradient(circle 3mm at 30% 60%,var(--accent) 90%,transparent 100%),radial-gradient(circle 3mm at 50% 30%,var(--accent) 90%,transparent 100%),radial-gradient(circle 3mm at 70% 60%,var(--accent) 90%,transparent 100%),radial-gradient(circle 3mm at 90% 30%,var(--accent) 90%,transparent 100%);opacity:.35;z-index:-1;pointer-events:none}

/* Flower mandala: the same six-petals-plus-centre bloom as bgBloomCorner,
   scaled up and centred on the whole page at very low opacity — a big
   flower-shaped watermark rather than bgRings'/bgQuarterCircle's plain
   circles, and centred rather than tucked into one corner. */
.doc-page[data-template="bgFlowerMandala"]:before{content:"";position:absolute;top:50%;left:50%;right:auto;bottom:auto;width:130mm;height:130mm;background:radial-gradient(circle 24mm at 93mm 65mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 24mm at 79mm 40.75mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 24mm at 51mm 40.75mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 24mm at 37mm 65mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 24mm at 51mm 89.25mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 24mm at 79mm 89.25mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 16mm at 65mm 65mm,var(--accent) 97%,transparent 100%);opacity:.07;transform:translate(-50%,-50%);z-index:-1;pointer-events:none}

/* Petal border: the small-flower-cluster tile from bgBloomCorner shrunk
   down and tiled horizontally (background-repeat:repeat-x) along the
   bottom margin — a garland ribbon of tiny blooms, the repeating
   counterpart to bgVineTop's single wavy stem along the top. */
.doc-page[data-template="bgPetalBorder"]:before{content:"";position:absolute;bottom:0;left:0;right:0;top:auto;height:20mm;background:radial-gradient(circle 3.5mm at 14.5mm 10mm,var(--accent) 96%,transparent 100%),radial-gradient(circle 3.5mm at 12.25mm 6.1mm,var(--accent) 96%,transparent 100%),radial-gradient(circle 3.5mm at 7.75mm 6.1mm,var(--accent) 96%,transparent 100%),radial-gradient(circle 3.5mm at 5.5mm 10mm,var(--accent) 96%,transparent 100%),radial-gradient(circle 3.5mm at 7.75mm 13.9mm,var(--accent) 96%,transparent 100%),radial-gradient(circle 3.5mm at 12.25mm 13.9mm,var(--accent) 96%,transparent 100%),radial-gradient(circle 2.5mm at 10mm 10mm,var(--accent) 96%,transparent 100%);background-size:20mm 20mm;background-repeat:repeat-x;opacity:.3;z-index:-1;pointer-events:none}

/* Five more floral/botanical background templates. */

/* Floral frame: a small 4-petal bloom (N/E/S/W petals + a centre circle,
   simpler than the 6-petal bloom above) in EVERY page corner instead of
   just one — since .doc-page only has two pseudo-elements, :before carries
   the top-left and bottom-right blooms and :after carries the top-right and
   bottom-left ones. Positions use calc() so this still works at any paper
   size/orientation: calc(100% - 46mm + X) mirrors the same relative offset
   X used for the near corner (6mm inset + 40mm bloom box = 46mm). */
.doc-page[data-template="bgFloralFrame"]:before{content:"";position:absolute;inset:0;height:auto;background:radial-gradient(circle 7mm at calc(6mm + 20mm) calc(6mm + 9mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(6mm + 31mm) calc(6mm + 20mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(6mm + 20mm) calc(6mm + 31mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(6mm + 9mm) calc(6mm + 20mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 5mm at calc(6mm + 20mm) calc(6mm + 20mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(100% - 46mm + 20mm) calc(100% - 46mm + 9mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(100% - 46mm + 31mm) calc(100% - 46mm + 20mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(100% - 46mm + 20mm) calc(100% - 46mm + 31mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(100% - 46mm + 9mm) calc(100% - 46mm + 20mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 5mm at calc(100% - 46mm + 20mm) calc(100% - 46mm + 20mm),var(--accent) 96%,transparent 100%);opacity:.3;z-index:-1;pointer-events:none}
.doc-page[data-template="bgFloralFrame"]:after{content:"";position:absolute;inset:0;background:radial-gradient(circle 7mm at calc(100% - 46mm + 20mm) calc(6mm + 9mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(100% - 46mm + 31mm) calc(6mm + 20mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(100% - 46mm + 20mm) calc(6mm + 31mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(100% - 46mm + 9mm) calc(6mm + 20mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 5mm at calc(100% - 46mm + 20mm) calc(6mm + 20mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(6mm + 20mm) calc(100% - 46mm + 9mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(6mm + 31mm) calc(100% - 46mm + 20mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(6mm + 20mm) calc(100% - 46mm + 31mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 7mm at calc(6mm + 9mm) calc(100% - 46mm + 20mm),var(--accent) 96%,transparent 100%),radial-gradient(circle 5mm at calc(6mm + 20mm) calc(100% - 46mm + 20mm),var(--accent) 96%,transparent 100%);opacity:.3;z-index:-1;pointer-events:none}

/* Wildflower patch: three small 3-petal blooms of different sizes at
   scattered (not neatly ringed) positions in the bottom-left corner — an
   organic cluster instead of bgBloomCorner's one clean symmetric flower. */
.doc-page[data-template="bgWildflowerPatch"]:before{content:"";position:absolute;bottom:6mm;left:6mm;top:auto;right:auto;width:40mm;height:40mm;background:radial-gradient(circle 3mm at 12mm 24mm,var(--accent) 94%,transparent 100%),radial-gradient(circle 3mm at 8.54mm 30mm,var(--accent) 94%,transparent 100%),radial-gradient(circle 3mm at 15.46mm 30mm,var(--accent) 94%,transparent 100%),radial-gradient(circle 2mm at 12mm 28mm,var(--accent) 94%,transparent 100%),radial-gradient(circle 4mm at 28mm 13mm,var(--accent) 94%,transparent 100%),radial-gradient(circle 4mm at 23.67mm 20.5mm,var(--accent) 94%,transparent 100%),radial-gradient(circle 4mm at 32.33mm 20.5mm,var(--accent) 94%,transparent 100%),radial-gradient(circle 2.5mm at 28mm 18mm,var(--accent) 94%,transparent 100%),radial-gradient(circle 3mm at 18mm 4mm,var(--accent) 94%,transparent 100%),radial-gradient(circle 3mm at 14.54mm 10mm,var(--accent) 94%,transparent 100%),radial-gradient(circle 3mm at 21.46mm 10mm,var(--accent) 94%,transparent 100%),radial-gradient(circle 2mm at 18mm 8mm,var(--accent) 94%,transparent 100%);opacity:.4;z-index:-1;pointer-events:none}

/* Fern pattern: the whole tile of leaf-ellipses is rotated 25deg as one
   layer (the element itself is oversized to 150% and recentred so the
   rotated box still fully covers the page) instead of leaving the ellipses
   axis-aligned like bgLeafScatter — the rotation is what reads as a
   directional frond/fern rather than a plain dot scatter. */
.doc-page[data-template="bgFernRows"]:before{content:"";position:absolute;top:-25%;left:-25%;right:auto;bottom:auto;width:150%;height:150%;background:radial-gradient(ellipse 3px 11px at 10px 10px,var(--accent) 88%,transparent 100%),radial-gradient(ellipse 3px 11px at 30px 25px,var(--accent) 88%,transparent 100%);background-size:40px 40px;opacity:.14;transform:rotate(25deg);z-index:-1;pointer-events:none}

/* Diagonal branch: a translucent band (:before) plus a row of small leaf-
   bud dots at alternating heights (:after, a separate layer so it can carry
   its own opacity) are both rotated the same amount, forming a diagonal
   sash across the middle of the page rather than confined to one edge or
   corner. Sized as percentages (not a fixed corner-to-corner mm diagonal)
   so it still looks right regardless of paper size/orientation. */
.doc-page[data-template="bgBranchSash"]:before{content:"";position:absolute;top:38%;left:-20%;right:auto;bottom:auto;width:140%;height:16mm;background:var(--accent);opacity:.14;transform:rotate(-20deg);z-index:-1;pointer-events:none}
.doc-page[data-template="bgBranchSash"]:after{content:"";position:absolute;top:38%;left:-20%;width:140%;height:16mm;background-image:radial-gradient(circle 3mm at 5% 50%,var(--accent) 90%,transparent 100%),radial-gradient(circle 3mm at 20% 30%,var(--accent) 90%,transparent 100%),radial-gradient(circle 3mm at 35% 60%,var(--accent) 90%,transparent 100%),radial-gradient(circle 3mm at 50% 30%,var(--accent) 90%,transparent 100%),radial-gradient(circle 3mm at 65% 60%,var(--accent) 90%,transparent 100%),radial-gradient(circle 3mm at 80% 30%,var(--accent) 90%,transparent 100%),radial-gradient(circle 3mm at 95% 50%,var(--accent) 90%,transparent 100%);opacity:.3;transform:rotate(-20deg);z-index:-1;pointer-events:none}

/* Big side bloom: the six-petals-plus-centre flower scaled up and anchored
   to the vertical middle of the LEFT edge, bleeding off-page to the left —
   an edge-anchored placement, unlike bgBloomCorner (corner), bgFlowerMandala
   (centred) or bgFloralFrame (all four corners). */
.doc-page[data-template="bgBigBloomSide"]:before{content:"";position:absolute;top:50%;left:-40mm;right:auto;bottom:auto;width:100mm;height:100mm;background:radial-gradient(circle 18mm at 72mm 50mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 18mm at 61mm 31.94mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 18mm at 39mm 31.94mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 18mm at 28mm 50mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 18mm at 39mm 68.06mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 18mm at 61mm 68.06mm,var(--accent) 97%,transparent 100%),radial-gradient(circle 12mm at 50mm 50mm,var(--accent) 97%,transparent 100%);opacity:.09;transform:translateY(-50%);z-index:-1;pointer-events:none}

/* Five more templates that change PLACEMENT, not just color — every rule
   above this point only ever recolors/reshapes the same top-to-bottom flow
   (head, then meta, then table, then totals, then notes, then sign). These
   instead move sections relative to each other: a real sidebar column, a
   mirrored layout, totals reordered before the table, every section boxed
   as its own card, and the title/letterhead order swapped. Still zero
   changes to any of the 126 generator pages themselves — every rule here
   targets .doc-page's DIRECT children generically (`>` combinator, mostly
   :not()-based rather than naming each section) specifically so it works
   whether a page's content siblings are .doc-meta/.doc-table/.doc-totals
   (most generators) or .receipt-title/.receipt-amount-box (receipt.html,
   which has neither of those two and no .doc-table at all) without this
   needing to know which shape a given page uses. */

/* Sidebar: a real two-column layout — the letterhead becomes a full-height
   left column, everything else flows in a wide right column. Deliberately
   NOT CSS Grid with a row-span: .doc-page has no explicit rows, so a
   grid-row:1/-1 span on .doc-head has no defined "last row" to reach and
   collapses to nothing, leaving the sidebar background only as tall as its
   own text (confirmed by rendering it — the box stopped after the
   letterhead instead of covering the page, with content actually
   overlapping it). Absolute positioning against .doc-page's own
   position:relative sidesteps that entirely: top:0/bottom:0 always matches
   .doc-page's real rendered height, however that height was determined,
   with no row count to get wrong. Every other child just stays in normal
   block flow, pushed right by .doc-page's own left padding — it doesn't
   need to know the sidebar exists at all. */
.doc-page[data-template="sidebar"]{padding:16mm 16mm 16mm 76mm}
.doc-page[data-template="sidebar"]:before{display:none}
.doc-page[data-template="sidebar"] > .doc-head{position:absolute;top:0;left:0;bottom:0;width:60mm;box-sizing:border-box;margin:0;padding:16mm 14px 16mm 16mm;flex-direction:column;align-items:flex-start;gap:16px;background:var(--accent-soft);border-bottom:none;border-right:3px solid var(--accent)}
.doc-page[data-template="sidebar"] .doc-brand-row{flex-direction:column;align-items:flex-start;gap:10px}
.doc-page[data-template="sidebar"] .doc-type,
.doc-page[data-template="sidebar"] .receipt-title{text-align:left}
.doc-page[data-template="sidebar"] .receipt-title h2{margin-left:0}
.doc-page[data-template="sidebar"] .doc-totals{margin-right:0}

/* Reversed: a full mirror — brand/title swap sides in the header, the
   from/to columns in .doc-meta swap sides, the totals box moves from the
   right edge to the left, and the two .doc-sign blocks swap which one is
   left/right. Only flex-direction flips on containers that were already
   flex rows, so nothing can overlap or overflow differently than the
   original layout already allows. */
.doc-page[data-template="reversed"] .doc-head{flex-direction:row-reverse}
.doc-page[data-template="reversed"] .doc-type{text-align:left}
.doc-page[data-template="reversed"] .doc-meta{flex-direction:row-reverse}
.doc-page[data-template="reversed"] .doc-totals{margin-left:0;margin-right:auto}
.doc-page[data-template="reversed"] .doc-sign{flex-direction:row-reverse}
.doc-page[data-template="reversed"] .receipt-amount-box{flex-direction:row-reverse}

/* Totals first: the total-due summary moves to right under the letterhead,
   ahead of the line-item table, for a "see the number first" read — common
   on simple bills/receipts. Achieved with flexbox `order` on .doc-page
   itself rather than reordering any markup; every child gets an explicit
   order so this doesn't depend on how many .doc-notes-like siblings a given
   page happens to have. */
.doc-page[data-template="totalsTop"]{display:flex;flex-direction:column}
.doc-page[data-template="totalsTop"] > .doc-head{order:0}
.doc-page[data-template="totalsTop"] > .doc-meta,
.doc-page[data-template="totalsTop"] > .receipt-title,
.doc-page[data-template="totalsTop"] > .receipt-row{order:1}
.doc-page[data-template="totalsTop"] > .doc-totals,
.doc-page[data-template="totalsTop"] > .receipt-amount-box{order:2;width:100%;margin:16px 0 4px;background:var(--accent-soft);padding:14px 18px;border-radius:10px}
.doc-page[data-template="totalsTop"] > .doc-table,
.doc-page[data-template="totalsTop"] > .doc-body{order:3;margin-top:4px}
.doc-page[data-template="totalsTop"] > .doc-notes{order:4}
.doc-page[data-template="totalsTop"] > .doc-sign{order:5}

/* Boxed: every section becomes its own bordered card on a light page
   background — a distinct "form/report" rhythm none of the templates above
   have, since those only ever box ONE section (the header banner, or the
   totals line) at most. */
.doc-page[data-template="boxed"]{background:#f4f6fb}
.doc-page[data-template="boxed"]:before{display:none}
.doc-page[data-template="boxed"] > *:not(.doc-watermark){background:#fff;border:1px solid #d8dce6;border-radius:10px;padding:14px 16px;margin-top:14px}
.doc-page[data-template="boxed"] > .doc-head{margin-top:0}
.doc-page[data-template="boxed"] > .doc-table{padding:10px 16px}

/* Formal: the document title moves ABOVE the letterhead instead of beside
   it — common on government/formal Indonesian letters ("SURAT...", title
   centered at the very top, company details below). `column-reverse`
   visually flips .doc-head's two children (brand-row, then doc-type in the
   markup) without touching the markup order itself. */
.doc-page[data-template="formal"] .doc-head{flex-direction:column-reverse;align-items:center;text-align:center;gap:10px;border-bottom:2px solid #20242c;padding-bottom:14px}
.doc-page[data-template="formal"] .doc-brand-row{justify-content:center}
.doc-page[data-template="formal"] .doc-type,
.doc-page[data-template="formal"] .receipt-title{text-align:center}
.doc-page[data-template="formal"] .doc-type h2,
.doc-page[data-template="formal"] .receipt-title h2{letter-spacing:.24em;font-size:calc(18px * var(--doc-title-scale, 1))}
.doc-page[data-template="formal"] .doc-meta{border:1px solid #20242c;padding:10px 14px}

/* Four more placement templates. Lesson learned from totalsTop above during
   its own verification: giving explicit `order` to every "keep in place"
   section is fragile — .doc-page's direct children turned out to include
   MORE shapes than the two this file's comments originally documented
   (.receipt-row, one per key/value line on receipt.html, and .doc-body,
   free-form letter text on mou.html/business-report.html/
   warranty-certificate.html, both un-enumerated at first and both actually
   rendering out of order until this comment was written). So these four
   only ever give an explicit order to the ONE OR TWO sections being
   deliberately pulled out of place, never to "everything else" — anything
   not named keeps its natural relative position automatically, including
   whatever future section shape this file doesn't know about yet. */

/* Table first: the substantive content (the item table, or a letter's
   .doc-body text) moves ahead of administrative meta (.doc-meta / receipt's
   .receipt-row lines) — "what this document is about" before "who it's
   between". .doc-sign is pinned to a very high order so it can never end up
   earlier than the meta it's supposed to follow, regardless of how many
   content sections a given page has between them. */
.doc-page[data-template="tableFirst"]{display:flex;flex-direction:column}
.doc-page[data-template="tableFirst"] > .doc-meta,
.doc-page[data-template="tableFirst"] > .receipt-row{order:10;margin-top:10px}
.doc-page[data-template="tableFirst"] > .doc-sign{order:20}

/* Stacked signatures: the two .sig blocks .doc-sign already lays out side
   by side move to a right-aligned vertical stack instead — for documents
   that read better as "approved by, then countersigned by" than two
   side-by-side blanks. Only touches .doc-sign itself (a single, always-
   present container), so this can't miss an unknown sibling class. */
.doc-page[data-template="stackedSign"] .doc-sign{flex-direction:column;align-items:flex-end;gap:22px}

/* Corner badge: the document type/number moves out of the header row into
   a colored badge floating at the page's top-right corner. Deliberately
   only targets .doc-type (which holds the actual title on every generator
   except receipt.html) rather than also touching .receipt-title — that one
   sits centered as its own full-width heading on receipt.html by design,
   and forcing it into a small corner badge would either crowd out or
   overlap .doc-head's own doc-no/date, which stays in normal flow right
   beside it. Receipts simply don't get the corner-badge treatment; every
   other generator does. */
/* The badge is an ordinary flex item of .doc-head (already a flex row with
   space-between), NOT position:absolute. It used to be absolute at the page's
   top-right with .doc-head only holding a fixed min-height:64px, so the
   header never knew how tall the badge was: a long title ("Berita Acara
   Serah Terima", "Laporan Inspeksi Kualitas") wrapped to several lines inside
   its 140px, hung below the header and printed over the first label of the
   Tanggal/Periode block underneath — measured on 29 of the generators.
   In-flow, the header grows to contain it, and it lands in the same corner
   (the header's right end is the page's right padding). */
.doc-page[data-template="cornerBadge"] .doc-type{flex:0 0 140px;width:140px;box-sizing:border-box;text-align:right;background:var(--accent);color:#fff;padding:9px 14px;border-radius:10px;word-break:break-word}
.doc-page[data-template="cornerBadge"] .doc-type h2{color:#fff;margin:0;font-size:calc(14px * var(--doc-title-scale, 1));letter-spacing:0}
.doc-page[data-template="cornerBadge"] .doc-type .doc-no{color:rgba(255,255,255,.85);font-size:10px}

/* Stamp corner: .doc-sign leaves the normal bottom-of-document flow
   entirely and becomes a fixed block anchored to the page's bottom-right
   corner, like a physical rubber stamp/seal placement — freeing whatever
   comes before it (.doc-notes, a letter's closing .doc-body paragraph) to
   use the full page width instead of stopping short to leave room for two
   side-by-side signature blocks. Both .sig blocks are kept (no signer is
   ever hidden, e.g. an MOU's two named parties) — they just stack instead
   of sitting side by side, matching the narrower corner space. */
.doc-page[data-template="stampCorner"]{position:relative}
.doc-page[data-template="stampCorner"] .doc-sign{position:absolute;bottom:16mm;right:16mm;margin:0;flex-direction:column;align-items:flex-end;gap:16px}

/* Five more, same "only move what's deliberately moved" discipline. */

/* Left accent: the page's accent strip leaves the top edge and runs down
   the full left edge instead, with the whole document indented past it —
   a different page geometry rather than a different header treatment. */
.doc-page[data-template="leftAccent"]{padding-left:26mm}
.doc-page[data-template="leftAccent"]:before{top:0;bottom:0;left:0;right:auto;width:9px;height:auto}

/* Split letterhead: .doc-head's two halves stop sharing one row and each
   take a full-width row of their own, each with its own rule under it —
   brand across the top, document type across the line below. Different
   from "formal", which centres them and swaps their order; here the
   reading order is unchanged and it's the WIDTH that changes. */
.doc-page[data-template="headerSplit"] .doc-head{flex-direction:column;align-items:stretch;gap:10px;border-bottom:none;padding-bottom:0}
.doc-page[data-template="headerSplit"] .doc-brand-row{padding-bottom:10px;border-bottom:2px solid var(--accent)}
.doc-page[data-template="headerSplit"] .doc-type,
.doc-page[data-template="headerSplit"] .receipt-title{text-align:right;padding-bottom:10px;border-bottom:1px solid #d8dce6}

/* Wide table: the item table breaks out of the page's own margins to run
   edge to edge, with the outer cells re-padded so their text still lines
   up with the rest of the document. Reads as a data sheet rather than a
   letter with a table in it. Only pages that HAVE a .doc-table change. */
.doc-page[data-template="wideTable"] .doc-table{width:calc(100% + 32mm);margin-left:-16mm;margin-right:-16mm}
.doc-page[data-template="wideTable"] .doc-table th:first-child,
.doc-page[data-template="wideTable"] .doc-table td:first-child{padding-left:16mm}
.doc-page[data-template="wideTable"] .doc-table th:last-child,
.doc-page[data-template="wideTable"] .doc-table td:last-child{padding-right:16mm}

/* Meta box: the from/to block becomes one bordered panel split down the
   middle, its two halves given equal width instead of being pushed to
   opposite edges by space-between. */
.doc-page[data-template="metaBox"] .doc-meta{border:1px solid #d8dce6;border-radius:10px;padding:0;gap:0;overflow:hidden}
.doc-page[data-template="metaBox"] .doc-meta>*{flex:1;padding:12px 16px;min-width:0}
.doc-page[data-template="metaBox"] .doc-meta>*+*{border-left:1px solid #d8dce6}

/* Card header: the page itself goes tinted and the letterhead lifts off it
   as a single floating white card. Deliberately only the header — "boxed"
   above already covers carding EVERY section, and doing both would make
   the two indistinguishable. */
.doc-page[data-template="cardHeader"]{background:#f4f6fb}
.doc-page[data-template="cardHeader"]:before{display:none}
.doc-page[data-template="cardHeader"] .doc-head{background:#fff;border:1px solid #e3e7ef;border-bottom-color:#e3e7ef;border-radius:14px;box-shadow:0 10px 30px -18px rgba(15,18,30,.45);padding:18px 22px}

/* Five more, each taking a placement none of the 24 above touch: the right
   edge, the bottom edge, a stacked (rather than side-by-side) info block,
   a single-line letterhead, and multi-column body text. */

/* Right sidebar: same full-height letterhead column as "sidebar", on the
   other side. Not the same as "reversed", which mirrors the normal
   top-to-bottom flow without ever making a column of anything. */
.doc-page[data-template="sidebarRight"]{padding:16mm 76mm 16mm 16mm}
.doc-page[data-template="sidebarRight"]:before{display:none}
.doc-page[data-template="sidebarRight"] > .doc-head{position:absolute;top:0;right:0;bottom:0;width:60mm;box-sizing:border-box;margin:0;padding:16mm 16mm 16mm 14px;flex-direction:column;align-items:flex-start;gap:16px;background:var(--accent-soft);border-bottom:none;border-left:3px solid var(--accent)}
.doc-page[data-template="sidebarRight"] .doc-brand-row{flex-direction:column;align-items:flex-start;gap:10px}
.doc-page[data-template="sidebarRight"] .doc-type,
.doc-page[data-template="sidebarRight"] .receipt-title{text-align:left}
.doc-page[data-template="sidebarRight"] .doc-totals{margin-right:0}

/* Footer band: the signature block leaves the flow and becomes a
   full-bleed strip along the bottom edge of the page — the one page edge
   nothing else here uses. The page takes matching bottom padding so
   content can never run underneath it, however short or long the item list
   turns out to be. */
.doc-page[data-template="footerBand"]{padding-bottom:46mm}
.doc-page[data-template="footerBand"] .doc-sign{position:absolute;left:0;right:0;bottom:0;margin:0;padding:14px 16mm 16mm;background:var(--accent-soft);border-top:3px solid var(--accent)}

/* Stacked info: the from/to halves stop sitting side by side and become
   two full-width blocks, each behind its own accent rule. "metaBox" keeps
   them side by side (equal width, divider between); this is the opposite
   answer to the same section. */
.doc-page[data-template="metaStack"] .doc-meta{flex-direction:column;gap:12px}
.doc-page[data-template="metaStack"] .doc-meta>*{border-left:3px solid var(--accent);padding-left:12px}

/* Slim letterhead: the whole header compressed onto one shallow line —
   small logo, small brand, small type — for documents where the content
   should dominate the page. Nothing is hidden (the address line is only
   scaled down, never display:none'd): a business document's own contact
   details aren't the template's to remove. */
.doc-page[data-template="slimHeader"] .doc-head{align-items:center;padding-bottom:8px;border-bottom:1px solid #d8dce6}
.doc-page[data-template="slimHeader"] .doc-logo{width:calc(34px * var(--doc-logo-scale, 1));height:calc(34px * var(--doc-logo-scale, 1))}
.doc-page[data-template="slimHeader"] .doc-brand{font-size:calc(14px * var(--doc-brand-scale, 1))}
.doc-page[data-template="slimHeader"] .doc-brand-sub{font-size:calc(9.5px * var(--doc-body-scale, 1));margin-top:2px}
.doc-page[data-template="slimHeader"] .doc-type h2,
.doc-page[data-template="slimHeader"] .receipt-title h2{font-size:calc(13px * var(--doc-title-scale, 1));letter-spacing:.12em}

/* Two-column body text: only the free-form letter body (.doc-body) is
   affected, so this reshapes announcements/circulars/MOUs and leaves every
   table-based document untouched — a table split down two narrow columns
   would be unreadable, and .doc-table is deliberately not included here. */
.doc-page[data-template="twoColumnText"] .doc-body{column-count:2;column-gap:22px;column-rule:1px solid #e3e7ef;text-align:justify}

/* Ribbon: the letterhead becomes a full-bleed accent band with everything
   in it reversed out to white, so the top of the page reads as one solid
   masthead instead of a white area with a rule under it. The negative
   margins bleed it past the page padding to the paper edge; the default
   6px :before bar is removed since the band replaces it. Text colour is
   forced on the header's own children only — nothing below it changes. */
.doc-page[data-template="ribbon"]:before{display:none}
.doc-page[data-template="ribbon"] .doc-head{margin:-16mm -16mm 18px;padding:14mm 16mm 12mm;background:var(--accent);border-bottom:none;align-items:center}
.doc-page[data-template="ribbon"] .doc-brand,
.doc-page[data-template="ribbon"] .doc-brand-sub,
.doc-page[data-template="ribbon"] .doc-type h2,
.doc-page[data-template="ribbon"] .receipt-title h2,
.doc-page[data-template="ribbon"] .doc-type div,
.doc-page[data-template="ribbon"] .receipt-title div{color:#fff}
.doc-page[data-template="ribbon"] .doc-brand-sub,
.doc-page[data-template="ribbon"] .doc-type div,
.doc-page[data-template="ribbon"] .receipt-title div{opacity:.85}
.doc-page[data-template="ribbon"] .doc-logo{background:#fff;padding:4px;box-sizing:border-box}

/* Ruled form: the "official form" look — every section sits on a visible
   hairline grid, the item table gets real cell borders instead of the
   default card-style rows, and the from/to blocks become bordered cells.
   Deliberately squares off every radius: a stamped-and-filed form doesn't
   have rounded corners. */
.doc-page[data-template="ruled"] .doc-head{border-bottom:2px solid #20242c;padding-bottom:10px}
.doc-page[data-template="ruled"] .doc-meta{gap:0;border:1px solid #b9c0cc;margin-top:14px}
.doc-page[data-template="ruled"] .doc-meta>*{flex:1;padding:10px 12px;box-sizing:border-box}
.doc-page[data-template="ruled"] .doc-meta>*+*{border-left:1px solid #b9c0cc}
.doc-page[data-template="ruled"] .doc-table{border-collapse:collapse;border-spacing:0}
.doc-page[data-template="ruled"] .doc-table th{background:#eef1f7;color:#20242c;border:1px solid #b9c0cc}
.doc-page[data-template="ruled"] .doc-table td{border:1px solid #b9c0cc;border-radius:0;background:#fff}
.doc-page[data-template="ruled"] .doc-table tr{box-shadow:none;transform:none}
.doc-page[data-template="ruled"] .doc-totals .r{border:1px solid #b9c0cc;border-top:none}
.doc-page[data-template="ruled"] .doc-totals .r:first-child{border-top:1px solid #b9c0cc}
/* :not(:empty) matters — a document has two .doc-notes blocks (notes and
   bank details) and either can legitimately be blank when the business
   hasn't filled it in. Bordering those unconditionally drew an empty box on
   the finished document. */
.doc-page[data-template="ruled"] .doc-notes:not(:empty){border:1px solid #b9c0cc;padding:10px 12px;margin-top:16px}

/* Highlighted total: for quotations/invoices where the number is the whole
   message. The totals block spans the full width and the grand-total row
   becomes a solid accent band — the loudest element on the page. */
.doc-page[data-template="grandTotal"] .doc-totals{width:100%;margin-left:0;margin-top:18px;border:2px solid var(--accent);padding:4px}
.doc-page[data-template="grandTotal"] .doc-totals .r{padding:6px 12px}
.doc-page[data-template="grandTotal"] .doc-totals .r.grand{background:var(--accent);color:#fff;border-top:none;margin-top:4px;padding:12px;font-size:calc(19px * var(--doc-body-scale, 1))}

/* Dark letterhead: a charcoal masthead with the accent kept as the single
   highlight underneath it. Same full-bleed band as "ribbon" but reading as
   restrained/premium rather than colourful — the accent survives as the
   underline and on the table header, so a business's chosen colour is
   still present rather than being overridden entirely. */
.doc-page[data-template="darkHeader"]:before{display:none}
.doc-page[data-template="darkHeader"] .doc-head{margin:-16mm -16mm 18px;padding:13mm 16mm 11mm;background:#20242c;border-bottom:4px solid var(--accent);align-items:center}
.doc-page[data-template="darkHeader"] .doc-brand,
.doc-page[data-template="darkHeader"] .doc-brand-sub{color:#fff}
.doc-page[data-template="darkHeader"] .doc-brand-sub{opacity:.75}
.doc-page[data-template="darkHeader"] .doc-type h2,
.doc-page[data-template="darkHeader"] .receipt-title h2{color:#fff}
.doc-page[data-template="darkHeader"] .doc-type div,
.doc-page[data-template="darkHeader"] .receipt-title div{color:#fff;opacity:.8}
.doc-page[data-template="darkHeader"] .doc-logo{background:#fff;padding:4px;box-sizing:border-box}

/* Five more placement templates (see the "Five more..." comments above for
   the discipline these follow: only move what's deliberately being moved,
   `>` only against .doc-page's confirmed direct-child section shapes). */

/* Centered column: every section narrows to a single centered column with
   wide margins either side, editorial-article style — distinct from
   "formal" (only the header centers) and "framed" (a decorative border,
   sections merely re-margined, not actually narrowed). */
.doc-page[data-template="centeredNarrow"] .doc-head,
.doc-page[data-template="centeredNarrow"] .doc-meta,
.doc-page[data-template="centeredNarrow"] .doc-table,
.doc-page[data-template="centeredNarrow"] .doc-totals,
.doc-page[data-template="centeredNarrow"] .doc-notes,
.doc-page[data-template="centeredNarrow"] .doc-body,
.doc-page[data-template="centeredNarrow"] .receipt-title,
.doc-page[data-template="centeredNarrow"] .receipt-row,
.doc-page[data-template="centeredNarrow"] .receipt-amount-box,
.doc-page[data-template="centeredNarrow"] .doc-sign{max-width:150mm;margin-left:auto;margin-right:auto}
.doc-page[data-template="centeredNarrow"] .doc-head{flex-direction:column;align-items:center;text-align:center;gap:8px}
.doc-page[data-template="centeredNarrow"] .doc-brand-row{justify-content:center}
.doc-page[data-template="centeredNarrow"] .doc-type,
.doc-page[data-template="centeredNarrow"] .receipt-title{text-align:center}

/* Info cards: the from/to halves each get their own soft filled card
   (rounded, no border) instead of metaBox's single divided panel or
   metaStack's stacked accent-rule blocks. */
.doc-page[data-template="metaCards"] .doc-meta{gap:12px}
.doc-page[data-template="metaCards"] .doc-meta>*{background:#f7f8fb;border-radius:10px;padding:10px 14px;flex:1;min-width:0}

/* Full background: the whole page is tinted and every section becomes its
   own floating white card with a soft shadow (no border) — including the
   letterhead, which is left transparent so brand/title sit directly on the
   tinted page instead of inside a card, unlike every other template here.
   Different from "boxed" (flat, bordered cards, light grey-blue, header
   included in the boxing) and "cardHeader" (only the header floats). */
.doc-page[data-template="fullBleed"]{background:#eef1f7}
.doc-page[data-template="fullBleed"]:before{display:none}
.doc-page[data-template="fullBleed"] > .doc-head{background:transparent;border-bottom:none}
.doc-page[data-template="fullBleed"] > .doc-meta,
.doc-page[data-template="fullBleed"] > .receipt-title,
.doc-page[data-template="fullBleed"] > .receipt-row,
.doc-page[data-template="fullBleed"] > .doc-table,
.doc-page[data-template="fullBleed"] > .doc-totals,
.doc-page[data-template="fullBleed"] > .receipt-amount-box,
.doc-page[data-template="fullBleed"] > .doc-notes,
.doc-page[data-template="fullBleed"] > .doc-body,
.doc-page[data-template="fullBleed"] > .doc-sign{background:#fff;border-radius:12px;padding:14px 16px;margin-top:12px;box-shadow:0 4px 14px -10px rgba(15,18,30,.25)}

/* Centered signatures: both signature blocks pull together into the middle
   of the page instead of spreading to the edges — the one placement none of
   stackedSign (right, vertical stack) or stampCorner (bottom-right, fixed)
   already cover. */
.doc-page[data-template="signCenter"] .doc-sign{justify-content:center;gap:50px}

/* Title banner: the document type/title (.doc-type, nested in .doc-head for
   most generators; .receipt-title, its own top-level section on
   receipt.html) drops onto its own full-width coloured band under the
   letterhead instead of sitting inline beside it. flex-wrap on .doc-head is
   what forces .doc-type onto that new line; .receipt-title needs no such
   trick, since it is already a full-width block on its own. */
.doc-page[data-template="bannerTitle"] .doc-head{flex-wrap:wrap;border-bottom:none;padding-bottom:0}
.doc-page[data-template="bannerTitle"] .doc-type{flex:0 0 100%}
.doc-page[data-template="bannerTitle"] .doc-type,
.doc-page[data-template="bannerTitle"] .receipt-title{width:100%;box-sizing:border-box;background:var(--accent);color:#fff;text-align:center;padding:10px 16px;margin-top:14px;border-radius:8px}
.doc-page[data-template="bannerTitle"] .doc-type h2,
.doc-page[data-template="bannerTitle"] .receipt-title h2{color:#fff;background:none;margin:0}
.doc-page[data-template="bannerTitle"] .doc-type div,
.doc-page[data-template="bannerTitle"] .receipt-title div{color:#fff;opacity:.85}

/* Five more placement templates. */

/* Numbered sections: a small numbered circle badge before each major
   section, process-step style — a genuinely different visual language from
   any recolor/reshape template above. counter-reset lives on .doc-page
   itself so the count is shared across every :before below regardless of
   which section shapes a given generator actually has. */
.doc-page[data-template="numbered"]{counter-reset:sect}
.doc-page[data-template="numbered"] > .doc-meta,
.doc-page[data-template="numbered"] > .receipt-row,
.doc-page[data-template="numbered"] > .doc-table,
.doc-page[data-template="numbered"] > .doc-body,
.doc-page[data-template="numbered"] > .doc-totals,
.doc-page[data-template="numbered"] > .receipt-amount-box,
.doc-page[data-template="numbered"] > .doc-sign{position:relative;padding-left:26px;counter-increment:sect}
.doc-page[data-template="numbered"] > .doc-meta:before,
.doc-page[data-template="numbered"] > .receipt-row:before,
.doc-page[data-template="numbered"] > .doc-table:before,
.doc-page[data-template="numbered"] > .doc-body:before,
.doc-page[data-template="numbered"] > .doc-totals:before,
.doc-page[data-template="numbered"] > .receipt-amount-box:before,
.doc-page[data-template="numbered"] > .doc-sign:before{content:counter(sect);position:absolute;left:0;top:0;width:18px;height:18px;border-radius:50%;background:var(--accent);color:#fff;font-size:10px;font-weight:800;display:flex;align-items:center;justify-content:center}

/* Spaced rules: every major section gets a plain hairline rule above it and
   extra breathing room — a quiet uniform rhythm, distinct from ruled's cell
   borders (every table cell boxed) and boxed's filled cards. */
.doc-page[data-template="hairlineRhythm"] > .doc-meta,
.doc-page[data-template="hairlineRhythm"] > .receipt-row,
.doc-page[data-template="hairlineRhythm"] > .doc-table,
.doc-page[data-template="hairlineRhythm"] > .doc-body,
.doc-page[data-template="hairlineRhythm"] > .doc-totals,
.doc-page[data-template="hairlineRhythm"] > .receipt-amount-box,
.doc-page[data-template="hairlineRhythm"] > .doc-notes,
.doc-page[data-template="hairlineRhythm"] > .doc-sign{border-top:1px solid #e3e7ef;padding-top:14px;margin-top:14px}

/* Notes first: the notes/bank-details block (terms, payment info) moves
   ahead of everything else that isn't the letterhead — for documents where
   the terms matter more than the line items. Only .doc-notes gets an
   explicit order (default order:0 keeps every other section exactly where
   it already was), same minimal-touch discipline as tableFirst/stackedSign. */
.doc-page[data-template="noteFirst"]{display:flex;flex-direction:column}
.doc-page[data-template="noteFirst"] > .doc-notes{order:-1;margin-bottom:10px}

/* Signature first: the signature block moves to the very top, under the
   letterhead — an approval-first reading order some internal forms want.
   Mirrors noteFirst exactly, one section pulled forward. */
.doc-page[data-template="signFirst"]{display:flex;flex-direction:column}
.doc-page[data-template="signFirst"] > .doc-sign{order:-1;margin-bottom:14px}

/* Logo on top: the letterhead's brand mark stacks above the business name
   instead of sitting beside it, and the whole header centres — a plainer,
   un-bordered cousin of "formal" (which also swaps the title above the
   brand row and adds a heavy rule) and "framed" (which additionally boxes
   the whole page). */
.doc-page[data-template="logoTop"] .doc-head{flex-direction:column;align-items:center;text-align:center;gap:10px}
.doc-page[data-template="logoTop"] .doc-brand-row{flex-direction:column;align-items:center;text-align:center;gap:8px}
.doc-page[data-template="logoTop"] .doc-type,
.doc-page[data-template="logoTop"] .receipt-title{text-align:center}

/* Item table (invoice/quotation/PO/delivery-note) */
/* Item table (invoice/quotation/PO/delivery-note/payslip/credit-note/
   handover-report — one shared component, see item-table.js). Rows render
   as separate "cards" (border-spacing between <tr>s + rounded first/last
   cell) with a hover lift and a numbered badge (pure CSS counter — no JS
   needed to keep it in sync as rows are added/removed/reordered) instead of
   a flat plain grid. */
.items-table{width:100%;table-layout:fixed;border-collapse:separate;border-spacing:0 8px;font-size:13px;margin-bottom:-8px}
.items-table th{text-align:left;font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--faint);padding:0 8px 6px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.items-table th:first-child{padding-left:28px}
.items-table th:last-child{width:34px}
.items-table tbody{counter-reset:item-row}
.items-table tbody tr{counter-increment:item-row;animation:itemRowIn .22s ease}
.items-table tbody tr:hover td{border-color:color-mix(in srgb, var(--accent) 35%, var(--line));box-shadow:0 6px 16px -10px rgba(15,18,30,.2)}
@keyframes itemRowIn{from{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:none}}
.items-table td{padding:7px 6px;background:var(--card);border-top:1px solid var(--line);border-bottom:1px solid var(--line);transition:border-color .15s ease,box-shadow .15s ease;overflow:hidden}
.items-table td:first-child{border-left:1px solid var(--line);border-radius:10px 0 0 10px;position:relative;padding-left:28px}
.items-table td:first-child:before{content:counter(item-row);position:absolute;left:7px;top:50%;transform:translateY(-50%);width:17px;height:17px;border-radius:50%;background:var(--accent-soft);color:var(--accent);font-size:9.5px;font-weight:800;display:flex;align-items:center;justify-content:center;flex:none}
.items-table td:last-child{border-right:1px solid var(--line);border-radius:0 10px 10px 0}
.items-table input{padding:8px 7px;border:1px solid var(--line);border-radius:8px;background:#fbfcfe;font-size:12.5px;width:100%;min-width:0;box-sizing:border-box}
.items-table input:focus{outline:none;border-color:var(--accent);background:#fff;box-shadow:0 0 0 3px var(--accent-soft)}
.items-table .col-qty input,.items-table .col-price input{text-align:right}
/* The item columns are narrow (Harga ends up ~44px, Disk. % ~23px), so the
   browser's native number spinner sits right where the user clicks to place
   a caret — a click meant to edit "50000" would step it to "49000" instead.
   The arrows are unusable at that size anyway; typing and Alt+Arrow row
   moves are the real input paths here. */
.items-table input[type=number]{-moz-appearance:textfield;appearance:textfield}
.items-table input[type=number]::-webkit-outer-spin-button,
.items-table input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.items-table .row-total{white-space:nowrap;text-align:right;padding:0 10px;font-weight:800;font-size:12.5px;color:var(--accent);overflow:hidden;text-overflow:ellipsis}
.items-table .row-del{width:34px;text-align:center;padding:7px 0}
.row-del button{width:28px;height:28px;border-radius:50%;border:1px solid var(--line);background:#fff;color:var(--faint);font-size:13px;line-height:1;transition:.15s}
/* Only the delete button goes red on hover — the row's other three tools
   (move up/down, duplicate) share the same base style but are not
   destructive, so they get the neutral accent hover instead. */
.row-del button.rt-del:hover{background:var(--bad);border-color:var(--bad);color:#fff;transform:scale(1.08)}
/* Four bordered circles crammed into one cell read as a pile of buttons, so
   the row tools are flat icons instead: no border, no fill, dimmed until the
   row is hovered/focused. The single delete button kept its circular chip
   look because it sat alone in the cell; four of them do not. */
.items-table td.row-tools{width:40px;padding:5px 0;vertical-align:middle}
.items-table th.th-tools{width:40px}
/* The grid lives on an inner div, not the <td> — display:grid on a table
   cell drops it out of the table layout and takes the row's rounded right
   edge with it. */
.row-tools-grid{display:grid;grid-template-columns:17px 17px;grid-auto-rows:17px;gap:2px;justify-content:center;align-content:center}
.items-table .row-tools button{width:17px;height:17px;border:none;background:none;border-radius:5px;color:var(--faint);font-size:8.5px;line-height:1;display:flex;align-items:center;justify-content:center;padding:0;opacity:.55;transition:opacity .15s ease,background .15s ease,color .15s ease}
/* Touch devices never fire :hover, so the icons would stay dimmed for good. */
@media (hover:none){.items-table .row-tools button{opacity:.9}}
.items-table .row-tools button.rt-del{font-size:12px}
.items-table tbody tr:hover .row-tools button,
.items-table .row-tools button:focus-visible{opacity:1}
.items-table .row-tools button:hover{opacity:1;background:var(--accent-soft);color:var(--accent)}
.items-table .row-tools button.rt-del:hover{background:color-mix(in srgb, var(--bad) 14%, transparent);color:var(--bad);transform:none}
.items-table .col-disc input{text-align:right}
/* Hidden by default: six data columns do not fit the form panel, so the
   table keeps its usual five until the user asks for line discounts. */
.items-table .col-disc{display:none}
.items-table.has-disc .col-disc{display:table-cell}
.items-table-scroll{overflow-x:auto}
.items-table-scroll .items-table.has-disc{min-width:500px}
.item-disc-toggle{display:flex;align-items:center;gap:7px;margin:-2px 0 10px;font-size:12px;color:var(--muted);cursor:pointer;user-select:none}
.item-disc-toggle input{width:15px;height:15px;accent-color:var(--accent);cursor:pointer;flex:none}
/* Per-item discount is shown on the finished document only when it is
   actually used, so an invoice with no line discounts keeps the same five
   clean columns it has always had. */
.doc-table .col-disc{display:none}
.doc-table.has-disc .col-disc{display:table-cell}
/* Set by validateDocForm() when Cetak/Unduh PDF is blocked, cleared as soon
   as the field is touched again. */
.field-invalid,.items-table input.field-invalid{border-color:var(--bad)!important;box-shadow:0 0 0 3px color-mix(in srgb, var(--bad) 18%, transparent)!important}
.add-row-btn{margin-top:10px;padding:10px 14px;border:1px dashed color-mix(in srgb, var(--accent) 55%, var(--line));border-radius:var(--radius-sm);background:var(--accent-soft);color:var(--accent);font-size:12.5px;font-weight:700;width:100%;transition:.15s}
.add-row-btn:hover{border-color:var(--accent);background:#fff;transform:translateY(-1px);box-shadow:0 8px 18px -10px rgba(15,18,30,.2)}
.add-row-btn:active{transform:none}

.totals-box{margin-top:14px;padding-top:14px;border-top:1px dashed var(--line);display:flex;flex-direction:column;gap:8px}
.totals-row{display:flex;align-items:center;justify-content:space-between;font-size:13.5px;color:var(--muted)}
.totals-row.grand{font-size:18px;font-weight:800;color:var(--ink);padding-top:10px;border-top:1px solid var(--line);font-family:var(--heading)}
.totals-row.grand b{color:var(--accent)}
.totals-row input{width:90px;text-align:right;padding:6px 8px;border:1px solid var(--line);border-radius:8px;font-size:13px}

.action-bar{display:flex;gap:10px;flex-wrap:wrap;margin-top:4px}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:12px 20px;border-radius:var(--radius-sm);font-size:13.5px;font-weight:700;border:1px solid transparent;transition:.18s;font-family:var(--heading)}
.btn[hidden]{display:none}
.btn-primary{background:var(--accent);color:var(--accent-ink);box-shadow:0 8px 20px -6px color-mix(in srgb, var(--accent) 55%, transparent)}
.btn-primary:hover{background:color-mix(in srgb, var(--accent) 88%, black);transform:translateY(-1px);box-shadow:0 10px 24px -6px color-mix(in srgb, var(--accent) 60%, transparent)}
.btn-ghost{background:var(--card);border-color:var(--line);color:var(--ink)}
.btn-ghost:hover{border-color:var(--accent);color:var(--accent)}
.btn-danger{background:#fff;border-color:#f3caca;color:var(--bad)}
.btn-danger:hover{background:#fdeeee}
.btn-block{width:100%}

/* Printable document */
.doc-scale-wrap{overflow:auto;background-color:#e7e9f0;background-image:radial-gradient(#c3c9d9 1px,transparent 1px);background-size:20px 20px;border-radius:var(--radius);padding:24px;display:flex;justify-content:center}
/* isolation: keeps z-index:-1 template layers above the white fill in print, where transform:none drops the stacking context */
.doc-page{--doc-page-h:297mm;position:relative;isolation:isolate;flex-shrink:0;width:210mm;min-height:297mm;background:#fff;box-shadow:0 24px 60px rgba(15,18,30,.22);padding:16mm;font-size:12.5px;color:#20242c;font-family:var(--doc-font, inherit);transform:scale(var(--doc-zoom, .62));transform-origin:top center;margin-bottom:calc(-1 * var(--doc-page-h) * (1 - var(--doc-zoom, .62)))}
.doc-watermark{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;overflow:hidden;pointer-events:none}
.doc-watermark[hidden]{display:none}
.doc-watermark span{font-family:var(--heading);font-weight:800;font-size:60px;letter-spacing:.03em;color:rgba(15,18,30,.07);transform:rotate(-28deg);white-space:nowrap}
.doc-page:before{content:"";position:absolute;left:0;top:0;right:0;height:6px;background:var(--accent)}
/* Paper size — A4 is the plain default (no data-paper attribute needed).
   Landscape flips width/height for whichever paper size is active. */
.doc-page[data-paper="letter"]{--doc-page-h:279mm;width:216mm;min-height:279mm}
.doc-page[data-paper="f4"]{--doc-page-h:330mm;width:210mm;min-height:330mm}
.doc-page[data-paper="legal"]{--doc-page-h:356mm;width:216mm;min-height:356mm}
.doc-page[data-paper="a3"]{--doc-page-h:420mm;width:297mm;min-height:420mm}
.doc-page[data-paper="a5"]{--doc-page-h:210mm;width:148mm;min-height:210mm}
.doc-page[data-paper="a6"]{--doc-page-h:148mm;width:105mm;min-height:148mm}
.doc-page[data-paper="b5"]{--doc-page-h:250mm;width:176mm;min-height:250mm}
.doc-page[data-paper="executive"]{--doc-page-h:267mm;width:184mm;min-height:267mm}
.doc-page[data-paper="tabloid"]{--doc-page-h:432mm;width:279mm;min-height:432mm}
.doc-page.landscape{--doc-page-h:210mm;width:297mm;min-height:210mm}
.doc-page[data-paper="letter"].landscape{--doc-page-h:216mm;width:279mm;min-height:216mm}
.doc-page[data-paper="f4"].landscape{--doc-page-h:210mm;width:330mm;min-height:210mm}
.doc-page[data-paper="legal"].landscape{--doc-page-h:216mm;width:356mm;min-height:216mm}
.doc-page[data-paper="a3"].landscape{--doc-page-h:297mm;width:420mm;min-height:297mm}
.doc-page[data-paper="a5"].landscape{--doc-page-h:148mm;width:210mm;min-height:148mm}
.doc-page[data-paper="a6"].landscape{--doc-page-h:105mm;width:148mm;min-height:105mm}
.doc-page[data-paper="b5"].landscape{--doc-page-h:176mm;width:250mm;min-height:176mm}
.doc-page[data-paper="executive"].landscape{--doc-page-h:184mm;width:267mm;min-height:184mm}
.doc-page[data-paper="tabloid"].landscape{--doc-page-h:279mm;width:432mm;min-height:279mm}
/* The larger default belongs to the STACKED layout, where the preview gets
   the full page width — so it has to track the same 900px breakpoint the
   form panel stacks at. While the two-pane layout still applies (901-1080px)
   the base .62 is correct; at .9 the page overflowed its scroll box. */
@media(max-width:900px){.doc-page{transform:scale(var(--doc-zoom, .9));margin-bottom:calc(-1 * var(--doc-page-h) * (1 - var(--doc-zoom, .9)))}}
@media(max-width:640px){.doc-page{transform:scale(var(--doc-zoom, .42));margin-bottom:calc(-1 * var(--doc-page-h) * (1 - var(--doc-zoom, .42)))}}

.doc-head{display:flex;justify-content:space-between;align-items:flex-start;gap:20px;padding-bottom:14px;border-bottom:2px solid var(--accent)}
.doc-brand-row{display:flex;align-items:center;gap:12px}
.doc-logo{width:calc(68px * var(--doc-logo-scale, 1));height:calc(68px * var(--doc-logo-scale, 1));object-fit:contain;flex:none;border-radius:8px}
.doc-logo[hidden]{display:none}
.doc-brand{font-family:var(--doc-font, var(--heading));font-size:calc(19px * var(--doc-brand-scale, 1));font-weight:800;letter-spacing:-.01em}
.doc-brand-sub{color:#5b6472;font-size:calc(11px * var(--doc-body-scale, 1));margin-top:4px;white-space:pre-line}
.doc-type{text-align:right}
.doc-type h2{font-family:var(--doc-font, var(--heading));margin:0;font-size:calc(21px * var(--doc-title-scale, 1));letter-spacing:.03em;color:var(--accent);font-weight:800}
/* A handful of long agreement/contract titles (e.g. "PERJANJIAN KERJA SAMA
   SUPPLIER") hardcode a smaller inline font-size so they don't wrap
   awkwardly — !important reproduces that same 15px baseline instead of
   losing it to the 21px rule above, while still respecting the title-size
   control below. */
h2[id="pvTitle"]{font-size:calc(15px * var(--doc-title-scale, 1)) !important}
.doc-type .doc-no{font-size:calc(11.5px * var(--doc-body-scale, 1));color:#5b6472;margin-top:4px}
.doc-meta{display:flex;justify-content:space-between;gap:24px;margin-top:16px}
.doc-meta .block b{display:block;font-size:calc(10.5px * var(--doc-body-scale, 1));text-transform:uppercase;letter-spacing:.06em;color:#8a93a3;margin-bottom:4px}
.doc-meta .block div{white-space:pre-line;font-size:calc(12.5px * var(--doc-body-scale, 1))}
.doc-table{width:100%;border-collapse:collapse;margin-top:20px;font-size:calc(12px * var(--doc-body-scale, 1))}
.doc-table th{text-align:center;background:var(--accent);color:#fff;padding:8px 10px;font-size:calc(10.5px * var(--doc-body-scale, 1));text-transform:uppercase;letter-spacing:.04em}
.doc-table td{padding:8px 10px;border-bottom:1px solid #e3e7ef;text-align:center}
.doc-table tr:last-child td{border-bottom:2px solid var(--accent)}
/* Item-table cells are centred, headings and values alike. `.num` used to
   right-align the money and quantity columns; it stays as a hook the 126
   generator pages already emit, but it no longer overrides the centring —
   the Document Editor's canvas centres every cell too (see
   lib/documentContent.js's buildTable), and the two must agree. */
.doc-table td.num,.doc-table th.num{text-align:center}
.doc-totals{margin-top:12px;margin-left:auto;width:56%}
.doc-totals .r{display:flex;justify-content:space-between;padding:5px 10px;font-size:calc(12.5px * var(--doc-body-scale, 1))}
.doc-totals .r.grand{font-weight:800;font-size:calc(14.5px * var(--doc-body-scale, 1));border-top:2px solid var(--accent);margin-top:4px;padding-top:8px;color:var(--accent)}
.doc-notes{margin-top:22px;font-size:calc(11.5px * var(--doc-body-scale, 1));color:#5b6472;white-space:pre-line}
.doc-sign{display:flex;justify-content:space-between;margin-top:48px}
.doc-sign .sig{text-align:center;width:190px;font-size:calc(12px * var(--doc-sign-text-scale, 1))}
.doc-sign .sig .space{height:calc(100px * var(--doc-sign-scale, 1));display:flex;align-items:flex-end;justify-content:center}
.doc-sign .sig .space .signature-img{max-height:calc(96px * var(--doc-sign-scale, 1));max-width:calc(185px * var(--doc-sign-scale, 1));object-fit:contain;pointer-events:none}
.doc-sign .sig .name{border-top:1px solid var(--accent);padding-top:6px;font-weight:700}
/* A per-document counterparty title ("Jabatan") is hardcoded inline
   (style="font-size:11px"/"11.5px") on many generator pages instead of a
   shared class — !important reproduces that same intent (a slightly
   smaller line under the signer name) while still letting the signature
   text-size control below scale it. */
.doc-sign .sig>div:not(.space):not(.name){font-size:calc(11px * var(--doc-sign-text-scale, 1)) !important}
.doc-foot{margin-top:26px;padding-top:10px;border-top:1px solid #e3e7ef;font-size:calc(10px * var(--doc-body-scale, 1));color:#8a93a3;text-align:center}

/* Receipt-specific */
.doc-page.receipt{display:flex;flex-direction:column;justify-content:flex-start}
.receipt-title{text-align:center;margin-bottom:6px}
.receipt-title h2{font-family:var(--doc-font, var(--heading));margin:0;font-size:calc(23px * var(--doc-title-scale, 1));letter-spacing:.14em;color:var(--accent);font-weight:800}
.receipt-row{display:flex;gap:10px;padding:9px 0;border-bottom:1px dotted #c7cedb;font-size:calc(13px * var(--doc-body-scale, 1))}
.receipt-row b{width:150px;flex:none;color:#5b6472;font-weight:600}
.receipt-amount-box{margin:18px 0;padding:14px 18px;background:var(--accent-soft);border:1px solid color-mix(in srgb, var(--accent) 30%, white);border-radius:10px;display:flex;justify-content:space-between;align-items:center}
.receipt-amount-box .amt{font-family:var(--heading);font-size:calc(22px * var(--doc-body-scale, 1));font-weight:800;color:var(--accent)}

/* Certificate-specific */
.doc-page.certificate{border:var(--cert-border, 10px solid var(--accent));outline:var(--cert-outline, 2px solid var(--accent));outline-offset:-18px;background-image:var(--cert-bg, none);background-size:var(--cert-bg-size, cover);background-position:center;background-repeat:no-repeat;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:6px;padding:22mm}
.doc-page.certificate:before{display:none}
.cert-eyebrow{letter-spacing:.3em;font-size:calc(11px * var(--doc-body-scale, 1));color:#8a93a3;text-transform:uppercase}
.cert-title{font-family:var(--doc-font, var(--heading));font-size:calc(32px * var(--doc-title-scale, 1));font-weight:800;color:var(--accent);margin:6px 0 18px;letter-spacing:.01em}
.cert-given{font-size:calc(12px * var(--doc-body-scale, 1));color:#5b6472}
.cert-name{font-size:calc(30px * var(--doc-body-scale, 1));font-weight:800;margin:10px 0;border-bottom:2px solid var(--accent);padding-bottom:8px;min-width:60%}
.cert-desc{max-width:75%;font-size:calc(13px * var(--doc-body-scale, 1));color:#3a3f49;margin:8px 0 26px;line-height:1.7}
.cert-sign-row{display:flex;gap:60px;margin-top:20px}
/* Certificate signatures get size limits like a document's signature block
   (.doc-sign above), scaled by the same "Ukuran Tanda Tangan" setting. Without
   them an uploaded signature was drawn at the image's own pixel size — often
   wider than half the certificate, pushing everything below it off the page. */
.cert-sign-row .sig .space{display:flex;align-items:flex-end;justify-content:center}
.cert-sign-row .sig .space .signature-img{display:block;width:auto;height:auto;max-height:calc(70px * var(--doc-sign-scale, 1));max-width:calc(170px * var(--doc-sign-scale, 1));object-fit:contain;pointer-events:none}

/* Business letter specific */
.doc-page.letter .doc-body{margin-top:26px;font-size:calc(12.8px * var(--doc-body-scale, 1));line-height:1.85;white-space:pre-line}
.letter-refs{margin-top:16px;font-size:calc(12px * var(--doc-body-scale, 1))}
.letter-refs .r{display:flex;gap:8px}
.letter-refs .r b{width:80px;flex:none}

/* Auth pages (login / register) */
.auth-shell{min-height:100vh;display:grid;grid-template-columns:1fr 1fr}
.auth-brand{position:relative;background:linear-gradient(175deg,var(--navy) 0%,var(--navy-2) 62%,#1b2140 100%);overflow:hidden;padding:52px;display:flex;flex-direction:column;justify-content:center}
.auth-brand:before{content:"";position:absolute;width:460px;height:460px;border-radius:50%;right:-160px;top:-160px;background:radial-gradient(circle,rgba(60,99,224,.35),transparent 70%);filter:blur(10px)}
.auth-brand:after{content:"";position:absolute;width:340px;height:340px;border-radius:50%;left:-140px;bottom:-160px;background:radial-gradient(circle,rgba(201,162,39,.18),transparent 70%);filter:blur(10px)}
.auth-brand-inner{position:relative;z-index:1;max-width:420px}
.brand-light{color:#fff}
.brand-light em{color:#aab2cc}
.auth-brand-inner h1{font-family:var(--heading);color:#fff;font-size:clamp(26px,3vw,34px);line-height:1.25;letter-spacing:-.02em;margin:34px 0 14px;font-weight:800}
.auth-brand-inner>p{color:#aab2cc;font-size:14.5px;line-height:1.65;margin:0 0 28px}
.auth-points{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:14px}
.auth-points li{display:flex;align-items:center;gap:12px;color:#dfe3f5;font-size:13.5px}
.auth-points i{display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:rgba(15,157,88,.18);color:#3ddc84;font-size:10px;flex:none}
.auth-form-side{display:flex;align-items:center;justify-content:center;padding:40px 32px;background:var(--paper)}
.auth-card{width:100%;max-width:380px}
.auth-card h2{font-family:var(--heading);font-size:24px;margin:0 0 6px;letter-spacing:-.02em;font-weight:800}
.auth-sub{margin:0 0 26px;color:var(--muted);font-size:13.5px}
.auth-sub a{color:var(--accent);font-weight:700}
.auth-error{padding:10px 12px;border-radius:9px;background:#fdeeee;border:1px solid #f3caca;color:var(--bad);font-size:12.5px;margin-bottom:14px}
.auth-success{padding:10px 12px;border-radius:9px;background:#e8faf0;border:1px solid #bfe9cf;color:var(--good);font-size:12.5px;margin-bottom:14px}
.auth-remember{display:flex;align-items:center;gap:8px;margin:-4px 0 16px;font-size:13px;color:var(--muted);cursor:pointer;user-select:none}
.auth-remember input{width:15px;height:15px;accent-color:var(--accent);cursor:pointer}
.auth-mobile-brand{display:none}
.auth-divider{display:flex;align-items:center;gap:12px;margin:18px 0;color:var(--faint);font-size:12px}
.auth-divider:before,.auth-divider:after{content:"";flex:1;height:1px;background:var(--line)}
.btn-google{background:#fff;border-color:var(--line);color:var(--ink);gap:10px}
.btn-google:hover{border-color:#c7cedb;background:#fbfcfe}
.btn-google svg{flex:none}
@media(max-width:900px){
  .auth-shell{grid-template-columns:1fr}
  .auth-brand{display:none}
  .auth-mobile-brand{display:flex;align-items:center;gap:10px;justify-content:center;padding:26px 0 6px}
}

/* How it works */
.steps-section{padding:8px 0 52px}
.steps-panel{position:relative;margin-top:14px;padding:44px 40px;border-radius:22px;background:linear-gradient(175deg,var(--navy) 0%,var(--navy-2) 68%,#1b2140 100%);overflow:hidden}
.steps-panel:before{content:"";position:absolute;width:340px;height:340px;border-radius:50%;right:-120px;top:-140px;background:radial-gradient(circle,rgba(60,99,224,.32),transparent 70%);filter:blur(8px)}
.steps-panel:after{content:"";position:absolute;width:260px;height:260px;border-radius:50%;left:-100px;bottom:-120px;background:radial-gradient(circle,rgba(201,162,39,.18),transparent 70%);filter:blur(8px)}
.steps-grid{position:relative;z-index:1;display:grid;grid-template-columns:1fr 44px 1fr 44px 1fr;align-items:start}
.step-item{text-align:center;padding:0 10px}
.step-num{position:relative;display:inline-grid;place-items:center;width:56px;height:56px;border-radius:50%;background:linear-gradient(155deg,#e7c866,var(--gold));color:#171b23;font-size:18px;margin-bottom:18px;box-shadow:0 10px 24px -8px rgba(201,162,39,.5)}
.step-num b{position:absolute;right:-4px;bottom:-4px;display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:#171b23;color:#fff;font-family:var(--heading);font-size:11px;font-weight:800;border:2px solid var(--navy)}
.step-item h3{margin:0 0 8px;font-size:15.5px;letter-spacing:-.01em;color:#fff}
.step-item p{margin:0;color:#9aa2c2;font-size:12.8px;line-height:1.6;max-width:240px;margin-inline:auto}
.step-connector{display:flex;align-items:center;justify-content:center;height:56px;color:#4b5487;font-size:14px}
@media(max-width:900px){.steps-panel{padding:36px 24px}.steps-grid{grid-template-columns:1fr;gap:26px}.step-connector{display:none}.step-item{margin-bottom:2px}}

/* Pricing */
.pricing-section{padding:8px 0 40px}
.pricing-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-top:18px;align-items:stretch}
.pricing-card{position:relative;background:var(--card);border:1px solid var(--line);border-radius:16px;padding:26px 22px;box-shadow:var(--shadow);display:flex;flex-direction:column;transition:transform .2s ease,box-shadow .2s ease}
.pricing-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-lg)}
.pricing-card.popular{background:linear-gradient(175deg,var(--navy) 0%,var(--navy-2) 100%);border-color:transparent;box-shadow:var(--shadow-lg);transform:scale(1.03);z-index:1}
.pricing-card.popular:hover{transform:scale(1.03) translateY(-4px)}
.popular-badge{position:absolute;top:-13px;left:50%;transform:translateX(-50%);padding:6px 14px;border-radius:100px;background:var(--gold);color:#171b23;font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;white-space:nowrap}
.pricing-card.current{border-color:var(--good);box-shadow:0 0 0 2px var(--good)}
.current-badge{position:absolute;top:-13px;right:16px;padding:5px 12px;border-radius:100px;background:var(--good);color:#fff;font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.05em}
.pricing-icon{display:grid;place-items:center;width:36px;height:36px;border-radius:10px;background:var(--accent-soft);color:var(--accent);font-size:14px;margin-bottom:14px}
.pricing-card.popular .pricing-icon{background:rgba(255,255,255,.1);color:var(--gold)}
.pricing-tier{font-family:var(--heading);font-size:13px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;color:var(--accent)}
.pricing-card.popular .pricing-tier{color:var(--gold)}
.pricing-price{margin:14px 0 20px;display:flex;align-items:baseline;gap:6px}
.pricing-price .amt{font-family:var(--heading);font-size:27px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.pricing-card.popular .pricing-price .amt{color:#fff}
.pricing-price .period{font-size:12.5px;color:var(--muted)}
.pricing-card.popular .pricing-price .period{color:#aab2cc}
.pricing-features{list-style:none;margin:0 0 24px;padding:0;display:flex;flex-direction:column;gap:11px;flex:1}
.pricing-features li{display:flex;align-items:center;gap:10px;font-size:12.8px;color:var(--muted)}
.pricing-card.popular .pricing-features li{color:#dfe3f5}
.pricing-features li i{display:inline-grid;place-items:center;width:17px;height:17px;border-radius:50%;background:rgba(15,157,88,.12);color:var(--good);font-size:8px;flex:none}
.pricing-card.popular .pricing-features li i{background:rgba(61,220,132,.16);color:#3ddc84}
.pricing-note{text-align:center;margin-top:22px;color:var(--faint);font-size:12px}
.payment-embed-section{margin-top:28px;opacity:0;transform:translateY(10px);animation:cardIn .35s ease forwards}
.payment-embed-card{position:relative;background:var(--card);border:1px solid var(--line);border-radius:20px;box-shadow:var(--shadow-lg);padding:28px;max-width:560px;margin:0 auto;overflow:hidden}
.payment-embed-card:before{content:"";position:absolute;top:0;left:0;right:0;height:4px;background:linear-gradient(90deg,var(--accent),var(--gold))}
.payment-embed-header{display:flex;flex-direction:column;gap:12px;margin-bottom:22px;padding-bottom:18px;border-bottom:1px solid var(--line)}
.payment-embed-header .btn{align-self:flex-start}
.payment-embed-title{display:flex;align-items:center;gap:12px}
.payment-embed-title-icon{flex:none;width:38px;height:38px;border-radius:11px;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;font-size:15px}
.payment-embed-title-text{display:flex;flex-direction:column;gap:3px}
.payment-embed-title span{font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.08em;color:var(--accent)}
.payment-embed-title strong{font-family:var(--heading);font-size:19px;color:var(--ink)}
.payment-embed-secure{display:flex;align-items:center;gap:6px;font-size:11.5px;color:var(--faint)}
.payment-embed-secure i{color:var(--good)}

.checkout-flow{min-height:420px}

.method-picker{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
.method-picker[hidden]{display:none}
.method-card{display:flex;flex-direction:column;align-items:center;gap:10px;padding:20px 12px;border:1px solid var(--line);border-radius:14px;background:var(--card);cursor:pointer;transition:transform .15s ease,box-shadow .15s ease,border-color .15s ease;font-family:inherit}
.method-card:hover{transform:translateY(-3px);box-shadow:var(--shadow);border-color:var(--accent)}
.method-card:focus-visible{outline:none;box-shadow:0 0 0 3px var(--accent-soft)}
.method-card-icon{width:42px;height:42px;border-radius:11px;background:var(--accent-soft);color:var(--accent);display:grid;place-items:center;font-size:17px}
.method-card-label{font-size:12.5px;font-weight:700;color:var(--ink);text-align:center}

.paypal-checkout-section{margin-top:18px;padding-top:16px;border-top:1px dashed var(--line);text-align:center}
.paypal-checkout-section[hidden]{display:none}
.paypal-checkout-divider{font-size:12px;color:var(--muted);margin:0 0 12px}
.paypal-checkout-amount{font-weight:800;color:var(--ink)}
.paypal-checkout-note{font-size:11px;color:var(--muted);margin:10px 0 0}
#paypalButtonContainer{max-width:320px;margin:0 auto}

.method-detail{display:flex;flex-direction:column;gap:16px}
.method-detail[hidden]{display:none}
.method-detail-back{align-self:flex-start}
.method-detail-loading{display:flex;justify-content:center;padding:60px 0;font-size:24px;color:var(--accent)}
.method-detail-loading[hidden]{display:none}

.va-display,.qr-display{display:flex;flex-direction:column;align-items:center;text-align:center;gap:12px;padding:8px 0 4px}
.va-display[hidden],.qr-display[hidden]{display:none}
.va-bank-badge{padding:5px 14px;border-radius:100px;background:var(--accent-soft);color:var(--accent);font-size:11px;font-weight:800;text-transform:uppercase;letter-spacing:.06em}
.va-number-row{display:flex;align-items:center;gap:10px;font-family:var(--mono,monospace);font-size:22px;font-weight:700;color:var(--ink);letter-spacing:.02em}
.va-instructions{margin:0;max-width:380px;color:var(--muted);font-size:12.5px;line-height:1.6}
.checkout-countdown{padding:6px 14px;border-radius:100px;background:var(--paper);color:var(--muted);font-size:12px;font-weight:600;font-family:var(--mono,monospace)}
.checkout-countdown.is-urgent{background:#fdeeee;color:var(--bad)}
.checkout-countdown[hidden]{display:none}

/* A QR code needs a real white quiet-zone regardless of the site's theme —
   same deliberate "always render on white" exception used for the Midtrans
   iframe frame this replaced. */
.qr-image{width:220px;height:220px;object-fit:contain;background:#fff;border-radius:14px;padding:14px;box-shadow:0 1px 0 rgba(0,0,0,.04),0 10px 26px -14px rgba(20,25,40,.22)}
.qr-instructions{margin:0;max-width:380px;color:var(--muted);font-size:12.5px;line-height:1.6}

.card-form{max-width:380px;margin:0 auto}
.card-form-error{margin:0 0 12px;padding:9px 12px;border-radius:9px;background:#fdeeee;color:var(--bad);font-size:12.5px}
.card-form-error[hidden]{display:none}

.threeds-modal{position:fixed;inset:0;background:rgba(15,23,42,.55);display:grid;place-items:center;z-index:60;padding:20px}
.threeds-modal[hidden]{display:none}
.threeds-modal-box{position:relative;width:min(420px,100%);height:min(640px,90vh);background:#fff;border-radius:16px;overflow:hidden;box-shadow:var(--shadow-lg)}
.threeds-modal-close{position:absolute;top:10px;right:10px;width:32px;height:32px;border-radius:50%;border:none;background:rgba(15,23,42,.06);color:#20242c;display:grid;place-items:center;cursor:pointer;z-index:1}
.threeds-modal-close:hover{background:rgba(15,23,42,.12)}
#threeDsFrame{width:100%;height:100%;border:none}

.payment-result-state{display:flex;flex-direction:column;align-items:center;text-align:center;padding:50px 20px;gap:8px;min-height:420px;justify-content:center}
.payment-result-state[hidden]{display:none}
.payment-result-icon{width:72px;height:72px;border-radius:50%;display:grid;place-items:center;font-size:28px;margin-bottom:8px}
.payment-result-icon.processing{background:var(--accent-soft);color:var(--accent)}
.payment-result-icon.success{background:#e8faf0;color:var(--good);animation:popIn .4s ease}
.payment-result-icon.error{background:#fdeeee;color:var(--bad);animation:popIn .4s ease}
.payment-result-icon.waiting{background:#fdf5e2;color:#a16207}
@keyframes popIn{0%{transform:scale(.5);opacity:0}70%{transform:scale(1.08)}100%{transform:scale(1);opacity:1}}
.payment-result-state h3{margin:0;font-family:var(--heading);font-size:19px;color:var(--ink)}
.payment-result-state p{margin:0;color:var(--muted);font-size:13.5px;max-width:360px;line-height:1.6}
.payment-result-actions{display:flex;gap:10px;margin-top:16px}
@media(max-width:1080px){.pricing-grid{grid-template-columns:repeat(2,1fr)}.pricing-card.popular{transform:none}}
@media(max-width:640px){.pricing-grid{grid-template-columns:1fr}}

/* FAQ */
.faq-section{padding:8px 0 52px}
.faq-list{margin-top:14px;border-top:1px solid var(--line)}
.faq-item{border-bottom:1px solid var(--line);padding:2px 0;transition:background-color .15s}
.faq-item:hover{background:color-mix(in srgb, var(--accent) 3%, transparent)}
.faq-item summary{cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:14px;padding:16px 10px;font-weight:700;font-size:14.5px;font-family:var(--heading)}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary i{color:var(--faint);font-size:12px;transition:.2s;flex:none}
.faq-item[open] summary i{transform:rotate(180deg);color:var(--accent)}
.faq-item p{margin:0 10px 18px;color:var(--muted);font-size:13.5px;line-height:1.65;max-width:720px}

/* Closing CTA */
.cta-band{margin:8px 0 60px;padding:52px 40px;border-radius:20px;background:linear-gradient(160deg,var(--navy) 0%,var(--navy-2) 70%,#1b2140 100%);text-align:center;position:relative;overflow:hidden}
.cta-band:before{content:"";position:absolute;width:360px;height:360px;border-radius:50%;right:-120px;top:-140px;background:radial-gradient(circle,rgba(201,162,39,.22),transparent 70%);filter:blur(6px)}
.cta-band-inner{position:relative;z-index:1;max-width:560px;margin:0 auto}
.cta-band h2{font-family:var(--heading);color:#fff;font-size:clamp(22px,2.6vw,30px);margin:0 0 12px;letter-spacing:-.02em;font-weight:800}
.cta-band p{color:#aab2cc;margin:0 0 26px;font-size:14.5px;line-height:1.6}
@media(max-width:640px){.cta-band{padding:40px 24px}}

/* Full footer (landing page) */
.site-footer-full{background:var(--navy);color:#aab2cc;margin-top:0;padding:52px 0 0}
.footer-grid{display:grid;grid-template-columns:1.1fr 2fr .85fr .85fr;gap:32px;padding:32px 0 36px;border-bottom:1px solid rgba(255,255,255,.1)}
.footer-brand-col p{margin:14px 0 0;font-size:12.8px;line-height:1.6;color:#8891b3;max-width:280px}
.footer-col{display:flex;flex-direction:column;gap:11px}
.footer-col b{color:#fff;font-family:var(--heading);font-size:11.5px;text-transform:uppercase;letter-spacing:.08em;margin-bottom:4px}
.footer-col a{color:#aab2cc;font-size:13px;transition:.15s}
.footer-col a:hover{color:#fff}
/* 14 category dropdowns stacked in one narrow column made this the single
   tallest thing in the footer by far, next to a short paragraph and two
   short link lists. Flowing them into a CSS multi-column layout instead
   (column-count, not flex — the two are mutually exclusive) roughly halves
   the height; the heading spans across both via column-span so it still
   reads as one section, and break-inside keeps each dropdown intact
   instead of splitting across the column break. */
.footer-col-products{display:block;column-count:2;column-gap:28px}
.footer-col-products>b{display:block;column-span:all;margin-bottom:8px;text-align:center}
.footer-drop{border-bottom:1px solid rgba(255,255,255,.08);break-inside:avoid}
.footer-drop:last-of-type{border-bottom:none}
.footer-drop summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;gap:8px;color:#aab2cc;font-size:13px;padding:9px 0;transition:color .15s}
.footer-drop summary::-webkit-details-marker{display:none}
.footer-drop summary i{font-size:9px;color:#7981a3;transition:transform .2s ease;flex:none}
.footer-drop[open] summary i{transform:rotate(180deg);color:var(--gold)}
.footer-drop summary:hover{color:#fff}
.footer-drop-links{display:flex;flex-direction:column;gap:8px;padding:2px 0 12px 2px}
.footer-drop-links a{color:#8891b3;font-size:12px;transition:color .15s}
.footer-drop-links a:hover{color:#fff}
.footer-bottom{display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px;padding:20px 0;font-size:11.5px;color:#7981a3}
@media(max-width:900px){.footer-grid{grid-template-columns:1fr 1fr;gap:28px 20px}.footer-col-products{grid-column:1/-1}}
@media(max-width:560px){.footer-grid{grid-template-columns:1fr}.footer-col-products{column-count:1}}

.no-print{}
/* Printable area isolation: this used to be `body *{visibility:hidden}` +
   un-hiding .doc-scale-wrap via `position:absolute;inset:0`. That measured
   itself against the on-screen browser viewport instead of the true A4
   page — on any window shorter than ~297mm-worth of pixels (i.e. almost
   every real browser window), the doc-page content overflowed that box,
   which the print engine paginated as extra blank trailing pages. Fully
   removing the chrome via `display:none` (zero box, nothing to overflow
   against) and letting .doc-scale-wrap sit in normal flow sidesteps the
   whole class of bug — its height is then driven purely by its own content. */
@media print{
  .topbar,.gen-header,.form-panel,.preview-label,.no-print,.related-docs,.panel-resizer,#thChatBtn,#thChatPanel{display:none !important}
  .gen-shell,.gen-layout,.preview-panel{margin:0 !important;padding:0 !important}
  .admin-main{margin-left:0 !important}
  .doc-scale-wrap{padding:0;background:#fff;overflow:visible}
  /* Chrome/Edge/Firefox all skip background-image/background-color by
     default on the native print dialog (Ctrl+P / the "Cetak" button's
     window.print()) unless the viewer manually checks "Background
     graphics" — most never do. That silently dropped the certificate
     template image (a background-image) and every accent-colored table
     header/bar on every doc type, even though the same page looks
     correct on screen and the separate "Download PDF" button (server-
     side Puppeteer, printBackground:true) was never affected. Forcing it
     here makes what's on screen match what's printed by default. */
  .doc-page,.doc-page *{-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}
  .doc-page{transform:none;box-shadow:none;margin:0 auto}
  @page{size:A4;margin:0}
  /* `@page landscape{...}` below is a CSS named page — on its own it's
     inert; the `page: landscape` property here is what actually assigns
     .doc-page.landscape's content to it. Without it, every landscape
     document (certificates, a few reports) printed/PDF'd on the default
     portrait @page above regardless of how it looked on-screen. */
  .doc-page.landscape{width:297mm;min-height:210mm;page:landscape}
  @page landscape{size:A4 landscape;margin:0}
  #batchWrap .doc-page{page-break-before:always}
  #batchWrap .doc-page:first-child{page-break-before:auto}
}

/* ===== SweetAlert2 re-skin =====
   The library ships its own visual identity (Nunito-ish system font, teal/
   red icon rings, boxy buttons) that clashes with the rest of the app.
   Everything below just re-points its classes at our own tokens (fonts,
   radius, shadows, accent) so a confirm dialog or toast looks like it
   belongs here instead of a generic library default. !important is needed
   throughout since some of the library's own selectors (e.g. its toast
   variant) are more specific than a flat class match. */
.swal2-popup{font-family:var(--sans) !important;border-radius:var(--radius) !important;box-shadow:var(--shadow-lg) !important;background:var(--card) !important;color:var(--ink) !important;padding:28px 26px 24px !important}
.swal2-title{font-family:var(--heading) !important;font-size:19px !important;font-weight:800 !important;letter-spacing:-.01em !important;color:var(--ink) !important;padding:0 !important;margin:6px 0 6px !important}
.swal2-html-container{font-size:13.5px !important;line-height:1.6 !important;color:var(--muted) !important;margin:6px 6px 0 !important}
.swal2-actions{margin-top:22px !important;gap:10px !important}
.swal2-styled{border-radius:var(--radius-sm) !important;font-family:var(--heading) !important;font-weight:700 !important;font-size:13px !important;padding:11px 22px !important;box-shadow:none !important;transition:filter .15s ease,transform .15s ease !important}
.swal2-styled:focus{box-shadow:0 0 0 3px var(--accent-soft) !important}
.swal2-styled.swal2-confirm{background-color:var(--accent);box-shadow:0 8px 20px -6px color-mix(in srgb, var(--accent) 55%, transparent) !important}
.swal2-styled.swal2-confirm:hover{filter:brightness(.92);transform:translateY(-1px)}
.swal2-styled.swal2-cancel{background:var(--paper) !important;color:var(--muted) !important}
.swal2-styled.swal2-cancel:hover{background:var(--line) !important}
.swal2-icon{border-width:2.5px !important;margin:16px auto 8px !important}
.swal2-icon.swal2-success{border-color:var(--good) !important;color:var(--good) !important}
.swal2-icon.swal2-success .swal2-success-ring{border-color:color-mix(in srgb, var(--good) 30%, transparent) !important}
.swal2-icon.swal2-success [class^="swal2-success-line"]{background-color:var(--good) !important}
.swal2-icon.swal2-error{border-color:var(--bad) !important;color:var(--bad) !important}
.swal2-icon.swal2-error [class^="swal2-x-mark-line"]{background-color:var(--bad) !important}
.swal2-icon.swal2-warning{border-color:var(--gold) !important;color:var(--gold) !important}
.swal2-icon.swal2-info{border-color:var(--accent) !important;color:var(--accent) !important}
.swal2-icon.swal2-question{border-color:var(--accent) !important;color:var(--accent) !important}
.swal2-input,.swal2-select,.swal2-textarea{border-radius:var(--radius-sm) !important;border:1px solid var(--line) !important;background:var(--card) !important;color:var(--ink) !important;font-family:var(--sans) !important;font-size:13.5px !important;box-shadow:none !important}
.swal2-input:focus,.swal2-select:focus,.swal2-textarea:focus{border-color:var(--accent) !important;box-shadow:0 0 0 3px var(--accent-soft) !important}
.swal2-validation-message{border-radius:var(--radius-sm) !important;background:#fdeeee !important;color:var(--bad) !important;font-size:12.5px !important}
.swal2-validation-message::before{background-color:var(--bad) !important}
.swal2-close{color:var(--faint) !important;transition:color .15s ease !important}
.swal2-close:hover{color:var(--ink) !important;background:none !important}
.swal2-timer-progress-bar{background:var(--accent) !important}
/* Scoped to real modals only — SweetAlert2 reuses .swal2-container for
   toasts too (see THB.toast, e.g. "Profil bisnis tersimpan"), which get
   their own body.swal2-toast-shown class specifically because they must
   NOT have a backdrop. An unscoped rule here painted that dark tint behind
   every toast as a full-viewport overlay — exactly the "full kebawah,
   background hitam transparan" bug. */
body:not(.swal2-toast-shown) .swal2-container{background:rgba(11,16,32,.45) !important}

/* Toast variant (THB.toast) — anchored to a corner, so it stays compact:
   smaller icon/title, tighter padding, no title/body stacking gap. */
.swal2-popup.swal2-toast{border-radius:var(--radius-sm) !important;box-shadow:var(--shadow-lg) !important;padding:12px 16px !important;border:1px solid var(--line) !important}
.swal2-popup.swal2-toast .swal2-title{font-size:13px !important;font-weight:700 !important;margin:0 !important}
.swal2-popup.swal2-toast .swal2-icon{font-size:11px !important;width:2em !important;height:2em !important;min-width:2em !important;margin:0 10px 0 0 !important}
.swal2-popup.swal2-toast .swal2-timer-progress-bar-container{border-radius:0 0 var(--radius-sm) var(--radius-sm) !important;overflow:hidden !important}

/* ===== Dark mode overrides =====
   Core tokens (--ink/--muted/--paper/--card/--line/--accent-soft) are
   redefined up in :root's html[data-theme="dark"] block, so most components
   already adapt automatically. What's left here is: (1) surfaces with a
   hardcoded light color instead of a token (translucent white topbar,
   #fff-on-hover buttons, #fbfcfe input fills), and (2) pastel accent badges
   whose background comes from --accent-soft pinned via inline style (tool
   cards set --accent-soft on themselves) or a body[data-accent] rule more
   specific than the :root override — both bypassed here with !important
   since there's no other way to out-specificity an inline style. Printable
   documents (.doc-page) and the always-dark navy bands (hero/dash-hero/
   admin-sidebar/auth panel) are intentionally left alone: they already look
   the same regardless of theme by design. */
html[data-theme="dark"] .topbar{background:rgba(13,15,22,.86)}
html[data-theme="dark"] .admin-topbar{background:rgba(13,15,22,.88)}
html[data-theme="dark"] .lang-toggle{background:var(--card)}
html[data-theme="dark"] .topbar-user-menu .lang-toggle{background:var(--paper)}

html[data-theme="dark"] .tool-card .tool-icon,
html[data-theme="dark"] .tool-badge,
html[data-theme="dark"] .tool-category-title i,
html[data-theme="dark"] .quick-action-icon,
html[data-theme="dark"] .feature-strip-icon,
html[data-theme="dark"] .pricing-icon,
html[data-theme="dark"] .history-type-badge,
html[data-theme="dark"] .add-row-btn,
html[data-theme="dark"] .items-table td:first-child:before,
html[data-theme="dark"] .draft-banner,
html[data-theme="dark"] .doc-theme-locked,
html[data-theme="dark"] .card h2 i,
html[data-theme="dark"] .admin-section h2 i,
html[data-theme="dark"] .stat-icon.usage,
html[data-theme="dark"] .kpi-icon.usage,
html[data-theme="dark"] .kpi-trend.new,
html[data-theme="dark"] .plan-pill.plan-basic{
  background:color-mix(in srgb, var(--accent) 22%, var(--card)) !important;
}
html[data-theme="dark"] .zoom-toolbar button:hover,
html[data-theme="dark"] .tool-carousel-btn:hover,
html[data-theme="dark"] .admin-feature-actions button:hover,
html[data-theme="dark"] .topbar-user-menu a:hover{
  background:color-mix(in srgb, var(--accent) 22%, var(--card));
}

html[data-theme="dark"] .stat-icon.plan,
html[data-theme="dark"] .kpi-icon.plan,
html[data-theme="dark"] .plan-pill.plan-pro{background:color-mix(in srgb,#c9a227 24%, var(--card)) !important;color:#e7c866 !important}
html[data-theme="dark"] .stat-icon.history,
html[data-theme="dark"] .kpi-icon.history{background:color-mix(in srgb,#0f766e 26%, var(--card)) !important;color:#5eead4 !important}
html[data-theme="dark"] .stat-icon.crm,
html[data-theme="dark"] .kpi-icon.crm{background:color-mix(in srgb,#6d28d9 26%, var(--card)) !important;color:#c4b5fd !important}
html[data-theme="dark"] .plan-pill.plan-free{background:color-mix(in srgb,#ffffff 10%, var(--card)) !important;color:var(--muted) !important}
html[data-theme="dark"] .plan-pill.plan-business{background:color-mix(in srgb,#3730a3 26%, var(--card)) !important;color:#a5b4fc !important}
html[data-theme="dark"] .kpi-trend.up{background:color-mix(in srgb, var(--good) 24%, var(--card)) !important;color:#6ee7b7 !important}
html[data-theme="dark"] .kpi-trend.down{background:color-mix(in srgb, var(--bad) 22%, var(--card)) !important;color:#fca5a5 !important}
html[data-theme="dark"] .admin-feature-actions [data-delete]:hover{background:color-mix(in srgb, var(--bad) 22%, var(--card)) !important}
html[data-theme="dark"] .status-badge.good{background:color-mix(in srgb, var(--good) 24%, var(--card));color:#6ee7b7}
html[data-theme="dark"] .status-badge.warn{background:color-mix(in srgb,#c9a227 24%, var(--card));color:#e7c866}
html[data-theme="dark"] .status-badge.bad{background:color-mix(in srgb, var(--bad) 22%, var(--card));color:#fca5a5}
html[data-theme="dark"] .payment-result-icon.success{background:color-mix(in srgb, var(--good) 24%, var(--card));color:#6ee7b7}
html[data-theme="dark"] .payment-result-icon.error{background:color-mix(in srgb, var(--bad) 22%, var(--card));color:#fca5a5}
html[data-theme="dark"] .payment-result-icon.waiting{background:color-mix(in srgb,#c9a227 24%, var(--card));color:#e7c866}
html[data-theme="dark"] .checkout-countdown.is-urgent{background:color-mix(in srgb, var(--bad) 22%, var(--card));color:#fca5a5}
html[data-theme="dark"] .card-form-error{background:color-mix(in srgb, var(--bad) 22%, var(--card));color:#fca5a5}

html[data-theme="dark"] .field input,
html[data-theme="dark"] .field select,
html[data-theme="dark"] .field textarea,
html[data-theme="dark"] .items-table input{background:var(--paper);color:var(--ink);border-color:var(--line)}
html[data-theme="dark"] .field input:focus,
html[data-theme="dark"] .field select:focus,
html[data-theme="dark"] .field textarea:focus,
html[data-theme="dark"] .items-table input:focus{background:var(--card)}
/* The row tools are flat (no chip), so they must stay transparent here —
   the .row-del rule just below would otherwise give each one a card-coloured
   fill and bring the "pile of buttons" look back in dark mode. */
html[data-theme="dark"] .items-table .row-tools button{background:none}
html[data-theme="dark"] .items-table .row-tools button:hover{background:color-mix(in srgb, var(--accent) 26%, var(--card));color:#fff}
html[data-theme="dark"] .items-table .row-tools button.rt-del:hover{background:color-mix(in srgb, var(--bad) 26%, var(--card));color:#fff}
html[data-theme="dark"] .row-del button,
html[data-theme="dark"] .add-row-btn:hover,
html[data-theme="dark"] .btn-danger,
html[data-theme="dark"] .btn-google{background:var(--card)}
html[data-theme="dark"] .btn-danger{border-color:color-mix(in srgb, var(--bad) 35%, var(--card))}
html[data-theme="dark"] .btn-danger:hover{background:color-mix(in srgb, var(--bad) 18%, var(--card))}
html[data-theme="dark"] .admin-feature-list li{background:var(--paper)}
html[data-theme="dark"] .swal2-validation-message{background:color-mix(in srgb, var(--bad) 22%, var(--card)) !important;color:#fca5a5 !important}
html[data-theme="dark"] body:not(.swal2-toast-shown) .swal2-container{background:rgba(0,0,0,.6) !important}

/* Document picker shown when a cashier turns a Kasir record into a formal
   document (see app.js's openKasirDocPicker). One row per offered document
   type — the choice is always the cashier's, nothing is auto-generated. */
.kasir-doc-options{display:flex;flex-direction:column;gap:8px}
.kasir-doc-option{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;padding:11px 14px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--paper);cursor:pointer;text-align:left;transition:border-color .15s,background-color .15s}
.kasir-doc-option:hover{border-color:var(--accent);background:var(--accent-soft)}
.kasir-doc-option-name{font-size:13.5px;font-weight:700;color:var(--ink)}
.kasir-doc-option-desc{font-size:11.5px;color:var(--muted)}


/* ==========================================================================
   RESPONSIVE PASS — phones & tablets
   ==========================================================================
   Appended last on purpose: everything here is a narrow-width override of a
   rule defined earlier in this file, so equal-specificity selectors must win
   by source order rather than by being made artificially more specific.

   Each block below was written against a measured failure (horizontal
   overflow or an unusable layout) at 320/390/768/1024px, not added
   speculatively. Breakpoints reuse the ones already in this file (1080 =
   tablet landscape / sidebar collapse, 900 = tablet portrait, 640 = large
   phone, 400 = small phone) so there is no third competing scale.
   ========================================================================== */

/* --- 1. Grid blowout ------------------------------------------------------
   A `1fr` track keeps an implicit `min-width:auto`, so it refuses to shrink
   below the widest item's min-content size. On /panduan that pushed the
   single-column content track to 527px inside a 280px screen — the whole page
   scrolled sideways. minmax(0,1fr) lets the track actually reach the viewport
   width, and min-width:0 lets each child do the same. */
@media(max-width:1100px){
  .content-editor-layout{grid-template-columns:minmax(0,1fr)}
  .content-editor-layout>*{min-width:0}
}
@media(max-width:900px){
  .doc-layout{grid-template-columns:minmax(0,1fr)}
  .doc-layout>*{min-width:0}
  .doc-toc,.doc-section{min-width:0}
  /* Long unbroken strings (a URL in a doc paragraph, an API key sample) would
     otherwise re-create the same blowout from inside a child. */
  .doc-section p,.doc-section li,.doc-toc a{overflow-wrap:anywhere}
}

/* --- 2. Admin & Kasir shell header ---------------------------------------
   .admin-topbar is one flex row: [hamburger + title/subtitle] ... [lang,
   user, logout]. On a phone the right-hand cluster took ~200px of a 390px
   screen, squeezing the title column to ~150px — the descriptive subtitle
   then wrapped to 8 lines and the sticky header grew to ~400px tall, pushing
   all real content off-screen. The subtitle is decorative (every one of these
   pages states its purpose in the content), so it goes first; the title
   truncates rather than wraps. */
@media(max-width:640px){
  .admin-topbar{gap:10px;padding:11px 14px}
  .admin-topbar-left{flex:1;min-width:0;gap:10px}
  .admin-topbar-title{min-width:0}
  .admin-topbar-title span{display:none}
  .admin-topbar-title strong{font-size:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .admin-content{padding:16px 14px 44px}
  .admin-sidebar-toggle{width:36px;height:36px}
}

/* --- 3. Public / generator topbar ----------------------------------------
   Two different topbars share .topbar-inner: the marketing one (brand + auth
   buttons) and the generator one (back link + document title + user). Both
   overflowed a 320px screen — the generator one had its back button visually
   colliding with the title. The back link keeps its arrow but drops the word
   "Dashboard" (an arrow alone is a universally understood back affordance),
   and the eyebrow "TH BUSINESS" above the document name is dropped since the
   brand is already in view. */
@media(max-width:640px){
  .topbar-inner{gap:8px}
  .topbar-back{padding:8px 11px;gap:0;font-size:0}
  .topbar-back i{font-size:14px}
  .topbar-title{min-width:0}
  .topbar-title span{display:none}
  .topbar-title strong{font-size:13.5px;padding-left:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .topbar-right{gap:8px}
  .lang-toggle button{padding:5px 9px;font-size:11px}
}
@media(max-width:400px){
  /* The default gutter is calc(100% - 40px); at 320px that leaves only 280px
     for a row that needs ~334px. */
  .topbar-inner{width:calc(100% - 22px)}
  .brand{font-size:15px;gap:8px}
  /* Matches `.brand .brand-mark` above rather than `.brand img`, which loses
     on specificity (0,1,1 vs 0,2,0) and silently left the logo at 32px. */
  .brand .brand-mark{width:26px;height:26px}
  .topbar-right{gap:6px}
  .topbar-user{gap:6px}
}

/* --- 3b. Laptop two-pane sizing ------------------------------------------
   The generator and the POS both keep their side-by-side layout down to
   900px now (see the .gen-header block above) instead of collapsing at
   1080px, which used to push the live preview off a 1024px laptop screen.

   NOTE: the panel WIDTH is capped in JS (initPanelResizer's viewportCap in
   public/assets/js/app.js), not here — applyWidth writes --sidebar-w as an
   inline style on <html>, which outranks any stylesheet rule, so a @media
   override of that variable would silently never apply. Only the preview
   scale is handled below. */
@media(max-width:1100px){
  .gen-layout{padding:18px 24px 60px}
  .gen-header{padding:24px 24px 6px}
}

/* --- 4. Generator page chrome -------------------------------------------- */
@media(max-width:640px){
  .gen-header{padding:18px 14px 4px}
  .gen-header h1{font-size:19px;gap:8px}
  .gen-header h1 i{font-size:16px}
  .gen-header p{font-size:12.5px}
  .gen-layout{padding:14px 14px 48px}
  .gen-progress{margin-top:12px;max-width:none}
  .action-bar{flex-wrap:wrap}
  .action-bar .btn{flex:1 1 auto;justify-content:center}
}

/* --- 4b. Admin grids -----------------------------------------------------
   Same `1fr` blowout as the docs layout, found by sweeping widths the first
   pass had skipped: /admin/features scrolled sideways by up to 261px at
   1099-1280px and /admin/prices by 73px at 901px, because a feature name or a
   price label set a min-content width the 1fr track could not go below.
   These are the base rules restated with minmax(0,1fr) at every breakpoint,
   so they apply at all widths rather than only inside a media query. */
.admin-price-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
.admin-feature-grid{grid-template-columns:repeat(4,minmax(0,1fr))}
.admin-price-field,.admin-feature-col{min-width:0}
.admin-feature-list li{overflow-wrap:anywhere}
@media(max-width:1080px){.admin-feature-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:760px){.admin-price-grid{grid-template-columns:minmax(0,1fr)}}
@media(max-width:640px){.admin-feature-grid{grid-template-columns:minmax(0,1fr)}}

/* --- 4c. Filter toolbars -------------------------------------------------
   .history-toolbar (25 pages) is a wrapping flex row whose controls size to
   their content, so on a phone the last row was usually only half full and
   left an obvious empty gap on the right — e.g. /kasir/riwayat put the search
   box on row 1, channel + "from" date on row 2, and the lone "to" date on row
   3 beside a hole.

   `flex:1 1 140px` makes every control both wrap AND stretch to fill whatever
   room its row has left, so the row is always flush no matter how many
   filters a given page happens to have (they range from 2 to 5). The
   !important is needed because several of these controls carry an inline
   `min-width:200px`/`flex:1`, and an inline declaration otherwise outranks
   this rule.

   Scoped to the actual controls rather than `> *`: these toolbars also carry
   plain text such as the "0 dokumen" count on /history, and stretching a
   short label to half a row looks like a bug of its own. */
@media(max-width:640px){
  .history-toolbar{gap:8px}
  .history-toolbar > .field,
  .history-toolbar > .admin-toolbar-search,
  .history-toolbar > input,
  .history-toolbar > select,
  .history-toolbar > button,
  .history-toolbar > .btn{flex:1 1 140px!important;min-width:0!important;width:auto}
  .history-toolbar input,.history-toolbar select{width:100%;box-sizing:border-box}
}

/* --- 4d. Pagination bar (11 pages share .history-pagination) -------------
   "Sebelumnya"/"Berikutnya" at the default .btn-sm size (padding:9px 16px)
   are long enough in Indonesian that the two buttons plus the "Halaman X/Y"
   label between them don't fit a phone width — the label got squeezed
   until IT wrapped onto two lines, and the second button overflowed past
   the bar's own right edge (clipped by the card's border-radius, not
   visible as a scrollbar, so it just looked cut off / "too big for its
   spot"). Shrinking just the buttons here (not .btn-sm globally, which
   would resize every small button on every page) and adding flex-wrap as a
   safety net for anything still not fitting a truly small phone. */
@media(max-width:480px){
  .history-pagination{gap:8px;row-gap:6px;flex-wrap:wrap;margin:16px 0 32px}
  .history-pagination .btn{padding:7px 11px;font-size:11.5px}
  .history-pagination span{font-size:12px;white-space:nowrap}
}

/* --- 5. Tables -----------------------------------------------------------
   These already sit in overflow-x wrappers, so they scroll rather than break
   the page. What was missing is the affordance: on a phone a table that is
   cut off at the edge with no scrollbar looks like broken layout rather than
   something you can swipe. */
@media(max-width:640px){
  .history-table{font-size:12.5px}
  .history-table th,.history-table td{padding-left:10px;padding-right:10px}
  .api-endpoint-table{font-size:11.5px}
}

/* --- 6. Modals -----------------------------------------------------------
   SweetAlert's default width leaves almost no gutter on a small phone. */
@media(max-width:480px){
  .swal2-popup{width:calc(100vw - 24px)!important;padding:18px 14px!important}
  .swal2-title{font-size:17px!important}
  .swal2-html-container{font-size:13px!important;margin:8px 2px 0!important}
  .swal2-actions{gap:8px;flex-wrap:wrap}
}

/* --- 7. Touch targets ----------------------------------------------------
   Applied only where the pointer really is coarse, so mouse layouts keep
   their current density. 38px is a pragmatic floor for a thumb. */
@media (hover:none) and (pointer:coarse){
  .btn,.admin-nav-link,.kasir-pay-toggle button{min-height:38px}
  .btn-sm{min-height:34px}
}

/* "Kirim ke Email Klien" compose dialog — app.js composeEmailDialog. */
.thb-compose{display:grid;gap:12px;margin-top:4px;text-align:left}
.thb-compose-intro{margin:0;font-size:13.5px;color:var(--muted)}
.thb-compose-row{display:grid;gap:5px}
.thb-compose-head{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.thb-compose-label{font-size:12px;font-weight:700;color:var(--ink);letter-spacing:.02em}
.thb-compose-link{padding:0;border:0;background:none;font:inherit;font-size:12px;font-weight:600;color:var(--accent);cursor:pointer}
.thb-compose-link:hover,.thb-compose-link:focus-visible{text-decoration:underline}
.thb-chips{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:42px;padding:6px 8px;box-sizing:border-box;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);cursor:text}
.thb-chips:focus-within,.thb-compose-input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);outline:0}
.thb-chip{display:inline-flex;align-items:center;gap:2px;max-width:100%;padding:3px 3px 3px 10px;border-radius:999px;background:var(--accent-soft);color:var(--ink);font-size:12.5px;font-weight:600;line-height:1.4;overflow-wrap:anywhere}
.thb-chip.is-bad{background:color-mix(in srgb, var(--bad) 12%, var(--card));color:var(--bad);box-shadow:inset 0 0 0 1px var(--bad)}
.thb-chip button{display:inline-grid;place-items:center;width:20px;height:20px;padding:0;border:0;border-radius:50%;background:transparent;color:inherit;font-size:15px;line-height:1;cursor:pointer;opacity:.65}
.thb-chip button:hover,.thb-chip button:focus-visible{opacity:1;background:color-mix(in srgb, currentColor 14%, transparent);outline:0}
.thb-chips-input{flex:1 1 140px;min-width:110px;padding:4px 2px;border:0;outline:0;background:transparent;color:var(--ink);font:inherit;font-size:13.5px}
.thb-compose-input{width:100%;box-sizing:border-box;padding:10px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);color:var(--ink);font:inherit;font-size:13.5px}
textarea.thb-compose-input{min-height:76px;line-height:1.5;resize:vertical}
.thb-compose-hint{margin-top:-6px;font-size:11.5px;color:var(--muted)}
.thb-compose-help{margin-top:-6px;font-size:12px;color:var(--muted)}
.thb-compose-help summary{width:fit-content;font-weight:600;color:var(--accent);cursor:pointer}
.thb-compose-help summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.thb-compose-help ol{display:grid;gap:4px;margin:8px 0 0;padding:10px 12px 10px 30px;border-radius:var(--radius-sm);background:var(--paper);line-height:1.5}
.thb-compose-help b{color:var(--ink)}
.thb-compose-help code{padding:1px 5px;border-radius:4px;background:var(--card);color:var(--ink);font-size:11.5px}
.thb-compose-bad{color:var(--bad);font-weight:600}
.thb-compose-row{position:relative}
.thb-suggest{position:absolute;left:0;right:0;top:calc(100% + 4px);z-index:5;display:grid;max-height:240px;overflow-y:auto;padding:4px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);box-shadow:var(--shadow-lg)}
.thb-suggest[hidden]{display:none}
.thb-suggest-item{display:grid;gap:1px;padding:7px 10px;border-radius:7px;cursor:pointer;text-align:left}
.thb-suggest-item:hover,.thb-suggest-item.is-active{background:var(--accent-soft)}
.thb-suggest-name{font-size:13px;font-weight:600;color:var(--ink)}
.thb-suggest-email{font-size:12px;color:var(--muted);overflow-wrap:anywhere}

/* History > "Riwayat Kirim" (history.html showShares). */
.share-list{display:grid;gap:10px;max-height:60vh;overflow-y:auto;text-align:left}
.share-card{display:grid;gap:5px;padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card)}
.share-card-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;margin-bottom:2px}
.share-state{padding:2px 9px;border-radius:999px;font-size:11.5px;font-weight:700;letter-spacing:.02em}
.share-state.is-active{background:color-mix(in srgb, var(--good) 14%, var(--card));color:var(--good)}
.share-state.is-revoked{background:color-mix(in srgb, var(--bad) 12%, var(--card));color:var(--bad)}
.share-state.is-expired{background:var(--paper);color:var(--muted)}
.share-when{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.share-line{font-size:12.5px;color:var(--ink);line-height:1.5;overflow-wrap:anywhere}
.share-line b{display:inline-block;min-width:54px;margin-right:4px;font-weight:600;color:var(--muted)}
.share-track{color:var(--muted)}
.share-track.is-yes{color:var(--ink)}
.share-track i{width:16px;margin-right:4px;color:var(--accent)}
.share-muted{font-size:12px;color:var(--muted)}
.share-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;margin-top:4px;padding-top:8px;border-top:1px dashed var(--line)}
.share-revoke{color:var(--bad) !important}
.share-empty{padding:18px;text-align:center;font-size:13px;color:var(--muted)}
.share-note{font-size:12px;color:var(--good);font-weight:600}
.share-note.is-bad{color:var(--bad)}

/* /aktivitas — the business activity log (activity.html). */
.activity-card{padding:6px 18px 12px}
.activity-day{position:sticky;top:0;padding:14px 0 6px;background:var(--card);font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.activity-row{display:flex;gap:12px;align-items:flex-start;padding:10px 0;border-top:1px solid var(--line)}
.activity-day + .activity-row{border-top:0}
.activity-icon{display:grid;place-items:center;flex:none;width:32px;height:32px;border-radius:50%;background:var(--accent-soft);color:var(--accent);font-size:13px}
.activity-text{min-width:0}
.activity-summary{font-size:13.5px;color:var(--ink);line-height:1.5;overflow-wrap:anywhere}
.activity-summary a{color:inherit;text-decoration:none}
.activity-summary a:hover,.activity-summary a:focus-visible{color:var(--accent);text-decoration:underline}
.activity-meta{margin-top:2px;font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.share-wa{color:#16a34a}
.share-wa{color:#16a34a}
.reminder-box{display:grid;gap:6px;padding:12px 14px;border:1px solid color-mix(in srgb, var(--accent) 35%, var(--line));border-radius:var(--radius-sm);background:var(--accent-soft);font-size:12.5px;color:var(--ink);text-align:left}
.reminder-box.is-off{display:block;border-color:var(--line);background:var(--paper);color:var(--muted)}
.reminder-box.is-off i{margin-right:6px;color:var(--accent)}
.reminder-toggle{display:flex;gap:8px;align-items:center;cursor:pointer}
.reminder-detail{line-height:1.6;color:var(--muted)}
.reminder-detail select{padding:2px 6px;border:1px solid var(--line);border-radius:6px;background:var(--card);color:var(--ink);font:inherit}
.history-recurring-badge{display:inline-flex;align-items:center;gap:4px;margin-left:6px;padding:3px 8px;border-radius:100px;background:color-mix(in srgb, var(--accent) 14%, var(--card));color:var(--accent);font-size:10.5px;font-weight:700;white-space:nowrap}

/* Kasir dashboard — cashier shift card (kasir.html). */
.shift-hint{margin:0 0 12px;font-size:13px;color:var(--muted);line-height:1.55}
.shift-open-form{display:flex;flex-wrap:wrap;align-items:flex-end;gap:10px}
.shift-label{flex-basis:100%;font-size:12px;font-weight:700;color:var(--ink)}
.shift-input{flex:1 1 200px;max-width:280px;padding:9px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);color:var(--ink);font:inherit;font-variant-numeric:tabular-nums}
.shift-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px}
.shift-grid>div{display:grid;gap:2px;padding:10px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--paper)}
.shift-grid span{font-size:11.5px;color:var(--muted)}
.shift-grid b{font-size:15px;color:var(--ink);font-variant-numeric:tabular-nums}
.shift-grid small{font-size:11px;color:var(--muted)}
.shift-grid>div.is-key{border-color:var(--accent);background:var(--accent-soft)}
.shift-grid>div.is-key b{color:var(--accent);font-size:17px}
.shift-actions{display:flex;justify-content:flex-end;margin-top:12px}
.shift-ok{color:var(--good) !important;font-weight:600}
.shift-off{color:var(--bad) !important;font-weight:600}
.shift-open-pill{padding:2px 8px;border-radius:999px;background:var(--accent-soft);color:var(--accent);font-size:11px;font-weight:700}
.shift-table td,.shift-table th{font-size:12.5px;white-space:nowrap;font-variant-numeric:tabular-nums}

/* Template Isian — picker dialog and the banner on a generator page (app.js). */
.ftp{display:grid;gap:14px;text-align:left}
.ftp-section{display:grid;gap:6px}
.ftp-title{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.ftp-title i{margin-right:4px;color:var(--accent)}
.ftp-item{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card)}
.ftp-item:hover{border-color:var(--accent)}
.ftp-main{display:grid;gap:2px;min-width:0}
.ftp-main b{font-size:13.5px;color:var(--ink);overflow-wrap:anywhere}
.ftp-main span{font-size:12.5px;color:var(--muted);overflow-wrap:anywhere}
.ftp-main small{font-size:11.5px;color:var(--muted)}
.ftp-empty{margin:0;padding:12px;border:1px dashed var(--line);border-radius:var(--radius-sm);font-size:12.5px;color:var(--muted)}
.ftp-more{justify-self:start;font-size:12.5px;font-weight:600;color:var(--accent);text-decoration:none}
.ftp-more:hover{text-decoration:underline}
.tpl-banner{display:flex;align-items:center;gap:12px;margin:0 0 14px;padding:12px 14px;border:1px solid color-mix(in srgb, var(--accent) 40%, var(--line));border-radius:var(--radius-sm);background:var(--accent-soft);color:var(--ink);font-size:13px}
.tpl-banner>i{color:var(--accent);font-size:16px}
.tpl-banner.is-editing{border-color:var(--gold, #b7791f);background:color-mix(in srgb, var(--gold, #b7791f) 12%, var(--card))}
.tpl-banner.is-editing>i{color:var(--gold, #b7791f)}
.tpl-banner-text{flex:1;min-width:0;line-height:1.5}
.tpl-banner-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.tpl-banner-close{width:28px;height:28px;border:0;border-radius:50%;background:transparent;color:var(--muted);font-size:18px;cursor:pointer}
.tpl-banner-close:hover{background:color-mix(in srgb, currentColor 12%, transparent);color:var(--ink)}
.tpl-banner-done{font-size:12.5px;font-weight:600;color:var(--good)}
@media (max-width:640px){.tpl-banner{flex-wrap:wrap}.tpl-banner-actions{width:100%}}

/* /template — the template library (templates.html). */
.lib-hero{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}
.lib-hero>div{flex:1 1 420px;min-width:0}
.lib-tabs{display:flex;gap:6px;margin:4px 0 14px;border-bottom:1px solid var(--line)}
.lib-tab{display:inline-flex;align-items:center;gap:7px;padding:10px 14px;border:0;border-bottom:2px solid transparent;margin-bottom:-1px;background:none;color:var(--muted);font:inherit;font-size:14px;font-weight:600;cursor:pointer}
.lib-tab:hover{color:var(--ink)}
.lib-tab.is-active{color:var(--accent);border-bottom-color:var(--accent)}
.lib-tab:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}
.lib-tab-count{min-width:20px;padding:1px 7px;border-radius:999px;background:var(--paper);color:var(--muted);font-size:11.5px;font-variant-numeric:tabular-nums}
.lib-tab-count:empty{display:none}
.lib-tab.is-active .lib-tab-count{background:var(--accent-soft);color:var(--accent)}
.lib-toolbar{margin-bottom:12px}
.lib-note{margin:0 0 12px;font-size:12.5px;color:var(--muted)}
.lib-note a{color:var(--accent);font-weight:600}
.lib-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:16px;margin-bottom:18px}
.lib-grid>.history-empty,.lib-grid>.lib-empty{grid-column:1/-1}
.lib-card{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--radius);background:var(--card);overflow:visible;transition:border-color .15s ease,box-shadow .15s ease}
.lib-card:hover{border-color:color-mix(in srgb, var(--accent) 45%, var(--line));box-shadow:0 10px 28px -18px rgba(11,16,32,.45)}
.lib-thumb{display:grid;place-items:center;height:150px;padding:14px;border-bottom:1px solid var(--line);border-radius:var(--radius) var(--radius) 0 0;background:var(--paper);overflow:hidden}
.lib-paper{display:grid;align-content:start;gap:6px;width:min(170px,100%);height:100%;padding:12px 12px 10px;border-radius:4px;background:#fff;box-shadow:0 4px 14px -6px rgba(11,16,32,.3);color:#1f2433;overflow:hidden}
.lib-paper b{margin-bottom:4px;padding-bottom:5px;border-bottom:2px solid var(--accent);font-size:10.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--accent);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lib-paper-line{display:block;height:6px;border-radius:3px;background:#e7eaf2}
.lib-paper-line.short{width:60%}
.lib-paper-line.has-text{height:auto;padding:1px 0;background:none;border-bottom:1px solid #eef0f5;font-size:9.5px;line-height:1.3;color:#3d4457;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lib-paper small{font-size:9px;color:#8a91a5}
.lib-design{position:relative;display:grid;place-items:center;width:100%;height:100%;color:var(--accent);font-size:34px;opacity:.7}
.lib-design img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
.lib-design.has-img{opacity:1}
.lib-design.has-img i{display:none}
.lib-body{display:grid;gap:7px;padding:14px 14px 10px;flex:1}
.lib-body h3{margin:0;font-size:15px;line-height:1.35;color:var(--ink);overflow-wrap:anywhere}
.lib-chips{display:flex;flex-wrap:wrap;gap:5px}
.lib-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:999px;background:var(--paper);color:var(--muted);font-size:11px;font-weight:600}
.lib-chip.is-form{background:var(--accent-soft);color:var(--accent)}
.lib-chip.is-design{background:color-mix(in srgb, #7c3aed 14%, var(--card));color:#7c3aed}
.lib-chip.is-link{background:color-mix(in srgb, var(--good) 14%, var(--card));color:var(--good)}
.lib-chip.is-pub{background:color-mix(in srgb, #b7791f 16%, var(--card));color:#b7791f}
.lib-desc{margin:0;font-size:12.5px;line-height:1.5;color:var(--muted);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.lib-meta{font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums}
.lib-actions{display:flex;align-items:center;gap:6px;flex-wrap:wrap;padding:10px 14px 14px}
.lib-own{font-size:12px;font-weight:600;color:var(--good)}
.lib-mod{margin-left:auto;color:var(--bad) !important}
.lib-menu{position:relative;margin-left:auto}
.lib-menu-list{position:absolute;right:0;bottom:calc(100% + 6px);z-index:20;display:grid;min-width:210px;padding:5px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);box-shadow:var(--shadow-lg)}
.lib-menu-list[hidden]{display:none}
.lib-menu-list button{display:flex;align-items:center;gap:8px;padding:8px 10px;border:0;border-radius:7px;background:none;color:var(--ink);font:inherit;font-size:13px;text-align:left;cursor:pointer}
.lib-menu-list button:hover,.lib-menu-list button:focus-visible{background:var(--paper);outline:0}
.lib-menu-list button i{width:16px;color:var(--muted)}
.lib-menu-list .is-danger,.lib-menu-list .is-danger i{color:var(--bad)}
.lib-empty{display:grid;justify-items:center;gap:8px;padding:44px 20px;border:1px dashed var(--line);border-radius:var(--radius);text-align:center;color:var(--muted)}
.lib-empty>i{font-size:30px;color:var(--accent)}
.lib-empty h3{margin:0;color:var(--ink)}
.lib-empty p{max-width:520px;margin:0;font-size:13.5px;line-height:1.6}
.lib-empty div{display:flex;gap:8px;flex-wrap:wrap;justify-content:center}
.lib-share{display:grid;gap:12px;text-align:left}
.lib-share section{display:grid;gap:7px;padding:12px 14px;border:1px solid var(--line);border-radius:var(--radius-sm)}
.lib-share h4{margin:0;font-size:13.5px;color:var(--ink)}
.lib-share h4 i{margin-right:6px;color:var(--accent)}
.lib-share p{margin:0;font-size:12.5px;line-height:1.55;color:var(--muted)}
.lib-link-row{display:flex;gap:8px}
.lib-link-row input{flex:1;min-width:0;font-size:12.5px}
.lib-danger{justify-self:start;color:var(--bad) !important}
.lib-new{display:grid;gap:10px}
.lib-new-opt{display:grid;grid-template-columns:auto 1fr;gap:4px 12px;align-items:center;padding:14px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);color:var(--ink);font:inherit;text-align:left;cursor:pointer}
.lib-new-opt:hover,.lib-new-opt:focus-visible{border-color:var(--accent);background:var(--accent-soft);outline:0}
.lib-new-opt i{grid-row:span 2;font-size:22px;color:var(--accent)}
.lib-new-opt b{font-size:14px}
.lib-new-opt span{font-size:12.5px;color:var(--muted);line-height:1.5}
.lib-shared{display:grid;gap:10px;text-align:left}
.lib-shared .lib-thumb{border:1px solid var(--line);border-radius:var(--radius-sm)}
html[data-theme="dark"] .lib-paper{background:#f4f5f8}
.lib-warn{padding:8px 10px;border-radius:8px;background:color-mix(in srgb, #b7791f 12%, var(--card));color:#8a5a12 !important}
html[data-theme="dark"] .lib-warn{color:#f6c56b !important}
.lib-warn i{margin-right:4px}
.tpl-banner{flex-wrap:wrap}
.tpl-banner-text{flex:1 1 220px}
.doc-expiry-hint{display:block;margin-top:4px;font-size:11.5px;color:var(--muted);line-height:1.45}
.staff-perm-line{margin-top:3px;font-size:11.5px;color:#b7791f}
.staff-perm-line i{margin-right:4px}
.perm-list{display:grid;gap:8px;text-align:left}
.perm-row{display:flex;gap:10px;align-items:flex-start;padding:10px 12px;border:1px solid var(--line);border-radius:var(--radius-sm);cursor:pointer}
.perm-row input{margin-top:3px}
.perm-row span{display:grid;gap:2px}
.perm-row b{font-size:13.5px;color:var(--ink)}
.perm-row small{font-size:12px;color:var(--muted);line-height:1.45}
.perm-row.is-approval{border-color:color-mix(in srgb, #b7791f 45%, var(--line));background:color-mix(in srgb, #b7791f 8%, var(--card))}

/* History: selection, labels, approval, row menu, attachments, bulk bar. */
.history-table .sel-cell{width:34px;text-align:center}
.history-table tr.is-selected td{background:color-mix(in srgb, var(--accent) 7%, var(--card))}
.row-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}
.row-tag{padding:1px 8px;border:0;border-radius:999px;background:color-mix(in srgb, #7c3aed 12%, var(--card));color:#7c3aed;font:inherit;font-size:11px;font-weight:600;cursor:pointer}
.row-tag:hover{background:color-mix(in srgb, #7c3aed 22%, var(--card))}
.row-clip{font-size:11px;color:var(--muted);white-space:nowrap}
.approval-badge{display:inline-block;margin-top:4px;padding:2px 8px;border-radius:999px;font-size:10.5px;font-weight:700;white-space:nowrap}
.approval-badge.is-pending{background:color-mix(in srgb, #b7791f 16%, var(--card));color:#b7791f}
.approval-badge.is-approved{background:color-mix(in srgb, var(--good) 14%, var(--card));color:var(--good)}
.approval-badge.is-rejected{background:color-mix(in srgb, var(--bad) 12%, var(--card));color:var(--bad)}
.row-menu{position:fixed;z-index:1060;display:grid;min-width:230px;padding:5px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);box-shadow:var(--shadow-lg)}
.row-menu button{display:flex;align-items:center;gap:9px;padding:8px 10px;border:0;border-radius:7px;background:none;color:var(--ink);font:inherit;font-size:13px;text-align:left;cursor:pointer}
.row-menu button:hover,.row-menu button:focus-visible{background:var(--paper);outline:0}
.row-menu button i{width:16px;color:var(--muted)}
.row-menu button.is-danger,.row-menu button.is-danger i{color:var(--bad)}
#approvalFilterBtn.is-active{border-color:#b7791f;color:#b7791f;background:color-mix(in srgb, #b7791f 10%, var(--card))}
.row-actions{display:flex;gap:6px;align-items:center}
.bulk-bar{position:fixed;left:0;right:0;bottom:18px;z-index:50;width:max-content;margin-inline:auto;display:flex;flex-wrap:wrap;align-items:center;gap:6px;max-width:calc(100vw - 32px);padding:10px 14px;border:1px solid var(--line);border-radius:14px;background:var(--card);box-shadow:var(--shadow-lg)}
.bulk-bar[hidden]{display:none}
.bulk-count{font-size:13px;font-weight:700;color:var(--ink);margin-right:4px}
.bulk-bar .btn-sm{padding:7px 12px}
.bulk-bar select{padding:7px 10px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);color:var(--ink);font:inherit;font-size:12.5px}
.bulk-danger{color:var(--bad) !important}
.tag-suggest{display:flex;flex-wrap:wrap;gap:5px;margin-top:4px}
.att-wrap{display:grid;gap:12px;text-align:left}
.att-list{display:grid;gap:6px}
.att-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--line);border-radius:var(--radius-sm)}
.att-item>i{font-size:18px;color:var(--accent)}
.att-main{flex:1;min-width:0;display:grid}
.att-main b{font-size:13px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.att-main small{font-size:11.5px;color:var(--muted)}
.att-del{color:var(--bad) !important}
.att-drop{display:grid;justify-items:center;gap:4px;padding:18px;border:1.5px dashed var(--line);border-radius:var(--radius-sm);text-align:center;color:var(--muted);cursor:pointer}
.att-drop i{font-size:22px;color:var(--accent)}
.att-drop b{font-size:13px;color:var(--ink)}
.att-drop small{font-size:11.5px}
.att-drop:hover,.att-drop.is-over{border-color:var(--accent);background:var(--accent-soft)}

/* /laporan — the document report (reports.html). */
:root{--chart-bar:#1d4ed8;--chart-bar-hover:#1e40af}
html[data-theme="dark"]{--chart-bar:#7aa2ff;--chart-bar-hover:#a5c0ff}
.rpt-range{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:0 0 16px}
.rpt-preset{padding:7px 12px;border:1px solid var(--line);border-radius:999px;background:var(--card);color:var(--muted);font:inherit;font-size:12.5px;font-weight:600;cursor:pointer}
.rpt-preset:hover{color:var(--ink)}
.rpt-preset.is-active{border-color:var(--accent);background:var(--accent);color:var(--accent-ink)}
.rpt-custom{display:inline-flex;align-items:center;gap:6px;margin-left:auto;color:var(--muted)}
.rpt-custom input{padding:6px 8px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);color:var(--ink);font:inherit;font-size:12.5px}
.rpt-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:12px;margin-bottom:16px}
.rpt-tile{display:grid;gap:3px;padding:14px 16px;border:1px solid var(--line);border-radius:var(--radius);background:var(--card)}
.rpt-tile-label{font-size:12px;font-weight:600;color:var(--muted)}
.rpt-tile-value{font-family:var(--heading);font-size:22px;color:var(--ink);font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.rpt-tile-sub{font-size:11.5px;color:var(--muted)}
.rpt-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
.rpt-wide{grid-column:1/-1}
@media (max-width:800px){.rpt-grid{grid-template-columns:1fr}.rpt-custom{margin-left:0}}
.rpt-card{min-width:0}
.rpt-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:10px}
.rpt-head h2{margin:0;font-size:15px}
.rpt-sub{font-size:12px;color:var(--muted)}
.rpt-chart{width:100%;overflow-x:auto}
.rpt-svg{display:block;max-width:none}
.rpt-grid-line{stroke:var(--line);stroke-width:1}
.rpt-grid-line.is-base{stroke:color-mix(in srgb, var(--muted) 55%, transparent)}
.rpt-tick{fill:var(--muted);font-size:12px;font-variant-numeric:tabular-nums}
.rpt-hit{fill:transparent}
.rpt-mark{fill:var(--chart-bar)}
.rpt-bar.is-hover .rpt-mark{fill:var(--chart-bar-hover)}
.rpt-bar.is-hover .rpt-hit{fill:color-mix(in srgb, var(--chart-bar) 7%, transparent)}
.rpt-tip{position:absolute;z-index:60;display:grid;gap:2px;padding:7px 10px;border:1px solid var(--line);border-radius:8px;background:var(--card);box-shadow:var(--shadow-lg);font-size:12px;color:var(--ink);pointer-events:none;white-space:nowrap}
.rpt-tip[hidden]{display:none}
.rpt-tip span{color:var(--muted);font-variant-numeric:tabular-nums}
.rpt-hbars{display:grid;gap:8px}
.rpt-hrow{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,2fr) auto;align-items:center;gap:10px}
.rpt-hlabel{font-size:12.5px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rpt-htrack{height:8px;border-radius:4px;background:var(--paper)}
.rpt-hfill{display:block;height:100%;border-radius:0 4px 4px 0;background:var(--chart-bar)}
.rpt-hvalue{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.rpt-status{display:flex;flex-wrap:wrap;gap:8px}
.rpt-status-chip{display:inline-flex;align-items:center;gap:8px;padding:6px 12px;border:1px solid var(--line);border-radius:999px;color:var(--ink);font-size:12.5px;text-decoration:none}
.rpt-status-chip:hover{border-color:var(--accent);color:var(--accent)}
.rpt-status-chip b{font-variant-numeric:tabular-nums}
.rpt-empty{margin:0;font-size:12.5px;color:var(--muted)}
.rpt-table{margin:16px 0 30px}
.rpt-table summary{cursor:pointer;font-size:13px;font-weight:600;color:var(--accent)}

/* API & Integrations — webhooks (api-settings.html). */
.webhook-item{display:grid;gap:8px;padding:12px 14px;margin-bottom:10px;border:1px solid var(--line);border-radius:var(--radius-sm)}
.webhook-top{display:flex;align-items:center;justify-content:space-between;gap:10px}
.webhook-url{min-width:0;overflow-wrap:anywhere;font-size:12.5px;color:var(--ink)}
.webhook-toggle{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted);white-space:nowrap}
.webhook-events{display:flex;flex-wrap:wrap;gap:5px}
.webhook-secret{display:flex;align-items:center;flex-wrap:wrap;gap:8px;font-size:12px;color:var(--muted)}
.webhook-secret code{padding:2px 6px;border-radius:5px;background:var(--paper);color:var(--ink);overflow-wrap:anywhere}
.webhook-foot{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px}
.webhook-last{font-size:12px;color:var(--muted)}
.webhook-last.is-ok{color:var(--good)}
.webhook-last.is-bad{color:var(--bad)}
.webhook-actions{display:flex;gap:6px;flex-wrap:wrap}
.webhook-help{margin-top:6px}
.webhook-help summary{cursor:pointer;font-size:12.5px;font-weight:600;color:var(--accent)}
.webhook-help p{font-size:12.5px;color:var(--muted)}
.webhook-event-pick{display:grid;gap:6px}
.webhook-event-pick code{font-size:11px;color:var(--muted)}

/* "Pilih Template": the content templates saved for this document type
   (app.js renderSavedTemplateStrip), above the design styles. */
.saved-tpl-strip{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 12px;padding:10px 12px;border:1px dashed var(--line);border-radius:10px;background:var(--paper);font-size:13px;color:var(--ink)}
.saved-tpl-strip > i{color:var(--accent)}
.saved-tpl-strip > span{flex:1 1 220px;min-width:0;line-height:1.5}

/* Design templates from the Document Editor, on a generator page
   (app.js renderDesignTemplates): in the certificate template card's
   "Template Desain" tab and in the picker opened from "Pilih Template". */
.design-tpl-note{margin:0 0 10px;font-size:12.5px;line-height:1.55;color:var(--muted)}
.design-tpl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:10px}
.design-tpl-card{display:flex;flex-direction:column;gap:4px;padding:8px;border:1px solid var(--line);border-radius:10px;background:var(--card);color:var(--ink);text-align:left;cursor:pointer;font:inherit;transition:border-color .15s,box-shadow .15s}
.design-tpl-card:hover,.design-tpl-card:focus-visible{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft, rgba(29,78,216,.15));outline:none}
.design-tpl-card:disabled{opacity:.6;cursor:wait}
.design-tpl-card.is-busy{border-color:var(--accent)}
.design-tpl-thumb{display:grid;place-items:center;aspect-ratio:297/210;border-radius:6px;background:var(--paper);color:var(--muted);font-size:20px;overflow:hidden}
.design-tpl-thumb img{width:100%;height:100%;object-fit:contain;background:#fff}
.design-tpl-thumb img[hidden]{display:none}
.design-tpl-thumb.has-img i{display:none}
.design-tpl-name{font-size:12.5px;font-weight:700;line-height:1.3;overflow-wrap:anywhere}
.design-tpl-meta{font-size:11px;color:var(--muted);display:flex;gap:4px;align-items:center}
.design-tpl-picker{text-align:left}

/* Kasir's first-run card (kasir.html #activationGate): one centred block. */
.card.kasir-gate{display:flex;flex-direction:column;align-items:center;text-align:center;gap:12px;padding:44px 24px}
.kasir-gate-icon{width:56px;height:56px;border-radius:16px;display:grid;place-items:center;background:var(--accent-soft);color:var(--accent);font-size:24px}
.card h2.kasir-gate-title{display:block;margin:4px 0 0;font-size:21px;text-transform:none;letter-spacing:0;color:var(--ink);font-weight:800}
.kasir-gate-text{margin:0;max-width:520px;color:var(--muted);font-size:13.5px;line-height:1.6}
.kasir-gate-points{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin:4px 0 6px}
.kasir-gate-points > span{display:inline-flex;align-items:center;gap:7px;padding:7px 12px;border-radius:999px;border:1px solid var(--line);background:var(--paper);font-size:12.5px;font-weight:600;color:var(--ink)}
.kasir-gate-points i{color:var(--accent);font-size:12px}

/* ---- Dashboard: find a document, the business summary, the chart ---------
   (dashboard.html). The search sits in the welcome, full width under it;
   four tiles and a six-month chart replace the plan/usage/history cards. */
.sr-only{position:absolute !important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.dash-plan{display:inline-flex;align-items:center;gap:5px;margin-left:6px;padding:3px 9px;border-radius:999px;background:rgba(201,162,39,.18);color:#f3d27a;font-size:10.5px;letter-spacing:.06em}
.dash-plan i{color:#f3d27a}
.dash-find-wrap{position:relative;z-index:3;flex-basis:100%;display:flex;flex-direction:column;gap:10px}
.dash-find{position:relative;display:flex;align-items:center}
.dash-find > i{position:absolute;left:16px;color:#94a3b8;font-size:15px;pointer-events:none}
.dash-find input{width:100%;padding:14px 46px 14px 44px;border-radius:14px;border:1px solid rgba(255,255,255,.14);background:rgba(255,255,255,.96);color:#0f172a;font:inherit;font-size:14.5px;box-shadow:0 10px 30px rgba(2,6,23,.25)}
.dash-find input::placeholder{color:#64748b}
.dash-find input:focus{outline:none;border-color:#93b4ff;box-shadow:0 0 0 4px rgba(59,99,224,.35),0 10px 30px rgba(2,6,23,.25)}
.dash-find-key{position:absolute;right:14px;padding:2px 8px;border-radius:6px;border:1px solid #cbd5e1;background:#f1f5f9;color:#475569;font:600 11px/1.4 inherit}
.dash-find input:focus ~ .dash-find-key{display:none}
.dash-find-list{position:absolute;left:0;right:0;top:calc(100% + 6px);background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow-lg);padding:6px;max-height:360px;overflow:auto}
.dash-find-item{display:flex;align-items:center;gap:12px;padding:9px 10px;border-radius:10px;color:var(--ink)}
.dash-find-item.is-active,.dash-find-item:hover{background:var(--accent-soft)}
.dfi-icon{width:34px;height:34px;flex:none;border-radius:9px;display:grid;place-items:center;background:var(--accent-soft);color:var(--accent);font-size:14px}
.dfi-text{display:flex;flex-direction:column;min-width:0;flex:1}
.dfi-text b{font-size:13.5px}
.dfi-text small{font-size:11.5px;color:var(--muted)}
.dfi-go{color:var(--faint);font-size:12px}
.dash-find-item.is-active .dfi-go{color:var(--accent)}
.dash-find-empty{padding:14px;color:var(--muted);font-size:13px;text-align:center}
.dash-quick{display:flex;flex-wrap:wrap;align-items:center;gap:7px}
.dash-quick-label{font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#aab2cc;margin-right:2px}
.dash-hero .dash-quick-chip{display:inline-flex;align-items:center;gap:7px;padding:7px 12px;border-radius:999px;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.14);color:#e2e8f0;font-size:12.5px;font-weight:600;transition:.15s}
.dash-hero .dash-quick-chip:hover{background:rgba(255,255,255,.16);color:#fff}
.dash-quick-chip i{color:#93b4ff;font-size:11.5px}

.dash-stats{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);gap:16px;align-items:stretch}
.dash-tiles{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.dash-tiles.is-single{grid-template-columns:1fr}
.dash-stats:has(.dash-tiles.is-single){grid-template-columns:1fr}
a.stat-card.dash-tile{color:inherit;transition:border-color .15s,transform .15s}
a.stat-card.dash-tile:hover{border-color:var(--accent);transform:translateY(-1px)}
.dash-tile .stat-value small{font-size:12px;font-weight:600;color:var(--muted)}
.stat-icon.billed{background:#e8faf0;color:#047857}
.stat-icon.unpaid{background:#fff4e5;color:#b45309}
.stat-icon.overdue{background:#fdecec;color:#b91c1c}
.stat-icon.ontime{background:#e8faf0;color:#047857}
.stat-card.dash-tile.is-alert{border-color:color-mix(in srgb,#dc2626 35%,var(--line))}
.stat-card.dash-tile.is-alert .stat-value{color:#b91c1c}
.dash-chart{margin:0;padding:18px 20px 14px;display:flex;flex-direction:column;--dc-bar:#1d4ed8}
.dash-chart-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px}
.dash-chart-head h2{margin:0}
.dash-chart-total{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
.dc-plot{flex:1;min-height:170px;display:grid;grid-template-columns:repeat(6,1fr);gap:10px;align-items:stretch;padding-top:26px}
.dc-col{display:flex;flex-direction:column;align-items:center;gap:6px;height:100%;min-width:0}
.dc-track{position:relative;flex:1;width:100%;display:flex;align-items:flex-end;justify-content:center;border-bottom:1px solid var(--line);outline:none;cursor:default}
.dc-track:focus-visible{box-shadow:0 0 0 2px var(--accent)}
.dc-bar{width:min(34px,70%);background:var(--dc-bar);border-radius:4px 4px 0 0;transition:opacity .15s}
.dc-bar.is-zero{height:2px !important;background:var(--line)}
.dc-track:hover .dc-bar,.dc-track:focus .dc-bar{opacity:.85}
.dc-value{position:absolute;left:50%;transform:translateX(-50%);font-size:11px;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums}
.dc-track[data-tip]:hover::after,.dc-track[data-tip]:focus::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 4px);left:50%;transform:translateX(-50%);white-space:nowrap;padding:5px 9px;border-radius:7px;background:var(--ink);color:var(--card);font-size:11.5px;font-weight:600;z-index:2;pointer-events:none}
.dc-label{font-size:11px;color:var(--muted);white-space:nowrap}
.dc-label.is-now{color:var(--ink);font-weight:700}
.dash-chart-more{align-self:flex-end;margin-top:10px;font-size:12.5px;font-weight:600;color:var(--accent)}
html[data-theme="dark"] .dash-chart{--dc-bar:#3b63e0}
html[data-theme="dark"] .dash-find input{background:var(--card);color:var(--ink);border-color:var(--line)}
html[data-theme="dark"] .dash-find-key{background:var(--paper);border-color:var(--line);color:var(--muted)}
@media(max-width:900px){
  .dash-stats{grid-template-columns:1fr}
}
/* The welcome on a phone: the lead line and the progress hint go, the
   buttons share one row, so the search and the summary are in sight. */
@media(max-width:640px){
  .dash-hero{margin-top:16px;padding:20px 18px;gap:14px}
  .dash-hero h1{font-size:21px;margin-bottom:4px}
  .dash-hero-lead{display:none}
  .dash-hero-inner,.dash-find-wrap{width:100%;max-width:none;align-self:stretch;min-width:0}
  .dash-quick-label{white-space:nowrap}
  .dash-hero-actions{width:100%;display:grid;grid-template-columns:1fr auto auto;gap:8px}
  .dash-hero-actions .btn{padding:10px 12px;font-size:13px;justify-content:center}
  .dash-hero-actions .btn-ghost-light span{display:none}
  .dash-find input{padding:12px 14px 12px 40px;font-size:14px}
  .dash-find-key{display:none}
  .dash-quick{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;padding-bottom:2px}
  .dash-quick::-webkit-scrollbar{display:none}
  .dash-quick-chip{flex:none}
  .dash-tiles{gap:10px}
  .dash-tiles .stat-card{padding:14px;gap:10px}
  .dash-tiles .stat-icon{width:34px;height:34px;font-size:14px}
}
/* The welcome's glow as background layers rather than clipped pseudo
   circles, so it no longer needs overflow:hidden — which cut the search
   results off at its edge. */
.dash-hero{overflow:visible;background:
  radial-gradient(circle at 96% -10%, rgba(60,99,224,.38), transparent 34%),
  radial-gradient(circle at -4% 112%, rgba(201,162,39,.2), transparent 30%),
  linear-gradient(155deg,var(--navy) 0%,var(--navy-2) 65%,#1b2140 100%)}
.dash-hero:before,.dash-hero:after{display:none}

/* ---- Generator pages (app.js): the locale card's summary, the phone's
   preview button, the empty-profile hint. */
.card-summary{margin-left:auto;font-size:11.5px;font-weight:600;text-transform:none;letter-spacing:0;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.card:not(.collapsed) > h2 .card-summary{display:none}
.card-summary + .card-chevron{margin-left:8px}
.preview-jump{display:none}
@media(max-width:900px){
  .preview-jump{display:inline-flex;align-items:center;gap:8px;position:fixed;left:50%;bottom:16px;transform:translateX(-50%);z-index:99990;padding:11px 18px;border-radius:999px;border:none;background:var(--navy);color:#fff;font:inherit;font-size:13.5px;font-weight:700;box-shadow:0 10px 26px rgba(2,6,23,.3);cursor:pointer;transition:transform .2s ease,opacity .2s ease}
  .preview-jump i{color:#93b4ff}
  .preview-jump.is-away{transform:translate(-50%,90px);opacity:0;pointer-events:none}
  .gen-layout{padding-bottom:84px}
}
@media(prefers-reduced-motion:reduce){.preview-jump{transition:none}}
.profile-hint{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:12px;border:1px solid color-mix(in srgb,var(--accent) 30%,var(--line));background:var(--accent-soft);font-size:12.5px;color:var(--ink);line-height:1.45}
.profile-hint > i{color:var(--accent)}
.profile-hint > span{flex:1;min-width:0}
.profile-hint .btn{flex:none}
.profile-hint-close{flex:none;border:none;background:none;color:var(--muted);font-size:18px;line-height:1;cursor:pointer;padding:2px 4px}

/* ---- Riwayat (history.html): filters on one line, a summary row, the
   categories on one scrolling line, sortable headings, status pills. */
.history-toolbar .field input[type="text"].thb-date-text{width:150px}
.history-subbar{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-top:12px}
.history-summary{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0;flex:1 1 0}
/* The tools stay together on the summary's line: a long summary wraps its
   own pills, and on a narrower laptop the tools show their icons only
   (each keeps its name as a tooltip). */
.history-tools{display:flex;align-items:center;gap:8px;flex-wrap:nowrap;flex:none;margin-left:auto}
.history-tools .btn{white-space:nowrap}
@media(min-width:641px) and (max-width:1280px){
  .history-tools .ht-label{display:none}
  .history-tools .btn{padding-inline:10px}
}
.sum-pill{display:inline-flex;align-items:center;gap:6px;padding:6px 11px;border-radius:999px;border:1px solid var(--line);background:var(--card);color:var(--ink);font:inherit;font-size:12.5px;font-weight:600;cursor:pointer;font-variant-numeric:tabular-nums;transition:.15s}
.sum-pill:disabled{cursor:default}
.sum-pill:not(:disabled):hover{border-color:var(--accent)}
.sum-pill.is-value i{color:var(--accent)}
.sum-pill.is-paid i{color:#15803d}
.sum-pill.is-open i{color:#b45309}
.sum-pill.is-overdue{border-color:color-mix(in srgb,#dc2626 40%,var(--line));color:#b91c1c}
.history-cat-row{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:thin;padding-bottom:4px;-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 40px),transparent);mask-image:linear-gradient(90deg,#000 calc(100% - 40px),transparent)}
.history-cat-row > *{flex:none}
.history-table th[data-sort]{padding:0}
.th-sort{display:inline-flex;align-items:center;gap:6px;width:100%;padding:12px;border:none;background:none;font:inherit;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--faint);cursor:pointer;text-align:left}
.th-sort i{font-size:10px;opacity:.55}
.th-sort:hover,.th-sort.is-on{color:var(--ink)}
.th-sort.is-on i{opacity:1;color:var(--accent)}
.status-pill{display:inline-flex;align-items:center;gap:7px;padding:5px 10px 5px 9px;border-radius:999px;border:1px solid color-mix(in srgb,var(--accent) 28%,transparent);background:var(--accent-soft);color:var(--accent);font:inherit;font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap}
.status-pill:disabled{cursor:default;opacity:.9}
.status-pill i{font-size:9px;opacity:.7}
.status-pill:not(:disabled):hover{box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 18%,transparent)}
.status-dot{width:7px;height:7px;border-radius:50%;background:var(--accent);flex:none}
.status-menu{position:fixed;z-index:1000;min-width:180px;max-height:320px;overflow:auto;padding:6px;background:var(--card);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow-lg)}
.status-menu button{display:flex;align-items:center;gap:9px;width:100%;padding:8px 10px;border:none;border-radius:8px;background:none;color:var(--ink);font:inherit;font-size:13px;font-weight:600;text-align:left;cursor:pointer}
.status-menu button:hover,.status-menu button:focus-visible{background:var(--accent-soft);outline:none}
.status-menu button i{margin-left:auto;color:var(--accent);font-size:11px}
html[data-theme="dark"] .status-pill{background:color-mix(in srgb,var(--accent) 22%,var(--card));color:color-mix(in srgb,var(--accent) 55%,#fff)}
@media(max-width:640px){
  .history-subbar{flex-direction:column;align-items:stretch}
  .history-tools{justify-content:flex-start;flex-wrap:wrap;margin-left:0}
}

/* ---- Dashboard: first steps for a new account (dashboard.html's
   onboarding card) — three steps, each ticked from the account's data. */
.onb-card{margin-bottom:20px;padding:20px 22px}
.onb-head{display:flex;align-items:flex-start;gap:16px}
.onb-intro{flex:1;min-width:0}
.onb-intro h2{margin-bottom:6px}
.onb-intro p{margin:0;font-size:13.5px;color:var(--muted);max-width:60ch}
.onb-progress{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex:none;padding-top:2px}
.onb-count{font-size:12px;font-weight:700;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.onb-bar{display:block;width:120px;height:6px;border-radius:999px;background:var(--line);overflow:hidden}
.onb-bar i{display:block;height:100%;width:0;background:var(--accent);border-radius:inherit;transition:width .4s ease}
.onb-close{flex:none;width:30px;height:30px;border:none;border-radius:8px;background:none;color:var(--faint);cursor:pointer;font-size:14px}
.onb-close:hover,.onb-close:focus-visible{background:var(--accent-soft);color:var(--ink);outline:none}
.onb-steps{list-style:none;margin:16px 0 0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.onb-step{display:flex;flex-direction:column;align-items:flex-start;gap:10px;padding:14px;border:1px solid var(--line);border-radius:12px;background:var(--card)}
.onb-step.is-current{border-color:color-mix(in srgb,var(--accent) 45%,var(--line));box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 12%,transparent)}
.onb-step.is-done{background:color-mix(in srgb,#15803d 5%,var(--card))}
.onb-mark{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:50%;border:1.5px solid var(--line);color:var(--muted);font-size:12px;font-weight:700;font-variant-numeric:tabular-nums}
.onb-step.is-current .onb-mark{border-color:var(--accent);color:var(--accent)}
.onb-step.is-done .onb-mark{border-color:#15803d;background:#15803d;color:#fff;font-size:11px}
.onb-text{display:flex;flex-direction:column;gap:3px;flex:1}
.onb-text b{font-size:14px;color:var(--ink)}
.onb-step.is-done .onb-text b{color:var(--muted)}
.onb-text small{font-size:12.5px;color:var(--muted);line-height:1.45}
.onb-step.is-done .onb-text small{color:#15803d;font-weight:600}
html[data-theme="dark"] .onb-step.is-done .onb-text small{color:#4ade80}
@media(max-width:760px){
  .onb-steps{grid-template-columns:1fr}
  .onb-step{flex-direction:row;align-items:center}
  .onb-step .btn{flex:none}
  .onb-head{flex-wrap:wrap}
  .onb-intro{flex-basis:calc(100% - 46px)}
  .onb-progress{order:3;flex-basis:100%;flex-direction:row;align-items:center;justify-content:space-between}
  .onb-bar{flex:1;width:auto;margin-left:12px}
}
@media(max-width:420px){
  .onb-step{flex-wrap:wrap}
  .onb-step .btn{margin-left:36px}
}
