/* The listing form, and the photograph dialog that belongs to it.
   Loaded by both panels -- the seller edits their own listing with this screen
   and an admin edits anybody's, and it is one file so the two cannot drift.
   See apps/shared/product-form.js, and the deploy, which copies this into both
   panel directories because neither has a bundler. */

/* ---- the listing form ----
   Two columns on a desktop: the piece down the middle, its photographs and
   where it belongs down the right. One column on a phone, in that order. */
.formwrap { padding-bottom: 76px }
.formcols { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 14px; align-items: start }
.f { margin-bottom: 14px }
.f > label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 5px }
.f input[type=text], .f input[type=number], .f select, .f textarea { width: 100% }
.f-hint { font-size: 12px; color: var(--faint); margin-top: 4px }
.f-hint .warn { color: var(--bad, #b3261e); font-weight: 600 }
.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0 14px }
.chk { display: flex; align-items: center; gap: 8px; font-size: 14px }
.chk input { width: auto }
.linky { font-size: 13px }

/* the tabs at the foot of the form, dark like WCFM's */
.panel.tabbed { display: grid; grid-template-columns: 170px minmax(0, 1fr); padding: 0; overflow: hidden }
.tabbed-side { background: var(--chrome); display: flex; flex-direction: column; padding: 8px 0 }
.tabbed-t {
  background: none; border: 0; border-radius: 0; text-align: left; color: #C8D4DC;
  padding: 11px 16px; font-size: 13.5px; border-left: 3px solid transparent;
}
.tabbed-t:hover { background: rgba(255,255,255,.06); color: #fff; border-color: transparent }
.tabbed-t.on { background: var(--chrome-on); color: #fff; border-left-color: #fff }
.tabbed-body { padding: 16px; min-width: 0 }

/* the photographs */
.shots { display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 8px }
.shot {
  position: relative; aspect-ratio: 1; border: 1px solid var(--line); border-radius: var(--r);
  overflow: hidden; background: var(--sunk); cursor: grab;
}
.shot img { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none }
.shot.cover { border-color: var(--chrome-on); border-width: 2px }
/* The one being carried, and the place it would land. */
.shot.dragging { opacity: .4; cursor: grabbing }
.shot.over { outline: 3px solid var(--chrome-on); outline-offset: -3px }
/* And a wash over it, because a thin line on a photograph of a dark coin is
   not a thing anyone sees while they are mid-drag. */
.shot.over::after {
  content: ''; position: absolute; inset: 0; background: var(--chrome-on); opacity: .28; pointer-events: none;
}
/* Moved off the bottom edge, which the arrows now occupy, and shrunk to a
   pill: it marks a tile rather than labelling it. */
.shot-tag {
  position: absolute; left: 3px; top: 3px; background: var(--chrome-on); color: #fff;
  font-size: 10px; line-height: 1; padding: 3px 5px; border-radius: 3px; max-width: calc(100% - 32px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Back and forward.
   Dragging is for a laptop; these are for every seller who opens this on a
   phone, where HTML drag-and-drop fires nothing at all. Always visible rather
   than on hover, for the same reason. */
.shot-move { position: absolute; left: 0; right: 0; bottom: 0; display: flex }
.shot-mv {
  flex: 1; border: 0; padding: 3px 0; line-height: 1; font-size: 16px; cursor: pointer;
  background: rgba(20,28,34,.72); color: #fff;
}
.shot-mv + .shot-mv { border-left: 1px solid rgba(255,255,255,.25) }
.shot-mv:hover:not(:disabled) { background: var(--chrome-on) }
.shot-mv:disabled { opacity: .3; cursor: default }
.shot-x {
  position: absolute; top: 3px; right: 3px; width: 22px; height: 22px; padding: 0; line-height: 1;
  border: 0; border-radius: 50%; background: rgba(20,28,34,.72); color: #fff; font-size: 15px; cursor: pointer;
}
.shot.add {
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  border-style: dashed; color: var(--muted); font-size: 12.5px; text-align: center; padding: 6px;
}
.shot.add:hover { border-color: var(--ink); color: var(--ink) }
.shot.add input { display: none }
/* The one way in is a button now rather than a <label> wrapping a file
   input, so it needs the plain-button reset a label never needed. */
.shot.add { background: var(--sunk); font: inherit; font-size: 12.5px }

/* ── the photograph dialog ─────────────────────────────────────────────────
   One dialog with two tabs, the shape WCFM and WordPress both had: upload a
   file, or take one the seller already has. Dimmed tiles in the gallery are
   on this listing already -- shown rather than hidden, because somebody
   hunting for a picture they cannot find needs to be told it is right there. */
.pk-wrap {
  position: fixed; inset: 0; z-index: 60; background: rgba(16,22,27,.5);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
.pk-box {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
  width: min(860px, 100%); max-height: min(88vh, 720px); display: flex; flex-direction: column;
  box-shadow: 0 18px 50px rgba(16,22,27,.26);
}
.pk-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--line) }
.pk-head input { flex: 1; min-width: 0 }
.pk-close {
  width: 30px; height: 30px; padding: 0; line-height: 1; border: 0; border-radius: 50%;
  background: var(--sunk); color: var(--ink); font-size: 19px; cursor: pointer;
}
/* The tabs. A row of two, the live one carrying the line under it, which is
   how every set of tabs this seller has ever used says which one is open. */
.pk-tabs { display: flex; gap: 2px; padding: 0 14px; border-bottom: 1px solid var(--line) }
.pk-tab {
  border: 0; background: none; font: inherit; font-size: 13.5px; color: var(--muted);
  padding: 9px 12px; margin-bottom: -1px; border-bottom: 2px solid transparent; cursor: pointer;
}
.pk-tab:hover { color: var(--ink) }
.pk-tab.on { color: var(--ink); font-weight: 600; border-bottom-color: var(--chrome-on) }

.pk-body { padding: 14px; overflow: auto; flex: 1 }
.pk-pane[hidden] { display: none }
.pk-find { margin-bottom: 10px }
.pk-find input { width: 100% }

/* Where files land. Big, because it is also the button that opens the file
   chooser, and a seller on a laptop drags onto it. */
.pk-drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  min-height: 190px; padding: 20px; text-align: center; cursor: pointer;
  border: 2px dashed var(--line); border-radius: var(--r); background: var(--sunk); color: var(--muted);
}
.pk-drop strong { color: var(--ink); font-size: 15px }
.pk-drop:hover, .pk-drop.on { border-color: var(--chrome-on); color: var(--ink) }
.pk-drop input { display: none }
.pk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 8px }
.pk {
  position: relative; aspect-ratio: 1; padding: 0; overflow: hidden; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r); background: var(--sunk);
}
.pk img { width: 100%; height: 100%; object-fit: cover; display: block }
.pk:hover { border-color: var(--ink) }
.pk.on { border-color: var(--chrome-on); border-width: 2px }
/* The tick, drawn rather than fetched. */
.pk.on::after {
  content: ''; position: absolute; top: 5px; left: 6px; width: 7px; height: 13px;
  border: solid #fff; border-width: 0 2.5px 2.5px 0; transform: rotate(42deg);
  filter: drop-shadow(0 0 2px rgba(16,22,27,.8));
}
.pk-used { cursor: default; opacity: .45 }
.pk-used:hover { border-color: var(--line) }
.pk-tag {
  position: absolute; left: 0; right: 0; bottom: 0; background: var(--chrome-on); color: #fff;
  font-size: 10px; text-align: center; padding: 2px 0;
}
.pk-n {
  position: absolute; top: 3px; right: 3px; min-width: 17px; height: 17px; border-radius: 9px;
  background: rgba(20,28,34,.72); color: #fff; font-size: 10.5px; line-height: 17px; text-align: center; padding: 0 4px;
}
.pk-more { display: flex; justify-content: center; margin-top: 12px }
.pk-foot {
  display: flex; align-items: center; gap: 8px; padding: 12px 14px; border-top: 1px solid var(--line);
}
.pk-foot .button:first-of-type { margin-left: auto }
@media (max-width: 560px) {
  .pk-wrap { padding: 0 }
  .pk-box { max-height: 100%; height: 100%; width: 100%; border: 0; border-radius: 0 }
  .pk-grid { grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)) }
  /* On a phone the dialog is the whole screen, so the drop target does not
     need to be most of it -- the seller is going to tap it, not drag onto it. */
  .pk-drop { min-height: 140px }
  .pk-tabs { padding: 0 10px }
}

/* the categories, scrolled rather than endless */
/* ── where the piece sits ──────────────────────────────────────────────────
   The old store manager's shape: a bordered box with the tree in it,
   children under their parent. What is chosen sits above it so it can be
   seen and taken off without scrolling, and there is a search, because 58
   categories is more than anyone reads. */
.cat-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 9px; min-height: 26px; align-items: center }
.cat-find {
  width: 100%; margin-bottom: 8px; padding: 8px 11px; font-size: 13.5px;
  border: 1px solid var(--line-2); border-radius: 8px;
}
.cats { max-height: 280px; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--r); padding: 6px 4px }
.cats .cat {
  display: flex; align-items: center; gap: 9px; padding: 6px 9px;
  font-size: 13.5px; border-radius: 6px; cursor: pointer;
}
.cats .cat:hover { background: var(--sunk) }
/* Indented, and against a line, so a child reads as belonging to the name
   above it rather than as one more item in a list of fifty-eight. */
.cats .cat.sub { margin-left: 16px; padding-left: 14px; border-left: 2px solid var(--line); color: var(--muted) }
.cats input { width: auto; margin: 0; flex: none }
.cat-none { padding: 10px }

/* the bar that follows you down the form */
/* The bar that saves. Its contents sit in the same reading column the form
   does, so Publish is under the last field rather than out at the edge of a
   desktop; and the word about what just happened sits beside it. */
.formbar {
  position: fixed; left: 224px; right: 0; bottom: 0; z-index: 25;
  background: var(--chrome); padding: 10px 18px;
}
.formbar-in {
  max-width: 820px; margin-inline: auto;
  display: flex; gap: 12px; align-items: center;
}
.formbar-l { min-width: 0; flex: 1 }
.formbar-r { display: flex; gap: 8px; flex: none }
.formbar button, .formbar .button { min-width: 108px; justify-content: center }
.formbar-note { color: #9FB0BC; font-size: 12.5px }
.formbar-msg:not(:empty) + .formbar-note { display: none }
.formbar-msg .ok, .formbar-msg .err {
  margin: 0; padding: 6px 11px; border-radius: 7px; font-size: 13px; font-weight: 600;
}
.formbar-msg .ok { background: rgba(21, 122, 67, .18); color: #7BE0A8; border: 1px solid rgba(123, 224, 168, .35) }
.formbar-msg .err { background: rgba(178, 0, 0, .2); color: #FFB3B3; border: 1px solid rgba(255, 179, 179, .35) }
/* ---- the attribute box, the shape WCFM gives it ----
   What is chosen sits inside the box as chips; the list at the end of them
   adds another. As many as apply. */
.attr-row { padding: 14px 0; border-bottom: 1px solid var(--line) }
.attr-row:last-child { border-bottom: 0 }
.attr-row > label { display: block; font-size: 14px; font-weight: 500; margin-bottom: 7px }
.tokens {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  min-height: 42px; padding: 6px; background: var(--sunk);
  border: 1px solid var(--line-2); border-radius: var(--r);
}
.token {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px 4px 6px;
  background: var(--card); border: 1px solid var(--line-2); border-radius: var(--r); font-size: 13.5px;
}
.token button {
  border: 0; background: none; padding: 0; width: 16px; height: 16px; line-height: 1;
  color: var(--muted); font-size: 15px; cursor: pointer;
}
.token button:hover { color: var(--accent) }
.token-add {
  flex: 1 1 150px; min-width: 130px; border: 0; background: transparent;
  font-size: 13.5px; color: var(--muted); padding: 4px 2px;
}
.token-add:focus { outline: none; color: var(--ink) }
.token-add:disabled { color: var(--faint) }

/* a photograph chosen before the listing existed */
.shot.pending { opacity: .72 }
.shot.pending::after {
  content: 'waiting'; position: absolute; left: 0; right: 0; bottom: 0;
  background: rgba(20,28,34,.72); color: #fff; font-size: 10px; text-align: center; padding: 2px 0;
}
.formbar .button, .formbar button:not(.primary) { background: transparent; color: #C8D4DC; border-color: rgba(255,255,255,.22) }
.formbar .button:hover, .formbar button:not(.primary):hover { color: #fff; border-color: #fff }
.button.primary-a { background: var(--accent); border-color: var(--accent); color: #fff }
.button.primary-a:hover { background: var(--accent-ink); border-color: var(--accent-ink); color: #fff; text-decoration: none }

/* panels */
.panel { background: var(--card); border: 1px solid var(--line); border-radius: var(--r); padding: 16px; margin-bottom: 14px }
.panel h3 { margin: 0 0 10px; font-size: 15px; font-weight: 500 }
.kv { display: grid; grid-template-columns: 130px 1fr; gap: 6px 12px; font-size: 14px }
.kv .k { color: var(--muted) }
.pager { display: flex; gap: 8px; justify-content: center; margin: 16px 0 }

/* Under 900px the column becomes a drawer: the same menu, slid in from the
   left over a dim, which is what WCFM does on a phone too. */
@media (max-width: 900px) {
  .layout { grid-template-columns: minmax(0, 1fr) }
  .formcols { grid-template-columns: minmax(0, 1fr) }
  .panel.tabbed { grid-template-columns: minmax(0, 1fr) }
  .tabbed-side { flex-direction: row; overflow-x: auto; padding: 0 }
  .tabbed-t { border-left: 0; border-bottom: 3px solid transparent; white-space: nowrap }
  .tabbed-t.on { border-left: 0; border-bottom-color: #fff }
  .formbar { left: 0 }
  .side {
    position: fixed; top: 0; left: 0; bottom: 0; width: 258px; height: 100dvh;
    transform: translateX(-100%); transition: transform .2s ease;
  }
  body.side-open .side { transform: none }
  body.side-open .side-dim { display: block; position: fixed; inset: 0; z-index: 25; background: rgba(12,20,26,.5) }
  body.side-open { overflow: hidden }
  .burger { display: block }
  .topbar-r { display: none }
}
@media (prefers-reduced-motion: reduce) { .side { transition: none } }

@media (max-width: 640px) {
  main { padding: 12px }
  th.hide-sm, td.hide-sm { display: none }
  .card .v { font-size: 19px }
  table { font-size: 13px }
  th, td { padding: 8px }
  .kv { grid-template-columns: 110px 1fr }
  /* Scoped to tables. Unscoped it also shrank the listing form's price and
     stock fields to a 72px stub -- the rule was written for the quick-edit
     row, where a narrow box is right, and reached the whole app. */
  table input[type=number] { width: 72px !important }
  .bars { height: 104px; gap: 4px }
  .mbar-l { font-size: 9.5px }
}

