/* Shared design system for the whole platform (landing page + both the
   sale and library tools). Merged from sale-processor's and
   library-checkout's near-identical original stylesheets — they'd already
   converged on the same variable names and component patterns
   independently, so this is mostly a union, not a redesign. Per-app
   decorative bits (Venmo/Cash App button colors, PENDING/SOLD badges for
   sale; the checked-out badge for library) live here too since there's
   only one stylesheet now, but stay clearly app-specific by name. */
:root {
  --bg: #f7f5f2;
  --card: #ffffff;
  --text: #1f2328;
  --muted: #6b7280;
  --border: #e2e0db;
  --accent: #2563eb;
  --venmo: #3d95ce;
  --cashapp: #00d632;
  --zeffy: #38369a;
  --cash: #059669;
  --danger: #dc2626;
  --warn: #b45309;
  --ok: #15803d;
  font-size: 16px;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

.wrap {
  max-width: 520px;
  margin: 0 auto;
  padding: 1.25rem 1rem 3rem;
}

.admin .wrap {
  max-width: 760px;
}

h1 {
  font-size: 1.4rem;
  margin: 0 0 0.25rem;
}

h2 {
  font-size: 1.1rem;
  margin: 1.5rem 0 0.5rem;
}

p.muted, .muted {
  color: var(--muted);
}

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.25rem;
  margin-bottom: 1rem;
}

/* sale */
.price {
  font-size: 1.6rem;
  font-weight: 700;
}

/* library */
.game-image {
  max-width: 100%;
  border-radius: 8px;
  display: block;
  margin: 0 0 0.75rem;
}

.badge {
  display: inline-block;
  padding: 0.15rem 0.6rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.badge-available { background: #dcfce7; color: var(--ok); }
.badge-pending { background: #fef3c7; color: var(--warn); }  /* sale */
.badge-sold { background: #fee2e2; color: var(--danger); }   /* sale */
.badge-out { background: #fee2e2; color: var(--danger); }    /* library */
.badge-closed { background: #e5e7eb; color: #4b5563; }       /* sale: RETURNED/DONATED */

/* admin: one badge per permission on a user row */
.badge-perm-sales { background: #dbeafe; color: #1e3a8a; }
.badge-perm-library { background: #dcfce7; color: var(--ok); }
.badge-perm-superadmin { background: #ede9fe; color: #5b21b6; }
.perm-badges { display: flex; gap: 0.3rem; flex-wrap: wrap; }

/* library */
.meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  color: var(--muted);
  font-size: 0.9rem;
  margin: 0.5rem 0;
}

.tag-group {
  margin: 0.5rem 0;
  font-size: 0.9rem;
}
.tag-group .label {
  color: var(--muted);
  font-weight: 600;
  margin-right: 0.3rem;
}

label {
  display: block;
  font-weight: 600;
  font-size: 0.9rem;
  margin: 0.75rem 0 0.25rem;
}

input, select, textarea {
  width: 100%;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 1rem;
  font-family: inherit;
  background: var(--card);
  color: var(--text);
}

textarea {
  min-height: 5rem;
  resize: vertical;
}

/* sale */
.checkbox-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.9rem;
}
.checkbox-row input { width: auto; }
.checkbox-row label { margin: 0; }

button, .btn {
  display: inline-block;
  border: none;
  border-radius: 8px;
  padding: 0.7rem 1rem;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  color: white;
  background: var(--accent);
}

button:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-venmo { background: var(--venmo); }     /* sale */
.btn-cashapp { background: var(--cashapp); } /* sale */
.btn-zeffy { background: var(--zeffy); }     /* sale */
.btn-cash { background: var(--cash); }       /* sale */
.btn-secondary { background: #4b5563; }
.btn-danger { background: var(--danger); }
.btn-ok { background: var(--ok); }
.btn-block { display: block; width: 100%; margin-top: 0.6rem; }
.btn-link {
  background: none;
  color: var(--accent);
  padding: 0;
  font-size: 0.85rem;
  font-weight: 600;
}

.row { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.row > * { flex: 1; }

.error {
  background: #fee2e2;
  color: var(--danger);
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  margin: 0.75rem 0;
  font-size: 0.9rem;
}

.notice {
  background: #dbeafe;
  color: #1e3a8a;
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  margin: 0.75rem 0;
  font-size: 0.9rem;
}

.wrap-scroll {
  overflow-x: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

th, td {
  text-align: left;
  padding: 0.5rem 0.4rem;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}

th { color: var(--muted); font-weight: 600; font-size: 0.8rem; text-transform: uppercase; }
th.sortable { cursor: pointer; user-select: none; }  /* library */
th.sortable:hover { color: var(--text); }
th .sort-arrow { font-size: 0.7rem; margin-left: 0.15rem; }

tfoot td { border-bottom: none; border-top: 2px solid var(--border); } /* sale */

.item-actions { display: flex; gap: 0.4rem; flex-wrap: wrap; }
.item-actions button, .item-actions a { padding: 0.35rem 0.6rem; font-size: 0.85rem; }

nav.top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1rem;
  gap: 1rem;
  flex-wrap: wrap;
}
nav.top a { color: var(--accent); text-decoration: none; font-weight: 600; }
nav.top .links { display: flex; gap: 1rem; flex-wrap: wrap; }

.brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  font-size: 1.05rem;
}

.logo {
  height: 32px;
  width: auto;
  display: block;
}

.site-header {
  display: flex;
  justify-content: center;
  margin-bottom: 1.25rem;
}
.site-header .logo {
  height: 44px;
}

/* Shared landing page: permission-gated links to each tool */
.tool-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
}
.tool-card {
  display: block;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.5rem 1.5rem 1.25rem;
  text-decoration: none;
  color: var(--text);
}
.tool-card:hover { border-color: var(--accent); }
.tool-card h2 { margin: 0 0 0.4rem; font-size: 1.15rem; }
.tool-card p { margin: 0; color: var(--muted); font-size: 0.9rem; }

.label-print {
  display: none;
}

/* Two supported label formats, selected per-print via the <select> built
   by qr-label.js's formatSelectHtml and applied as a `.format-<key>` class
   on .label-print by bindPrintButton (which also sets @page's size — see
   its _setPageSize, since @page can't be scoped by an element's class the
   way the rules below are). */
@media print {
  /* display:none (not visibility:hidden) so hidden siblings drop out of
     layout entirely — visibility:hidden keeps their layout box, which
     left extra blank/partial pages behind the one real label page.
     Excluding :has(.label-print.printing) as well as .label-print.printing
     itself/its descendants matters because .label-print sits nested
     several levels deep (body > .wrap > #app > ... > .label-print on the
     real admin pages) — display:none on any of those ancestors would
     blank out .label-print too, since a hidden ancestor removes its whole
     subtree from rendering no matter what a descendant's own display
     says. An earlier version of this rule only exempted .label-print and
     its descendants, not its ancestors, which printed a blank page every
     time on the real admin pages (only invisible in an isolated test
     where .label-print had no wrapping elements to hide).

     Gating on .printing (added by a specific "Print label" button click,
     see qr-label.js's bindPrintButton) rather than the bare .label-print
     class matters once a page can hold more than one .label-print at once
     (a multi-box game's admin page prints one label per box) — without
     it every label on the page would show at once with no break between
     them, running together on the continuous label tape instead of
     cutting one label per print job. */
  body *:not(.label-print.printing, .label-print.printing *, :has(.label-print.printing)) { display: none !important; }

  /* --- Brother QL-700, 62mm continuous tape (e.g. DK-2205-style rolls) ---
     Page width fixed to the tape width, height "auto" so the driver cuts
     to the label's actual content length instead of a fixed square. No
     border — on a fixed-width sheet a dashed border was a handy cut
     guide, but on continuous tape it would just print as ink on the
     label. */
  .label-print.printing.format-ql700 {
    display: block !important;
    /* Deliberately NOT position:absolute: everything else is display:none
       (not just hidden), so this is already the only thing in normal
       flow. Taking it out of flow with position:absolute stopped it
       contributing to the page's height, so `@page { size: 2.4in auto }`
       had nothing to auto-size to and fell back to a full-length page —
       that's where the trailing blank tape after the label was coming
       from. */
    width: 2.4in;
    padding: 0.1in;
    text-align: center;
    /* The QL-700 driver reports an asymmetric printable area for
       continuous 62mm media — content renders (and prints) ~7mm right of
       tape-center on both label types, confirmed in Print Preview and on
       physical prints. Not something @page margin can fix (that's margin
       *within* the driver's printable area, not the printable area
       itself), so nudge the content left in CSS to compensate. Re-tune
       this if the offset looks different on another install/printer. */
    transform: translateX(-7mm);
  }
  /* img is inline by default, so with two images (logo + QR) they'd sit
     side by side on one line instead of stacking. display:block +
     margin:auto stacks and centers them regardless of text-align. */
  .format-ql700 .label-logo { display: block; height: 0.35in; width: auto; margin: 0 auto 0.05in; }
  .format-ql700 .label-header { font-weight: 700; font-size: 10pt; letter-spacing: 0.02em; margin-bottom: 0.05in; }
  .format-ql700 img#qr-print-img { display: block; width: 1.5in; height: 1.5in; margin: 0 auto; }
  .format-ql700 .label-title { font-weight: 700; font-size: 13pt; margin: 0.03in 0; }
  .format-ql700 .label-price { font-weight: 700; font-size: 16pt; } /* sale */
  .format-ql700 .label-id { font-size: 9pt; color: #555; }          /* library */

  /* --- Niimbot 50x30mm die-cut label, landscape ---
     Fixed page size (not continuous tape), so the QR code shares the
     label with the text side-by-side instead of stacking above it: the
     QR fills the left 25mm (the largest square that leaves usable room
     for text), and everything else — logo, header, title, extra lines —
     flows in a column to its right. A CSS grid (rather than flex) lets
     the QR span every text row without qr-label.js needing to wrap the
     text lines in their own container: every non-QR child below gets
     grid-column 2, the QR gets grid-column 1 spanning all rows, so it
     ends up vertically centered next to however many text lines a given
     label has. Font sizes and the 25mm QR are a starting tune, not
     verified against a physical Niimbot printer yet — re-check against
     real output the way the QL-700 offset above was. */
  .label-print.printing.format-niimbot {
    display: grid !important;
    grid-template-columns: 25mm 1fr;
    align-items: center;
    column-gap: 1mm;
    width: 50mm;
    height: 30mm;
    padding: 1mm;
    box-sizing: border-box;
    text-align: left;
  }
  /* No room for the con logo at this size — the library label's logo
     simply goes unused in this format. */
  .format-niimbot .label-logo { display: none; }
  .format-niimbot img#qr-print-img {
    grid-column: 1;
    grid-row: 1 / -1;
    width: 25mm;
    height: 25mm;
  }
  .format-niimbot .label-header,
  .format-niimbot .label-title,
  .format-niimbot .label-price,
  .format-niimbot .label-id {
    grid-column: 2;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .format-niimbot .label-header { font-weight: 700; font-size: 6pt; letter-spacing: 0.02em; }
  .format-niimbot .label-title { font-weight: 700; font-size: 7pt; }
  .format-niimbot .label-price { font-weight: 700; font-size: 8pt; } /* sale */
  .format-niimbot .label-id { font-size: 5.5pt; color: #555; }      /* library */
}
