/* ==========================================================================
   Invoice & Surat
   Two things live here: the working UI (history list + editor), and the
   printed document itself. The document is real on-page HTML rather than a
   generated image or a PDF library's canvas — the browser's own "Save as
   PDF" then produces the file, so what is proofread on screen is exactly
   what is sent, and there is no library to keep in sync with the layout.
   ========================================================================== */

/* ---- History list ------------------------------------------------------ */
/* One line that slides sideways, like the month tabs elsewhere in the app:
   wrapping pushed the list down a row on a phone for no gain. */
.doc-filters {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  overflow-x: auto;
  padding-bottom: 2px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.doc-filters > * {
  flex-shrink: 0;
  white-space: nowrap;
}

.doc-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* The whole row opens the preview, so it has to look like it does. */
.doc-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.doc-card:hover {
  border-color: #059669;
  box-shadow: 0 2px 10px rgba(5, 150, 105, 0.14);
}

.doc-card:focus-visible {
  outline: 2px solid #059669;
  outline-offset: 2px;
}

/* The small actions keep their own pointer and are not part of the row's
   click target. */
.doc-card-actions {
  cursor: default;
}

.doc-card-main {
  flex: 1;
  min-width: 0;
}

.doc-card-title {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}

.doc-card-name {
  font-size: 0.88rem;
  font-weight: 800;
  color: var(--ink);
}

.doc-badge {
  flex-shrink: 0;
  font-size: 0.6rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 2px 8px;
  border-radius: var(--radius-full);
}

.doc-badge--invoice { background: #E4F1FE; color: #0284C7; }
.doc-badge--lunas { background: #DCFCE7; color: #15803D; }
.doc-badge--dp { background: #FEF3C7; color: #B45309; }
/* Tombol "Tandai lunas" di kartu; hijau penuh kalau sudah lunas */
.doc-btn-lunas.is-lunas { background: #DCFCE7; border-color: #86EFAC; color: #15803D; }
.doc-filter-pisah { width: 1px; height: 22px; background: var(--border); margin: 0 2px; align-self: center; }
.doc-filter-bayar.active { background: #15803D; border-color: #15803D; }
/* Dialog tandai lunas */
.doc-lunas-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; margin: 8px 0 6px; }
.doc-lunas-field { display: flex; flex-direction: column; gap: 5px; font-size: 0.74rem; font-weight: 700; color: var(--ink-soft); min-width: 0; }
.doc-lunas-field input, .doc-lunas-uang {
  width: 100%; box-sizing: border-box; min-height: 40px; padding: 8px 11px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--ink); font-family: inherit; font-size: 0.84rem; font-weight: 600; outline: none;
}
.doc-lunas-uang { display: flex; align-items: center; gap: 6px; padding: 0 11px; }
.doc-lunas-uang span { color: var(--muted); font-size: 0.78rem; }
.doc-lunas-uang input { border: 0; background: transparent; padding: 0; min-height: 38px; flex: 1; }
.doc-lunas-field input:focus, .doc-lunas-uang:focus-within { border-color: var(--red); background: #fff; }
.doc-lunas-sisa { margin: 0 0 12px; font-size: 0.76rem; font-weight: 700; color: #B45309; }
.doc-lunas-sisa.is-pas { color: #15803D; }
@media (max-width: 600px) { .doc-lunas-grid { grid-template-columns: 1fr; } }
.doc-badge--sph     { background: #FDF1DC; color: #B45309; }
.doc-badge--brand   { background: var(--bg); color: var(--muted); }

.doc-card-sub {
  display: block;
  margin-top: 3px;
  font-size: 0.7rem;
  color: var(--muted);
}

.doc-card-total {
  flex-shrink: 0;
  text-align: right;
  font-size: 0.88rem;
  font-weight: 800;
  color: var(--ink);
  white-space: nowrap;
}

.doc-card-actions {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 4px;
}

/* ---- Editor ------------------------------------------------------------ */
.doc-editor-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px 16px;
}

@media (max-width: 720px) {
  .doc-editor-grid { grid-template-columns: 1fr; }
}

.doc-items-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}

.doc-items-table th {
  padding: 6px 8px;
  text-align: left;
  font-size: 0.64rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
}

.doc-items-table td {
  padding: 5px 4px;
  vertical-align: top;
  border-bottom: 1px solid var(--border);
}

/* Lebar kolom pindah dari atribut style di markup ke sini, supaya aturan
   layar sempit di bawah bisa mengubahnya tanpa harus melawan style sebaris
   dengan !important. */
.doc-it-jumlah { width: 74px; }
.doc-it-harga { width: 110px; }
.doc-item-foto { width: 64px; }
.doc-it-hapus { width: 36px; }

/* ---- Baris barang di layar sempit ---------------------------------------
   Lima kolom tidak muat di layar HP. Empat di antaranya berlebar tetap
   (74+110+64+36 = 284px) plus jarak antar-sel, jadi di layar 375px kolom
   Nama Barang - satu-satunya yang melar - tersisa belasan piksel saja:
   kotak isian paling penting di halaman ini justru yang paling sempit.

   Jadi di bawah 720px barisnya berhenti jadi baris tabel dan menjadi satu
   kartu: nama barang selebar layar di atas, lalu jumlah/harga/foto berjajar
   di bawahnya. Judul kolom di <thead> ikut disembunyikan (tidak ada lagi
   kolom untuk dijuduli) dan digantikan label kecil per kotak lewat
   data-label, supaya tidak ada kotak yang kehilangan namanya.

   Hanya berlaku untuk tabel barang. Daftar rekening di jendela Pengaturan
   memakai kelas .doc-items-table yang sama tapi tetap tabel biasa. */
@media (max-width: 720px) {
  .doc-items-table--barang,
  .doc-items-table--barang > tbody { display: block; }
  .doc-items-table--barang > thead { display: none; }

  .doc-items-table--barang .doc-item-row {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr auto;
    grid-template-areas:
      "nama   nama  nama"
      "jumlah harga foto";
    gap: 8px 10px;
    /* start, bukan end: tombol foto lebih tinggi dari kotak isian di
       sebelahnya, jadi kalau dasarnya yang disejajarkan, label "FOTO"
       terangkat sendirian di atas label "JUMLAH"/"HARGA". */
    align-items: start;
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
  }

  /* Tombol hapus baris dikeluarkan dari kisi dan ditempel di pojok kanan
     atas kartu. Kalau ia ikut jadi kolom kisi, kolom itu ikut menyempitkan
     baris nama di atasnya - padahal justru nama yang perlu selebar mungkin.
     Ditaruh di ATAS, bukan berdampingan dengan tombol foto di bawah: di
     sana sudah ada tanda x lain (.doc-foto-clear) untuk menghapus fotonya,
     dan dua tanda x bersebelahan dengan arti berbeda hanya membingungkan. */
  .doc-items-table--barang .doc-it-hapus {
    position: absolute;
    top: 10px;
    right: 0;
  }

  /* Bobot pemilihnya harus menyamai "... .doc-item-row > td { padding: 0 }"
     di atas - kalau tidak, padding ini kalah dan kotak namanya melebar
     sampai menyelip di bawah tombol hapus. */
  .doc-items-table--barang .doc-item-row > td.doc-it-nama { padding-right: 32px; }

  .doc-items-table--barang .doc-item-row > td {
    width: auto;
    padding: 0;
    border-bottom: none;
  }

  .doc-items-table--barang .doc-it-nama { grid-area: nama; }
  .doc-items-table--barang .doc-it-jumlah { grid-area: jumlah; }
  .doc-items-table--barang .doc-it-harga { grid-area: harga; }
  .doc-items-table--barang .doc-item-foto { grid-area: foto; }

  /* Judul kolom yang hilang dikembalikan sebagai label kecil di atas tiap
     kotak. Foto ikut diberi label: tombolnya memang bertuliskan "+ Foto"
     selagi kosong, tapi begitu terisi ia berubah jadi gambar tanpa tulisan
     apa pun. */
  .doc-items-table--barang .doc-item-row > td[data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 3px;
    font-size: 0.62rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--muted);
  }

  /* Sekarang selebar layar, jadi ada ruang untuk benar-benar membaca apa
     yang sedang diketik - nama barang di sini sering satu kalimat penuh. */
  .doc-items-table--barang .doc-f-deskripsi { min-height: 66px; }
}

.doc-item-remove {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  color: var(--muted);
  cursor: pointer;
}

.doc-item-remove:hover { background: #FDEBEC; color: var(--red); }
.doc-item-remove svg { width: 14px; height: 14px; }

/* ==========================================================================
   The printed document
   On screen it sits inside the preview modal at a fixed A4 width so the
   line breaks match the paper; when printing, everything else on the page
   is hidden and this becomes the whole sheet.
   ========================================================================== */
/* A column, so the footer decoration can be pushed to the foot of the
   page rather than trailing whatever content happens to end above it. */
.doc-paper {
  display: flex;
  flex-direction: column;
  width: 210mm;
  min-height: 297mm;
  /* Tighter at the head than the foot: the letterhead should start near
     the top of the sheet, while the bottom padding stays 16mm because the
     footer decoration cancels exactly that much to bleed off the page. */
  padding: 5mm 15mm 16mm;
  margin: 0 auto;
  background: #fff;
  color: #1a1a1a;
  font-size: 10pt;
  line-height: 1.45;
  box-sizing: border-box;
}

/* The letterhead: mark on the left, the issuing office on the right, a rule
   under both. The company address used to sit beside the customer's in the
   body, which read as if the two were parties to a negotiation rather than
   sender and recipient. */
.doc-paper-kop {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10mm;
  padding-bottom: 2.5mm;
}

.doc-paper-kop-mark {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2mm;
  flex: 0 0 auto;
}

.doc-paper-kop-info {
  flex: 1;
  min-width: 0;
  text-align: right;
  font-size: 8.5pt;
  line-height: 1.45;
  color: #444;
}

.doc-paper-kop-info strong {
  display: block;
  margin-bottom: 1mm;
  font-size: 11pt;
  color: #1a1a1a;
}

.doc-paper-kop-info p {
  margin: 0;
}

/* Two solid bars rather than one gradient: a gradient is a paint the
   canvas renderer behind the PDF cannot read back, and a rule made of
   plain blocks looks identical. */
.doc-paper-kop-rule {
  display: flex;
  height: 1.6mm;
  margin-bottom: 4.5mm;
}

.doc-paper-kop-rule span:first-child {
  flex: 0 0 38%;
  background: var(--warna-brand, #c8102e);
}

.doc-paper-kop-rule span:last-child {
  flex: 1;
  background: #1a1a1a;
}

.doc-paper-judul {
  padding-bottom: 4mm;
  text-align: center;
  font-size: 17pt;
  font-weight: 800;
  letter-spacing: 0.08em;
}

/* Label and value in two columns so the colons line up down the block. */
.doc-paper-meta {
  border-collapse: collapse;
  font-size: 9pt;
  line-height: 1.45;
}

.doc-paper-meta td {
  padding: 0 0 0.6mm;
  vertical-align: top;
}

.doc-paper-meta td:first-child {
  width: 25mm;
  color: #555;
}

/* The colon gets its own column instead of sitting inline with the value.
   Inline, only the first line of a wrapped value sits past it — every line
   after that starts flush at the cell edge, a step to the left of where the
   first line's text began. A fixed column keeps every wrapped line flush
   with the others. */
.doc-paper-meta td:nth-child(2) {
  width: 3mm;
  padding-right: 2mm;
  white-space: nowrap;
}

/* Bold, but the same size as the label beside it. A larger value sitting on
   the same line as its label rides on a different baseline and reads as
   untidy — the weight alone is enough to pick it out. */
.doc-paper-meta strong {
  font-weight: 800;
}

.doc-paper-party--nomor {
  flex: 0 0 auto;
}

.doc-paper-ident {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3mm;
  min-width: 0;
}

/* A set height rather than a cap, so the letterhead line is the same on
   every document whatever the logo file happens to measure — a capped size
   left a small source image printing small. Width follows the aspect ratio,
   and a very wide wordmark is held to max-width instead. */
.doc-paper-logo {
  display: block;
  height: 34mm;
  width: auto;
  max-width: 115mm;
  object-fit: contain;
  object-position: left center;
}

.doc-paper-brand {
  font-size: 15pt;
  font-weight: 800;
  letter-spacing: -0.01em;
}

.doc-paper-kind {
  text-align: right;
}

.doc-paper-kind strong {
  display: block;
  font-size: 22pt;
  font-weight: 800;
  letter-spacing: 0.06em;
}

.doc-paper-kind span {
  font-size: 9pt;
  color: #555;
}

.doc-paper-parties {
  display: flex;
  gap: 12mm;
  padding-bottom: 5mm;
}

.doc-paper-party {
  flex: 1;
  min-width: 0;
}


.doc-paper-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 9.5pt;
}

/* A ruled grid in the brand's colour, with the heading reversed out of a
   solid band. Every cell carries its own border rather than relying on
   collapsed shorthand, because the canvas painter behind the PDF reads
   borders one edge at a time from each element. */
.doc-paper-table thead th {
  padding: 1.8mm 2mm;
  text-align: center;
  font-size: 8.5pt;
  font-weight: 800;
  letter-spacing: 0.03em;
  color: #fff;
  background: var(--warna-brand, #c8102e);
  border: 0.6pt solid var(--warna-brand, #c8102e);
}

.doc-paper-table tbody td {
  padding: 1.8mm 2mm;
  vertical-align: middle;
  border: 0.6pt solid var(--warna-brand, #c8102e);
}

.doc-paper-num { width: 10mm; }
.doc-paper-right { text-align: right; white-space: nowrap; }

/* Jumlah adalah cacah, bukan uang — rata tengah seperti kolom No, bukan
   rata kanan seperti kolom-kolom rupiah di sebelahnya. */
.doc-paper-jumlah { text-align: center; white-space: nowrap; }

.doc-paper-table tbody td.doc-paper-num { text-align: center; }

/* The photo and its description share a cell, side by side. */
.doc-paper-item {
  display: flex;
  align-items: center;
  gap: 4mm;
}

.doc-paper-item-foto {
  flex: 0 0 auto;
  width: 16mm;
  height: 16mm;
  object-fit: contain;
}

/* The summary rows belong to the item table, so their rules continue the
   same column edges instead of approximating them. */
.doc-total-kosong {
  border: none !important;
}

.doc-total-row.is-total td {
  font-weight: 800;
  font-size: 11pt;
}

.doc-total-row.is-sisa td {
  font-weight: 800;
}

.doc-paper-foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12mm;
  padding-top: 8mm;
}

.doc-paper-pay {
  font-size: 9pt;
}

.doc-paper-pay-title {
  margin-bottom: 2.5mm;
}

.doc-paper-pay-table td:first-child {
  width: 26mm;
  color: #555;
}

.doc-paper-sign {
  text-align: center;
  font-size: 9.5pt;
}

/* Room for a real signature between "Hormat kami," and the name — and, when
   the scans have been uploaded, for the images themselves. The stamp sits
   behind the signature and a little to the left, the way one is actually
   pressed beside a signed name. */
.doc-paper-sign .doc-sign-space {
  position: relative;
  height: 16mm;
  min-width: 55mm;
}

.doc-sign-cap,
.doc-sign-ttd {
  position: absolute;
  top: 50%;
  left: 50%;
  max-height: 16mm;
  max-width: 40mm;
  width: auto;
  object-fit: contain;
}

.doc-sign-cap {
  transform: translate(-72%, -50%);
  z-index: 0;
}

.doc-sign-ttd {
  transform: translate(-38%, -50%);
  z-index: 1;
}

/* The decorative band under the footer: bled out to the physical page edge
   with negative margins matching .doc-paper's own padding, since the wave
   is meant to run to the paper's corner rather than stop at the text
   column. The wave <img> comes first in markup so it paints — on screen,
   in print, and in the canvas-based PDF export, which draws strictly in
   document order — behind the contact row that follows it, without either
   element needing z-index (which the PDF painter does not read). */
/* Sized by the contact lines it carries, with the wave pinned behind them.
   It used to be the other way round — a fixed-height box with the contacts
   positioned inside it — and a block taller than the box simply had its top
   clipped away by `overflow: hidden`. */
.doc-paper-footer-deco {
  position: relative;
  /* The negative sides and bottom cancel .doc-paper padding so the wave
     bleeds to the paper edge. The top margin is a fixed measure, not auto:
     the page-number line above it takes the free space instead, and the
     paginator has to be able to read this height as a number. */
  margin: 6mm -15mm -16mm;
  padding: 3mm 15mm 4mm;
  flex: 0 0 auto;
  min-height: 24mm;
  overflow: hidden;
}

/* fill, not cover: the SVG already carries preserveAspectRatio="none", so
   it stretches itself to the box correctly and nothing needs cropping.
   Pinned to the foot of the block, and first in the markup, so the canvas
   painter behind the PDF — which draws in document order and reads no
   z-index — lays it down before the contacts that sit over it. */
.doc-paper-wave {
  position: absolute;
  left: 0;
  bottom: 0;
  display: block;
  width: 100%;
  height: 24mm;
  object-fit: fill;
}

.doc-paper-contact {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2.5mm;
}

.doc-contact-row {
  display: flex;
  align-items: center;
  gap: 3mm;
  font-size: 8.5pt;
}

.doc-contact-icon {
  display: block;
  width: 7mm;
  height: 7mm;
}

/* Stempel LUNAS (invoice yang pelunasannya sudah tercatat di Data PO) */
/* Stempel LUNAS di kaki dokumen (kolom kiri, tempat blok rekening yang
   tidak tampil lagi saat lunas) - tipis dan tidak mencolok. */
.doc-paper-stempel {
  display: inline-block; margin: 2mm 0 0 2mm; transform: rotate(-8deg);
  padding: 1.2mm 4mm; border: 0.45mm solid rgba(200, 30, 43, .45); border-radius: 2mm;
  color: rgba(200, 30, 43, .5); font-size: 14pt; font-weight: 700; letter-spacing: .14em; line-height: 1.1;
}
.doc-status-lunas { color: #C81E2B; }
.doc-total-row.is-lunas td { color: #C81E2B; }
.doc-paper-lunas-ket { padding-top: 7mm; font-size: 9.5pt; font-weight: 600; color: #1a1a1a; }
/* Kepala pratinjau satu baris: judul | tab versi | zoom - hemat tinggi supaya
   lembarnya dapat ruang sebesar mungkin. Di layar sempit melipat. */
.doc-preview-kepala { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; flex-shrink: 0; margin-bottom: 4px; }
.doc-preview-kepala .doc-preview-judul { margin: 0; flex: 1 1 220px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-preview-kepala .doc-zoom-bar { padding: 0; flex: 0 0 auto; }
.doc-versi-tab { display: flex; justify-content: center; gap: 6px; flex-wrap: wrap; flex: 0 0 auto; }
.doc-versi-tab .month-tab { padding: 6px 14px; font-size: 0.8rem; }
@media (max-width: 760px) { .doc-preview-kepala .doc-preview-judul { flex-basis: 100%; } }
/* Metode pembayaran (opsional) - di atas catatan, sebelum kaki dokumen. */
.doc-paper-metode { padding-top: 7mm; font-size: 9pt; color: #333; }
.doc-paper-metode-judul { font-weight: 800; color: #111; margin-bottom: 1.5mm; }
.doc-paper-metode ol { margin: 0; padding-left: 5mm; line-height: 1.5; }
.doc-paper-metode p { margin: 0; line-height: 1.5; }
/* Ceklis metode pembayaran di editor */
.doc-cek-metode { display: flex; align-items: center; gap: 8px; font-size: 0.82rem; color: var(--ink); cursor: pointer; padding: 6px 0 2px; }
.doc-cek-metode input { width: 16px; height: 16px; accent-color: var(--red); }
.doc-cek-metode-ket { margin: 2px 0 0 24px; font-size: 0.74rem; color: var(--muted); line-height: 1.5; white-space: pre-line; }

.doc-paper-note {
  padding-top: 8mm;
  font-size: 9pt;
  color: #333;
  white-space: pre-line;
}

/* Preview modal shows the sheet at whatever zoom fits the screen. */
.doc-preview-scroll {
  overflow: auto;
  background: #55585F;
  padding: 12px;
  flex: 1;
  min-height: 0;
}

/* The sheet keeps its true A4 width here and is scaled to fit by script,
   which can measure the screen. A fixed scale used to live in a media
   query instead: it shrank every phone to the same 0.45 whatever the
   width, and the flex container squeezed the sheet below A4 first, so the
   preview came out both cramped and smaller than it needed to be. */
.doc-preview-scroll .doc-paper {
  flex-shrink: 0;
  margin: 0 auto;
}

/* ---- Printing ----------------------------------------------------------
   Everything except the sheet is taken out of the flow, and the sheet
   loses its screen framing so it starts at the paper's own margin. */
@media print {
  @page { size: A4; margin: 0; }

  body > *:not(.doc-print-root) { display: none !important; }

  .doc-print-root,
  .doc-print-root * { visibility: visible; }

  .doc-print-root {
    position: static !important;
    display: block !important;
    background: #fff;
    padding: 0;
    inset: auto;
  }

  .doc-print-root .doc-paper {
    width: 100%;
    height: 297mm;
    min-height: 0;
    margin: 0;
    transform: none !important;
    box-shadow: none;
    /* Each sheet is its own printed page. `avoid` inside keeps the printer
       from finding its own break part way down one. */
    break-after: page;
    page-break-after: always;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  /* A trailing break would print a blank final page. */
  .doc-print-root .doc-paper:last-child {
    break-after: auto;
    page-break-after: auto;
  }
}

/* ---- Logo picker inside Pengaturan Umum --------------------------------- */

.doc-logo-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 8px;
}

.doc-logo-box {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 84px;
  height: 64px;
  padding: 6px;
  border: 1px dashed var(--border);
  border-radius: 10px;
  background: var(--surface-2, #fafafa);
  overflow: hidden;
}

.doc-logo-box img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.doc-logo-box span {
  font-size: 0.66rem;
  color: var(--muted);
  text-align: center;
  line-height: 1.3;
}

.doc-logo-actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.doc-logo-buttons {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* The shared button rules carry a flex-grow meant for full-width action
   bars; here the pair should hug its own label instead. */
.doc-logo-buttons button {
  flex: 0 0 auto;
  padding: 6px 12px;
  font-size: 0.74rem;
}

/* .impor-export-btn sets display:flex, which outranks the `hidden`
   attribute's UA display:none — without this the Hapus button shows even
   when there is nothing to delete. */
.doc-logo-buttons button[hidden],
.doc-foto-clear[hidden] {
  display: none;
}

.doc-logo-hint {
  font-size: 0.68rem;
  color: var(--muted);
  line-height: 1.4;
}

/* ---- Item photos -------------------------------------------------------- */

/* In the editor: the thumbnail is the button. */
.doc-item-foto {
  position: relative;
  vertical-align: top;
}

.doc-foto-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  padding: 0;
  overflow: hidden;
  border: 1px dashed var(--border);
  border-radius: 8px;
  background: var(--surface-2, #fafafa);
  color: var(--muted);
  font-size: 0.62rem;
  font-weight: 700;
  cursor: pointer;
}

.doc-foto-btn:hover {
  border-style: solid;
  border-color: #059669;
  color: #059669;
}

.doc-foto-btn img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.doc-foto-clear {
  position: absolute;
  top: -4px;
  left: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: #DC2626;
  color: #fff;
  cursor: pointer;
}

.doc-foto-clear svg {
  width: 11px;
  height: 11px;
}

/* The three fields already decided before the form opened: still editable,
   but visibly not part of the typing path. */
.doc-editor-preset {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-2, #fafafa);
}

/* What was ordered, on the row itself — enough to recognise a past document
   without opening it. One line: the row is a list entry, not a summary. */
.doc-card-items {
  display: block;
  margin-top: 3px;
  overflow: hidden;
  color: var(--muted);
  font-size: 0.74rem;
  line-height: 1.4;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- Preview zoom ------------------------------------------------------- */

.doc-zoom-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 6px 0 8px;
  flex-shrink: 0;
}

.doc-zoom-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  height: 30px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-full, 999px);
  background: var(--card);
  color: var(--text);
  font-size: 0.9rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

.doc-zoom-btn:hover {
  border-color: #059669;
  color: #059669;
}

.doc-zoom-btn--wide {
  font-size: 0.72rem;
}

.doc-zoom-level {
  min-width: 52px;
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 700;
  text-align: center;
}

/* Sit between Tutup and the print button; green because they are the
   friendly path, not the committing one. */
.doc-share-btn,
.doc-share-teks-btn {
  border-color: #059669 !important;
  background: #ECFDF5 !important;
  color: #059669 !important;
}

/* .impor-field is a flex container, and an author display rule outranks the
   `hidden` attribute's UA display:none — without this the DP percentage box
   stays on screen after choosing Lunas. */
.impor-field[hidden] {
  display: none;
}

/* Panning stays with the browser, pinching does not: the page's own pinch
   would zoom the whole app, chrome and all, instead of the sheet. */
.doc-preview-scroll {
  touch-action: pan-x pan-y;
}

/* Four actions rather than two, so they wrap onto a second row on a phone
   instead of squeezing every label into a thumbnail. */
.doc-preview-actions {
  flex-wrap: wrap;
}

/* Five actions now. The basis is set so a phone gets three across and
   then two, rather than three rows of buttons eating into the sheet. */
.doc-preview-actions .confirm-modal-btn {
  flex: 1 1 88px;
  padding-left: 8px;
  padding-right: 8px;
  white-space: nowrap;
}

.doc-preview-actions .confirm-modal-btn:disabled {
  opacity: 0.6;
  cursor: progress;
}

/* ---- SPH wording -------------------------------------------------------- */

/* A quotation is a letter, so it opens and closes like one. An invoice is a
   demand for payment and needs neither. */
.doc-paper-salam {
  padding-bottom: 3.5mm;
  font-size: 9.5pt;
}

.doc-paper-salam p {
  margin: 0;
}

/* Left aligned rather than justified: the canvas painter behind the PDF
   redraws each line with ordinary word spacing, so a justified line would
   stretch on screen and fall short of the margin in the file. */
.doc-paper-penutup {
  padding-top: 5mm;
  font-size: 9.5pt;
}

/* ---- Pages -------------------------------------------------------------- */

/* The stack of A4 sheets. Scaled as one in the preview, so zooming does not
   leave the first page resized and the rest at full size. */
.doc-lembar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8mm;
  /* Sized to the sheets it holds, not to the window. As a plain block it
     took the container width and the fit-to-screen maths concluded an A4
     page already fitted a phone. */
  width: max-content;
  /* Centres the stack when it is shown at full size; the script centres it
     itself once a scale is applied. */
  margin: 0 auto;
}

/* Each page is exactly A4 — a fixed height, not a minimum. The paginator
   decides what fits, so a sheet that grew past 297mm would mean it got its
   sums wrong, and silently stretching would hide that. */
.doc-lembar .doc-paper,
.doc-print-root .doc-paper {
  height: 297mm;
  min-height: 0;
}

/* Continuation pages say what they continue, since the letterhead alone does
   not distinguish page two from a second document. */
.doc-paper-lanjutan {
  padding-bottom: 3.5mm;
  font-size: 9pt;
  color: #555;
}

/* Pushed to the foot of the page, carrying the decoration down with it. */
.doc-paper-nomor-halaman {
  margin-top: auto;
  padding-top: 4mm;
  text-align: right;
  font-size: 8pt;
  color: #666;
}

.doc-paper-nomor-halaman:empty {
  padding-top: 0;
}

/* ==========================================================================
   Pemilih barang dari Database Barang (tombol "+ Dari Database" di editor
   dokumen) — daftar hasil pencarian yang tinggal diklik untuk jadi satu
   baris Barang. Ringkas saja: foto kecil, nama + varian, lalu harga
   Partner-nya di kanan.
   ========================================================================== */
/* ---- Editor invoice/SPH di PC: bukan selebar layar, ~3/4 layar dan
   tetap di tengah; di HP (di bawah 900px) tetap penuh layar. ---- */
@media (min-width: 900px) {
  .confirm-overlay--fullscreen.doc-editor-overlay { padding: 24px; }
  .confirm-modal--fullscreen.doc-editor-modal {
    width: 76vw;
    max-width: 1120px;
    height: calc(100vh - 48px);
    height: calc(100dvh - 48px);
    max-height: calc(100vh - 48px);
    max-height: calc(100dvh - 48px);
    border-radius: var(--radius-lg);
    box-shadow: 0 24px 60px rgba(15, 23, 42, .28);
  }
}
/* Tombol kecil "+ Dari Data Customer" di sebelah label Nama Penerima. */
.doc-label-aksi { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.doc-pick-customer {
  padding: 3px 10px; border: 1px solid #17803D; border-radius: 999px; background: #F0FDF4;
  color: #17803D; font-family: inherit; font-size: 0.7rem; font-weight: 800; cursor: pointer; text-transform: none; letter-spacing: 0;
}
.doc-pick-customer:hover { background: #17803D; color: #fff; }

.doc-barang-list {
  max-height: 46vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 6px;
  background: var(--bg);
}

.doc-barang-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--card);
  text-align: left;
  cursor: pointer;
  font: inherit;
}

.doc-barang-item:hover { border-color: var(--red); }

/* Sudah dimasukkan ke tabel Barang — pemilihnya sengaja tetap terbuka
   supaya beberapa barang bisa dipilih sekaligus, jadi butuh penanda mana
   saja yang sudah masuk. */
.doc-barang-item.added {
  border-color: #17803D;
  background: #F0FDF4;
}

.doc-barang-foto {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--bg);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.doc-barang-foto img { width: 100%; height: 100%; object-fit: cover; }

.doc-barang-teks {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.doc-barang-teks strong {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.doc-barang-teks small { font-size: 0.68rem; color: var(--muted); }

/* Harga Partner — angka yang sama dengan kolom "Partner" di kartu Database
   Barang. Dilabeli supaya jelas harga mana yang dipakai mengisi barisnya
   (bukan harga modal, bukan Tokopedia/Shopee). */
.doc-barang-harga {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
  font-size: 0.8rem;
  font-weight: 800;
  color: var(--ink);
}

.doc-barang-harga small {
  font-size: 0.58rem;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.doc-barang-harga em { font-style: normal; font-weight: 600; color: var(--muted); font-size: 0.7rem; }
