/* The public catalogue's typefaces, so the Typeface picker in Site settings
   can show each pairing in the face it actually is. */
@import url("/static/fonts/fonts.css");

:root {
  --brand: #1d4ed8;
  --ink: #0f172a;
  --muted: #64748b;
  --line: #e2e8f0;
  --bg: #f1f5f9;
  --card: #ffffff;
  --ok: #059669;
  --warn: #b45309;
  --bad: #dc2626;
  --radius: 10px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: var(--ink);
  background: var(--bg);
  -webkit-text-size-adjust: 100%;
}

a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3 { margin: 0 0 .5rem; line-height: 1.25; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }
p { margin: 0 0 .75rem; }
small, .small { font-size: .82rem; }
.muted { color: var(--muted); }
.right { text-align: right; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .85em; }

/* ---------------------------------------------------------------- layout */
.shell { display: flex; min-height: 100vh; }

.side {
  width: 232px;
  flex: 0 0 232px;
  background: var(--ink);
  color: #cbd5e1;
  padding: 1rem .75rem;
}
.side .logo {
  color: #fff; font-weight: 700; font-size: 1.05rem;
  padding: .35rem .5rem 1rem; display: block;
}
.side .logo:hover { text-decoration: none; }
.side .logo span { display: block; font-size: .72rem; font-weight: 400; color: #94a3b8; }
.side nav a {
  display: block; padding: .5rem .6rem; border-radius: 7px;
  color: #cbd5e1; font-size: .9rem; margin-bottom: 1px;
}
.side nav a:hover { background: #1e293b; color: #fff; text-decoration: none; }
.side nav a.on { background: var(--brand); color: #fff; font-weight: 600; }
.side .sec {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .08em;
  color: #64748b; padding: 1rem .6rem .3rem;
}
.side .foot { margin-top: 1.5rem; padding: .75rem .6rem; border-top: 1px solid #1e293b; font-size: .78rem; }

.main { flex: 1; min-width: 0; padding: 1.25rem 1.5rem 4rem; }
.topbar {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  margin-bottom: 1rem;
}
.topbar h1 { margin: 0; flex: 1; }

/* ----------------------------------------------------------------- parts */
.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1rem; margin-bottom: 1rem;
}
.card > h2:first-child, .card > h3:first-child { margin-top: 0; }

.grid { display: grid; gap: 1rem; }
.grid.g2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid.g3 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.grid.g4 { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }

.stat { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: .9rem 1rem; }
.stat b { display: block; font-size: 1.7rem; line-height: 1.1; }
.stat span { font-size: .8rem; color: var(--muted); }

.btn {
  display: inline-block; padding: .5rem .85rem; border-radius: 7px;
  border: 1px solid var(--brand); background: var(--brand); color: #fff;
  font-size: .88rem; font-weight: 600; cursor: pointer; text-align: center;
  font-family: inherit; line-height: 1.4;
}
.btn:hover { filter: brightness(1.08); text-decoration: none; }
.btn.ghost { background: #fff; color: var(--ink); border-color: var(--line); }
.btn.ghost:hover { border-color: var(--muted); filter: none; }
.btn.danger { background: var(--bad); border-color: var(--bad); }
.btn.sm { padding: .28rem .55rem; font-size: .78rem; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

label { display: block; font-size: .82rem; font-weight: 600; margin-bottom: .25rem; color: #334155; }
label.inline { display: inline-flex; align-items: center; gap: .4rem; font-weight: 500; }
input[type=text], input[type=password], input[type=number], input[type=file],
input[type=color], input[type=email], select, textarea {
  width: 100%; padding: .48rem .6rem; border: 1px solid #cbd5e1;
  border-radius: 7px; font: inherit; background: #fff; color: var(--ink);
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--brand); outline-offset: -1px; border-color: var(--brand); }
textarea { min-height: 72px; resize: vertical; }
.field { margin-bottom: .8rem; }
.row { display: flex; gap: .6rem; flex-wrap: wrap; align-items: flex-end; }
.row > * { flex: 1; min-width: 140px; }
.row > .fixed { flex: 0 0 auto; min-width: 0; }

table { width: 100%; border-collapse: collapse; font-size: .87rem; }
th, td { padding: .5rem .55rem; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
th { font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; background: #f8fafc; position: sticky; top: 0; }
tbody tr:hover { background: #f8fafc; }
.scroll { overflow-x: auto; max-width: 100%; }

.tag {
  display: inline-block; padding: .12rem .45rem; border-radius: 20px;
  font-size: .72rem; font-weight: 600; white-space: nowrap;
}
.tag.in_stock { background: #d1fae5; color: #065f46; }
.tag.order { background: #fef3c7; color: #92400e; }
.tag.discontinued { background: #fee2e2; color: #991b1b; }
.tag.create { background: #d1fae5; color: #065f46; }
.tag.update { background: #dbeafe; color: #1e40af; }
.tag.skip { background: #e2e8f0; color: #475569; }
.tag.grey { background: #e2e8f0; color: #475569; }

.flash { padding: .65rem .9rem; border-radius: 8px; margin-bottom: .8rem; font-size: .9rem; }
.flash.ok { background: #d1fae5; color: #065f46; }
.flash.error { background: #fee2e2; color: #991b1b; }

.note { background: #eff6ff; border-left: 3px solid var(--brand); padding: .6rem .8rem; border-radius: 0 8px 8px 0; font-size: .86rem; margin-bottom: .9rem; }
.note.warn { background: #fffbeb; border-color: var(--warn); }

.pager { display: flex; gap: .35rem; align-items: center; margin-top: .9rem; flex-wrap: wrap; }
.pager a, .pager span { padding: .3rem .6rem; border: 1px solid var(--line); border-radius: 6px; background: #fff; font-size: .84rem; }
.pager .on { background: var(--brand); color: #fff; border-color: var(--brand); }

.steps { display: flex; gap: .4rem; margin-bottom: 1rem; flex-wrap: wrap; font-size: .82rem; }
.steps div { padding: .3rem .7rem; border-radius: 20px; background: #e2e8f0; color: var(--muted); }
.steps div.on { background: var(--brand); color: #fff; font-weight: 600; }
.steps div.done { background: #d1fae5; color: #065f46; }

.thumb { width: 40px; height: 40px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); background: #f8fafc; }

/* Category tile photo, set on the Categories screen. */
.catphoto { display: flex; align-items: center; gap: .4rem; }
.catphoto > span { display: grid; gap: .25rem; min-width: 0; }
.catphoto input[type=file] { font-size: .7rem; width: 100%; padding: .2rem; }
.thumb.noshot {
  display: flex; align-items: center; justify-content: center;
  font-size: .62rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--muted); flex: 0 0 40px;
}

/* ------------------------------------------------------------ public site */
.pub-head { background: var(--brand); color: #fff; padding: .8rem 1rem; }
.pub-head .wrap { max-width: 1100px; margin: 0 auto; display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }
.pub-head a { color: #fff; }
.pub-head .name { font-weight: 700; font-size: 1.1rem; }
.pub-head .name span { display: block; font-size: .72rem; opacity: .85; font-weight: 400; }
.wrap { max-width: 1100px; margin: 0 auto; padding: 0 1rem; }

.searchbar { padding: .7rem 0; position: sticky; top: 0; background: var(--bg); z-index: 20; border-bottom: 1px solid var(--line); }
.searchbar input[type=text] { font-size: 1rem; padding: .6rem .8rem; }

.chips { display: flex; gap: .35rem; overflow-x: auto; padding: .55rem 0; -webkit-overflow-scrolling: touch; }
.chips a {
  padding: .32rem .7rem; border-radius: 20px; background: #fff; border: 1px solid var(--line);
  font-size: .82rem; white-space: nowrap; color: var(--ink);
}
.chips a.on { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 600; }
.chips a:hover { text-decoration: none; }

.plist { display: grid; gap: .7rem; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); padding: .8rem 0 6rem; }

/* Photo-first card: the image is the biggest thing on it, because that is
   what a retailer's eye lands on when scanning a long list. */
.pcard {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  display: flex; flex-direction: column; overflow: hidden;
}
.pcard .shot {
  display: block; width: 100%; height: 168px; background: #f1f5f9;
  position: relative; flex: 0 0 168px; border-bottom: 1px solid var(--line);
}
.pcard .shot img { width: 100%; height: 100%; object-fit: contain; display: block; padding: .4rem; }
.pcard .shot .noimg {
  width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
  color: #cbd5e1; font-size: 2.1rem; font-weight: 700; letter-spacing: .05em;
}
.pcard .shot .badge { position: absolute; left: .45rem; top: .45rem; }
.pcard .body { flex: 1; min-width: 0; padding: .6rem .7rem .7rem; display: flex; flex-direction: column; }
.pcard .nm { font-weight: 600; font-size: .92rem; display: block; color: var(--ink); }
.pcard .meta { font-size: .76rem; color: var(--muted); margin: .15rem 0 .35rem; }
.pcard .price { font-size: .98rem; font-weight: 700; margin-top: auto; }
.pcard .mrp { font-size: .76rem; color: var(--muted); text-decoration: line-through; font-weight: 400; margin-left: .25rem; }
.pcard .margin { color: var(--ok); font-size: .76rem; font-weight: 700; margin-left: .25rem; }
.pcard label.pick {
  display: flex; align-items: center; gap: .35rem; font-size: .78rem;
  margin: .45rem -.7rem -.7rem; padding: .45rem .7rem; color: var(--muted);
  font-weight: 500; border-top: 1px solid var(--line); cursor: pointer;
}
.pcard label.pick:hover { background: #f8fafc; }
.pcard label.pick input { width: 16px; height: 16px; }

.crumbs { font-size: .82rem; color: var(--muted); padding: .5rem 0 0; }
.crumbs a { color: var(--muted); }
.crumbs b { color: var(--ink); }

.orderbar {
  position: fixed; left: 0; right: 0; bottom: 0; background: var(--ink); color: #fff;
  padding: .7rem 1rem; display: none; align-items: center; gap: .8rem; z-index: 50;
}
.orderbar.show { display: flex; }
.orderbar .wrap { display: flex; align-items: center; gap: .8rem; width: 100%; max-width: 1100px; }
.orderbar b { flex: 1; font-size: .9rem; }
.orderbar .btn { background: #22c55e; border-color: #22c55e; }

.pub-head .phones { display: flex; gap: .7rem; flex-wrap: wrap; font-size: .88rem; }
.pub-head .phones a { white-space: nowrap; }

/* Quantity sheet shown before the order goes to WhatsApp. */
.sheet-bg {
  position: fixed; inset: 0; background: rgba(15, 23, 42, .55); z-index: 100;
  display: none; align-items: flex-end; justify-content: center;
}
.sheet-bg.show { display: flex; }
.sheet {
  background: #fff; width: 100%; max-width: 520px; border-radius: 14px 14px 0 0;
  max-height: 88vh; display: flex; flex-direction: column;
}
.sheet header { padding: .9rem 1rem .6rem; border-bottom: 1px solid var(--line); }
.sheet header h2 { margin: 0; font-size: 1.05rem; }
.sheet header p { margin: .2rem 0 0; font-size: .82rem; color: var(--muted); }
.sheet .lines { overflow-y: auto; padding: .4rem 1rem; flex: 1; }
.qline {
  display: flex; align-items: center; gap: .6rem; padding: .55rem 0;
  border-bottom: 1px solid var(--line);
}
.qline:last-child { border-bottom: 0; }
.qline .who { flex: 1; min-width: 0; }
.qline .who b { display: block; font-size: .88rem; font-weight: 600; }
.qline .who span { font-size: .74rem; color: var(--muted); }
.qline input {
  width: 74px; flex: 0 0 74px; text-align: center; font-size: 1rem;
  padding: .4rem .3rem;
}
.qline .unit { font-size: .74rem; color: var(--muted); flex: 0 0 auto; width: 30px; }
.sheet footer { padding: .8rem 1rem; border-top: 1px solid var(--line); display: grid; gap: .45rem; }

@media (min-width: 560px) {
  .sheet-bg { align-items: center; }
  .sheet { border-radius: 14px; }
}

.spec { width: 100%; font-size: .88rem; }
.spec td { padding: .4rem .3rem; border-bottom: 1px solid var(--line); }
.spec td:first-child { color: var(--muted); width: 42%; }

.empty { text-align: center; padding: 3rem 1rem; color: var(--muted); }

/* ===========================================================================
   ADMIN ON A PHONE

   The desktop layout is deliberately untouched -- everything here lives inside
   the max-width query. What it fixes, measured on the Add-product screen:

     * 401px of navigation (19 links) sat above the content on EVERY page, so
       every screen began by scrolling past the whole menu. It is now behind a
       button in a bar, and the form starts at the top of the screen.
     * "Save product" was 2582px down a 2811px page. It is now a fixed bar at
       the bottom of the screen, reachable from anywhere in the form.

   Both matter because the job here is entering one product after another on a
   phone, not admiring the layout.
   =========================================================================== */

.m-bar { display: none; }                  /* desktop never sees these */
.m-actions { display: none; }

@media (max-width: 800px) {
  .shell { flex-direction: column; }
  .main { padding: .8rem .8rem 5.5rem; }   /* room for the fixed save bar */

  /* ---- the menu becomes a drawer behind a button ---- */
  .m-bar {
    display: flex; align-items: center; gap: .6rem;
    position: sticky; top: 0; z-index: 40;
    padding: .55rem .7rem;
    background: var(--ink); color: #fff;
  }
  .m-bar b { font-size: .95rem; font-weight: 600; flex: 1; min-width: 0;
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .m-burger {
    width: 42px; height: 38px; flex: none;
    display: flex; flex-direction: column; justify-content: center; gap: 4px;
    padding: 0 9px; background: transparent; border: 0; cursor: pointer;
  }
  .m-burger span { display: block; height: 2.5px; border-radius: 2px; background: #fff; }
  .m-bar .navcount { flex: none; }

  .side {
    position: fixed; inset: 0 auto 0 0; z-index: 60;
    width: min(82vw, 320px); flex: none;
    padding: .6rem;
    overflow-y: auto;
    transform: translateX(-102%);
    transition: transform .2s ease;
  }
  .shell .side.open { transform: translateX(0) !important; }
  .side nav a { font-size: .95rem; padding: .6rem .6rem; }  /* thumb-sized */
  .m-scrim {
    display: none; position: fixed; inset: 0; z-index: 55;
    background: rgba(0, 0, 0, .45);
  }
  .m-scrim.on { display: block; }

  /* ---- the primary action, always within reach ---- */
  .m-actions {
    display: flex; gap: .5rem; align-items: center;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
    padding: .55rem .7rem calc(.55rem + env(safe-area-inset-bottom));
    background: var(--card); border-top: 1px solid var(--line);
    box-shadow: 0 -4px 14px rgba(0, 0, 0, .09);
  }
  .m-actions .btn { flex: 1; min-height: 46px; font-size: .95rem; }

  /* Typing a product in is the whole job, so the fields get bigger and the
     16px minimum stops iOS zooming the page on every focus. */
  input[type=text], input[type=number], input[type=search], input[type=password],
  input[type=date], select, textarea {
    font-size: 16px; min-height: 44px;
  }
  textarea { min-height: 96px; }
  .row { flex-direction: column; gap: .5rem; }
  .row > div { max-width: none !important; width: 100%; }
  .topbar { margin-bottom: .7rem; gap: .4rem; }
  .topbar h1 { display: none; }
  .topbar .btn { padding: .35rem .6rem; font-size: .82rem; min-height: 36px; }
  .topbar:empty { display: none; }
  .card { padding: .8rem .75rem; }

  /* A wide table cannot be made narrow; let it scroll rather than crush it.
     Must stay scoped to <table>: .grid is also the card layout class. */
  table.grid { display: block; overflow-x: auto; white-space: nowrap; }
  .grid.g2, .grid.g3 { grid-template-columns: 1fr; }
}

/* Two across on a phone keeps photos big while still showing several at once. */
@media (max-width: 560px) {
  .plist { grid-template-columns: 1fr 1fr; gap: .5rem; }
  .pcard .shot, .pcard .shot { height: 132px; flex-basis: 132px; }
  .pcard .nm { font-size: .84rem; }
  .pcard .meta { font-size: .7rem; }
  .pcard .body { padding: .5rem .55rem .55rem; }
  .pcard label.pick { margin: .4rem -.55rem -.55rem; padding: .4rem .55rem; }
}

@media print {
  .side, .searchbar, .orderbar, .btn, .pager { display: none !important; }
  body { background: #fff; }
  .card { break-inside: avoid; }
}

/* ---------------------------------------------- theme picker (settings) */
.themepick {
  display: grid; gap: .6rem;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
}
.themecard {
  display: block; cursor: pointer; font-weight: 500;
  border: 2px solid var(--line); border-radius: 10px;
  padding: .55rem; background: #fff; text-align: center;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.themecard:hover { border-color: var(--muted); }
.themecard.on { border-color: var(--brand); box-shadow: 0 0 0 3px rgba(0,0,0,.05); }
.themecard input { position: absolute; opacity: 0; pointer-events: none; }
.themecard b { display: block; font-size: .9rem; margin-top: .4rem; }
.themecard .swatch {
  display: block; height: 62px; border-radius: 6px; overflow: hidden;
  border: 1px solid var(--line); position: relative; padding: 6px;
}
.themecard .swatch .bar { display: block; height: 14px; margin: -6px -6px 7px; }
.themecard .swatch .chip {
  display: inline-block; width: 26px; height: 7px; border-radius: 3px; margin-bottom: 5px;
}
.themecard .swatch .line {
  display: block; height: 6px; border-radius: 3px; background: #fff;
  border: 1px solid rgba(0,0,0,.07); margin-bottom: 4px;
}
.themecard .swatch .line.short { width: 60%; }

/* ------------------------------------- multi-category picker (fields page) */
.catpick { border: 1px solid var(--line); border-radius: 8px; background: #fff; }
.catpick-head {
  display: flex; align-items: center; gap: .35rem;
  padding: .3rem .45rem; border-bottom: 1px solid var(--line); background: #f8fafc;
}
.catpick-head span[data-count] { flex: 1; font-weight: 600; }
.catpick-list { max-height: 148px; overflow-y: auto; padding: .3rem .45rem; }
.catpick-list label {
  display: flex; align-items: center; gap: .4rem;
  font-size: .84rem; font-weight: 500; margin-bottom: .12rem;
  padding-top: .12rem; padding-bottom: .12rem; cursor: pointer;
}
.catpick-list label:hover { background: #f1f5f9; border-radius: 4px; }
.catpick-list input { width: 15px; height: 15px; flex: 0 0 15px; }

/* ================================================= drafts / approval queue */

/* Count on the sidebar link, so work waiting is visible from any admin page. */
.navcount {
  display: inline-block; min-width: 20px; padding: 0 .35rem;
  border-radius: 10px; background: var(--bad); color: #fff;
  font-size: .7rem; font-weight: 700; text-align: center; line-height: 18px;
  margin-left: .25rem;
}

.draftlist { display: grid; gap: .5rem; }

.draft {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr) auto;
  gap: .7rem; align-items: start;
  padding: .6rem; border: 1px solid var(--line); border-radius: 8px;
  background: #fff;
}
/* Sent-back rows are the owner's own words coming back at them; amber marks
   them as somebody else's turn to act. */
.draft.back { border-left: 3px solid var(--warn); background: #fffdf7; }

.dshot {
  width: 72px; height: 72px; border-radius: 6px; overflow: hidden;
  border: 1px solid var(--line); background: #f8fafc;
  display: flex; align-items: center; justify-content: center;
}
.dshot img { width: 100%; height: 100%; object-fit: contain; }
.dshot .noshot { font-size: .66rem; color: var(--muted); text-align: center; }

.dbody { min-width: 0; }
.dname { font-weight: 700; font-size: 1rem; display: block; line-height: 1.25; }
.dmeta { font-size: .8rem; color: var(--muted); margin-top: .2rem; }
.dmeta b { color: var(--ink); }
.warnink { color: var(--bad) !important; }

.dnote {
  margin-top: .45rem; padding: .4rem .6rem; border-radius: 6px;
  background: #fffbeb; border: 1px solid #fde68a; font-size: .84rem;
}

.dact { display: grid; gap: .35rem; justify-items: stretch; min-width: 190px; }
.dact form { margin: 0; }
.dact .btn { width: 100%; }
.dact .sendback { display: flex; gap: .25rem; }
.dact .sendback input { font-size: .78rem; padding: .3rem .45rem; min-width: 0; }
.dact .sendback .btn { width: auto; flex: 0 0 auto; white-space: nowrap; }

/* Only the owner gets a tick box, so the column only exists for them --
   staff never see a control they are not allowed to use. */
.draft.ticked { grid-template-columns: 22px 72px minmax(0, 1fr) auto; }
.dpick { margin: 0; padding-top: .2rem; }
.dpick input { width: 17px; height: 17px; }

.btn.ghost.on { border-color: var(--brand); color: var(--brand); font-weight: 700; }

/* Draft banner on the product edit screen. */
.reviewbar {
  border: 1px solid var(--line); border-left: 3px solid var(--warn);
  background: #fffbeb; border-radius: 0 8px 8px 0;
  padding: .7rem .9rem; margin-bottom: 1rem;
}
.reviewbar b { display: block; margin-bottom: .15rem; }
.reviewbar .note-back {
  margin-top: .45rem; padding-top: .45rem; border-top: 1px solid #fde68a;
  font-size: .88rem;
}

@media (max-width: 800px) {
  .draft { grid-template-columns: 56px minmax(0, 1fr); }
  .draft.ticked { grid-template-columns: 22px 56px minmax(0, 1fr); }
  .dshot { width: 56px; height: 56px; }
  .dact { grid-column: 1 / -1; min-width: 0; }
}

/* The drafts tile is a link, and turns amber when there is work waiting. */
a.stat { display: block; color: inherit; }
a.stat:hover { border-color: var(--muted); text-decoration: none; }
a.stat.urgent { border-color: var(--warn); background: #fffbeb; }
a.stat.urgent b { color: var(--warn); }

/* ------------------------------------------- brand circle + banner previews */
.brandlogo { display: flex; align-items: center; gap: .4rem; }
.brandlogo > span:last-child { display: grid; gap: .25rem; min-width: 0; }
.brandlogo input[type=file] { font-size: .68rem; width: 100%; padding: .15rem; }
.circlepv {
  flex: 0 0 44px; width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  color: #fff; font-weight: 800; font-size: .72rem; letter-spacing: .02em;
}
.circlepv img { width: 100%; height: 100%; object-fit: contain; background: #fff; }

.schemepick { display: flex; gap: .3rem; flex-wrap: wrap; }
.schemecard { margin: 0; cursor: pointer; }
.schemecard input { position: absolute; opacity: 0; pointer-events: none; }
.schemecard span {
  display: block; padding: .4rem .7rem; border-radius: 6px;
  font-size: .78rem; font-weight: 700; border: 2px solid transparent;
}
.schemecard input:checked + span { border-color: var(--ink); }

.bnr-head { display: flex; gap: .8rem; align-items: center; flex-wrap: wrap; }
/* Mirrors what the strip actually does: the photo fills the whole banner,
   darkened from the left, with the words pinned into the first quarter of it.
   If this drifts from .offer in catalog.css the preview starts lying about
   what the customer will see. */
.bnr-prev {
  flex: 1; min-width: 220px; position: relative; display: block;
  border-radius: 8px; overflow: hidden; min-height: 84px;
}
.bnr-prev img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.bnr-prev .wash {
  position: absolute; inset: 0;
  background: linear-gradient(90deg,
              rgba(0, 0, 0, .88) 0%,
              rgba(0, 0, 0, .74) 38%,
              rgba(0, 0, 0, .32) 72%,
              rgba(0, 0, 0, .05) 100%);
}
.bnr-prev .wash + .words { color: #fff; }
.bnr-prev .words {
  position: relative; z-index: 2;
  width: 26%; min-width: 0; padding: .6rem .7rem;
}
.bnr-prev em { display: block; font-style: normal; font-weight: 800; font-size: .8rem; line-height: 1.15;
               overflow-wrap: anywhere; }
.bnr-prev i { display: block; font-style: normal; font-size: .66rem; opacity: .85; margin-top: .2rem;
              line-height: 1.2; overflow-wrap: anywhere; }
.bnr-red   { background: #C8102E; color: #fff; }
.bnr-black { background: #141414; color: #fff; }
.bnr-amber { background: #F2B705; color: #1A1A1A; }
.bnr-green { background: #15803D; color: #fff; }
.bnr-blue  { background: #12448C; color: #fff; }
.bnr-cream { background: #F3EDE1; color: #1A1A1A; }
.bnr-state { display: flex; gap: .35rem; align-items: center; flex-wrap: wrap; }

/* ------------------------------------------------ keywords + AI description */
.labelrow { display: flex; align-items: center; gap: .5rem; margin-bottom: .25rem; }
.labelrow label { margin: 0; flex: 1; }

.aibtn { display: inline-flex; align-items: center; gap: .3rem; white-space: nowrap; }
.aispark { color: var(--brand); font-size: .95em; }
.aibtn:disabled { opacity: .6; }
.aihint {
  margin-top: .35rem; padding: .4rem .6rem; border-radius: 6px;
  background: #eff6ff; color: #1e40af; font-size: .82rem;
}
.aihint.bad { background: #fee2e2; color: #991b1b; }

/* Chips, so a long list of layman words stays readable while it is typed. */
.kwbox {
  display: flex; flex-wrap: wrap; align-items: center; gap: .3rem;
  min-height: 42px; padding: .3rem .4rem;
  border: 1px solid #cbd5e1; border-radius: 7px; background: #fff;
  cursor: text;
}
.kwbox:focus-within { outline: 2px solid var(--brand); outline-offset: -1px; border-color: var(--brand); }
.kwbox input {
  flex: 1; min-width: 120px; width: auto;
  border: 0; padding: .2rem; outline: none;
}
.kwchip {
  display: inline-flex; align-items: center; gap: .25rem;
  padding: .18rem .3rem .18rem .5rem;
  border-radius: 20px; background: #e2e8f0; color: var(--ink);
  font-size: .82rem; font-weight: 500;
}
.kwchip button {
  border: 0; background: transparent; cursor: pointer;
  color: var(--muted); font-size: 1rem; line-height: 1;
  padding: 0 .2rem;
}
.kwchip button:hover { color: var(--bad); }

/* ------------------------------------------------- AI provider picker */
.aiprov { display: grid; gap: .5rem; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.provcard {
  display: block; cursor: pointer; margin: 0;
  border: 2px solid var(--line); border-radius: 8px;
  padding: .6rem .7rem; background: #fff; font-weight: 500;
}
.provcard:hover { border-color: var(--muted); }
.provcard.on { border-color: var(--brand); background: #f8faff; }
.provcard input { position: absolute; opacity: 0; pointer-events: none; }
.provcard b { display: block; font-size: .95rem; margin-bottom: .15rem; }
.provcard span { display: block; line-height: 1.35; }
.provcard .mono { color: var(--brand); margin-top: .2rem; }

.aitest { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-top: .6rem; }
.aitest .small { flex: 1; min-width: 160px; }


/* ------------------------------------------- typeface picker (settings page)
   Each card renders its own sample in the pairing it offers, so the choice is
   made by looking rather than by reading font names. */
.fontpick {
  display: grid; gap: .6rem;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}
.fontcard {
  display: block; cursor: pointer; position: relative;
  border: 2px solid var(--line); border-radius: 10px;
  padding: .7rem .75rem .6rem; background: #fff;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.fontcard:hover { border-color: var(--muted); }
.fontcard.on { border-color: var(--brand); box-shadow: 0 0 0 3px rgba(0,0,0,.05); }
.fontcard input { position: absolute; opacity: 0; pointer-events: none; }
.fontcard .fsample {
  display: block; border: 1px solid var(--line); border-radius: 6px;
  padding: .55rem .6rem; margin-bottom: .5rem; background: #fff;
}
.fontcard .fsample .fhead {
  display: block; font-weight: 700; font-size: 1.15rem; line-height: 1.05;
  text-transform: uppercase; letter-spacing: -.01em; color: #111;
}
.fontcard .fsample .fbody {
  display: block; font-size: .8rem; line-height: 1.35; color: #444; margin-top: .3rem;
}
.fontcard .fsample .fprice {
  display: block; font-weight: 700; font-size: .95rem; margin-top: .35rem; color: #111;
}
.fontcard > b { display: block; font-size: .92rem; }
.fontcard > .small { display: block; }

/* A listing taken off the catalogue is the one dashboard row that should not
   read like the others -- it means customers are not seeing stock right now. */
tr.alarm td { background: #FEF2F2; }
tr.alarm td:first-child { box-shadow: inset 3px 0 0 #C8102E; }
.navcount.warn { background: #C8102E; color: #fff; }

/* ------------------------------------------------ product photo gallery
   One product, several angles. The first is the cover and is what the
   catalogue, the cards and the WhatsApp share preview all use. */
.shots { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: .5rem; }
.shot {
  position: relative; display: block; border: 1px solid var(--line);
  border-radius: 8px; overflow: hidden; background: #fff;
}
.shot.cover { border-color: var(--brand); box-shadow: 0 0 0 2px rgba(0,0,0,.05); }
.shot img { display: block; width: 100%; height: 104px; object-fit: contain; background: #f8fafc; }
.shot-tag {
  position: absolute; top: 4px; left: 4px;
  background: var(--brand); color: #fff; border-radius: 4px;
  font-size: .64rem; font-weight: 700; padding: .1rem .3rem;
  text-transform: uppercase; letter-spacing: .04em;
}
.shot-acts { display: flex; align-items: center; justify-content: space-between;
             gap: .3rem; padding: .3rem .35rem; border-top: 1px solid var(--line); }
.shot-acts .btn.sm { padding: .15rem .35rem; font-size: .68rem; }
.shot-drop { display: flex; align-items: center; gap: .2rem; font-size: .7rem; color: var(--muted); }
.shot-drop input { margin: 0; }

/* Three order quantities side by side. A dropdown you can also type into:
   the datalist offers the usual figures, the number input takes anything. */
.bulkfields { display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; }

/* ===================================================================== orders
   Orders a customer sent from the catalogue. The whole screen is arranged
   around one action -- download the quotation -- because the thing that wins
   a wholesale order is answering before the other shop does. */

/* Green, not red. Work waiting in Drafts is a chore; an order waiting is
   money, and it should not read like a warning light. */
.navcount.hot { background: var(--ok); color: #fff; }

.tabrow { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .9rem; }
.tab {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .4rem .75rem; border: 1px solid var(--line); border-radius: 999px;
  background: #fff; color: var(--ink) !important; font-size: .86rem; font-weight: 600;
}
.tab:hover { border-color: var(--muted); text-decoration: none; }
.tab span { color: var(--muted); font-size: .78rem; font-weight: 700; }
.tab.on { background: var(--ink); border-color: var(--ink); color: #fff !important; }
.tab.on span { color: #cbd5e1; }

/* An order nobody has opened. A left edge rather than a filled row, so a list
   of twenty new orders is still a list and not a block of colour. */
tr.unseen td { background: #F0FDF4; }
tr.unseen td:first-child { box-shadow: inset 3px 0 0 var(--ok); }

.tag.new { background: #dcfce7; color: #166534; }
.tag.st-new    { background: #dcfce7; color: #166534; }
.tag.st-quoted { background: #dbeafe; color: #1e40af; }
.tag.st-won    { background: #0f766e; color: #fff; }
.tag.st-lost   { background: #e2e8f0; color: #475569; }

.quoteout {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 1rem; border: 1px solid var(--ok); box-shadow: inset 4px 0 0 var(--ok);
}
.quoteout h2 { margin: 0 0 .2rem; }
.quoteout p { margin: 0; max-width: 46ch; }
.quotebtns { display: flex; gap: .5rem; flex-wrap: wrap; }

.ometa { display: flex; flex-wrap: wrap; gap: 1.6rem; }
.ometa > div { display: flex; flex-direction: column; gap: .1rem; }
.ometa span { font-size: .74rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.ometa b { font-size: 1.02rem; }

.othumb { width: 44px; height: 44px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); display: block; }

.statusrow { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: .5rem; }

@media (max-width: 800px) {
  .quoteout { flex-direction: column; align-items: stretch; }
  .quotebtns .btn { flex: 1; text-align: center; }
  .ometa { gap: .9rem 1.4rem; }
}

/* ------------------------------------------- finding a category to edit
   Sixty-odd rows is past the point where scrolling to one is reasonable. */
.treehead {
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem 1rem;
  justify-content: space-between; margin-bottom: .7rem;
}
.treehead h2 { margin: 0; }

/* Sized to be aimed at, not hunted for. It grows into whatever the heading
   leaves free rather than sitting at a fixed width, so on a wide screen it is
   the obvious thing on the row. */
.catfind {
  display: flex; align-items: center; gap: .6rem;
  flex: 1 1 380px; max-width: 560px; min-width: 0;
  padding: 0 .55rem 0 .9rem;
  border: 1px solid var(--line); border-radius: 999px; background: #fff;
  color: var(--muted);
}
.catfind:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px rgba(29, 78, 216, .12); }
.catfind svg { width: 20px; height: 20px; flex: none; }
.catfind input {
  flex: 1; min-width: 0; height: 46px; padding: 0;
  border: 0; outline: 0; background: transparent;
  font: inherit; font-size: 1.02rem; color: var(--ink);
  -webkit-appearance: none; appearance: none;
}
.catfind input::placeholder { color: var(--muted); }
.catfind input::-webkit-search-cancel-button { display: none; }
.catclear {
  width: 30px; height: 30px; border: 0; border-radius: 50%;
  background: var(--line); color: var(--ink); font-size: 1.2rem; line-height: 1;
  cursor: pointer; flex: none;
}
.catcount { font-size: .84rem; color: var(--muted); white-space: nowrap; padding-right: .45rem; }

/* A row hides rather than moves: its Save button lives in another cell and
   points at the row's form by id, and that link must survive filtering. */
tbody tr[hidden] { display: none; }

@media (max-width: 800px) {
  /* Stacked, and the width said outright. A wrapping column flex container
     sizes its line to the widest item rather than to itself, so "stretch"
     alone let this run off the side of the card and gave the admin a
     sideways scroll. */
  .treehead { flex-direction: column; align-items: stretch; flex-wrap: nowrap; }
  .catfind { flex: 0 0 auto; width: 100%; max-width: none; }
}

/* ------------------------------------- price review: the windows themselves
   A list rather than a table: one name, one dropdown, nothing else to read.
   The indent carries the tree, so setting a Category and watching the rows
   under it change is the whole explanation of how inheritance works here. */
.winrow {
  display: flex; align-items: center; gap: 1rem;
  padding: .45rem .2rem; border-bottom: 1px solid var(--line);
}
.winrow:last-of-type { border-bottom: 0; }
.winrow form { margin: 0; display: flex; align-items: center; gap: .4rem; }
.winrow select { min-width: 230px; max-width: 260px; }
.winname { flex: 1; min-width: 0; font-weight: 600; }
.winname .small { display: block; font-weight: 400; }
.winrow.lvl1 .winname { padding-left: 1.4rem; font-weight: 500; }
.winrow.lvl2 .winname { padding-left: 2.8rem; font-weight: 400; }

/* The shop-wide line is not one of the categories and should not read as one. */
.winrow.site {
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
  padding: .6rem .8rem; margin-bottom: .6rem;
}

@media (max-width: 800px) {
  .winrow { flex-direction: column; align-items: stretch; gap: .35rem; padding: .6rem .2rem; }
  .winrow select { min-width: 0; max-width: none; width: 100%; }
  .winrow form { display: block; }
  .winrow.lvl1 .winname { padding-left: .9rem; }
  .winrow.lvl2 .winname { padding-left: 1.8rem; }
}
