/*
 * Customer portal.
 *
 * This was 79 lines of `echo` inside class-pc-portal.php, which meant the
 * portal was the one surface of ModuleFest Pet Services with nowhere to put a design
 * token: you cannot declare a variable in a string that is concatenated a
 * line at a time. It also meant every portal page carried its own stylesheet
 * inline, uncached, on every request.
 *
 * What stayed behind in PHP is only what genuinely varies per site: the
 * accent colour and its derived shades, and a customer-chosen body font.
 * Those are custom properties, declared inline before this file loads, so
 * everything here can refer to them.
 *
 * @package ModuleFest Pet Services
 */

*{box-sizing:border-box}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;color:var(--ink);background:#f5f7fb;-webkit-font-smoothing:antialiased}.wrap{max-width:700px;margin:0 auto;padding:0 16px 40px}header{background:linear-gradient(150deg,var(--accent),var(--accent-d));color:#fff;padding:22px 20px 24px;border-radius:0 0 20px 20px;box-shadow:0 8px 24px var(--ring);display:flex;align-items:center;gap:13px}header .mk{width:46px;height:46px;flex:0 0 auto;border-radius:12px;background:#fff;padding:3px;box-shadow:0 2px 8px rgba(0,0,0,.14)}header .mk img{width:100%;height:100%;object-fit:contain;display:block}header h1{margin:0;font-size: var(--pc-t-l);letter-spacing:-.02em;font-weight:750}header p{margin:3px 0 0;font-size: var(--pc-t-s);opacity:.92}.card{background:#fff;border:1px solid var(--line);border-radius:16px;padding:18px;margin:14px 0;box-shadow:var(--shadow)}table{width:100%;border-collapse:separate;border-spacing:0}td,th{padding:9px 4px;text-align:left;font-size: var(--pc-t-m);border-bottom:var(--rule,1px solid var(--line2))}th{color:var(--muted);font-weight:650}tr:last-child td{border-bottom:0}.r{text-align:right}.badge{display:inline-block;padding:3px 11px;border-radius:999px;font-size: var(--pc-t-s);font-weight:700}.btn{display:inline-flex;align-items:center;gap:7px;background:linear-gradient(180deg,color-mix(in srgb,var(--accent) 92%,#fff),var(--accent));color:#fff;text-decoration:none;padding:11px 17px;border-radius:12px;font-weight:650;margin:6px 8px 2px 0;box-shadow:0 1px 2px rgba(16,24,40,.12),0 3px 10px var(--ring);transition:filter .12s ease,transform .05s ease}.btn:hover{filter:brightness(1.05)}.btn:active{transform:translateY(1px)}.btn.alt{background:#fff;color:var(--ink);border:1px solid var(--line);box-shadow:0 1px 2px rgba(16,24,40,.04)}.btn.alt:hover{background:var(--accent-50);border-color:color-mix(in srgb,var(--accent) 40%,var(--line))}.qlinks{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:6px}.pc-price-was{text-decoration:line-through;color:#94a3b8;font-weight:500;margin-right:4px}.pc-price-now{font-weight:800;color:var(--ink)}.pc-sale-badge{display:inline-block;background:#dc2626;color:#fff;font-size: var(--pc-t-xs);font-weight:800;letter-spacing:.05em;padding:1px 6px;border-radius:999px;margin-left:4px;vertical-align:middle}.pc-sale-banner{background:linear-gradient(90deg,#dc2626,#ef4444);color:#fff;font-weight:700;text-align:center;padding:10px 14px;border-radius:12px;margin:0 0 12px;box-shadow:0 4px 14px rgba(220,38,38,.25)}.qlinks .btn{width:100%;margin:0;justify-content:center;text-align:center;background:#fff;color:var(--ink);border:1px solid var(--line);box-shadow:0 1px 2px rgba(16,24,40,.05);font-weight:700}.qlinks .btn:hover{filter:brightness(.97);box-shadow:0 3px 10px rgba(16,24,40,.08)}.qlinks .btn:active{transform:translateY(1px)}.qlinks .btn:last-child:nth-child(odd){grid-column:1 / -1}.qlinks .ql-green{background:#e9f9ef;color:#047857;border-color:#b7ebc9}.qlinks .ql-blue{background:#eaf2fe;color:#1d4ed8;border-color:#c3dafc}.qlinks .ql-purple{background:#f2effe;color:#6d28d9;border-color:#dcd3fb}.qlinks .ql-amber{background:#fdf3e7;color:#b45309;border-color:#f8dab0}.qlinks .ql-rose{background:#fdeef0;color:#be123c;border-color:#f8ccd3}.muted{color:var(--muted);font-size: var(--pc-t-s)}.bank div{display:flex;justify-content:space-between;gap:12px;padding:5px 0;border-bottom:1px dashed var(--line);font-size: var(--pc-t-s)}.pnav{display:flex;gap:6px;flex-wrap:wrap;margin:14px 0 2px;padding:6px;background:#fff;border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow)}.pnav a{flex:1 1 auto;text-align:center;padding:10px 14px;border-radius:11px;text-decoration:none;color:var(--ink2);font-size: var(--pc-t-m);font-weight:650;white-space:nowrap;transition:background .12s ease,color .12s ease}.pnav a.on{background:var(--accent);color:#fff;box-shadow:0 2px 8px var(--ring)}.pnav a:not(.on):hover{background:var(--accent-50);color:var(--ink)}.hd{display:flex;justify-content:space-between;align-items:baseline;gap:10px;margin:0 0 8px}.hd h2{margin:0;font-size: var(--pc-t-m);font-weight:700;letter-spacing:-.01em}.tile{display:flex;gap:12px;align-items:center;padding:12px 0;border-bottom:var(--rule,1px solid var(--line2))}.tile:last-child{border-bottom:0}.pc-bkrow{border-bottom:var(--rule,1px solid var(--line2))}.pc-bkrow:last-child{border-bottom:0}.pc-bkrow .tile{border-bottom:0}.tile .em{width:40px;height:40px;border-radius:12px;background:var(--accent-50);display:grid;place-items:center;font-size: var(--pc-t-l);flex:0 0 auto}.tile .tt{font-weight:650}.tile .ts{color:var(--muted);font-size: var(--pc-t-s)}.tile .ta{margin-left:auto;text-align:right}.petpic{width:46px;height:46px;border-radius:13px;object-fit:cover;flex:0 0 auto;border:1px solid var(--line)}.avatar{width:60px;height:60px;border-radius:50%;object-fit:cover;border:2px solid var(--accent-50);flex:0 0 auto}.kv{display:flex;justify-content:space-between;gap:12px;padding:10px 0;border-bottom:var(--rule,1px solid var(--line2));font-size: var(--pc-t-m)}.kv:last-child{border-bottom:0}.kv .k{color:var(--muted)}.big{font-size: var(--pc-t-2xl);font-weight:750;letter-spacing:-.02em}.empty{color:var(--muted);text-align:center;padding:14px 0}.ribbon{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:9px;justify-content:center;background:#0f172a;color:#fff;font-size: var(--pc-t-s);font-weight:600;padding:9px 14px;text-align:center}.ribbon b{color:color-mix(in srgb,var(--accent) 45%,#fff)}@media print{.no-print{display:none!important}.ribbon,nav,.portal-nav,header a,.btn{display:none!important}body{background:#fff!important}.card{box-shadow:none!important;border:1px solid #ddd!important}@page{margin:14mm 14mm 40mm}/* The bottom margin reserves the invoice's footer band. The band is drawn by a position:fixed copy pinned to the foot of every page, and its height is held in the flow by the table's <tfoot> - but a <tfoot> is only guaranteed room on pages where content continues. On the LAST page Chromium lays every row out first and then finds the band will not fit, so it moves the band alone to a page of its own: page two, blank apart from the footer. Measured at every invoice length from 1 to 80 lines; it happened at 21. Reserving the band's own height (26mm) in the page margin is the only arrangement of the three tried that prints no blank page, keeps the footer on every page, and never lays content underneath it - a spacer inside the cell gets pushed onto a new page itself, and dropping the tfoot prints the address over the last treatment lines. */}.svc-pills{display:flex;gap:8px;flex-wrap:wrap;margin:2px 0 14px}.svc-pill{flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;padding:9px 15px;border-radius:999px;border:1px solid var(--line);background:#fff;color:var(--ink2);font-weight:650;font-size: var(--pc-t-m);cursor:pointer;transition:background .12s ease,color .12s ease}.svc-pill.on{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:0 2px 8px var(--ring)}.svc-pill:not(.on):hover{background:var(--accent-50)}.avail-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin:2px 0 6px}.avail-month{font-weight:700;font-size:var(--pc-t-m);color:var(--ink)}.avail-arrow{width:38px;height:38px;flex:0 0 auto;display:grid;place-items:center;border:1px solid var(--line);border-radius:11px;background:#fff;color:var(--ink2);font-size:20px;line-height:1;cursor:pointer;box-shadow:0 1px 2px rgba(16,24,40,.05)}.avail-arrow:hover:not(:disabled){background:var(--accent-50);border-color:color-mix(in srgb,var(--accent) 40%,var(--line))}.avail-arrow:disabled{opacity:.35;cursor:default}.avail-strip{display:flex;gap:8px;overflow-x:auto;padding:4px 2px 10px;scrollbar-width:thin}.avail-strip::-webkit-scrollbar{height:6px}.avail-strip::-webkit-scrollbar-thumb{background:var(--line);border-radius:6px}.avail-day{flex:0 0 auto;min-width:64px;text-align:center;border:1px solid var(--line);border-radius:13px;padding:9px 6px 8px;background:#fff;cursor:pointer;transition:border-color .12s ease}.avail-day .dow{font-size: var(--pc-t-xs);color:var(--muted);text-transform:uppercase;letter-spacing:.03em}.avail-day .dnum{font-size: var(--pc-t-l);font-weight:750;line-height:1.15}.avail-day .dot{margin-top:4px;font-size: var(--pc-t-xs);font-weight:700;color:var(--accent)}.avail-day.closed{opacity:.45;cursor:default}.avail-day.closed .dot{color:var(--muted);font-weight:600}.avail-day:not(.closed):hover{border-color:color-mix(in srgb,var(--accent) 45%,var(--line))}.avail-day.on{background:var(--accent);border-color:var(--accent);color:#fff}.avail-day.on .dow,.avail-day.on .dot{color:#fff;opacity:.95}.install-banner{display:none;align-items:center;gap:12px;background:var(--accent-50);border:1px solid color-mix(in srgb,var(--accent) 30%,var(--line));border-radius:14px;padding:12px 14px;margin:12px 0}.install-banner .ib-ic{width:38px;height:38px;border-radius:11px;background:#fff;display:grid;place-items:center;font-size:20px;flex:0 0 auto;box-shadow:var(--shadow)}.install-banner .ib-t{font-size: var(--pc-t-m);font-weight:650}.install-banner .ib-s{font-size: var(--pc-t-s);color:var(--muted)}.install-banner .ib-go{margin-left:auto;background:var(--accent);color:#fff;border:0;border-radius:10px;padding:9px 14px;font-weight:650;font-size: var(--pc-t-s);cursor:pointer;flex:0 0 auto}.install-banner .ib-x{background:none;border:0;color:var(--muted);font-size: var(--pc-t-l);line-height:1;cursor:pointer;padding:0 2px;flex:0 0 auto}body{padding-bottom:calc(76px + env(safe-area-inset-bottom))}.app-tabbar{position:fixed;left:0;right:0;bottom:0;z-index:30;display:flex;max-width:700px;margin:0 auto;background:#fff;border-top:1px solid var(--line);box-shadow:0 -2px 14px rgba(16,24,40,.08);padding:6px 4px calc(6px + env(safe-area-inset-bottom))}.app-tabbar a{flex:1;text-align:center;text-decoration:none;color:var(--muted);font-size: var(--pc-t-xs);font-weight:600;padding:6px 2px;border-radius:10px}.app-tabbar a .ti{display:flex;align-items:center;justify-content:center;height:24px;margin-bottom:3px}.app-tabbar a .ti svg{display:block}.app-tabbar a.on{color:var(--accent)}.slots{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin:6px 0 8px;min-height:22px}.slotbtn{display:flex;align-items:center;justify-content:center;text-align:center;min-height:46px;padding:11px 10px;border:1px solid var(--line);border-radius:12px;background:#fff;color:var(--ink);font-size: var(--pc-t-m);font-weight:700;line-height:1.15;cursor:pointer;text-decoration:none;box-shadow:0 1px 2px rgba(16,24,40,.05);transition:border-color .12s ease,background .12s ease,box-shadow .12s ease,transform .04s ease}.slotbtn:hover{border-color:color-mix(in srgb,var(--accent) 55%,var(--line));background:color-mix(in srgb,var(--accent) 7%,#fff);box-shadow:0 3px 8px rgba(16,24,40,.08)}.slotbtn:active{transform:translateY(1px)}.slotbtn.on{background:var(--accent);color:#fff;border-color:var(--accent);box-shadow:0 3px 10px color-mix(in srgb,var(--accent) 35%,transparent)}.slotnote{grid-column:1/-1;color:var(--muted);font-size: var(--pc-t-s)}


/* ==================================================================
   Invoices  (2.228.0)
   ------------------------------------------------------------------
   Six columns of table in a 390px phone put the View link off the
   right edge, broke invoice numbers over two lines and wrapped the
   "Still to pay" heading inside itself. The one thing a customer
   comes here to do was the thing hanging off the screen.

   A list instead. Each row is a link, so there is no View to reach
   for — you tap the invoice.
   ================================================================== */
.pinv-due {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	margin: 0 0 12px;
	padding: 14px 16px;
	background: var(--accent-50);
	border: 1px solid var(--accent-100);
	border-radius: 14px;
}
.pinv-due-l { font-size: 13px; font-weight: 600; color: var(--ink2); }
.pinv-due-v { font-size: 22px; font-weight: 800; color: var(--ink); }

.pinv-card { padding: 0; overflow: hidden; }
.pinv-list { display: block; }

.pinv-row {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 13px 16px;
	border-bottom: var(--rule, 1px solid var(--line2));
	text-decoration: none;
	color: inherit;
}
.pinv-row:last-child { border-bottom: 0; }
.pinv-row:hover { background: var(--accent-50); }

.pinv-main { flex: 1 1 auto; min-width: 0; }
.pinv-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
.pinv-no {
	font-weight: 700;
	font-size: 15px;
	color: var(--ink);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.pinv-sub { display: block; margin-top: 2px; font-size: 12.5px; color: var(--muted); }

/* The money is the answer, so it is set like one and never wraps. */
.pinv-money { flex: 0 0 auto; text-align: right; }
.pinv-bal {
	display: block;
	font-size: 16px;
	font-weight: 800;
	color: var(--ink);
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}
.pinv-bal.is-clear { font-weight: 600; color: var(--muted); }
.pinv-of { display: block; font-size: 11.5px; color: var(--muted); white-space: nowrap; }

/* An invoice with money on it earns a marker down its edge. Settled ones
   do not — a list where everything is emphasised emphasises nothing. */
.pinv-row.is-owed { box-shadow: inset 3px 0 0 var(--accent); }

@media (max-width: 340px) {
	.pinv-row { padding-left: 12px; padding-right: 12px; }
	.pinv-no { font-size: 14px; }
}


/* ==================================================================
   Disclosure sections  (2.229.0)
   ------------------------------------------------------------------
   A <summary> is a control, and it was not dressed as one. Bold text
   with a small "›" in front of it looks exactly like a heading with a
   stray character, so people read it and scroll past — the care
   details, the vet and the emergency contact all sat behind something
   nobody knew to press.

   So: a tinted band the full width of the card, a chevron in a circle
   on the right that turns when it opens, and a word underneath saying
   what is inside. Nothing here is decoration; each part answers a
   different question — is it a button, what will it do, what is in it.
   ================================================================== */
details.pdisc { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
details.pdisc + details.pdisc { margin-top: 8px; }

details.pdisc > summary {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 13px 14px;
	background: var(--accent-50);
	cursor: pointer;
	list-style: none;
	font-weight: 700;
	font-size: 15px;
	color: var(--ink);
	-webkit-tap-highlight-color: transparent;
}
details.pdisc > summary::-webkit-details-marker { display: none; }
details.pdisc > summary::marker { content: ""; }
details.pdisc > summary:hover { background: var(--accent-100); }

/* The label and the line under it. The second line is the point: it says
   what is behind the control, so opening it is a decision rather than a
   guess. */
.pdisc-t { flex: 1 1 auto; min-width: 0; }
.pdisc-t small {
	display: block;
	font-weight: 500;
	font-size: 12.5px;
	color: var(--muted);
	margin-top: 2px;
}

/* The chevron is in a ring so it reads as a button rather than a
   punctuation mark, and it turns rather than swapping to a different
   character — the movement is what tells you the panel is yours to open
   and close again. */
.pdisc-c {
	flex: 0 0 auto;
	width: 28px;
	height: 28px;
	border-radius: 50%;
	background: #fff;
	border: 1px solid var(--accent-100);
	display: grid;
	place-items: center;
	color: var(--accent);
	transition: transform .18s ease;
}
.pdisc-c svg { display: block; }
details.pdisc[open] > summary { border-bottom: 1px solid var(--line); }
details.pdisc[open] .pdisc-c { transform: rotate(180deg); }

.pdisc-body { padding: 14px; }

/* Keyboard users get the same affordance as everybody else. */
details.pdisc > summary:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: -2px;
}

@media (prefers-reduced-motion: reduce) {
	.pdisc-c { transition: none; }
}


/* ==================================================================
   The shop  (2.243.0)
   A grid of things, each with a quantity box. No basket that has to
   survive the tab closing, and no card form: an order goes on the
   invoice the customer already has.
   ================================================================== */
/* minmax(0, 1fr), not 1fr: a plain 1fr column grows to its widest unbreakable
   content, and a product name that will not wrap pushed the quantity box off
   the edge of the card on a phone. */
.pshop { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; }
@media (min-width: 560px) { .pshop { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.pshop-item { min-width: 0; }

.pshop-item {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 10px;
	border: 1px solid var(--line);
	border-radius: 14px;
	background: #fff;
}
.pshop-item.is-out { opacity: .6; }

.pshop-img {
	width: 54px;
	height: 54px;
	flex: 0 0 auto;
	border-radius: 12px;
	object-fit: cover;
	background: var(--accent-50);
}
.pshop-img--none { display: grid; place-items: center; font-size: 24px; }

.pshop-body { flex: 1 1 auto; min-width: 0; }
.pshop-name {
	/* Two lines, not one with an ellipsis: "Shampoo…" hides the 500ml that
	   tells it apart from the 250ml, which is the part the customer needs. */
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	line-clamp: 2;
	overflow: hidden;
	overflow-wrap: anywhere;
	font-weight: 700;
	font-size: 15px;
	line-height: 1.25;
	color: var(--ink);
}
.pshop-price { display: block; font-size: 13px; color: var(--muted); margin-top: 1px; }
.pshop-out { display: block; font-size: 12px; font-weight: 600; color: #b32d2e; margin-top: 2px; }

.pshop-qty {
	flex: 0 0 auto;
	width: 62px;
	padding: 9px 8px;
	text-align: center;
	border: 1px solid var(--line);
	border-radius: 10px;
	font-size: 15px;
	font-variant-numeric: tabular-nums;
}

/* ---- Adding a treatment to a booking you already have (2.329.0) ---- */
.pc-addon{margin:12px 0 0;padding:14px;border:1px solid var(--line);border-radius:14px;background:#fff}
.pc-addon--ask{background:var(--accent-50);border-color:color-mix(in srgb,var(--accent) 28%,var(--line))}
.pc-addon-row{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:var(--rule,1px solid var(--line2))}
.pc-addon-row:last-child{border-bottom:0}
.pc-addon-name{font-weight:650;flex:0 0 auto}
.pc-addon-meta{color:var(--muted);font-size:var(--pc-t-s);flex:1 1 auto;min-width:0}
.pc-addon-row .btn{margin:0;flex:0 0 auto;padding:8px 14px}
.pc-flash{margin:12px 0;padding:11px 14px;border-radius:12px;font-size:var(--pc-t-m);font-weight:600}
.pc-flash--ok{background:#e9f9ef;color:#047857;border:1px solid #b7ebc9}
.pc-flash--bad{background:#fdeef0;color:#be123c;border:1px solid #f8ccd3}
@media(max-width:520px){.pc-addon-row{flex-wrap:wrap}.pc-addon-meta{flex:1 0 100%;order:3}}

/* ---- Deposit due on a booking (2.344.0) --------------------------- */
.pc-dep{margin:12px 0 0;padding:12px 14px;border-radius:12px;background:var(--accent-50);border:1px solid color-mix(in srgb,var(--accent) 30%,var(--line))}
.pc-dep .btn{margin:0}
#pc-extras-sum{margin:8px 0 0;padding:9px 12px;border-radius:10px;background:var(--accent-50);font-weight:700;font-size:var(--pc-t-s)}

/* ---- How to pay (2.358.0) ----------------------------------------- */
.pc-howpay{margin:12px 0 0;padding:14px;border:1px solid var(--line);border-radius:14px;background:#fff}
.pc-howpay-row{padding:10px 0;border-bottom:var(--rule,1px solid var(--line2))}
.pc-howpay-row:last-child{border-bottom:0}
.pc-howpay-row:first-of-type{padding-top:0}
.pc-howpay-row strong{display:block;font-size:var(--pc-t-m)}
.pc-howpay-row p{color:var(--muted);font-size:var(--pc-t-s)}
.pc-howpay-row .btn{margin:4px 0 0}
/* Money columns: figures of the same width, so digits stack in a column
   rather than drifting with the shape of each numeral. */
td.r,th.r{font-variant-numeric:tabular-nums;white-space:nowrap}

/* ---- The invoice itself (2.393.0) ---------------------------------
   Laid out to be read on a phone and printed on A4: the same document
   either way, rather than a screen version and a paper one. */
.pc-inv{--ink:#3d2b1f;--soft:#8a7968;--edge:#e8e0d5;--brand:var(--accent,#10B981);
	background:#fdfaf5;color:var(--ink);padding:26px;border-radius:16px;border:1.5px solid var(--ink)}
.pc-inv-top{display:flex;justify-content:space-between;align-items:flex-start;gap:20px;
	padding-bottom:16px;border-bottom:2px solid var(--edge);margin-bottom:18px}
.pc-inv-biz h1{margin:0;font-size:26px;font-weight:800;letter-spacing:-.02em}
.pc-inv-tag{margin:2px 0 8px;font-size:11px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--soft)}
.pc-inv .pc-inv-line{margin:1px 0;font-size:12.5px;color:var(--soft)}
.pc-inv-vatno{display:inline-block;margin:9px 0 0;padding:4px 10px;border-radius:5px;
	background:var(--ink);color:#fff;font-size:11.5px;font-weight:700;letter-spacing:.02em}
.pc-inv-title{font-size:26px;font-weight:800;letter-spacing:.02em;color:var(--brand);text-align:right;white-space:nowrap}
.pc-inv-cards{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:18px}
/* The boxes are drawn in the same ink as the business's name at the top of
   the page, and a shade thicker: the old hairline in --edge is a pale beige
   that a laser printer renders as almost nothing, so a printed invoice had
   the layout of a boxed document and none of the boxes. */
.pc-inv-card{background:#fff;border:1.5px solid var(--ink);border-radius:10px;padding:14px 16px}
.pc-inv-card h2{margin:0 0 9px;font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--brand)}
.pc-inv-who{margin:0 0 2px;font-size:16px;font-weight:750}
.pc-inv-chip{display:inline-block;margin:8px 0 0;padding:4px 10px;border-radius:999px;
	background:#f4ede3;font-size:11.5px;font-weight:700;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.pc-inv-kv{display:flex;justify-content:space-between;gap:14px;padding:4px 0;font-size:12.5px}
.pc-inv-kv span{color:var(--soft)}
.pc-inv-kv b{font-weight:750;font-variant-numeric:tabular-nums}
/* The invoice says Paid or Outstanding; the older workflow names are kept
   because other screens still use this class for their own labels. */
.pc-inv-st-outstanding,.pc-inv-st-overdue,.pc-inv-st-sent,.pc-inv-st-partial{color:#c2410c}
.pc-inv-st-paid{color:#15803d}
.pc-inv-st-void,.pc-inv-st-refunded{color:var(--soft)}
.pc-inv-lines{width:100%;border-collapse:collapse;margin-bottom:18px;border-radius:8px;overflow:hidden}
.pc-inv-lines thead th{background:var(--accent,#10B981);color:#fff;padding:11px 12px;font-size:10.5px;
	font-weight:800;letter-spacing:.08em;text-transform:uppercase;border:0}
.pc-inv-lines tbody td{padding:12px;font-size:13px;border-bottom:var(--rule,1px solid var(--line));vertical-align:top}
.pc-inv-lines tbody tr:nth-child(odd){background:#fff}
.pc-inv-lines tbody tr:last-child td{border-bottom:0}
.pc-inv-lines .r{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.pc-inv-foot{display:grid;grid-template-columns:1fr 1fr;gap:14px;align-items:start}
.pc-inv-pay{background:#fff;border:1.5px solid var(--ink);border-radius:10px;padding:14px 16px}
.pc-inv-pay h3{margin:0 0 8px;font-size:11px;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--ink)}
/* Cash and Cheque carry no class of their own, so a rule aimed at .muted
   left them at the inherited size and the one-line answer to "how do I pay"
   printed larger than the account number above it. Sized from the same token
   the bank rows use, so the two ways to pay read as one block — the wide
   layout sets its own 12px for both and out-specifies this. */
.pc-inv .pc-howpay-row p:not(.pc-howpay-ref){font-size:var(--pc-t-s)}
.pc-inv-sums{background:#fff;border:1.5px solid var(--ink);border-radius:10px;padding:14px 16px}
.pc-inv-due{margin:12px -16px -14px;padding:16px;border-radius:0 0 10px 10px;background:var(--brand);color:#fff;text-align:right}
.pc-inv-due span{display:block;font-size:11px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;opacity:.92}
.pc-inv-due strong{display:block;margin-top:2px;font-size:27px;font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.pc-inv-note{margin:18px 0 0;padding-top:14px;border-top:1px solid var(--edge);text-align:center;font-size:12px;color:var(--soft)}
/* How to reach them, on the paper they are holding. */
.pc-inv-reach{margin:14px 0 0;padding-top:12px;border-top:1px solid var(--edge);text-align:center;font-size:12px;font-weight:650;color:var(--ink)}
.pc-inv-note + .pc-inv-reach{margin-top:8px;padding-top:0;border-top:0}
.pc-inv-social{margin:8px 0 0;text-align:center;font-size:11.5px;color:var(--soft);
	display:flex;flex-wrap:wrap;justify-content:center;gap:6px 16px}
.pc-inv-socitem{display:inline-flex;align-items:center;gap:6px}
/* The badge is drawn inside the SVG, not set here, so it survives printing. */
.pc-inv-soc{flex:0 0 auto;display:block}
@media(max-width:640px){
	.pc-inv{padding:18px}
	.pc-inv-top{flex-direction:column;gap:10px}
	.pc-inv-title{text-align:left}
	.pc-inv-cards,.pc-inv-foot{grid-template-columns:1fr}
	.pc-inv-lines thead th,.pc-inv-lines tbody td{padding:9px 7px;font-size:12px}
}
@media print{.pc-inv{border:0;padding:0;background:#fff}}
/* The sheet: one body cell holding the invoice, one footer row that repeats.
   The global td rule gives every cell padding and a bottom rule, which on a
   wrapper is a stray line across the page — killed here for this table's own
   cells only, so the line-item table inside it keeps its own. */
.pc-inv-sheet{width:100%;border-collapse:collapse;border-spacing:0}
.pc-inv-sheet>tbody>tr>td,.pc-inv-sheet>tfoot>tr>td{padding:0;border:0;text-align:left;font-size:inherit;vertical-align:top}
/* The band repeats on every page, so it is measured in a way that can afford
   to: the terms lead it and carry its rule, and the top margin is the gap
   above a footer rather than the gap after a paragraph. */
.pc-inv-sheet-foot .pc-inv-note{margin-top:12px}
.pc-inv-sheet-foot > :first-child{margin-top:14px}
/* On screen the table's own footer is the one you see, once, at the end. */
.pc-inv-pagefoot{display:none}
@media print{
	/* Nothing may break inside the footer, or half of it lands on the next page
	   and the other half is the last thing on this one. */
	.pc-inv-sheet-foot{break-inside:avoid;page-break-inside:avoid}
	.pc-inv-reach,.pc-inv-social,.pc-inv-note{break-inside:avoid;page-break-inside:avoid}
	/* Printing swaps their jobs. The table footer keeps its height — that is
	   what holds the strip open at the foot of every page so nothing flows
	   into it — but stops painting; the fixed copy is what is seen, pinned to
	   the bottom of every page. visibility rather than display, because a
	   display:none footer reserves nothing. */
	.pc-inv-sheet-foot{visibility:hidden}
	.pc-inv-pagefoot{display:block;position:fixed;left:0;right:0;bottom:0;visibility:visible}
	/* Trailing space that only the screen needs.
	   body reserves 76px for the customer app's tab bar and .wrap another 40px
	   under the content. The tab bar is .no-print, so on paper that is 116px —
	   about 31mm — of nothing after the invoice, and an invoice that ends near
	   the foot of page one pushed that emptiness onto a page two of its own:
	   blank apart from the footer band, which repeats on every page including
	   that one. Zeroed for print, where nothing is reserving room for. */
	body{padding-bottom:0}
	.wrap{padding-bottom:0}
}
/* Totals to the right, how to pay full width beneath (2.395.0).
   The totals belong on the right where a reader's eye ends up after a column
   of figures; the account details get their own width below, close enough
   together that a label and its value still read as a pair. */
.pc-inv .pc-inv-foot{grid-template-columns:1fr;justify-items:end}
.pc-inv .pc-inv-sums{width:100%;max-width:340px}
.pc-inv .pc-inv-pay-wide{margin-top:14px;width:100%;padding:14px 18px}
.pc-inv .pc-inv-pay-wide h3{margin:0 0 10px}

/* The ways to pay, side by side with a rule between them.
   Two columns keep the box short on a long invoice; the rule stops the second
   column reading as a continuation of the first, which is what made "Cash"
   look like part of the bank details. */
/* Laid out as a row so the divider runs the full height of the box. Set side
   by side as blocks it only reached as far as the shorter column, which reads
   as an unfinished line rather than a division. */
/* The methods are wrapped in .pc-howpay by the shared block, so the row
   layout has to be applied there rather than on the outer box — applied
   outside it, the rules reached a single child and nothing lined up. */
.pc-inv .pc-inv-pay-wide .pc-howpay{display:flex;flex-wrap:wrap;align-items:stretch}
.pc-inv .pc-inv-pay-wide .pc-howpay > h3{flex:0 0 100%;margin:0 0 10px}
.pc-inv .pc-inv-pay-wide .pc-howpay-row{
	flex:1 1 0;box-sizing:border-box;padding:0 20px 0 0;margin:0;min-width:0}
.pc-inv .pc-inv-pay-wide .pc-howpay-row + .pc-howpay-row{
	padding:0 0 0 20px;border-left:1px solid var(--edge)}
.pc-inv .pc-inv-pay-wide .pc-howpay-row > strong{
	display:block;margin:0 0 8px;font-size:13px}

.pc-inv .pc-inv-pay-wide .bank{max-width:none}
.pc-inv .pc-inv-pay-wide .bank div{padding:4px 0;font-size:12px;border-bottom:1px solid var(--edge)}
.pc-inv .pc-inv-pay-wide .bank div:last-child{border-bottom:0}
.pc-inv .pc-inv-pay-wide .bank span:first-child{color:var(--soft)}

.pc-inv .pc-inv-pay-wide .pc-howpay-ref{font-size:11.5px;margin:8px 0 0;color:var(--soft)}
/* Everything inside a column reads at the same size as the details it
   sits beside, so neither way to pay looks more important than the other.
   Set on the paragraph rather than on a class: this was written as
   `.muted`, and Cash and Cheque do not carry that class — so the one-line
   answer to "how do I pay" was rendered larger than the bank details it sat
   under, which is the opposite of what this rule was for. A rule about
   everything in the column has to be addressed to everything in it.
   The reference line is deliberately smaller and is excluded, or this rule
   would out-specify it and quietly undo that. */
.pc-inv .pc-inv-pay-wide .pc-howpay-row p:not(.pc-howpay-ref){font-size:12px}
.pc-inv .pc-inv-pay-wide .pc-howpay-row .muted{font-size:12px;margin:0}
/* The note about paying several invoices belongs to the whole box, not to the
   column it happens to follow, so it clears both and sits under the rule. */
.pc-inv .pc-inv-pay-wide > .muted{
	display:block;margin:14px 0 0;padding-top:10px;
	border-top:1px solid var(--edge);font-size:11.5px}
@media(max-width:640px){
	/* The container has to stop being a row, not just its children.
	   Setting the rows to block left them as items of a flex parent, so they
	   stayed side by side and squeezed into slivers — two columns of one word
	   each, overlapping. */
	.pc-inv .pc-inv-pay-wide .pc-howpay{display:block}
	.pc-inv .pc-inv-pay-wide .pc-howpay-row{display:block;width:100%;padding:0}
	.pc-inv .pc-inv-pay-wide .pc-howpay-row + .pc-howpay-row{
		padding:12px 0 0;margin-top:12px;border-left:0;border-top:1px solid var(--edge)}
	/* Long account names and sort codes get their own line rather than
	   fighting the label for room. */
	.pc-inv .pc-inv-pay-wide .bank div{flex-wrap:wrap;gap:2px}
	.pc-inv .pc-inv-pay-wide .bank span:last-child{text-align:left}
}
/* Printing: keep the box whole. Half a set of bank details at the foot of a
   page is worse than a page break before it — somebody copying an account
   number should not have to turn over mid-number. */
@media print{
	/* Browsers drop background colours when printing to save ink, which took
	   the green off the column headings and the total block — the two things
	   that tell somebody at a glance what they are looking at. Asked for
	   exactly, so the printed invoice matches the one on screen. */
	.pc-inv,.pc-inv *{-webkit-print-color-adjust:exact;print-color-adjust:exact}
	.pc-inv .pc-inv-pay-wide,.pc-inv .pc-inv-pay-wide .pc-howpay-row,
	.pc-inv .pc-inv-sums,.pc-inv-due{break-inside:avoid;page-break-inside:avoid}
	.pc-inv-lines tr{break-inside:avoid;page-break-inside:avoid}
	.pc-inv-lines thead{display:table-header-group}
}
@media(max-width:640px){.pc-inv .pc-inv-sums{max-width:none}}
/* The booking reference under its description (2.401.0): a block of its own so
   it never splits across a wrap, quieter than the words above it. */
.pc-inv-lines .pc-inv-ref{display:block;margin-top:3px;font-size:11px;color:var(--soft);
	font-family:ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.02em}
/* The print button sits above the invoice and never on the paper (2.402.0). */
.pc-inv-print{margin:14px 0 0;text-align:right}
/* The account history on the portal (2.435.0). Compact, because it sits
   above the invoices rather than replacing them. */
.pc-acct-hist{width:100%;border-collapse:collapse;margin-top:10px;font-size:13px}
.pc-acct-hist th{text-align:left;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);padding:6px 8px;border-bottom:var(--rule,1px solid var(--line))}
.pc-acct-hist td{padding:8px;border-bottom:var(--rule,1px solid var(--line))}
.pc-acct-hist tr:last-child td{border-bottom:0}
.pc-acct-hist .r{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
@media(max-width:520px){.pc-acct-hist th,.pc-acct-hist td{padding:6px 4px;font-size:12px}}
.pc-acct-open{font-weight:650;text-decoration:none;white-space:nowrap}
.pc-acct-hist .sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}

/* ---------------------------------------------------------------------
 * Booking, as cards.
 *
 * One question per step, each answered by tapping rather than by opening a
 * dropdown and reading a list of names. The plain fields are still in the
 * form underneath — see .pc-classic — so the flow survives without script.
 * ------------------------------------------------------------------ */
.pc-classic.is-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.pc-steps { padding-bottom: 88px; }           /* room for the pinned total */
.pc-stepbar { display: flex; align-items: center; gap: 10px; }
.pc-steph { font-size: 20px; margin: 4px 0 14px; color: var(--ink); }
.pc-back {
	border: 1px solid var(--line); background: #fff; color: var(--ink);
	width: 34px; height: 34px; border-radius: 999px; cursor: pointer; font-size: 16px; line-height: 1;
	flex: 0 0 auto; margin-bottom: 10px;
}

.pc-chips { display: flex; gap: 8px; overflow-x: auto; padding: 2px 0 12px; -webkit-overflow-scrolling: touch; }
.pc-chip {
	flex: 0 0 auto; border: 1px solid var(--line); background: #fff; color: var(--ink2);
	border-radius: 999px; padding: 8px 15px; font-size: 14px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.pc-chip.on { background: var(--ink); border-color: var(--ink); color: #fff; }

/* Dates read as a strip of days, because a date input on a phone is a dialog. */
.pc-datechip { display: flex; flex-direction: column; align-items: center; gap: 1px; padding: 8px 14px; min-width: 62px; }
.pc-datechip span { font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
.pc-datechip b { font-size: 19px; line-height: 1.15; }
.pc-datechip.on, .pc-datechip.on span { color: #fff; }
.pc-datechip.on { background: var(--accent); border-color: var(--accent); }

.pc-cards { display: grid; gap: 10px; }
.pc-cards-col { grid-template-columns: 1fr; }
.pc-groupt { font-size: 15px; margin: 6px 0 10px; color: var(--ink); }

.pc-card {
	position: relative; display: block; width: 100%; text-align: left;
	background: #fff; border: 1.5px solid var(--line); border-radius: 14px;
	padding: 14px 52px 14px 16px; cursor: pointer; box-shadow: var(--shadow);
}
.pc-card:hover { border-color: var(--accent); }
.pc-card.on { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), var(--shadow); }
.pc-card-t { display: block; font-size: 16px; font-weight: 700; color: var(--ink); }
.pc-card-d { display: block; font-size: 13px; color: var(--muted); margin-top: 2px; }
.pc-card-x { display: block; font-size: 13px; color: var(--ink2); margin-top: 7px; line-height: 1.45; }
.pc-card-p { display: block; font-size: 16px; font-weight: 700; color: var(--ink); margin-top: 9px; }
/* Why this costs what it costs — a higher figure explained, not just charged. */
.pc-card-w { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }
.pc-card-add {
	position: absolute; top: 14px; right: 14px; width: 30px; height: 30px; border-radius: 999px;
	border: 1px solid var(--line); display: flex; align-items: center; justify-content: center;
	font-size: 17px; color: var(--ink2); background: #fff;
}
.pc-card.on .pc-card-add { background: var(--accent); border-color: var(--accent); color: #fff; }

/* The total, pinned — visible while choosing rather than found at the end. */
.pc-sticky {
	position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
	display: flex; align-items: center; gap: 14px;
	padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
	background: #fff; border-top: 1px solid var(--line);
	box-shadow: 0 -4px 20px rgba(16, 24, 40, .07);
}
.pc-sticky-sum { flex: 1 1 auto; min-width: 0; }
.pc-sticky-sum b { display: block; font-size: 19px; color: var(--ink); }
.pc-sticky-sum span { display: block; font-size: 12px; color: var(--muted); }
.pc-sticky .btn { flex: 0 0 auto; }

@media (min-width: 700px) {
	.pc-sticky { position: sticky; bottom: 12px; border-radius: 14px; border: 1px solid var(--line); }
	.pc-steps { padding-bottom: 12px; }
}


/* The bar is the navigation now: Back, the total, then Next or Request. */
.pc-sticky .pc-nav-btn { margin: 0; flex: 0 0 auto; }
.pc-sticky-sum b:empty, .pc-sticky-sum span:empty { display: none; }
.pc-stepbar { display: none; }


/* The basket: what is about to be sent, itemised.
   A confirmation screen is read once and has to be legible at a glance, so
   the lines are quiet and only the total is heavy. */
.pc-basket-t { width: 100%; border-collapse: collapse; margin: 0 0 14px }
.pc-basket-t td { padding: 10px 0; border-bottom: var(--rule, 1px solid var(--line, #e6e6e6)); vertical-align: top }
.pc-basket-p { text-align: right; white-space: nowrap; padding-left: 12px !important }
.pc-basket-w { display: block; font-size: 12px; opacity: .7; margin-top: 2px }
.pc-basket-tot td { font-weight: 700; font-size: 17px; border-bottom: 0 }
.pc-basket-facts { list-style: none; margin: 0; padding: 0 }
.pc-basket-facts li { display: flex; gap: 12px; padding: 7px 0; border-bottom: var(--rule, 1px solid var(--line, #e6e6e6)) }
.pc-basket-facts li:last-child { border-bottom: 0 }
.pc-basket-k { flex: 0 0 96px; opacity: .7 }


/* The running total opens the basket.

   The bar said what it came to and how many things were in it, which invites
   exactly one question - which things? - and the answer was two screens away.
   It is a button now, and the sheet it opens is drawn by the same function
   that draws the review step. Two renderers would be two opinions about the
   same money, which is the fault this codebase keeps finding. */
.pc-sticky-sum {
	appearance: none; -webkit-appearance: none; background: none; border: 0;
	font: inherit; color: inherit; text-align: left; padding: 0; cursor: pointer;
	display: flex; align-items: center; gap: 10px;
}
.pc-sticky-sum:disabled { cursor: default; }
.pc-sticky-txt { min-width: 0; }
.pc-sticky-sum .pc-sticky-cue {
	flex: 0 0 auto; display: block; font-size: 11px; font-weight: 700; letter-spacing: .02em;
	color: var(--accent); background: #fff; border: 1px solid var(--line);
	border-radius: 999px; padding: 3px 10px;
}
.pc-sticky-sum .pc-sticky-cue[hidden] { display: none; }

/* The sheet itself. Bottom-anchored on a phone, where a thumb is, and
   centred once there is room for it to be a dialog instead. */
.pc-sheet { position: fixed; inset: 0; z-index: 60; display: flex; align-items: flex-end; justify-content: center; }
.pc-sheet[hidden] { display: none; }
.pc-sheet-back { position: absolute; inset: 0; background: rgba(16, 24, 40, .45); }
.pc-sheet-box {
	position: relative; width: 100%; max-width: 560px; max-height: 82vh; overflow: auto;
	background: #fff; border-radius: 18px 18px 0 0;
	padding: 0 18px calc(18px + env(safe-area-inset-bottom, 0px));
	box-shadow: 0 -8px 40px rgba(16, 24, 40, .22);
}
.pc-sheet-head {
	position: sticky; top: 0; z-index: 1; background: #fff;
	display: flex; align-items: center; gap: 12px; padding: 16px 0 12px;
	border-bottom: 1px solid var(--line); margin-bottom: 14px;
}
.pc-sheet-head h3 { margin: 0; flex: 1 1 auto; font-size: 17px; color: var(--ink); }
.pc-sheet-x {
	appearance: none; -webkit-appearance: none; background: none; border: 0;
	font-size: 26px; line-height: 1; color: var(--muted); cursor: pointer; padding: 0 4px;
}
body.pc-noscroll { overflow: hidden; }

@media (min-width: 700px) {
	.pc-sheet { align-items: center; }
	.pc-sheet-box { border-radius: 18px; max-height: 78vh; }
}

/* Which card is the main treatment - it decides the slot, so it says so. */
.pc-card-m { display: inline-block; margin-top: 6px; font-size: 11px; font-weight: 700;
	letter-spacing: .04em; text-transform: uppercase; opacity: .75 }


/* "Anyone in particular?" - only drawn when the time genuinely suits two or
   more, so it never asks a question with one answer. */
.pc-prefwrap { margin-top: 16px; }
.pc-prefwrap .k { display: block; margin-bottom: 6px; }
.pc-prefsel { width: 100%; padding: 12px 14px; font-size: 16px; border: 1px solid var(--line);
	border-radius: 12px; background: #fff; color: inherit; }
.pc-prefwrap .slotnote { margin: 6px 0 0; }


/*
 * "We could not take this booking."
 *
 * A declined request is a cancelled booking, and a cancelled booking in a list
 * is a grey badge among green ones - the one fact that changes somebody's week,
 * styled as an aside. This is the opposite: the first thing on the page, in the
 * colour everything else on the page is not.
 */
.pc-declined {
	border: 1px solid #fca5a5;
	border-left: 5px solid #dc2626;
	background: #fef2f2;
	border-radius: 14px;
	padding: 14px 16px;
	margin: 0 0 16px;
}
.pc-declined-h { margin: 0; font-size: 17px; font-weight: 800; color: #991b1b; }
.pc-declined-w { margin: 4px 0 0; font-weight: 650; }
.pc-declined-r { margin: 8px 0 0; }
.pc-declined-n { margin: 8px 0 0; padding: 10px 12px; background: #fff; border-radius: 10px; }
.pc-declined-f { margin: 10px 0 0; font-size: 14px; color: #7f1d1d; }
/*
 * Clearing it is quiet. The panel is already the loudest thing on the page and
 * the customer is not being asked to do anything — only offered a way to put
 * it away once they have read it. A 44px target, because it is a phone.
 */
.pc-declined-act { margin: 12px 0 0; }
.pc-declined-x {
	background: #fff;
	border: 1px solid #fca5a5;
	color: #991b1b;
	border-radius: 10px;
	padding: 10px 16px;
	min-height: 44px;
	font: inherit;
	font-size: 14px;
	font-weight: 700;
	cursor: pointer;
}
.pc-declined-x:hover { background: #fee2e2; }

/* Shop: the customer's own orders (2.760.7). */
.pshop-orders h3{margin-bottom:8px}
.pshop-order{padding:10px 0;border-top:1px solid var(--line);font-size:14px}
.pshop-order:first-of-type{border-top:0}
.pshop-order-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.pshop-order-items{margin:4px 0 6px;color:var(--ink,#111827)}
.pshop-order-foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:6px 10px;color:var(--muted)}
.pshop-order-foot b{color:var(--ink,#111827)}
.pshop-paid{color:#166534;font-weight:700}
.pshop-tag{display:inline-block;padding:3px 10px;border-radius:999px;font-size:12px;font-weight:700;text-decoration:none;white-space:nowrap}
.pshop-tag.is-new{background:#fef3c7;color:#92400e}
.pshop-tag.is-ready{background:#dbeafe;color:#1e40af}
.pshop-tag.is-done{background:#dcfce7;color:#166534}
.pshop-tag.is-x{background:#f1f5f9;color:#64748b}
.pshop-acts{display:inline-flex;flex-wrap:wrap;align-items:center;gap:6px}
.pshop-inline{display:inline;margin:0}
.pshop-tag.is-pay{border:0;background:var(--accent);color:#fff;cursor:pointer;font:inherit;font-size:12px;font-weight:700;padding:5px 12px}
.pshop-tag.is-cancel{border:1px solid var(--line);background:#fff;color:#b32d2e;cursor:pointer;font:inherit;font-size:12px;font-weight:700;padding:4px 11px}
.pshop-note{margin-top:4px;color:var(--muted);font-size:12px;font-style:italic}
.pshop-waiting{margin:0 0 12px;padding:10px 14px;border-radius:12px;background:var(--accent-50,#fef2f2);font-weight:700}
.pshop-waiting a{color:var(--accent);text-decoration:none}

/* ==========================================================================
   Customer portal on a computer (2.771.8).

   Built for a phone, it drew a 700px phone column in the middle of a laptop
   screen with a tab bar stuck to the bottom of it. From 1100px wide the tab
   bar becomes a sidebar down the left, and the page uses a comfortable
   reading width beside it. Phones and tablets are untouched.
   ========================================================================== */
@media (min-width: 1100px) {
	body { padding-bottom: 0; background: #F3F5F8; }

	.wrap {
		max-width: none;
		margin: 0;
		padding: 28px 48px 56px 292px;
	}
	.wrap > * { max-width: 980px; }

	header { border-radius: 20px; padding: 26px 28px; }
	header .mk { width: 54px; height: 54px; }
	header h1 { font-size: var(--pc-t-xl); }

	.card { padding: 22px 24px; border-color: #E6E9EF; box-shadow: 0 1px 2px rgba(16, 24, 40, .04), 0 6px 18px -10px rgba(16, 24, 40, .10); }
	.pnav { padding: 5px; }

	/* The tab bar, as a sidebar. */
	.app-tabbar {
		top: 0; bottom: 0; left: 0; right: auto;
		width: 244px;
		max-width: none;
		margin: 0;
		flex-direction: column;
		gap: 2px;
		padding: 28px 16px 24px;
		border-top: 0;
		border-right: 1px solid var(--line);
		box-shadow: none;
		overflow-y: auto;
	}
	.app-tabbar a {
		flex: 0 0 auto;
		display: flex;
		align-items: center;
		gap: 12px;
		text-align: left;
		padding: 11px 14px;
		border-radius: 11px;
		font-size: var(--pc-t-m);
		font-weight: 600;
		color: var(--ink2, #334155);
	}
	.app-tabbar a .ti { height: 22px; margin: 0; flex: 0 0 22px; }
	.app-tabbar a:hover { background: var(--accent-50); color: var(--ink); }
	.app-tabbar a.on { background: var(--accent); color: #fff; box-shadow: 0 2px 8px var(--ring); }

	/* In preview mode the owner's ribbon sits across the top. */
	body:has(.ribbon) .app-tabbar { top: 39px; }
	.ribbon { z-index: 40; }

	/* "Add to your phone" is a phone's question, not a laptop's. */
	.install-banner { display: none !important; }

	/* More room for times and products. */
	.slots { grid-template-columns: repeat(4, 1fr); }
	.qlinks { grid-template-columns: repeat(3, 1fr); }
	.qlinks .btn:last-child:nth-child(odd) { grid-column: auto; }
}

/* ==========================================================================
   Customer portal on a computer, second pass (2.771.9).

   A frame for the page: a solid sidebar in the business colour, and the
   account as one bordered panel, two thirds of the screen wide and sitting
   against the sidebar. The coloured greeting is the panel's header, the
   tabs are a ruled strip beneath it, and the cards sit in a shaded well.
   ========================================================================== */
@media (min-width: 1100px) {
	body { background: #E8ECF1; }

	.wrap {
		--frame: #D5DCE4;
		--well: #F1F4F8;
		width: min(66vw, 1200px);
		box-sizing: border-box;
		margin: 28px 0 48px 272px;
		padding: 0 26px 26px;
		background: var(--well);
		border: 1px solid var(--frame);
		border-radius: 16px;
		box-shadow: 0 1px 2px rgba(16, 24, 40, .05), 0 8px 24px -12px rgba(16, 24, 40, .12);
		overflow: hidden;
	}
	.wrap > * { max-width: none; }

	header {
		margin: 0 -26px;
		border-radius: 0;
		box-shadow: none;
		padding: 24px 26px;
	}
	.pnav {
		margin: 0 -26px 20px;
		padding: 8px 26px;
		border: 0;
		border-bottom: 1px solid var(--frame);
		border-radius: 0;
		box-shadow: none;
		background: #fff;
	}
	.card { border: 1px solid var(--frame); border-radius: 12px; box-shadow: 0 1px 2px rgba(16, 24, 40, .04); }
	.wrap > p.muted:last-child { margin: 18px 0 0; }

	/* Sidebar: solid, in the business colour. */
	.app-tabbar {
		box-sizing: border-box;
		width: 244px;
		background: var(--accent-d, var(--accent));
		border-right: 0;
		padding-top: 32px;
	}
	.app-tabbar a { color: rgba(255, 255, 255, .80); }
	.app-tabbar a:hover { background: rgba(255, 255, 255, .10); color: #fff; }
	.app-tabbar a.on {
		background: rgba(255, 255, 255, .16);
		color: #fff;
		box-shadow: inset 3px 0 0 #fff;
	}
}

/* Settings that only mean something on a phone (2.771.12): installing to a
   home screen, swipe gestures, GPS, keeping the screen awake, whether this
   phone has WhatsApp. Hidden where there is a mouse and no touch screen,
   so a laptop or desktop is not asked about them. A phone or tablet, even
   a wide one, still shows them. */
@media (hover: hover) and (pointer: fine) {
	.pc-phone-only { display: none !important; }
}

/* A computer, however it points (2.771.13): set by a small script. */
html.pc-computer .pc-phone-only { display: none !important; }
