/* ========== Admin order sheets (주문서, design Rev 8, Rev 11 grid editor) ==========
   Loaded after base.css, admin.css, admin-products.css (reused: pl-, pt-, pa-, pe-head/pe-live/pe-spinner/pe-file-input).
   Prefix op-. Phone-first (K26). The editor is one spreadsheet-like grid on the phone and the PC (Rev 11 §2.5): sticky
   사진 + 색상 on the left, horizontal scroll, a sticky column header; widths are CSS variables per breakpoint.
   Text colours use the text-safe tokens only (AdminCssContrastTests): --kk-text, --kk-text-secondary, --kk-*-text.
   Every input is >= 16px (iOS Safari zooms into smaller fields) and every control >= 44px tall. */

/* ---------- Shared ---------- */
.op-muted-text { color: var(--kk-text-secondary); }

.op-edit .form-control,
.op-edit .form-select,
.op-picker .form-control,
.op-picker .form-select,
.op-filters .form-control {
  font-size: 16px;
  min-height: var(--kk-touch);
}
.op-edit .btn,
.op-picker .btn,
.op-cards .btn,
.op-table .btn { min-height: var(--kk-touch); display: inline-flex; align-items: center; justify-content: center; }
.op-edit .btn-sm,
.op-picker .btn-sm { min-height: var(--kk-touch); }

.op-icon-btn {
  min-width: var(--kk-touch);
  min-height: var(--kk-touch);
  padding: 0;
  font-size: 1.05rem;
  line-height: 1;
  border: 1px solid var(--kk-line-strong);
  color: var(--kk-text);
}
.op-icon-btn:focus-visible,
.op-fit button:focus-visible,
.op-pick-row:focus-visible,
.op-card-link:focus-visible,
.op-msg-close:focus-visible {
  outline: 3px solid var(--kk-focus-ring);
  outline-offset: 2px;
}

.op-print,
.op-private {
  font-size: 0.72rem;
  font-weight: 600;
  border-radius: 4px;
  padding: 0.05rem 0.35rem;
  margin-left: 0.25rem;
}
.op-print { background: var(--kk-info-bg); color: var(--kk-info-text); }
.op-private { background: #eef2f0; color: #52665c; }

.op-field { min-width: 0; }
.op-field-error {
  margin-top: 0.25rem;
  font-size: 0.82rem;
  color: var(--kk-danger-text);
}
.op-edit .form-control.is-invalid { border-color: var(--kk-danger); }

/* Status badges (작성 중 · 확정 · 완료 · 취소) */
.op-status-draft { background: var(--kk-warn-bg); color: var(--kk-warn-text); }
.op-status-confirmed { background: var(--kk-info-bg); color: var(--kk-info-text); }
.op-status-completed { background: var(--kk-success-bg); color: var(--kk-success-text); }
.op-status-cancelled { background: #e7e5e4; color: #57534e; }

/* ---------- Dashboard tile ---------- */
.op-stat-card { grid-column: 1 / -1; }
@media (min-width: 768px) {
  .stat-grid.op-stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .op-stat-card { grid-column: auto; }
}

/* ---------- List ---------- */
.op-search-row { display: flex; gap: 0.5rem; }
.op-search-row .form-control { flex: 1 1 auto; min-width: 0; }
.op-search-row .btn { flex: 0 0 auto; min-height: var(--kk-touch); white-space: nowrap; }
/* Six chips do not fit a phone: they wrap (a nowrap scroller would widen the admin grid track on narrow screens). */
.op-chips { margin-bottom: 0; flex-wrap: wrap; overflow-x: visible; }

.op-cards {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.op-card {
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
  background: var(--kk-surface);
  border: 1px solid var(--kk-line);
  border-radius: var(--kk-radius);
  box-shadow: var(--kk-shadow);
  padding: 0.6rem;
}
.op-card-link {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  color: var(--kk-text);
  text-decoration: none;
  border-radius: var(--kk-radius-sm);
  padding: 0.25rem;
}
.op-card-link:hover { opacity: 1; }
.op-card-link:hover .pl-name { color: var(--kk-accent-text); }
.op-card-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.op-card-meta { font-size: 0.82rem; color: var(--kk-text-secondary); overflow-wrap: anywhere; }
/* 「주문번호 · 주문일 · 고객」: the order number and the date never break inside (2026-10-<br>05); only the customer may. */
.op-card-meta .op-nowrap { white-space: nowrap; }
.op-card-xlsx { flex: 0 0 auto; align-self: center; }

.op-table .op-xlsx-cell { position: relative; z-index: 2; text-align: right; }
.op-table .op-list-customer { max-width: 12rem; overflow-wrap: anywhere; }

/* ---------- Editor ---------- */
.op-edit { padding-bottom: 0.5rem; }
.op-head { align-items: center; }
.op-orderno {
  font-variant-numeric: tabular-nums;
  font-weight: 650;
  color: var(--kk-text-secondary);
  letter-spacing: 0.01em;
}
.op-head-actions { margin-left: auto; display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; }

.op-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}
.op-banner-actions { display: inline-flex; flex-wrap: wrap; gap: 0.5rem; }
.op-fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }

/* While an editor field is focused, the browser keeps it clear of the sticky top bar + column header and the bar. The bar's
   real height (--op-bar-h, admin-orders.js; it grows with a notice) + 8px; 7rem until the script has measured it. */
html:has(.op-edit) {
  scroll-padding-top: calc(var(--op-sticky-top, 0px) + 52px);
  scroll-padding-bottom: calc(var(--op-bar-h, calc(7rem - 8px)) + 8px);
}

/* ---------- Settings card (title + order settings, Rev 11 §2.12) ---------- */
.op-settings { padding: 1rem; }
/* 주문 고객 · 주문일 above the title (2026-10-07): one row from a 375px phone (the customer takes the rest), stacked
   only on narrower screens. */
.op-head-fields {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 8.5rem;
  gap: 0.25rem 0.75rem;
  margin-bottom: 0.75rem;
}
.op-head-fields .form-label { font-weight: 650; }
.op-head-help { grid-column: 1 / -1; margin-top: 0; }
.op-date-input { font-variant-numeric: tabular-nums; }
@media (max-width: 339.98px) {
  .op-head-fields { grid-template-columns: minmax(0, 1fr); }
}
@media (min-width: 768px) {
  .op-head-fields { grid-template-columns: minmax(0, 24rem) 10rem; }
}
.op-title-labelrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.25rem 0.5rem;
  margin-bottom: 0.25rem;
}
.op-title-labelrow .form-label { margin-bottom: 0; }
.op-title-auto { flex: 0 0 auto; }
.op-title-field .form-label { font-weight: 650; }
.op-title-field .form-control { font-size: 1.05rem; font-weight: 650; }
.op-settings-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  min-height: var(--kk-touch);
  margin-top: 0.75rem;
  padding: 0.35rem 0.65rem;
  border: 1px solid var(--kk-line-strong);
  border-radius: var(--kk-radius-sm);
  background: var(--kk-bg);
  color: var(--kk-text);
  text-align: left;
}
.op-settings-toggle:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: 2px; }
.op-settings-caption { font-weight: 700; flex: 0 0 auto; }
.op-settings-summary { flex: 1 1 auto; min-width: 0; font-size: 0.8rem; color: var(--kk-text-secondary); overflow-wrap: anywhere; }
.op-settings-chevron { flex: 0 0 auto; color: var(--kk-text-secondary); }
/* Collapsible on the phone AND the PC (a PC opens a new order's settings; a saved order keeps the grid near the top). */
.op-settings-body { display: none; margin-top: 0.85rem; }
.op-settings.is-open .op-settings-body { display: block; }
.op-settings-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.75rem; }
@media (min-width: 576px) {
  .op-settings-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.op-switches { border: 0; padding: 0; margin: 0.85rem 0 0; min-width: 0; }
.op-switches legend { float: none; font-size: 0.875rem; margin-bottom: 0.15rem; }
/* Each switch is one <label> around the box and its text: the whole 44px-tall row takes the tap (CLAUDE.md §4). */
.op-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: var(--kk-touch);
  min-width: var(--kk-touch);
  margin: 0 1.25rem 0 0;
  padding-right: 0.25rem;
  cursor: pointer;
}
.op-switch .form-check-input { width: 1.35rem; height: 1.35rem; margin: 0; flex: 0 0 auto; cursor: pointer; }
.op-switch-text { line-height: 1.3; }
.op-switch-note { font-size: 0.8rem; color: var(--kk-text-secondary); margin: 0 0 0.25rem; }
.op-settings-body > * + * { margin-top: 0.85rem; }
.op-settings-body > .op-switches { margin-top: 0.5rem; }
.op-legacy {
  margin-top: 0.85rem;
  padding: 0.6rem 0.75rem;
  border: 1px dashed var(--kk-line-strong);
  border-radius: var(--kk-radius-sm);
  background: var(--kk-bg);
  font-size: 0.85rem;
}
.op-legacy-title { margin: 0 0 0.35rem; font-weight: 650; }
.op-legacy-list { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.2rem 0.75rem; margin: 0; }
.op-legacy-list dt { font-weight: 600; color: var(--kk-text-secondary); }
.op-legacy-list dd { margin: 0; overflow-wrap: anywhere; }

/* ---------- The grid (Rev 11 §2.5) ----------
   One horizontal scroller; every row (item, group header, 「+ 상품」, 합계, the header strip) is its own CSS grid with the
   shared template --op-template (Razor builds it from the width variables below). ☐ · 사진 · 색상 are sticky on the left
   with opaque backgrounds. Phones (< 768px): the grid is full-bleed (it cancels the 1.1rem page padding) and
   사진 76 + 색상 90 + 사이즈 56 + 수량 52 + 단가 96 = 370px, so the five inputs are fully visible from 375px and 금액
   peeks in as the scroll cue. Every item shows 6 line rows (the sheet's block, owner 2026-10-05); on a PC the photo
   column is wide enough for the thumbnail (sheet aspect 144:196) to fill those 6 rows, on a phone the 375px rule keeps
   it at the column width (a 6-row-tall photo would need about 200px there). No -webkit-overflow-scrolling (a no-op
   since iOS 13 that broke sticky in old WebKit) and no overflow:hidden on .op-grid (it would break the sticky header). */
.op-gridwrap { margin: 0 0 1rem; }
.op-grid-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.5rem;
  margin: 0 0 0.5rem;
}
.op-grid-title { font-size: 1rem; font-weight: 700; margin: 0 auto 0 0; }
.op-grid-title:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: 2px; }
/* 「업체·품번 →」: only while the grid can scroll further right (admin-orders.js sets data-kk-more on the wrap). */
/* (Scoped to the toolbar: a plain .op-more-cue loses to Bootstrap's .btn display.) */
.op-grid-toolbar .op-more-cue { display: none; min-height: 44px; white-space: nowrap; }
.op-gridwrap[data-kk-more] .op-grid-toolbar .op-more-cue { display: inline-flex; align-items: center; gap: 0.25rem; }
/* A column just switched on (data-kk-reveal, set for 1.8 s by admin-orders.js). */
@keyframes op-reveal {
  0%, 35% { box-shadow: inset 0 0 0 999px rgba(255, 196, 61, 0.35); }
  100% { box-shadow: inset 0 0 0 999px rgba(255, 196, 61, 0); }
}
.op-grid[data-kk-reveal="op-c-vendor"] .op-c-vendor,
.op-grid[data-kk-reveal="op-c-style"] .op-c-style,
.op-grid[data-kk-reveal="op-c-deposit"] .op-c-deposit,
.op-grid[data-kk-reveal="op-c-deposit"] .op-c-balance,
.op-grid[data-kk-reveal="op-c-deposit"] .op-c-done { animation: op-reveal 1.8s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .op-grid[data-kk-reveal="op-c-vendor"] .op-c-vendor,
  .op-grid[data-kk-reveal="op-c-style"] .op-c-style,
  .op-grid[data-kk-reveal="op-c-deposit"] .op-c-deposit,
  .op-grid[data-kk-reveal="op-c-deposit"] .op-c-balance,
  .op-grid[data-kk-reveal="op-c-deposit"] .op-c-done { animation: none; box-shadow: inset 0 0 0 999px rgba(255, 196, 61, 0.3); }
}
@media (min-width: 768px) {
  .op-select-toggle { display: none !important; }
}

.op-grid {
  --op-w-sel: 0px;
  --op-w-photo: 76px; /* 6 rows per item (owner, 2026-10-05): a wider photo; 사진·색상·사이즈·수량·단가 still fit 375px */
  --op-w-color: 90px; /* 90 − 1px border − ⋯ 44px leaves 「+ 줄」 its 44px touch target (CLAUDE.md §4) */
  --op-w-size: 56px;
  --op-w-qty: 52px;
  --op-w-price: 96px;
  --op-w-amount: 100px;
  --op-w-vendor: 52px;
  --op-w-style: 140px;
  --op-w-deposit: 108px;
  --op-w-balance: 108px;
  --op-w-done: 140px;
  --op-w-del: 44px;
  --op-t-color: var(--op-w-color); /* the template's 색상 and 품번 tracks */
  --op-t-style: var(--op-w-style);
  --op-row: 44px;
  --op-line: #ece2dd;
  --op-line-strong: #d3c1b8;
  --op-cell-bg: #fff;
  --op-head-bg: #f6efeb;
  position: relative;
  background: #fff;
  border-top: 1px solid var(--op-line-strong);
  border-bottom: 1px solid var(--op-line-strong);
}
.op-grid.is-selecting { --op-w-sel: 44px; }
@media (max-width: 767.98px) {
  .op-grid { margin-inline: -1.1rem; padding-left: env(safe-area-inset-left, 0px); }
  .op-grid:not(.is-selecting) .op-c-sel { display: none; }
}
@media (min-width: 768px) {
  .op-grid {
    --op-w-sel: 44px;
    --op-w-photo: 200px; /* (200 − 8) / (144/196) ≈ 261px tall: the photo fills the 6 line rows (6 × 45px), like the sheet */
    --op-w-color: 140px;
    --op-w-size: 80px;
    --op-w-qty: 72px;
    --op-w-price: 112px;
    --op-w-amount: 112px;
    --op-w-vendor: 64px;
    --op-w-style: 144px;
    --op-w-deposit: 120px;
    --op-w-balance: 120px;
    --op-w-done: 144px;
    /* Fixed tracks, like the sheet: stretched, a short colour sat ~450px left of its size (1280px), and a stretched 품번
       (now before 사진) pushed the photo away from its 업체. The rows simply end after the last column. */
    --op-t-color: var(--op-w-color);
    --op-t-style: var(--op-w-style);
    border: 1px solid var(--op-line-strong);
    border-radius: 2px;
  }
}
@media (min-width: 768px) and (max-width: 1365.98px) {
  /* 업체 + 품번 both shown (every order from before Rev 11) without 분납: a 160px photo keeps 금액 and ✕ inside a
     1280px screen next to the sidebar (the photo is then 207px of the 270px rows); 분납 scrolls anyway. */
  .op-grid.has-lead-cols:not(.is-deposit) { --op-w-photo: 160px; }
}
/* "More columns to the right" (set by admin-orders.js while the body can scroll further). */
.op-grid[data-kk-more]::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 18px;
  pointer-events: none;
  z-index: 7;
  background: linear-gradient(to right, rgba(61, 47, 42, 0), rgba(61, 47, 42, 0.13));
}

.op-grid-head {
  position: sticky;
  top: var(--op-sticky-top, 0px);
  z-index: 6;
  overflow: hidden;
  background: var(--op-head-bg);
  border-bottom: 2px solid var(--op-line-strong);
}
.op-grid-head,
.op-grid-scroll {
  /* width 0 + min-width 100%: no min-content contribution, so the wide grid never widens the admin layout track
     (a 1fr track would otherwise grow to the grid and the phone page would zoom out). */
  width: 0;
  min-width: 100%;
}
.op-grid-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-padding-inline-start: calc(var(--op-w-sel) + var(--op-w-photo) + var(--op-w-color));
}
.op-grid-body { width: max-content; min-width: 100%; }
.op-grow,
.op-gitem {
  display: grid;
  grid-template-columns: var(--op-template);
  grid-auto-rows: minmax(var(--op-row), auto);
  width: max-content;
  min-width: 100%;
}
.op-gitem { position: relative; border-bottom: 1px solid var(--op-line-strong); }
.op-gitem.is-alt { --op-cell-bg: #fcf7f4; }

.op-cell {
  position: relative;
  min-width: 0;
  min-height: var(--op-row);
  display: flex;
  align-items: stretch;
  background: var(--op-cell-bg);
  border-right: 1px solid var(--op-line);
  border-bottom: 1px solid var(--op-line);
}
.op-c-sel,
.op-c-photo,
.op-c-color,
.op-c-glabel,
.op-c-tlabel { position: sticky; z-index: 3; }
.op-c-sel { left: 0; align-items: center; justify-content: center; }
.op-c-photo { left: var(--op-w-sel); }
.op-c-color { left: calc(var(--op-w-sel) + var(--op-w-photo)); border-right-color: var(--op-line-strong); }
.op-c-glabel,
.op-c-tlabel { left: var(--op-w-sel); border-right-color: var(--op-line-strong); } /* over 사진 + 색상, after ☐ */
.op-grid[data-kk-scrolled] .op-c-color,
.op-grid[data-kk-scrolled] .op-c-glabel,
.op-grid[data-kk-scrolled] .op-c-tlabel { box-shadow: 6px 0 6px -4px rgba(61, 47, 42, 0.25); }

/* Column header strip */
.op-hcell {
  min-height: var(--kk-touch);
  align-items: center;
  padding: 0 0.4rem;
  background: var(--op-head-bg);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--kk-text-secondary);
  border-bottom: 0;
  white-space: nowrap;
}
.op-hcell.op-c-sel { padding: 0; }
.op-hnum { justify-content: flex-end; }

/* Inputs: the cell is the field (spreadsheet look), 16px text, numbers right-aligned. */
.op-gin {
  width: 100%;
  min-width: 0;
  min-height: var(--op-row);
  margin: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  font: inherit;
  font-size: 16px;
  line-height: 1.2;
  color: var(--kk-text);
  padding: 0 0.35rem;
}
.op-gin[type="text"] { -webkit-appearance: none; appearance: none; }
.op-gin:focus,
.op-gin:focus-visible {
  outline: 3px solid var(--kk-focus-ring);
  outline-offset: -3px;
  background: #fff;
}
.op-gin:disabled { color: var(--kk-text); -webkit-text-fill-color: var(--kk-text); opacity: 1; }
/* The datalist arrow would eat the narrow 색상/사이즈 cells (Chromium); the suggestions still open while typing. */
.op-gin::-webkit-calendar-picker-indicator { display: none !important; }
.op-gin-date::-webkit-calendar-picker-indicator { display: block !important; }
.op-num { text-align: right; font-variant-numeric: tabular-nums; }
.op-gin-size { text-align: center; padding: 0 0.2rem; }

.op-c-amount { background: #faf5f2; }
.op-amount {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 0.45rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--kk-text);
  white-space: nowrap;
}
.op-c-price.is-suggestion .op-gin { color: var(--kk-text-secondary); }

/* The line being edited and the ticked lines (the wrapper is display:contents). */
.op-gline { display: contents; }
.op-gline:focus-within > .op-cell { background: #fff4e6; }
.op-gline:focus-within > .op-c-amount { background: #fbecdc; }
.op-gline.is-selected > .op-cell { background: var(--kk-info-bg); }

/* Marks: errors and warnings are listed in 「확인할 것」; the cell gets a corner flag like a spreadsheet note. */
.op-cell.is-invalid,
.op-gin.is-invalid { background: var(--kk-danger-bg); }
.op-cell.is-invalid::after,
.op-cell.is-warn::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  border-style: solid;
  border-width: 0 11px 11px 0;
  border-color: transparent var(--kk-danger) transparent transparent;
  pointer-events: none;
}
.op-cell.is-warn::after { border-color: transparent var(--kk-warn) transparent transparent; }
.op-gin.is-warn { box-shadow: inset 3px 0 0 var(--kk-warn); }
.op-gin.is-invalid { box-shadow: inset 3px 0 0 var(--kk-danger); }

/* ☐ */
.op-sel {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: var(--op-row);
  margin: 0;
  cursor: pointer;
}
.op-sel input { width: 20px; height: 20px; margin: 0; cursor: pointer; }
.op-sel input:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: 2px; }
.op-selall {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: var(--kk-touch);
  padding: 0;
  border: 0;
  background: transparent;
}
.op-selall:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: -3px; }
.op-selbox {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border: 2px solid var(--kk-text-secondary);
  border-radius: 4px;
  background: #fff;
  color: #fff;
  font-size: 13px;
  font-weight: 800;
  line-height: 1;
}
.op-selall[aria-checked="true"] .op-selbox,
.op-selall[aria-checked="mixed"] .op-selbox { background: var(--kk-ink); border-color: var(--kk-ink); }

/* 사진 */
.op-c-photo { align-items: center; justify-content: center; }
.op-photo-cell {
  position: relative;
  width: 100%;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.op-thumb {
  display: block;
  /* the sheet box aspect, as large as the cell allows (never taller than the item's rows) */
  width: min(calc(var(--op-w-photo) - 8px), calc((var(--op-rows) * var(--op-row) - 8px) * var(--op-ar)));
  padding: 0;
  border: 0;
  border-radius: 2px;
  background: transparent;
  cursor: pointer;
}
.op-thumb:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: 2px; }
.op-thumb-box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  overflow: hidden;
  background: #fff;
  border: 1px solid #c8bfba;
}
.op-thumb-box img { width: 100%; height: 100%; display: block; }
.op-photo-add,
.op-photo-product {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  width: 100%;
  min-height: var(--op-row);
  margin: 0;
  padding: 0 0.2rem;
  font-size: 0.8rem;
  font-weight: 650;
  color: var(--kk-accent-text);
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: center;
  line-height: 1.1;
}
.op-photo-add { border-bottom: 1px dashed var(--op-line-strong); }
/* Phones: the narrow (76px) cell puts the centred 「＋ 사진」 under the item number badge (top-left, 18px): start the text below it. */
@media (max-width: 767.98px) {
  .op-photo-add { padding-top: 18px; }
}
.op-photo-add.disabled,
.op-photo-product:disabled { opacity: 0.5; pointer-events: none; }
.op-photo-add:focus-visible,
.op-photo-product:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: -3px; }
.op-photo-cell .op-photo-state { font-size: 0.7rem; padding: 0.25rem; }
.op-item-no {
  position: absolute;
  top: 3px;
  left: 3px;
  z-index: 1;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: rgba(61, 47, 42, 0.8);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
  pointer-events: none;
}
.op-photo-flag {
  position: absolute;
  top: 3px;
  right: 3px;
  z-index: 1;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--kk-danger-text);
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  line-height: 18px;
  text-align: center;
}

/* 「+ 줄」 row */
.op-c-addrow { --op-cell-bg: #fdfaf8; }
.op-gitem.is-alt .op-c-addrow { --op-cell-bg: #faf3ef; }
.op-addline {
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--op-row);
  padding: 0 0.5rem;
  border: 0;
  background: transparent;
  color: var(--kk-accent-text);
  font-weight: 650;
  font-size: 0.9rem;
  text-align: left;
  white-space: nowrap;
}
.op-item-more {
  flex: 0 0 var(--kk-touch);
  min-height: var(--op-row);
  border: 0;
  border-left: 1px solid var(--op-line);
  background: transparent;
  color: var(--kk-text-secondary);
  font-size: 1.15rem;
  line-height: 1;
}
.op-addline:focus-visible,
.op-item-more:focus-visible,
.op-vendor-cell:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: -3px; }
.op-addline:disabled,
.op-item-more:disabled { opacity: 0.5; }
/* A line's ✕ (the last column, not in the sheet). */
.op-c-del { align-items: center; justify-content: center; padding: 0; }
.op-del {
  width: 100%;
  min-width: var(--kk-touch);
  min-height: var(--op-row);
  border: 0;
  background: transparent;
  color: var(--kk-text-secondary);
  font-size: 1rem;
  line-height: 1;
}
.op-del:hover:not(:disabled) { color: var(--kk-danger-text); }
.op-del:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: -3px; }
.op-del:disabled { opacity: 0.5; }
.op-c-hint { align-items: center; }
.op-price-hint {
  margin: 0;
  padding: 0.2rem 0.45rem;
  font-size: 0.74rem;
  line-height: 1.25;
  color: var(--kk-info-text);
  background: var(--kk-info-bg);
  align-self: stretch;
  display: flex;
  align-items: center;
  width: 100%;
}

/* 업체 · 품번·소재 · 완납일 (item-level cells) */
.op-vendor-cell {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-height: var(--op-row);
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--kk-text);
}
.op-vendor-letter { font-weight: 800; font-size: 1.05rem; line-height: 1.1; }
.op-vendor-tag {
  font-size: 0.66rem;
  font-weight: 700;
  border-radius: 4px;
  padding: 0.05rem 0.3rem;
  background: var(--kk-info-bg);
  color: var(--kk-info-text);
}
.op-vendor-tag.is-manual { background: var(--kk-warn-bg); color: var(--kk-warn-text); }
.op-gitem .op-c-style { flex-direction: column; }
.op-gin-style { flex: 0 0 auto; font-weight: 650; border-bottom: 1px dashed var(--op-line); }
.op-gin-note { flex: 1 1 auto; }
.op-gitem .op-c-done { align-items: flex-start; }
.op-gin-date { font-size: 16px; }
.op-c-fill { --op-cell-bg: #fbf8f6; }

/* 분납 mode: group header row, menu, 「+ 상품」 row */
.op-ghead > .op-cell { --op-cell-bg: #f3ebe6; border-bottom: 1px solid var(--op-line-strong); }
.op-ghead .op-c-deposit,
.op-ghead .op-c-balance { --op-cell-bg: #fff; }
.op-c-glabel { align-items: center; justify-content: space-between; gap: 0.25rem; padding-left: 0.5rem; }
.op-glabel { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; font-size: 0.85rem; color: var(--kk-text); }
.op-gsum { font-size: 0.76rem; color: var(--kk-text-secondary); font-variant-numeric: tabular-nums; }
.op-gmenu-toggle { flex: 0 0 auto; background: transparent; border-radius: 8px; }
.op-gmenu > .op-cell,
.op-gadd > .op-cell { --op-cell-bg: #fff; }
.op-c-span { align-items: center; border-right: 0; }
.op-sticky-inner {
  position: sticky;
  left: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  max-width: min(100%, 100vw);
  padding: 0.35rem 0.5rem;
}
.op-gmenu .op-menu { margin: 0; border: 0; background: transparent; }
.op-gadd > .op-cell { border-bottom: 1px solid var(--op-line-strong); }
.op-gadd-actions .btn { white-space: nowrap; }

/* 합계 row */
.op-gtotal > .op-cell {
  --op-cell-bg: var(--op-head-bg);
  border-top: 2px solid var(--op-line-strong);
  border-bottom: 0;
  font-weight: 700;
}
.op-c-tlabel { align-items: center; gap: 0.3rem; padding: 0 0.5rem; }
.op-tcur { font-weight: 600; color: var(--kk-text-secondary); font-size: 0.85rem; }
.op-tnum {
  align-items: center;
  justify-content: flex-end;
  padding: 0 0.45rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--kk-text);
}

/* ---------- 「확인할 것」 (Rev 11 §2.11) ---------- */
.op-issues {
  margin: 0 0 1rem;
  padding: 0.75rem;
  border: 1px solid var(--kk-line-strong);
  border-radius: var(--kk-radius-sm);
  background: #fffdfb;
}
.op-issues-title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.5rem;
  margin: 0 0 0.45rem;
  font-size: 0.95rem;
  font-weight: 700;
}
.op-issues-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  height: 1.5rem;
  padding: 0 0.35rem;
  border-radius: 0.75rem;
  background: var(--kk-warn-bg);
  color: var(--kk-warn-text);
  font-size: 0.8rem;
}
.op-issues-note { font-size: 0.78rem; font-weight: 600; color: var(--kk-danger-text); }
.op-issues-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.35rem; }
.op-issue {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.2rem 0.25rem 0.2rem 0.5rem;
  border-radius: 8px;
  font-size: 0.85rem;
}
.op-issue.is-error { background: var(--kk-danger-bg); color: var(--kk-danger-text); }
.op-issue.is-warn { background: var(--kk-warn-bg); color: var(--kk-warn-text); }
.op-issue-icon { flex: 0 0 auto; font-weight: 800; }
.op-issue-text { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.op-issue-go { flex: 0 0 auto; background: #fff; }
/* The local LLM's colour suggestion (owner request 2026-10-06): a row of its own under the entry, past the ⚠. */
.op-issue-suggest {
  flex: 1 0 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.5rem;
  padding: 0 0 0.1rem 1.3rem;
  color: var(--kk-text);
}
.op-issue-suggest.is-pending { color: var(--kk-text-secondary); }
.op-suggest-note { font-size: 0.78rem; }
.op-suggest-text { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.op-suggest-actions { display: inline-flex; flex: 0 0 auto; gap: 0.35rem; }
.op-suggest-ignore { background: #fff; }
/* …and a small hint on the 색상 cell (the full text and [적용] are in 「확인할 것」); the typed text moves up a little. */
.op-c-color.has-hint .op-gin { padding-bottom: 0.7rem; }
.op-cell-hint {
  position: absolute;
  left: 0.35rem;
  right: 4px;
  bottom: 3px;
  font-size: 0.68rem;
  font-weight: 600;
  line-height: 1;
  color: var(--kk-info-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}
.op-cell-hint.is-pending { color: var(--kk-text-secondary); font-weight: 500; }
/* The bar's 「색상 제안 n」 (review 2026-10-06): jumps to the first [적용] in 「확인할 것」, which a phone shows out of sight. */
.op-suggest-jump {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-height: var(--kk-touch);
  margin-left: 0.25rem;
  padding: 0 0.6rem;
  border: 1px solid var(--kk-info);
  border-radius: 8px;
  background: var(--kk-info-bg);
  color: var(--kk-info-text);
  font-size: 0.8rem;
  font-weight: 650;
  white-space: nowrap;
}
.op-bar-sum .op-suggest-jump strong { color: inherit; }
.op-suggest-jump:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: 2px; }

/* ---------- Admin-only rows (Rev 11 §2.14) ---------- */
.op-adminrows {
  margin: 0 0 1rem;
  padding: 0.75rem;
  border: 2px dashed var(--kk-line-strong);
  border-radius: var(--kk-radius-sm);
  background: #fbfaf8;
}
.op-adminrows-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.5rem; margin-bottom: 0.5rem; }
.op-adminrows-title { margin: 0; font-size: 0.95rem; font-weight: 700; }
.op-adminrows-title:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: 2px; }
.op-arow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 6rem minmax(0, 8rem) var(--kk-touch);
  grid-template-areas: "label rate amount del";
  gap: 0.35rem;
  align-items: center;
  margin-bottom: 0.4rem;
}
.op-arow > .op-afield-label { grid-area: label; }
.op-arow > .op-afield-rate { grid-area: rate; }
.op-arow > .op-afield-amount { grid-area: amount; }
.op-arow > .op-icon-btn { grid-area: del; }
.op-afield { display: flex; flex-direction: column; min-width: 0; }
/* The field captions: visible on phones (the heading row is hidden there), for screen readers only from 576px where the
   heading row shows (each input also has its own aria-label with the row number). */
.op-acap {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.op-arow-head { font-size: 0.75rem; font-weight: 600; color: var(--kk-text-secondary); margin-bottom: 0.15rem; }
.op-arow-head > span:nth-child(1) { grid-area: label; }
.op-arow-head > span:nth-child(2) { grid-area: rate; }
.op-arow-head > span:nth-child(3) { grid-area: amount; }
.op-aright { text-align: right; }
.op-arate { position: relative; display: flex; align-items: center; }
.op-arate .form-control { padding-right: 1.6rem; }
.op-arate-suffix { position: absolute; right: 0.55rem; color: var(--kk-text-secondary); pointer-events: none; }
.op-aamount {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  min-width: 0;
  min-height: var(--kk-touch);
}
.op-aamount .form-control { flex: 1 1 auto; min-width: 0; }
/* A computed 금액 (rate row): the same input, read-only, with the read-only fill of the grid's 금액 cells. */
.op-aamount .form-control.is-auto {
  background: #faf5f2;
  border-color: var(--kk-line);
  font-weight: 650;
  color: var(--kk-text);
}
.op-auto {
  white-space: nowrap;
  flex: none;
  font-size: 0.66rem;
  font-weight: 700;
  border-radius: 4px;
  padding: 0.05rem 0.3rem;
  background: var(--kk-info-bg);
  color: var(--kk-info-text);
}
.op-adminrows-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.25rem; }
.op-adminrows-sum { margin-left: auto; font-size: 0.9rem; color: var(--kk-text-secondary); font-variant-numeric: tabular-nums; }
.op-adminrows-sum strong { color: var(--kk-text); }
/* 「추가 항목 포함해서 받기」 (owner, 2026-10-05): the explicit exports WITH these rows, set apart from the rows above and
   from the bar's normal files. Review (2026-10-05): the buttons looked exactly like the bar's 엑셀/PDF/공유 about 85px
   above them on a phone, so the group is a tinted panel with an accent rule and its buttons carry 「추가 항목 포함」 in
   their own text and colour (warn text #7a4a0c on white 8.6:1, its border the same colour). Buttons are 44px targets;
   phones: one row of three, the prefix on its own small line. aria-disabled (the hint shows, the tap still reaches the
   page, which says why) looks like disabled. */
.op-extras {
  margin-top: 0.75rem;
  padding: 0.6rem 0.65rem 0.7rem;
  border: 1px solid var(--kk-line-strong);
  border-left: 4px solid var(--kk-warn);
  border-radius: var(--kk-radius-sm);
  background: var(--kk-warn-bg);
}
.op-extras-title { margin: 0; font-size: 0.9rem; font-weight: 700; color: var(--kk-warn-text); }
.op-extras-help { margin: 0.15rem 0 0.45rem; font-size: 0.8rem; color: var(--kk-text); }
.op-extras-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.btn.op-extras-btn {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  min-height: var(--kk-touch);
  min-width: 5.5rem;
  background: #fff;
  border: 1px solid var(--kk-warn-text);
  color: var(--kk-warn-text);
  font-weight: 650;
  line-height: 1.2;
}
.btn.op-extras-btn:hover { background: #fffdf8; color: var(--kk-warn-text); border-color: var(--kk-warn-text); }
.btn.op-extras-btn:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: 2px; box-shadow: none; }
.btn.op-extras-btn[aria-disabled="true"] { opacity: 0.6; }
.op-extras-pre { margin-right: 0.3em; font-weight: 500; }
.op-extras-actions .op-xlsx-hint { color: var(--kk-text); }
@media (max-width: 575.98px) {
  .op-extras-actions { align-items: stretch; }
  .op-extras-actions .op-extras-btn { flex: 1 1 0; flex-direction: column; flex-wrap: nowrap; min-width: 0; padding: 0.3rem 0.35rem; }
  .op-extras-pre { display: block; margin: 0 0 0.05rem; font-size: 0.72rem; white-space: nowrap; }
  .op-extras-actions .op-xlsx-hint { flex-basis: 100%; }
}
@media (max-width: 575.98px) {
  .op-arow {
    grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr) var(--kk-touch);
    grid-template-areas:
      "label label del"
      "rate amount amount";
    align-items: end;
    padding-bottom: 0.4rem;
    border-bottom: 1px dashed var(--kk-line-strong);
  }
  .op-arow-head { display: none; }
  .op-acap {
    position: static;
    width: auto;
    height: auto;
    margin: 0 0 0.15rem;
    overflow: visible;
    clip: auto;
    white-space: normal;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--kk-text-secondary);
  }
}

/* ---------- Item sheet (Rev 11 §2.3.6) and its photo box ---------- */
.op-sheet-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: grid;
  grid-template-columns: minmax(0, 9rem) minmax(0, 1fr);
  gap: 0.85rem;
  align-items: start;
  padding-top: 0.25rem;
}
@media (min-width: 768px) {
  .op-picker.op-item-sheet { width: min(560px, 92vw); }
}
.op-sheet-row { margin-bottom: 0.7rem; }
.op-sheet-row .form-label { display: block; margin-bottom: 0.25rem; }
.op-sheet-row .form-text { margin-top: 0.2rem; }
.op-sheet-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.5rem 0; }
.op-sheet-danger { margin-top: 0.5rem; }
.op-vendor-edit { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.op-vendor-edit .op-vendor-input { width: 7rem; }

.op-photo { min-width: 0; }
.op-photo-box {
  position: relative;
  width: 100%;
  background: #fff;
  border: 1px solid #bfbfbf;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.op-photo-box img { width: 100%; height: 100%; display: block; }
.op-photo-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem;
  text-align: center;
  font-size: 0.8rem;
  color: var(--kk-text-secondary);
}
.op-photo-actions { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.4rem; }
.op-photo-actions .btn { flex: 1 1 auto; padding-left: 0.5rem; padding-right: 0.5rem; }
.op-photo-pick { cursor: pointer; }
.op-photo-pick.disabled { pointer-events: none; opacity: 0.55; }
.op-photo-pick:focus-visible { outline: 3px solid var(--kk-focus-ring); outline-offset: 2px; }
.op-fit {
  display: grid;
  grid-template-columns: 1fr;
  margin-top: 0.35rem;
  border: 1px solid var(--kk-line-strong);
  border-radius: var(--kk-radius-sm);
  overflow: hidden;
}
.op-fit button {
  min-height: var(--kk-touch);
  border: 0;
  background: var(--kk-surface);
  color: var(--kk-text);
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0 0.25rem;
}
.op-fit button + button { border-top: 1px solid var(--kk-line-strong); }
.op-fit button.is-on { background: var(--kk-ink); color: #fff; }
.op-photo-help { margin: 0.3rem 0 0; font-size: 0.75rem; color: var(--kk-text-secondary); }
.op-photo-error { margin-top: 0.35rem; }
.op-product-link { margin: 0 0 0.5rem; font-size: 0.85rem; color: var(--kk-text-secondary); overflow-wrap: anywhere; }
/* A 44px touch target like every other control (CLAUDE.md §4). */
.op-product-link a {
  display: inline-flex;
  align-items: center;
  min-height: var(--kk-touch);
  color: var(--kk-accent-text);
  font-weight: 600;
  text-decoration: underline;
}
.op-product-trashed { color: var(--kk-danger-text); font-weight: 600; }
.op-menu {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0.6rem 0 0;
  padding: 0.5rem;
  border-radius: var(--kk-radius-sm);
  background: var(--kk-bg);
  border: 1px solid var(--kk-line);
}

/* ---------- 일괄 입력 dialog (Rev 11 §2.8) ---------- */
.op-bulk-form { display: grid; gap: 0.75rem; margin-top: 0.25rem; }
.op-bulk-actions { display: flex; gap: 0.5rem; }
.op-bulk-actions .btn { flex: 1 1 0; }
@media (min-width: 768px) {
  .op-picker.op-bulk-dialog { width: min(420px, 92vw); }
}

.op-more-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.op-linked-error {
  margin: 0.75rem 0 0;
  color: var(--kk-danger-text);
}
.op-linked-shipments {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.op-linked-shipments a {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.75rem;
  min-height: var(--kk-touch);
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--kk-line);
  border-radius: var(--kk-radius-sm);
  color: var(--kk-text);
  text-decoration: none;
}
.op-linked-shipments a:hover,
.op-linked-shipments a:focus-visible {
  background: var(--kk-bg);
}

/* Sticky bottom bar: totals, 저장, 엑셀 (primary), PDF and 공유 (secondary), the bulk row and the messages. */
.sticky-actions.op-bar {
  flex-direction: column;
  align-items: stretch;
  gap: 0.4rem;
  padding: 0.6rem 0.5rem calc(0.6rem + env(safe-area-inset-bottom, 0px));
  margin-top: 0.5rem;
}
/* iOS keyboard open on an editor field (admin-orders.js, fail-open): the bar would sit behind the keyboard and jump
   over the field being typed. It returns when the keyboard closes (완료 also commits the field). */
html.op-kb-open .op-bar { display: none; }
.op-bulk {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.5rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--kk-line);
}
.op-bulk-count { margin-right: auto; font-size: 0.88rem; font-weight: 700; color: var(--kk-text); white-space: nowrap; }
.op-bulk .btn { padding-inline: 0.6rem; white-space: nowrap; }
@media (max-width: 575.98px) {
  /* 375px: 「n줄 선택」 and the four actions fit one row (a short bar leaves more of the grid visible). */
  .op-bulk { gap: 0.3rem; }
  .op-bulk-count { font-size: 0.8rem; }
  .op-bulk .btn { padding-inline: 0.45rem; font-size: 0.85rem; }
}
.op-bar-msgs:empty { display: none; }
.op-msg {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.35rem 0.35rem 0.35rem 0.75rem;
  font-size: 0.88rem;
  overflow-wrap: anywhere;
}
.op-msg-text { flex: 1 1 auto; min-width: 0; }
.op-msg-close {
  flex: 0 0 auto;
  min-width: var(--kk-touch);
  min-height: var(--kk-touch);
  border: 0;
  background: transparent;
  color: inherit;
  font-size: 1rem;
  border-radius: 8px;
}
.op-bar-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.75rem;
}
.op-bar-sum {
  flex: 1 1 14rem;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 0.35rem;
  font-size: 0.9rem;
  color: var(--kk-text-secondary);
  font-variant-numeric: tabular-nums;
}
.op-bar-sum strong { color: var(--kk-text); }
.op-dirty {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.75rem;
  font-weight: 650;
  color: var(--kk-warn-text);
  background: var(--kk-warn-bg);
  border-radius: 6px;
  padding: 0.15rem 0.45rem;
  margin-left: 0.25rem;
}
.op-dirty-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--kk-warn); }
.op-bar-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.op-bar-actions .op-save { min-width: 6rem; }
.op-xlsx-hint { font-size: 0.78rem; color: var(--kk-text-secondary); }

/* Secondary exports (R8-13): PDF and 공유 sit next to 엑셀 but lighter, so 저장 > 엑셀 > PDF/공유 at a glance.
   Excel stays the primary output ("엑셀 저장이 기본"). */
.btn.op-export-secondary {
  background: transparent;
  border: 1px solid var(--kk-line-strong);
  color: var(--kk-text-secondary);
  font-weight: 500;
  min-height: var(--kk-touch);
}
.btn.op-export-secondary:hover {
  background: var(--kk-bg);
  color: var(--kk-text);
}
.btn.op-export-secondary:focus-visible {
  outline: 3px solid var(--kk-focus-ring);
  outline-offset: 2px;
  box-shadow: none;
}

@media (max-width: 575.98px) {
  .op-bar-actions { width: 100%; }
  .op-bar-actions .btn { flex: 1 1 0; }
  /* 375px: 저장 and 엑셀 share the free width, PDF and 공유 take their text width (no horizontal scroll). */
  .op-bar-actions .op-export-secondary { flex: 0 1 auto; padding-inline: 0.6rem; }
  .op-bar-actions .op-xlsx-hint { flex-basis: 100%; }
}

/* ---------- Product picker: bottom sheet on phones, centred modal from 768px ---------- */
html.op-scroll-locked,
html.op-scroll-locked body { overflow: hidden; }
.op-picker-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1040;
  background: rgba(45, 36, 32, 0.45);
}
.op-picker {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1050;
  display: flex;
  flex-direction: column;
  max-height: 88vh;
  max-height: 88dvh;
  background: var(--kk-surface);
  border-radius: var(--kk-radius) var(--kk-radius) 0 0;
  box-shadow: 0 -8px 30px rgba(45, 36, 32, 0.2);
  padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
}
@media (min-width: 768px) {
  .op-picker {
    top: 50%;
    left: 50%;
    right: auto;
    bottom: auto;
    width: min(640px, 92vw);
    max-height: 80vh;
    transform: translate(-50%, -50%);
    border-radius: var(--kk-radius);
    padding-bottom: 1rem;
  }
}
.op-picker-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.5rem; }
.op-picker-search { display: flex; gap: 0.5rem; }
.op-picker-search .form-control { flex: 1 1 auto; min-width: 0; }
.op-picker-search .btn { flex: 0 0 auto; white-space: nowrap; }
.op-picker-help { font-size: 0.8rem; color: var(--kk-text-secondary); margin: 0.4rem 0 0.5rem; }
.op-picker-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.op-picker-list { list-style: none; margin: 0; padding: 0; }
.op-pick-row {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 64px;
  padding: 0.5rem 0.25rem;
  border: 0;
  border-bottom: 1px solid var(--kk-line);
  background: transparent;
  color: var(--kk-text);
  text-align: left;
}
.op-pick-row:hover { background: var(--kk-bg); }
.op-pick-thumb { width: 48px; height: 60px; object-fit: cover; border-radius: 6px; border: 1px solid var(--kk-line); flex: 0 0 48px; }
.op-pick-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.op-pick-name { font-weight: 650; overflow-wrap: anywhere; }
.op-pick-meta { font-size: 0.8rem; color: var(--kk-text-secondary); overflow-wrap: anywhere; }
.op-picker-empty { color: var(--kk-text-secondary); font-size: 0.9rem; padding: 1rem 0; text-align: center; margin: 0; }
.op-picker-more { margin-top: 0.5rem; }

/* ---------- 공유 sheet (R8-13): the picker's sheet, two big choices, 엑셀 first ---------- */
.op-share-choices { display: grid; gap: 0.5rem; }
.op-share-choice { width: 100%; min-height: var(--kk-touch); font-size: 1rem; }
.op-share-choice[aria-busy="true"] { cursor: progress; }
.op-share-note { font-size: 0.8rem; color: var(--kk-text-secondary); margin: 0; overflow-wrap: anywhere; }
.op-share-fallback { margin-top: 0.5rem; }
.op-share-status {
  min-height: 1.5em;
  margin: 0.6rem 0 0;
  font-size: 0.88rem;
  color: var(--kk-text);
  overflow-wrap: anywhere;
}
@media (min-width: 768px) {
  .op-picker.op-share-sheet { width: min(420px, 92vw); }
}

@media (prefers-reduced-motion: reduce) {
  .op-card-link { transition: none; }
}
