/* =========================================================
   The Laundry & Co - POS
   Brand cyan #00A8DC, deep navy #0A2A3F
   ========================================================= */
:root{
  --brand:#00A8DC;
  --brand-dark:#0089b5;
  --brand-darker:#00658a;
  --brand-tint:#e9f7fd;
  --brand-tint-2:#d3eefa;

  --navy:#0a2a3f;
  --navy-2:#134563;
  --ink:#0e2a3d;
  --text:#22333d;
  --muted:#6d818c;
  --line:#e2eaef;
  --line-soft:#eef3f6;
  --bg:#f2f6f9;
  --card:#ffffff;

  --ok:#15a34a;
  --warn:#e08600;
  --danger:#dc2626;

  --r:14px;
  --r-sm:10px;
  --sh-1:0 1px 2px rgba(14,42,61,.05);
  --sh-2:0 2px 4px rgba(14,42,61,.05), 0 8px 24px rgba(14,42,61,.07);
  --sh-3:0 12px 34px rgba(14,42,61,.13);
  --sh-brand:0 6px 18px rgba(0,168,220,.32);
}

*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:"Plus Jakarta Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  background:var(--bg); color:var(--text);
  font-size:15px; line-height:1.55;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  font-feature-settings:"tnum" 1;   /* lining figures so prices line up */
}
a{color:var(--brand-dark);text-decoration:none}
a:hover{text-decoration:underline}
h1,h2,h3,h4{margin:0 0 .5rem;line-height:1.25;color:var(--ink);letter-spacing:-.01em}
h1{font-size:1.45rem}
h2{font-size:1.1rem}
h3{font-size:1rem}
.muted{color:var(--muted)}
.small{font-size:.82rem}
.right{text-align:right}
.center{text-align:center}
.nowrap{white-space:nowrap}
.mt{margin-top:1rem}
.mb{margin-bottom:1.1rem}
.hidden{display:none !important}

/* ---------------- Login / setup ---------------- */
.auth-body{
  min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px;
  background:
    radial-gradient(1100px 620px at 12% -8%, rgba(0,168,220,.30), transparent 60%),
    radial-gradient(900px 560px at 108% 108%, rgba(0,168,220,.20), transparent 58%),
    linear-gradient(158deg,#103b57 0%,#0a2a3f 46%,#061a27 100%);
}
.auth-wrap{width:100%;max-width:392px}
.auth-card{
  width:100%;background:var(--card);border-radius:20px;padding:30px 30px 34px;
  box-shadow:0 26px 70px rgba(0,0,0,.42);
}
/* The logo sits on the dark page, not in the white card: the brand lockup is
   the light one, and it needs a dark ground to read as itself. */
.auth-logo{display:block;width:80%;max-width:250px;margin:0 auto 26px;
           filter:drop-shadow(0 8px 22px rgba(0,0,0,.45))}
.auth-card h1{text-align:center;font-size:1.22rem;margin-bottom:.15rem}
.auth-card > .muted{text-align:center;margin:0 0 .3rem}
.auth-card label{display:block;margin:.85rem 0 0;font-size:.78rem;color:var(--muted);
                 font-weight:700;text-transform:uppercase;letter-spacing:.06em}
.auth-card input{margin-top:.3rem}

/* ---- password box with a show/hide button (built by assets/js/ui.js) ---- */
.pw-wrap{position:relative;display:block}
.pw-wrap > input{padding-right:44px !important}
.pw-eye{
  position:absolute;top:50%;right:6px;transform:translateY(-50%);
  width:32px;height:32px;padding:0;display:flex;align-items:center;justify-content:center;
  border:0;background:transparent;color:var(--muted);cursor:pointer;border-radius:8px;
}
.pw-eye:hover{color:var(--brand-darker);background:var(--line-soft)}
.pw-eye svg{width:19px;height:19px;display:block}
.pw-caps{
  display:block;margin-top:5px;font-size:.75rem;font-weight:700;
  color:#b45309;text-transform:none;letter-spacing:0;
}

/* ---------------- Forms ---------------- */
input[type=text],input[type=password],input[type=number],input[type=date],
input[type=tel],input[type=search],input[type=email],select,textarea{
  width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:var(--r-sm);
  font-size:.95rem;font-family:inherit;background:#fff;color:var(--text);
  transition:border-color .14s, box-shadow .14s;
}
input::placeholder{color:#9fb0ba}
input:focus,select:focus,textarea:focus{
  outline:none;border-color:var(--brand);box-shadow:0 0 0 3.5px rgba(0,168,220,.16);
}
label.fld{display:block;margin-bottom:.8rem;font-size:.76rem;font-weight:700;color:var(--muted);
          text-transform:uppercase;letter-spacing:.05em}
/* .pw-wrap is in this list because the show/hide button puts a span between
   the label and its input, which would otherwise drop the input straight out
   of a direct-child selector and leave it unstyled. */
label.fld > input,label.fld > select,label.fld > textarea,
label.fld > .pw-wrap > input{
  margin-top:.3rem;font-weight:400;color:var(--text);text-transform:none;letter-spacing:0;font-size:.95rem;
}
label.fld > .pw-wrap{margin-top:0}
/* explanatory line under a field. The label itself is uppercase; a sentence
   in that treatment is unreadable, so this puts it back to normal prose. */
label.fld > .fld-hint{
  display:block;margin-top:.35rem;font-size:.78rem;font-weight:500;line-height:1.5;
  text-transform:none;letter-spacing:0;color:var(--muted);
}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:0 14px}
.grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:0 14px}

/* ---------------- Buttons ---------------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:10px 16px;border-radius:var(--r-sm);border:1px solid var(--line);background:#fff;
  color:var(--text);font-size:.9rem;font-weight:600;cursor:pointer;font-family:inherit;
  white-space:nowrap;box-shadow:var(--sh-1);transition:background .14s,border-color .14s,transform .08s,box-shadow .14s;
}
.btn:hover{text-decoration:none;background:#f7fafc;border-color:#cfdde5}
.btn:active{transform:translateY(1px)}
.btn-primary{background:linear-gradient(180deg,#12b6e6,#00a1d2);border-color:#0098c7;color:#fff;box-shadow:var(--sh-brand)}
.btn-primary:hover{background:linear-gradient(180deg,#00a8dc,#0089b5);border-color:#0089b5}
.btn-dark{background:var(--navy);border-color:var(--navy);color:#fff}
.btn-dark:hover{background:#123a54;border-color:#123a54}
.btn-danger{background:#fff;border-color:#f0cccc;color:var(--danger)}
.btn-danger:hover{background:#fdf3f3;border-color:#e6b3b3}
.btn-ghost{background:transparent;border-color:transparent;box-shadow:none}
.btn-ghost:hover{background:var(--line-soft)}
.btn-block{width:100%;margin-top:1rem;padding:12px}
.btn-sm{padding:6px 11px;font-size:.8rem;border-radius:8px}

/* The actions cell in a list row. Deliver, Open, Receipt, Void and delete
   is five controls; at normal button size they push the column wide enough
   to squeeze the customer name out. Smaller type and a tight wrap keeps
   them to two rows without the column growing. */
table.tbl td.row-actions{
  display:flex;flex-wrap:wrap;justify-content:flex-end;gap:4px;
  max-width:190px;margin-left:auto;
}
table.tbl td.row-actions > form{display:contents}
table.tbl td.row-actions .btn{
  padding:4px 9px;font-size:.74rem;border-radius:7px;font-weight:700;box-shadow:none;
}
.btn-lg{padding:14px 22px;font-size:1rem}
.btn:disabled{opacity:.45;cursor:not-allowed;box-shadow:none;transform:none}

/* ---------------- Layout ---------------- */
.app{display:flex;min-height:100vh}
.sidebar{
  width:224px;flex:0 0 224px;color:#b9cdd8;display:flex;flex-direction:column;
  position:sticky;top:0;height:100vh;
  background:linear-gradient(180deg,#103b57 0%,#0a2a3f 55%,#072130 100%);
}
.sidebar-logo{padding:18px 18px 14px;border-bottom:1px solid rgba(255,255,255,.07)}
.sidebar-logo img{height:36px;display:block}
.nav{padding:12px 10px;flex:1;overflow-y:auto}
.nav a{
  position:relative;display:flex;align-items:center;gap:10px;padding:10px 13px;border-radius:var(--r-sm);
  color:#a9c1ce;font-size:.9rem;font-weight:600;margin-bottom:3px;transition:background .14s,color .14s;
}
.nav a:hover{background:rgba(255,255,255,.07);color:#fff;text-decoration:none}
.nav a.active{background:linear-gradient(90deg,var(--brand),#0095c4);color:#fff;box-shadow:var(--sh-brand)}
.nav .nav-sep{margin:16px 13px 7px;font-size:.66rem;letter-spacing:.13em;text-transform:uppercase;color:#5d7a8a}
.nav .ic{width:18px;text-align:center;font-size:1rem;opacity:.95}
.sidebar-foot{padding:14px;border-top:1px solid rgba(255,255,255,.07);font-size:.8rem}
.sidebar-foot .who{color:#fff;font-weight:700}
.sidebar-foot .role{color:#7f9aab;font-size:.68rem;text-transform:uppercase;letter-spacing:.1em;margin-top:1px}
.sidebar-foot a{color:#9fb8c6;display:inline-block;margin-top:8px;font-weight:600}

.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{
  background:rgba(255,255,255,.9);backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line);padding:13px 22px;
  display:flex;align-items:center;gap:12px;position:sticky;top:0;z-index:30;
}
.topbar h1{margin:0;font-size:1.06rem}
.topbar .spacer{flex:1}
.content{padding:22px;flex:1}
.menu-toggle{display:none;background:none;border:0;font-size:1.4rem;cursor:pointer;color:var(--ink)}

/* ---------------- Cards & tables ---------------- */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh-2)}
.card-h{padding:14px 18px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px}
.card-h h2{margin:0;font-size:.98rem}
.card-h .spacer{flex:1}
.card-b{padding:18px}
.card-b.tight{padding:0}

.table-wrap{overflow-x:auto}
table.tbl{width:100%;border-collapse:collapse;font-size:.9rem}
table.tbl th,table.tbl td{padding:11px 14px;text-align:left;border-bottom:1px solid var(--line-soft);vertical-align:middle}
table.tbl th{background:#f8fbfc;font-size:.71rem;text-transform:uppercase;letter-spacing:.07em;
             color:var(--muted);font-weight:800;white-space:nowrap}
table.tbl tbody tr:hover{background:#f9fcfe}
table.tbl tbody tr:last-child td{border-bottom:0}
table.tbl td.num,table.tbl th.num{text-align:right;white-space:nowrap}
/* a totals row has to read as a sum, not as one more row of data */
table.tbl tfoot td{
  border-top:2px solid var(--line);border-bottom:0;
  background:#f8fbfc;font-weight:800;color:var(--text);
}
.empty{padding:38px 16px;text-align:center;color:var(--muted)}

/* ---------------- Badges / alerts ---------------- */
.badge{display:inline-block;padding:3px 10px;border-radius:99px;font-size:.71rem;font-weight:800;letter-spacing:.02em}
.b-received{background:var(--brand-tint);color:var(--brand-darker)}
.b-process{background:#fef3c7;color:#92400e}
.b-ready{background:#dcfce7;color:#166534}
.b-delivered{background:#e8edf1;color:#3c4c57}
.b-cancelled{background:#fee2e2;color:#991b1b}
.b-paid{background:#dcfce7;color:#166534}
.b-due{background:#fee2e2;color:#991b1b}

.alert{padding:12px 15px;border-radius:var(--r-sm);margin-bottom:14px;font-size:.9rem}
.alert-ok{background:#e9f9f0;color:#14532d;border:1px solid #bfe9cf}
.alert-err{background:#fdeeee;color:#7f1d1d;border:1px solid #f5cccc}
.alert-info{background:var(--brand-tint);color:#00506e;border:1px solid #bde7f7}

/* ---------------- Stats ---------------- */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px;margin-bottom:20px}
.stat{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:16px 18px;box-shadow:var(--sh-2)}
.stat .k{font-size:.7rem;text-transform:uppercase;letter-spacing:.09em;color:var(--muted);font-weight:800}
.stat .v{font-size:1.6rem;font-weight:800;color:var(--ink);margin-top:4px;letter-spacing:-.02em}
.stat.accent{border-top:3px solid var(--brand)}
.stat.warnline{border-top:3px solid var(--warn)}
.stat.okline{border-top:3px solid var(--ok)}

/* icon preview in Items & Prices */
.ipic{
  width:34px;height:34px;border-radius:9px;display:inline-flex;align-items:center;justify-content:center;
  background:var(--brand-tint);color:var(--brand-darker);border:1px solid #d3ecf7;
}
.ipic svg{width:21px;height:21px;display:block}

/* ---------------- Toolbar ---------------- */
.toolbar{display:flex;flex-wrap:wrap;gap:9px;align-items:flex-end;margin-bottom:16px}
.toolbar .fld{margin-bottom:0}
.toolbar input,.toolbar select{min-width:150px}

/* ================= POS ================= */
.pos{display:grid;grid-template-columns:minmax(0,1fr) 452px;gap:18px;align-items:start}
.pos-left{min-width:0}

.pos-search{display:flex;gap:9px;margin-bottom:14px}
.pos-search input[type=search]{
  flex:1;padding:14px 16px;font-size:1rem;border-radius:var(--r);box-shadow:var(--sh-1);
}
.pos-search .btn{padding:0 18px}

/* ---- category filters -------------------------------------------------
   The item grid below is a field of white tiles. A bare row of white
   category tiles above it simply merged into that field, so the filters
   now live in a tinted panel with its own heading: one glance separates
   "what am I filtering by" from "what can I add". */
.cat-bar{
  background:linear-gradient(180deg,#f1f9fd 0%,#e6f3fa 100%);
  border:1px solid #cfe4f0;border-radius:18px;
  padding:12px 14px 14px;margin-bottom:20px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9);
}
.cat-bar-h{
  font-size:.72rem;font-weight:800;letter-spacing:.09em;text-transform:uppercase;
  color:#5f8fa6;margin:0 2px 10px;
}
/* A grid rather than a wrapping row. Tiles sized to their own text wrapped
   wherever they happened to run out of room, which left the strip three
   rows deep with a single tile stranded on the last one. Equal columns,
   counted in pos.php so everything fits in two. */
.chips{display:grid;grid-template-columns:repeat(var(--cols,4),minmax(0,1fr));gap:14px}

/* Each tile carries its category's colour, but washed right down - the
   ::before layer is the tint at 12%, so the strip reads as one calm family
   while every category is still its own colour. --tint comes from pos.php. */
.chip{
  --tint:#00A8DC;
  position:relative;overflow:hidden;isolation:isolate;
  display:flex;align-items:center;gap:13px;min-width:0;
  padding:15px 16px 15px 15px;border-radius:19px;
  border:1.5px solid #d2e6f0;background:#fff;color:var(--text);
  box-shadow:0 1px 3px rgba(16,60,80,.07);
  font-weight:700;font-size:1.06rem;cursor:pointer;font-family:inherit;
  transition:transform .14s, box-shadow .14s, border-color .14s;
  text-align:left;line-height:1.2;letter-spacing:-.01em;
}
.chip::before{
  content:"";position:absolute;inset:0;z-index:-1;
  background:var(--tint);opacity:.12;
}
.chip .ci{
  position:relative;width:52px;height:52px;border-radius:15px;flex:0 0 52px;
  display:flex;align-items:center;justify-content:center;
  color:var(--tint);transition:transform .14s;
}
/* the same colour again, a little stronger, behind the icon */
.chip .ci::before{
  content:"";position:absolute;inset:0;border-radius:inherit;
  background:var(--tint);opacity:.18;
}
.chip .ci svg{position:relative;width:29px;height:29px;display:block;stroke-width:1.7}
/* Four to a row leaves a narrow column, and a name is no use half shown -
   "Home Te..." tells you less than a tile that is a line taller. So the
   label wraps instead of being cut, and the count rides along with it. */
.chip .cl{display:block;min-width:0;flex:1;line-height:1.24}
.chip .n{display:inline-block;margin-left:9px;vertical-align:middle}
.chip .n{
  min-width:34px;padding:4px 12px;border-radius:99px;text-align:center;
  background:rgba(255,255,255,.75);color:var(--muted);font-size:.9rem;font-weight:800;
}
.chip:hover{border-color:var(--tint);transform:translateY(-2px);box-shadow:var(--sh-2)}
.chip:hover .ci{transform:scale(1.06)}

/* the selected filter drops the wash and takes the colour at full strength */
.chip.active{
  border-color:var(--tint);color:#fff;
  box-shadow:0 6px 18px rgba(16,60,80,.22);
}
.chip.active::before{opacity:1}
.chip.active .ci{color:#fff}
.chip.active .ci::before{background:#fff;opacity:.24}
.chip.active .n{background:rgba(255,255,255,.26);color:#fff}
.chip.active::after{
  content:"";position:absolute;top:-22px;right:-22px;width:54px;height:54px;
  border-radius:50%;background:rgba(255,255,255,.16);
}

/* ---- category tabs (Items & Prices) -----------------------------------
   These carried no styling at all, so the categories rendered as one run of
   blue text - "Men Women Home Textile Wash & Fold" read as a sentence rather
   than as seven things you can click. */
.cat-tabs{
  display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px;padding:8px;
  border:1px solid #cfe4f0;border-radius:14px;
  background:linear-gradient(180deg,#f1f9fd 0%,#e6f3fa 100%);
}
.cat-tabs .tab{
  padding:9px 16px;border-radius:10px;white-space:nowrap;
  border:1px solid #dceaf2;background:#fff;color:var(--text);
  font-size:.92rem;font-weight:700;text-decoration:none;
  box-shadow:0 1px 2px rgba(16,60,80,.06);
  transition:background .14s, color .14s, border-color .14s, transform .14s;
}
.cat-tabs .tab:hover{border-color:#a9d3e6;transform:translateY(-1px);text-decoration:none}
.cat-tabs .tab.active{
  background:linear-gradient(155deg,#16bdec 0%,#0092c0 100%);
  border-color:#0092c0;color:#fff;
  box-shadow:0 4px 12px rgba(0,168,220,.35);
}

/* names the section under the filter panel, so the two never read as one list */
.items-head{display:flex;align-items:center;gap:12px;margin:0 2px 12px}
.items-head h3{margin:0;font-size:1rem;letter-spacing:-.01em;white-space:nowrap}
.items-head .cnt{font-size:.8rem;font-weight:700;color:var(--muted);white-space:nowrap}
.items-head::after{content:"";flex:1;height:1px;background:var(--line)}

.items-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(238px,1fr));gap:12px}

/* ---- the till fills the window, and only the items scroll -------------
   Letting the whole page scroll meant that on a laptop the category strip
   and the search box scrolled away with everything else, so the cashier
   lost their place on every order and the items below the fold looked
   simply missing. The window is the frame now: the strip and the ticket
   stay where they are and the item grid moves inside its own box.
   Narrow screens keep ordinary page scrolling - stacked on a phone, a
   fixed frame would leave nothing usable. */
@media (min-width:1101px){
  body.pos-fill{overflow:hidden}
  body.pos-fill .app{height:100vh}
  body.pos-fill .main{min-height:0}
  body.pos-fill .content{min-height:0;overflow:hidden;display:flex;flex-direction:column;padding-bottom:14px}
  /* The whole till is wrapped in <form id="orderForm">, so the form - not
     .pos - is what .content actually flexes. Without this the form sizes
     to its content, .pos inherits that height and the grid never gets a
     box to scroll inside. */
  body.pos-fill #orderForm{flex:1;min-height:0;display:flex;flex-direction:column}
  body.pos-fill .pos{flex:1;min-height:0;align-items:stretch}
  body.pos-fill .pos-left{display:flex;flex-direction:column;min-height:0}
  body.pos-fill .items-grid{
    flex:1;min-height:0;overflow-y:auto;align-content:start;
    padding:2px 6px 16px 2px;margin-right:-4px;
  }
  body.pos-fill .pos-right{position:static;min-height:0;display:flex}

  /* The ticket scrolls as one piece.
     Its contents come to roughly 900px - customer, cart, totals, and the
     footer with payment, delivery date, notes and the Save button. On a
     1366x768 laptop the panel is 600px, so making only the cart scroll
     left the last 300px clipped behind overflow:hidden: the Save button
     was simply not on screen and nothing could reach it. Scrolling the
     whole panel means everything is reachable, and the footer is pinned
     so Save is always under the thumb. */
  body.pos-fill .ticket{max-height:none;flex:1;overflow-y:auto}
  body.pos-fill .tk-cart{flex:0 0 auto}
  body.pos-fill .tk-lines{min-height:0;overflow:visible}
  body.pos-fill .tk-foot{
    position:sticky;bottom:0;z-index:2;background:var(--card);
    box-shadow:0 -6px 14px rgba(14,42,61,.06);
  }
}

/* A 768px-tall laptop has about 380px left for items once the strip, the
   search box and the section heading have taken their share. Give some of
   it back rather than making the cashier scroll for the second row. */
/* A 768px laptop has roughly 670px of usable window. The header, search
   box and category strip were taking 500 of it and leaving one row of
   items - so on a short screen the strip becomes a single row that
   scrolls sideways rather than wrapping onto three, and everything above
   the grid gives back what it can. Tall screens keep the big tiles. */
@media (max-height:820px){
  body.pos-fill .content{padding:14px 18px 10px}
  .cat-bar{padding:7px 0 8px;margin-bottom:11px;border-radius:12px}
  .cat-bar-h{margin:0 0 6px 12px;font-size:.66rem}
  /* back to a single scrolling row - display must be reset, the base rule
     is a grid and flex-wrap means nothing to it */
  .chips{display:flex;flex-wrap:nowrap;overflow-x:auto;gap:8px;padding:2px 12px 4px;scrollbar-width:none}
  .chips::-webkit-scrollbar{display:none}
  .chip{flex:0 0 auto;padding:8px 14px 8px 8px;font-size:.94rem;gap:10px;border-radius:13px}
  .chip .ci{width:36px;height:36px;flex:0 0 36px;border-radius:11px}
  .chip .ci svg{width:20px;height:20px}
  .chip .n{font-size:.76rem;padding:2px 8px;min-width:26px}
  .chip .cl{gap:9px}
  .pos-search{margin-bottom:9px}
  .pos-search input[type=search]{padding:10px 14px;font-size:.94rem}
  .items-head{margin-bottom:8px}
  .items-head h3{font-size:.92rem}
  .items-grid{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px}
}
.item-card{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r);
  padding:14px 14px 12px;box-shadow:var(--sh-2);display:flex;flex-direction:column;
  transition:transform .12s, box-shadow .12s, border-color .12s;
}
.item-card:hover{transform:translateY(-2px);box-shadow:var(--sh-3);border-color:#c9dfe9}

/* picture + name, so a card is recognisable at a glance */
.item-card .ihead{display:flex;align-items:flex-start;gap:11px;margin-bottom:12px}
.item-card .pic{
  width:50px;height:50px;flex:0 0 50px;border-radius:14px;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(160deg,#eaf7fd,#dcf0fa);color:var(--brand-darker);
  border:1px solid #d3ecf7;transition:transform .12s, background .12s;
}
.item-card .pic svg{width:30px;height:30px;display:block}
.item-card:hover .pic{transform:scale(1.06);background:linear-gradient(160deg,#dcf1fb,#c9e9f8)}
.item-card .nm{
  font-weight:700;font-size:.99rem;line-height:1.28;color:var(--ink);
  min-height:2.6em;display:flex;align-items:center;
}
.svc-row{display:flex;gap:7px;margin-top:auto}
.svc-btn{
  flex:1 1 0;min-width:0;padding:9px 4px;border-radius:var(--r-sm);border:1px solid var(--line);
  background:#f7fbfd;cursor:pointer;font-family:inherit;text-align:center;line-height:1.2;
  transition:all .12s;
}
.svc-btn:hover{background:var(--brand-tint);border-color:var(--brand);box-shadow:0 2px 8px rgba(0,168,220,.18)}
.svc-btn:active{transform:translateY(1px)}
.svc-btn .s{display:block;font-size:.69rem;color:var(--muted);font-weight:800;text-transform:uppercase;letter-spacing:.05em}
.svc-btn .p{display:block;font-size:1.12rem;font-weight:800;color:var(--ink);margin-top:2px;letter-spacing:-.01em}
.item-card.one .svc-btn{background:linear-gradient(180deg,#eaf8fe,#dff2fb);border-color:#b6e4f6}
.item-card.one .svc-btn .s{color:var(--brand-darker)}

/* ---------------- ticket ---------------- */
.pos-right{position:sticky;top:80px}
.ticket{
  background:var(--card);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh-2);
  display:flex;flex-direction:column;max-height:calc(100vh - 104px);overflow:hidden;
}
.tk-head{
  display:flex;align-items:center;gap:9px;font-size:.7rem;font-weight:800;
  text-transform:uppercase;letter-spacing:.1em;color:var(--muted);margin-bottom:10px;
}
.tk-head .tag{padding:3px 9px;border-radius:99px;background:var(--line-soft);color:var(--muted);
              font-size:.66rem;letter-spacing:.04em}
.tk-head .tag.ok{background:#dcfce7;color:#166534}
.tk-head .lnk{border:0;background:none;color:var(--brand-dark);font-size:.7rem;font-weight:800;cursor:pointer;
              text-transform:uppercase;letter-spacing:.07em;font-family:inherit;padding:0}

.tk-block{padding:14px 16px;border-bottom:1px solid var(--line)}
.tk-block input{margin-bottom:7px}
.tk-block input:last-child{margin-bottom:0}
.suggest{display:flex;flex-direction:column;gap:3px;margin:-3px 0 7px;font-size:.82rem}
.suggest a{padding:7px 10px;border-radius:8px;background:#f6fafc;color:var(--brand-darker);
           text-decoration:none;border:1px solid var(--line-soft)}
.suggest a:hover{background:var(--brand-tint);border-color:#bde7f7;text-decoration:none}

.tk-cart{padding:14px 16px 0;display:flex;flex-direction:column;min-height:0;flex:1}
/* the two least-used customer fields share a row, so the cart gets the
   height back - see the note in pos.php */
.cust-pair{display:grid;grid-template-columns:1fr 1fr;gap:0 8px}
.cust-pair input{margin-bottom:0}
.tk-lines{overflow-y:auto;margin:0 -16px;padding:0 6px;flex:1;min-height:100px}
.tk-empty{padding:30px 16px;text-align:center;color:var(--muted);font-size:.86rem}
.tk-empty .ic{font-size:1.9rem;opacity:.3;margin-bottom:8px}

.cline{display:flex;align-items:center;gap:9px;padding:9px 11px;border-radius:var(--r-sm)}
.cline + .cline{border-top:1px solid var(--line-soft)}
.cline.flash{animation:flashline .8s ease}
@keyframes flashline{from{background:var(--brand-tint-2)}to{background:transparent}}
.cline .info{flex:1;min-width:0}
.cline .info .n{font-size:.86rem;font-weight:700;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cline .info .s{font-size:.73rem;color:var(--muted)}
.cline .lt{width:66px;text-align:right;font-weight:800;font-size:.87rem}
.cline .rm{border:0;background:none;color:var(--danger);cursor:pointer;font-size:1.15rem;padding:0 2px;line-height:1}

.qty{display:flex;align-items:center;border:1px solid var(--line);border-radius:9px;overflow:hidden}
.qty button{width:28px;height:30px;border:0;background:#f5f9fb;cursor:pointer;font-size:1rem;line-height:1;color:var(--ink)}
.qty button:hover{background:var(--brand-tint)}
.qty input{width:38px;height:30px;border:0;border-left:1px solid var(--line);border-right:1px solid var(--line);
           text-align:center;padding:0;border-radius:0;font-size:.86rem}

.tk-totals{padding:12px 16px;border-top:1px solid var(--line);font-size:.9rem;background:#fbfdfe}
/* Discount and Delivery side by side: two short numbers that were each
   taking a full row in the one panel with no height to spare. */
.tk-totals .row.two-up{display:grid;grid-template-columns:1fr 1fr;gap:0 10px;align-items:end}
.tk-totals .row.two-up > label{
  display:block;font-size:.72rem;font-weight:700;color:var(--muted);
  text-transform:uppercase;letter-spacing:.05em;
}
.tk-totals .row.two-up input{width:100%;margin-top:3px;text-align:right}
.tk-totals .row.two-up .locked{display:flex;align-items:center;justify-content:flex-end;gap:6px;margin-top:5px}
.tk-totals .row.paidnote{color:#7c4a03;font-size:.82rem}
.tk-totals .row.paidnote b{font-weight:700}
.tk-totals .row{display:flex;justify-content:space-between;align-items:center;padding:4px 0}
.tk-totals input{width:100px;text-align:right;padding:6px 9px;font-size:.87rem}
.tk-totals .grand{
  border-top:1px dashed var(--line);margin-top:9px;padding-top:11px;
  font-size:1.4rem;font-weight:800;color:var(--ink);letter-spacing:-.02em;
}
.tk-totals .grand span:first-child{font-size:.72rem;letter-spacing:.11em;color:var(--muted);align-self:center;font-weight:800}
.tk-totals .bal b{color:var(--danger)}
.tk-totals .locked{display:flex;align-items:center;gap:6px;font-size:.78rem;color:var(--muted)}
.quick{display:flex;gap:6px;margin:5px 0 2px;justify-content:flex-end}
.quick .q{padding:5px 13px;border-radius:8px;border:1px solid var(--line);background:#fff;
          font-size:.74rem;font-weight:800;cursor:pointer;font-family:inherit;color:var(--muted)}
.quick .q:hover{background:var(--brand-tint);border-color:var(--brand);color:var(--brand-darker)}

.tk-foot{padding:14px 16px;border-top:1px solid var(--line)}
.tk-foot .fld{margin-bottom:.65rem}

/* ---- the cash ledger, read as one running sum ------------------------
   Each line carries its own sign so the direction is legible before the
   number is; the closing figure is the answer, so it gets the weight. */
.ledger{padding:4px 0 0}
.lg-row{
  display:grid;grid-template-columns:34px 1fr auto;align-items:baseline;gap:0 12px;
  padding:13px 18px;border-bottom:1px solid var(--line-soft);
}
.lg-row:first-child{background:#f8fbfc}
.lg-sign{
  font-size:1.05rem;font-weight:800;text-align:center;line-height:1;
  width:26px;height:26px;border-radius:8px;display:flex;align-items:center;justify-content:center;
}
.lg-plus{background:#e7f8ee;color:#15803d}
.lg-minus{background:#fdecec;color:#b91c1c}
.lg-base{background:var(--line-soft);color:var(--muted);font-size:.7rem}
.lg-label b{display:inline;font-size:.95rem;color:var(--ink)}
.lg-link{font-size:.74rem;font-weight:700;margin-left:8px}
.lg-hint{display:block;font-size:.78rem;color:var(--muted);margin-top:2px;line-height:1.45}
.lg-amt{font-size:1.02rem;font-weight:700;color:var(--ink);white-space:nowrap;font-variant-numeric:tabular-nums}
.lg-open .lg-amt{color:var(--muted);font-weight:600}

.lg-close{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:18px;background:linear-gradient(155deg,#103b57 0%,#0a2a3f 100%);color:#fff;
  border-radius:0 0 calc(var(--r) - 1px) calc(var(--r) - 1px);
}
.lg-close-k{font-size:.72rem;letter-spacing:.13em;text-transform:uppercase;font-weight:800;color:#8fc4dd}
.lg-close-s{font-size:.79rem;color:#9fc6d8;margin-top:3px}
.lg-close-v{font-size:1.75rem;font-weight:800;letter-spacing:-.02em;white-space:nowrap;
            font-variant-numeric:tabular-nums}
.ledger-card{overflow:hidden}

@media (max-width:700px){
  .lg-row{grid-template-columns:26px 1fr;row-gap:4px;padding:12px 14px}
  .lg-amt{grid-column:2;text-align:right}
  .lg-close{flex-direction:column;align-items:flex-start;padding:16px 14px}
}

/* ---- an order's summary, read as a statement of account ---------------
   The old markup leaned on a .totals class that went when the till ticket
   was rebuilt, so every label sat flush against its figure. This is its
   own block: the bill is worked out down to the Total, then what has
   actually been paid against it is a separate settlement below, because
   they answer two different questions. */
.sum{padding:2px 0 0;font-variant-numeric:tabular-nums}
.sum-row{display:flex;align-items:baseline;justify-content:space-between;gap:16px;padding:7px 0}
.sum-row .k{color:var(--muted);font-size:.85rem}
.sum-row .v{font-weight:700;font-size:.93rem;white-space:nowrap}
.sum-row .v .sign{color:var(--muted);font-weight:600;margin-right:1px}

.sum-total{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  border-top:1px dashed var(--line);margin-top:8px;padding:13px 0 4px;
}
.sum-total .k{font-size:.72rem;letter-spacing:.12em;text-transform:uppercase;font-weight:800;color:var(--muted)}
.sum-total .v{font-size:1.55rem;font-weight:800;letter-spacing:-.025em;white-space:nowrap}
.sum-total .v .cur{font-size:.9rem;font-weight:700;color:var(--muted);margin-right:3px}

/* what has been settled against that bill */
.sum-settle{margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.sum-settle .sum-row .v{font-weight:700}
.sum-bal .v{font-size:1.05rem}
.sum-bal.due .v{color:var(--danger)}
.sum-bal.clear .v{color:var(--ok)}

/* one line saying where the order stands, so the figures need no reading */
.sum-state{
  display:flex;align-items:center;gap:9px;margin-top:14px;padding:11px 13px;
  border-radius:11px;font-size:.85rem;line-height:1.45;
}
.sum-state .ic{font-size:1rem;line-height:1}
.sum-state.ok{background:#e7f8ee;color:#166534}
.sum-state.due{background:#fdecec;color:#8c1d1d}
.sum-state.acct{background:#fff7e6;color:#7c4a03}

/* ---- profit and loss: the answer before the working ------------------- */
.pl-head{border:0;color:#fff;overflow:hidden}
.pl-head.up  {background:linear-gradient(155deg,#12734a 0%,#0b4f33 100%)}
.pl-head.down{background:linear-gradient(155deg,#a12626 0%,#7a1717 100%)}
.pl-head .card-b{padding:22px 24px}
.pl-head-k{font-size:.72rem;letter-spacing:.13em;text-transform:uppercase;font-weight:800;opacity:.75}
.pl-head-v{font-size:2.4rem;font-weight:800;letter-spacing:-.03em;margin-top:4px;
           font-variant-numeric:tabular-nums;line-height:1.05}
.pl-head-s{font-size:.85rem;opacity:.8;margin-top:6px}
@media (max-width:700px){ .pl-head-v{font-size:1.9rem} }

/* ---------------- Modal ---------------- */
.modal{position:fixed;inset:0;z-index:80;display:none;align-items:flex-start;justify-content:center;padding:6vh 16px}
.modal.open{display:flex}
.modal-bg{position:absolute;inset:0;background:rgba(8,28,41,.55);backdrop-filter:blur(3px)}
.modal-box{position:relative;background:#fff;border-radius:18px;box-shadow:0 30px 80px rgba(0,0,0,.4);
           width:100%;max-width:620px;max-height:80vh;display:flex;flex-direction:column;overflow:hidden}
.modal-h{padding:16px 20px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:10px}
.modal-h h2{margin:0;font-size:1.02rem}
.modal-h .x{margin-left:auto;border:0;background:none;font-size:1.5rem;line-height:1;cursor:pointer;color:var(--muted)}
.modal-b{padding:16px 20px;overflow-y:auto}
.cust-list{display:flex;flex-direction:column;gap:8px;margin-top:12px}
.cust-row{display:flex;align-items:center;gap:12px;padding:12px 14px;border:1px solid var(--line);
          border-radius:var(--r-sm);background:#fff;cursor:pointer;text-align:left;font-family:inherit;width:100%}
.cust-row:hover{border-color:var(--brand);background:var(--brand-tint)}
.cust-row .av{width:38px;height:38px;border-radius:50%;background:var(--brand-tint);color:var(--brand-darker);
              display:flex;align-items:center;justify-content:center;font-weight:800;flex:0 0 38px}
.cust-row .cn{font-weight:700;color:var(--ink)}
.cust-row .cm{font-size:.8rem;color:var(--muted)}
.cust-row .cs{margin-left:auto;text-align:right;font-size:.78rem;color:var(--muted)}

/* ---------------- Responsive ---------------- */
@media (max-width: 1100px){
  .pos{grid-template-columns:1fr}
  .pos-right{position:static}
  .ticket{max-height:none}
  .tk-lines{max-height:44vh}
}
@media (max-width: 760px){
  .sidebar{position:fixed;left:0;top:0;bottom:0;z-index:60;transform:translateX(-100%);
           transition:transform .22s ease;box-shadow:0 0 50px rgba(0,0,0,.45)}
  body.nav-open .sidebar{transform:none}
  body.nav-open::after{content:"";position:fixed;inset:0;background:rgba(6,22,33,.5);z-index:50}
  .menu-toggle{display:block}
  .content{padding:14px}
  .grid2,.grid3{grid-template-columns:1fr}
  .items-grid{grid-template-columns:repeat(auto-fill,minmax(172px,1fr))}
  /* on a phone the filters scroll sideways in one row instead of eating
     half the screen; the tiles stay big enough to tap */
  /* one row that scrolls, rather than four rows of wrapped tabs */
  .cat-tabs{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .cat-tabs::-webkit-scrollbar{display:none}
  .cat-tabs .tab{flex:0 0 auto}

  .cat-bar{padding:10px 0 12px;border-radius:14px}
  .cat-bar-h{margin-left:12px}
  .chips{display:flex;flex-wrap:nowrap;overflow-x:auto;padding:2px 12px 6px;gap:10px;scrollbar-width:none}
  .chips::-webkit-scrollbar{display:none}
  .chip{flex:0 0 auto;padding:10px 16px 10px 10px;font-size:.98rem}
  .chip .ci{width:42px;height:42px;flex:0 0 42px;border-radius:12px}
  .chip .ci svg{width:23px;height:23px}
}

@media print{
  .sidebar,.topbar,.no-print,.modal{display:none !important}
  .content{padding:0}
  body{background:#fff}
  .card{box-shadow:none;border-color:#ccc}
}

/* ---- the photograph against an expense --------------------------------
   Small enough to sit in the amount cell without pushing the row about,
   big enough to tell one receipt from another at a glance. */
.exp-shot{display:block;width:54px;margin:6px 0 0 auto;line-height:0;border-radius:8px;overflow:hidden;
          border:1px solid var(--line);background:#f7fafb}
.exp-shot img{width:54px;height:54px;object-fit:cover;display:block;transition:transform .14s}
.exp-shot:hover{border-color:var(--brand)}
.exp-shot:hover img{transform:scale(1.06)}
@media print{ .exp-shot{display:none} }
