/* How the printed bill looks.
 *
 * One layout, five sets of clothes. The markup in receipt.js is the same for
 * every template — a header, a table, a summary and a foot — and everything
 * below only says how those are dressed. Five separate layouts would drift
 * apart within a month, and a shop would pick a design it never actually gets.
 *
 * Two custom properties carry the shop's own choices in from the settings:
 *   --inv-accent  the colour on headings, rules and the total
 *   --inv-scale   text size, 0.8 to 1.3
 * They are set on .paper itself, so everything inside can lean on them. */

.paper {
  --inv-accent: #0f766e;
  --inv-text: #111;
  --inv-scale: 1;
  font-size: calc(12px * var(--inv-scale));
  color: var(--inv-text);
}

/* The heading a shop wants above its own name — TAX INVOICE, CASH MEMO, or
 * nothing at all. */
.p-title {
  margin-bottom: 8px;
  font-size: calc(13px * var(--inv-scale));
  font-weight: 700;
  letter-spacing: 2px;
  text-align: center;
  text-transform: uppercase;
  color: var(--inv-accent);
}

/* A caption being retyped on the preview. Only the preview turns these on —
 * the printed bill carries the same markup with nothing editable in it. */
.editable {
  outline: 1px dashed transparent;
  outline-offset: 2px;
  cursor: text;
}
.editable:hover { outline-color: var(--inv-accent); background: rgba(0, 0, 0, .04); }
.editable:focus { outline: 1px solid var(--inv-accent); background: #fff; }

.p-a4 { width: 100%; }
.p-a5 { max-width: 148mm; }
.p-letter { max-width: 216mm; }
.paper.landscape { max-width: none; }

.p-logo {
  max-width: 130px;
  max-height: 56px;
  margin-bottom: 6px;
  object-fit: contain;
}

/* Shading alternate rows is a preference, not a template — a chemist reading
 * thirty lines across a counter wants it; one printing on a slow inkjet does
 * not. */
.paper.zebra .p-items tbody tr:nth-child(even) { background: #f7f8fa; }

/* ── Classic ──────────────────────────────────────────────────────
 * The default, and deliberately plain: black on white, one rule under the
 * heading. It is what a shop that has printed the same bill for ten years
 * expects to keep getting. */
.t-classic .p-items th { border-bottom: 1.5px solid #333; }
.t-classic .p-total { border-top: 1.5px solid #333; }

/* ── Modern ───────────────────────────────────────────────────────
 * A band of colour across the head and no outer frame. The shop's name is
 * the first thing read; the rules step back to hairlines. */
.t-modern { border: 0; padding: 0 18px 16px; }
.t-modern .p-head {
  padding: 14px 18px;
  color: #fff;
  background: var(--inv-accent);
}
.t-modern .p-head .p-meta span,
.t-modern .p-head .p-meta b { color: #fff; }
/* Everything is inset, and the band is what is exempted — not the other way
 * round.
 *
 * This was a list of five block names, written when the paper had five blocks
 * on it. The heading was never in it, so on a template that drops the paper's
 * own padding the heading sat hard against the left edge with the whole bill
 * indented under it. Naming what is FULL-BLEED is a list of one that cannot go
 * out of date; naming what is inset is a list that has to be remembered every
 * time the bill grows a block, and it was not.
 *
 * The inset is PADDING on the paper, and the band breaks back out of it with a
 * negative margin. It was the other way round — no padding, and a margin on
 * every child — and that is what cut the AMOUNT column off the bill.
 *
 * A block with `width: 100%` resolves the 100% against its containing block,
 * and margins are NOT taken off that width. So the item table came out the
 * full width of the paper and was then shoved 18px to the right, hanging off
 * the right-hand edge by exactly the inset. The table was never too wide; it
 * was in the wrong place, which is why every attempt to fix the table failed.
 * Padding cannot fail that way: it makes the containing block itself smaller,
 * so 100% is already the inset width, for this table and for whatever block
 * the bill grows next. */
.t-modern > .p-head { margin-left: -18px; margin-right: -18px; }
.t-modern .p-items th {
  color: var(--inv-accent);
  background: none;
  border-bottom: 2px solid var(--inv-accent);
}
.t-modern .p-items td { border-bottom: 1px solid #eef1f5; }
.t-modern .p-total {
  padding: 6px 10px;
  color: #fff;
  background: var(--inv-accent);
  border: 0;
  border-radius: 5px;
}

/* ── Bold ─────────────────────────────────────────────────────────
 * Read across a counter, by somebody not holding it. Large name, heavy
 * rules, headings in capitals. */
.t-bold .p-shop h2 {
  font-size: calc(26px * var(--inv-scale));
  letter-spacing: -.4px;
  color: var(--inv-accent);
}
.t-bold .p-head { padding-bottom: 10px; border-bottom: 3px solid var(--inv-accent); }
.t-bold .p-items th {
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .5px;
  border-bottom: 2px solid #222;
}
.t-bold .p-total { font-size: calc(15px * var(--inv-scale)); border-top: 3px solid var(--inv-accent); }
.t-bold .p-total b { font-size: calc(18px * var(--inv-scale)); }

/* ── Compact ──────────────────────────────────────────────────────
 * Thirty lines on one sheet. Nothing is removed — it is tightened. */
.t-compact { font-size: calc(10.5px * var(--inv-scale)); }
.t-compact .p-shop h2 { font-size: calc(14px * var(--inv-scale)); }
.t-compact .p-items th,
.t-compact .p-items td { padding: 2px 5px; }
.t-compact .p-head { gap: 10px; }
.t-compact .p-sum { margin-top: 6px; }

/* ── Elegant ──────────────────────────────────────────────────────
 * Serif, centred heading, hairlines. For the shop that thinks of its bill
 * as its letterhead. */
.t-elegant { font-family: Georgia, "Times New Roman", serif; }
.t-elegant .p-head { flex-direction: column; align-items: center; text-align: center; gap: 8px; }
.t-elegant .p-shop h2 {
  font-size: calc(21px * var(--inv-scale));
  font-weight: 400;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--inv-accent);
}
.t-elegant .p-meta { display: flex; gap: 22px; }
.t-elegant .p-items th {
  font-weight: 400;
  font-style: italic;
  border-top: 1px solid var(--inv-accent);
  border-bottom: 1px solid var(--inv-accent);
  background: none;
}
.t-elegant .p-items td { border-bottom: 1px solid #eee; }
.t-elegant .p-total { border-top: 1px solid var(--inv-accent); }
.t-elegant .p-foot { font-style: italic; }

/* Thermal ignores the dressing: 80mm of roll has room for the figures and
 * nothing else, whichever template is set. */
.p-thermal.t-modern .p-head { color: #111; background: none; padding: 8px 0; }
.p-thermal.t-modern > * { margin-left: 0; margin-right: 0; }
.p-thermal .p-logo { max-width: 90px; }
.p-thermal.t-elegant { font-family: "Consolas", "Courier New", monospace; }

/* ── The preview on the settings screen ───────────────────────────
 *
 * The real paper, shrunk. Not a drawing of it — a drawing would drift.
 *
 * Shrunk with `zoom`, not `transform: scale()`. A transform moves the pixels
 * and leaves the LAYOUT box its full size, so the panel was twice as tall as
 * what it showed: a small bill at the top and seven hundred pixels of nothing
 * under it. Scrolled down to the controls, the shop saw only the nothing.
 * Zoom reflows, so the box is the size of what is in it.
 *
 * It also sticks: the whole point is watching the bill change while the
 * controls beside it are being changed. */
.set-preview {
  position: sticky;
  top: 0;
  flex: 0 0 380px;
  min-width: 0;
}
/* The panel is the desk the sheet lies on, so the sheet's own edges show. */
.prev-paper {
  max-height: 62vh;
  overflow: auto;
  padding: 10px;
  background: #e9ecf1;
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: inset 0 1px 4px rgba(0, 0, 0, .06);
}

/* The paper at its REAL size, scaled to fit.
 *
 * It used to be forced to `width: 100%` at a fixed .58 zoom, so the preview
 * was the PANEL's shape rather than the paper's: A4 came out as a squat block
 * and an 80mm roll came out exactly as wide as A4 — the one thing a shop
 * chooses a roll to avoid. "Preview" then meant "roughly these words in
 * roughly this order", which is not what the word is for.
 *
 * So each paper carries its own width in millimetres and its own scale, and
 * the proportions on screen are the proportions that come off the printer. */
.prev-paper .paper {
  width: var(--prev-w, 210mm);
  max-width: none;
  zoom: var(--prev-z, .45);
  margin: 0 auto;
  background: #fff;
  border: 0;
  border-radius: 0;
  box-shadow: 0 1px 5px rgba(0, 0, 0, .25);
}
.prev-paper .p-a4     { --prev-w: 210mm; --prev-z: .45; }
.prev-paper .p-a5     { --prev-w: 148mm; --prev-z: .62; }
.prev-paper .p-letter { --prev-w: 216mm; --prev-z: .44; }
/* A roll is narrow enough to show at nearly its own size, which is most of
 * the reason for looking at one. */
.prev-paper .p-thermal   { --prev-w: 80mm; --prev-z: 1; }
.prev-paper .p-thermal58 { --prev-w: 58mm; --prev-z: 1; }
/* Turned sideways, the sheet is its own long edge across. */
.prev-paper .p-a4.landscape     { --prev-w: 297mm; --prev-z: .32; }
.prev-paper .p-a5.landscape     { --prev-w: 210mm; --prev-z: .45; }
.prev-paper .p-letter.landscape { --prev-w: 279mm; --prev-z: .34; }
.set-preview h4 {
  margin: 0 0 12px;
  padding-bottom: 7px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .7px;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
}


/* ── The patient block ────────────────────────────────────────────
 *
 * A pharmacy bill is a dispensing record with a patient on it, so this is a
 * labelled block and not a line of names: a pharmacist checking a returned
 * strip six weeks later reads down the labels, not across a sentence. */
.p-cust {
  display: flex;
  gap: 24px;
  align-items: flex-start;
  margin-top: 10px;
  padding: 8px 10px;
  background: #f7f8fa;
  border: 1px solid #e6e9ef;
  border-radius: 4px;
}
.p-patient, .p-doctors { display: grid; gap: 1px 14px; }
.p-patient { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); flex: 1; }
.p-doctors { flex: 0 0 auto; }
.p-cust > div > div { display: flex; gap: 6px; }
.p-cust span { min-width: 78px; color: #555; }
.p-cust b { font-weight: 600; }

/* What was handed over, and what is still owed. */
.p-sum .p-balance b { font-weight: 700; }
.p-notes { flex: 1; display: grid; gap: 2px; }
.p-words b { font-weight: 600; }
.p-signs { display: flex; gap: 30px; align-items: flex-end; }

/* ── Hospital ─────────────────────────────────────────────────────
 *
 * The one a hospital pharmacy prints: everything inside a ruled box, the
 * title in a band across the middle, the patient block boxed under it, and
 * the money in a labelled column on the right. Dense on purpose — this sheet
 * is filed, not admired. */
.t-hospital { border: 1.5px solid #333; padding: 10px 12px; }
.t-hospital .p-title {
  margin: 6px 0;
  padding: 2px 0;
  font-size: calc(12px * var(--inv-scale));
  letter-spacing: 1px;
  color: var(--inv-text);
  background: #eceff4;
  border-top: 1px solid #333;
  border-bottom: 1px solid #333;
}
.t-hospital .p-head { align-items: flex-start; text-align: center; flex-direction: column; }
.t-hospital .p-shop { width: 100%; }
.t-hospital .p-shop h2 { font-size: calc(15px * var(--inv-scale)); }
.t-hospital .p-meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  width: 100%;
  text-align: left;
}
.t-hospital .p-cust { background: none; border: 1px solid #333; border-radius: 0; }
.t-hospital .p-items th {
  background: none;
  border-top: 1px solid #333;
  border-bottom: 1px solid #333;
}
.t-hospital .p-items td { border-bottom: 0; }
.t-hospital .p-sum { border: 1px solid #333; padding: 6px 8px; }
.t-hospital .p-total { border-top: 1px solid #333; }
.t-hospital .p-foot { border-top: 1px solid #333; padding-top: 6px; }

/* ── Colour ───────────────────────────────────────────────────────
 *
 * A designed bill rather than a ruled one: a panel behind the heading, the
 * table head as a solid band, and the total as a block. For a shop whose
 * bill is also its card. */
.t-colour { border: 0; padding: 0 20px 18px; }
.t-colour .p-title {
  margin: 0;
  padding: 16px 20px 4px;
  font-size: calc(24px * var(--inv-scale));
  font-weight: 800;
  letter-spacing: -.5px;
  text-align: left;
  color: var(--inv-text);
  background: color-mix(in srgb, var(--inv-accent) 12%, #fff);
}
.t-colour .p-head {
  padding: 0 20px 16px;
  background: color-mix(in srgb, var(--inv-accent) 12%, #fff);
}
.t-colour .p-shop h2 { font-size: calc(15px * var(--inv-scale)); color: var(--inv-accent); }
/* Same rule as Modern: inset everything, exempt the panel. Here the heading
 * is PART of the coloured panel, so it is full-bleed with it. */
.t-colour > .p-title,
.t-colour > .p-head { margin-left: -20px; margin-right: -20px; }
.t-colour .p-cust { background: none; border: 0; border-bottom: 1px solid #e6e9ef; border-radius: 0; }
.t-colour .p-items th {
  padding: 7px 6px;
  color: #fff;
  background: var(--inv-accent);
  border: 0;
}
.t-colour .p-items td { border-bottom: 1px solid #eef1f5; }
.t-colour .p-total {
  margin-top: 4px;
  padding: 7px 10px;
  color: #fff;
  background: var(--inv-accent);
  border: 0;
  border-radius: 4px;
}
.t-colour .p-total b { font-size: calc(15px * var(--inv-scale)); }

/* Thermal has no room for a designed header whichever template is set. */
.p-thermal.t-colour .p-title,
.p-thermal.t-colour .p-head { padding: 6px 0; background: none; }
.p-thermal.t-colour > * { margin-left: 0; margin-right: 0; }
.p-thermal .p-cust { flex-direction: column; gap: 2px; }


/* The wholesale foot: the certificate a drug invoice carries, and where the
 * money goes. */
.p-decl { margin-top: 4px; font-style: italic; }
.p-bank { margin-top: 3px; }
.p-bank span { margin-right: 4px; color: #555; }
.p-bank span:not(:first-child) { margin-left: 12px; }


/* ── The letterhead, in three zones ───────────────────────────────
 *
 * The header is no longer "shop on the left, bill number on the right" — it
 * is three zones the shop arranges its own blocks into. The zones are always
 * present even when empty, because an empty zone is where a block is dropped. */
.p-head { display: flex; gap: 16px; align-items: flex-start; }
.p-zone { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
/* `flex: 1 1 0` is a ROW instruction: three zones sharing the width equally.
 * See the note under the stacked templates for what it does in a column. */
.z-left { flex: 1 1 0; align-items: flex-start; text-align: left; }
.z-center { flex: 1 1 0; align-items: center; text-align: center; }
.z-right { flex: 1 1 0; align-items: flex-end; text-align: right; }

/* ── A stacked head ──────────────────────────────────────────────────
 *
 * Elegant and Hospital run the head DOWN the page rather than across it. The
 * zones' `flex: 1 1 0` then applies to the height instead of the width: every
 * zone gets a basis of zero, its contents overflow the box it was given, and
 * the shop's name, its address and the bill number are drawn on top of one
 * another. That is what "template ka design tut raha hai" was — and it was
 * only ever the two templates that stack.
 *
 * A zone in a column is as tall as what is in it and as wide as the paper. */
.t-elegant .p-head > .p-zone,
.t-hospital .p-head > .p-zone {
  flex: 0 0 auto;
  width: 100%;
}
/* Stacked, they read down the middle rather than fleeing to the two edges. */
.t-elegant .p-head > .p-zone { align-items: center; text-align: center; }
.p-block { position: relative; max-width: 100%; }
.z-center .p-title { margin-bottom: 0; }

/* A zone with nothing in it takes no room on PAPER — the dashed target is a
 * thing only the editor draws.
 *
 * `.bare`, not `:empty`: the zone is written with a newline inside it, and a
 * node containing whitespace is not empty, so this rule never fired once. A
 * shop that dragged everything to the left still had two thirds of its
 * letterhead held open by nothing. */
.p-zone.bare { flex: 0 0 0; }

/* ── Bill book ────────────────────────────────────────────────────
 *
 * The carbon book that sits on the counter: a boxed head, every line ruled
 * across, and room at the foot to sign. It is not a colour change — a shop
 * that has torn a page off a book for twenty years is looking for the box
 * round the top and the lines it writes between, and those are what make it
 * recognisable rather than any accent. */
.t-billbook { border: 2px solid #333; padding: 0 12px; }
.t-billbook > .p-head,
.t-billbook > .p-title { margin: 0 -12px; }
.t-billbook .p-title {
  padding: 5px 12px;
  font-size: calc(13px * var(--inv-scale));
  font-weight: 800;
  letter-spacing: .12em;
  text-align: center;
  border-bottom: 2px solid #333;
}
.t-billbook .p-head { padding: 8px 12px; border-bottom: 2px solid #333; }
.t-billbook .p-cust {
  padding: 6px 0;
  background: none;
  border: 0;
  border-bottom: 1px solid #333;
  border-radius: 0;
}
/* Ruled all the way across, the way the book is printed. */
.t-billbook .p-items th {
  padding: 4px 6px;
  border-top: 1px solid #333;
  border-bottom: 1px solid #333;
}
.t-billbook .p-items th + th,
.t-billbook .p-items td + td { border-left: 1px solid #bbb; }
.t-billbook .p-items td { border-bottom: 1px solid #ddd; }
.t-billbook .p-total { border-top: 2px solid #333; }
/* The blank the counter signs on. A book always has one. */
.t-billbook .p-foot { padding-bottom: 20px; border-top: 1px solid #333; }

/* ── Spreadsheet ──────────────────────────────────────────────────
 *
 * Every cell ruled, nothing else. For a shop whose accountant wants the bill
 * to read like the worksheet he is going to copy it into — and for anyone
 * checking a long bill line by line down a column. */
.t-sheet { border: 1px solid #666; padding: 10px 12px; }
.t-sheet .p-title {
  margin-bottom: 6px;
  font-size: calc(13px * var(--inv-scale));
  font-weight: 700;
  text-align: left;
}
.t-sheet .p-cust { background: none; border: 1px solid #999; border-radius: 0; padding: 5px 7px; }
.t-sheet .p-items th,
.t-sheet .p-items td {
  padding: 3px 6px;
  border: 1px solid #999;
}
.t-sheet .p-items th {
  font-size: calc(9.5px * var(--inv-scale));
  text-transform: uppercase;
  letter-spacing: .04em;
  background: #eceff4;
}
.t-sheet .p-items tbody tr:nth-child(even) { background: #fafbfc; }
.t-sheet .p-tax table th, .t-sheet .p-tax table td { border: 1px solid #999; }
.t-sheet .p-sum { border: 1px solid #999; padding: 5px 8px; }
.t-sheet .p-total { border-top: 1px solid #999; }

/* ── Ledger ───────────────────────────────────────────────────────
 *
 * The way a ledger page is set: wide margins, hairline rules, no vertical
 * lines at all. Read DOWN a column rather than across a row — which is what
 * somebody totalling a month of bills is doing. */
.t-ledger { border: 0; padding: 18px 26px; }
.t-ledger .p-title {
  margin-bottom: 10px;
  padding-bottom: 6px;
  font-size: calc(12px * var(--inv-scale));
  font-weight: 600;
  letter-spacing: .22em;
  text-align: center;
  text-transform: uppercase;
  border-bottom: 1px solid #333;
}
.t-ledger .p-cust { background: none; border: 0; border-bottom: 1px solid #ccc; border-radius: 0; }
.t-ledger .p-items th {
  padding: 5px 4px;
  font-weight: 600;
  border-bottom: 1px solid #333;
}
/* Hairlines only, and none between the columns. */
.t-ledger .p-items td { padding: 4px 4px; border-bottom: 1px solid #e8e8e8; }
.t-ledger .p-items th + th,
.t-ledger .p-items td + td { border-left: 0; }
.t-ledger .p-total { border-top: 1px solid #333; border-bottom: 3px double #333; }
.t-ledger .p-foot { border-top: 0; }

/* A roll has no room for a boxed head or a ruled grid whichever of the three
 * is set — the same rule the other designed templates already follow. */
.p-thermal.t-billbook,
.p-thermal.t-sheet,
.p-thermal.t-ledger { border: 0; padding: 8px 6px; }
.p-thermal.t-billbook > *,
.p-thermal.t-sheet > *,
.p-thermal.t-ledger > * { margin-left: 0; margin-right: 0; }
.p-thermal.t-billbook .p-items th + th,
.p-thermal.t-billbook .p-items td + td,
.p-thermal.t-sheet .p-items th,
.p-thermal.t-sheet .p-items td { border: 0; }

/* ── Each head its own shape ──────────────────────────────────────
 *
 * Colours and rules alone do not make ten templates: seven of them left the
 * head exactly as it comes — shop on the left, bill number on the right, one
 * rule under — so a shop clicking through the cards saw the same bill ten
 * times with different borders. What a chemist recognises about a bill is its
 * TOP, and that is what these change.
 *
 * What they never change is WHICH block sits where. A letterhead is the
 * shop's own arrangement, dragged into place on the preview, and a template
 * that rearranged it would throw that away every time one was tried. */

/* Classic — the plain one. Shop left, bill right, a rule beneath. */
.t-classic .p-head { padding-bottom: 8px; border-bottom: 1px solid #333; }

/* Bold — the shop's name across the whole width, the details in a row under
 * it. For a counter read from three feet away. */
.t-bold .p-head { flex-wrap: wrap; }
.t-bold .z-left { flex: 1 1 100%; align-items: center; text-align: center; }
.t-bold .z-left .p-shop h2 { font-size: calc(21px * var(--inv-scale)); letter-spacing: -.4px; }
.t-bold .z-center, .t-bold .z-right { flex: 1 1 0; }

/* Compact — one tight line, no rule, nothing spare. Thirty items have to fit
 * on the page and the head is what gives up the room. */
.t-compact .p-head { gap: 10px; align-items: baseline; padding-bottom: 4px; }
.t-compact .p-zone { flex-direction: row; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
.t-compact .p-shop h2 { font-size: calc(12.5px * var(--inv-scale)); }
.t-compact .p-meta { display: flex; gap: 4px 10px; flex-wrap: wrap; }

/* Elegant — centred between two hairlines, the way a card is set. */
.t-elegant .p-head {
  padding: 10px 0;
  border-top: 1px solid #999;
  border-bottom: 1px solid #999;
}

/* Bill book — the head boxed, the way the printed book has it. */
.t-billbook .p-head { gap: 0; align-items: stretch; }
.t-billbook .p-zone { padding: 6px 10px; }
.t-billbook .p-zone + .p-zone { border-left: 1px solid #333; }

/* Spreadsheet — the head as ruled cells, like the worksheet it is meant to
 * read as. */
.t-sheet .p-head { gap: 0; align-items: stretch; margin-bottom: 8px; }
.t-sheet .p-zone { padding: 5px 8px; border: 1px solid #999; }
.t-sheet .p-zone + .p-zone { border-left: 0; }
.t-sheet .p-zone:empty { display: none; }

/* Ledger — no box anywhere. The shop and the bill sit on one baseline over a
 * single rule, which is how a ledger page opens. */
.t-ledger .p-head {
  align-items: baseline;
  padding-bottom: 8px;
  border-bottom: 1px solid #333;
}
.t-ledger .p-shop h2 { font-weight: 600; letter-spacing: .04em; }

/* ── Roll ─────────────────────────────────────────────────────────
 *
 * The receipt a thermal printer produces, available on any paper.
 *
 * "Thermal" was a paper SIZE, so a shop that wanted the look of a roll — the
 * narrow centred slip its customers already recognise — had to own a roll
 * printer to get it. This is that design as a choice: centred, monospaced,
 * dashed rules, no table borders, and a column of figures rather than a grid.
 * On an A4 sheet it prints as a slip down the middle of the page, which is
 * what a shop reprinting a receipt for a file actually wants. */
.t-roll {
  max-width: 82mm;
  margin-left: auto;
  margin-right: auto;
  padding: 10px 8px;
  font-family: "Consolas", "Courier New", monospace;
  font-size: calc(10.5px * var(--inv-scale));
  border: 1px dashed #999;
}
.t-roll .p-head { flex-direction: column; align-items: center; gap: 4px; text-align: center; }
.t-roll .p-head > .p-zone { flex: 0 0 auto; width: 100%; align-items: center; text-align: center; }
.t-roll .p-title {
  margin-bottom: 2px;
  font-size: calc(12px * var(--inv-scale));
  letter-spacing: .18em;
  text-align: center;
}
.t-roll .p-shop h2 { font-size: calc(12.5px * var(--inv-scale)); }
.t-roll .p-cust {
  padding: 4px 0;
  background: none;
  border: 0;
  border-top: 1px dashed #999;
  border-bottom: 1px dashed #999;
  border-radius: 0;
}
/* A slip has no grid — it has a list with a dashed rule over the figures. */
.t-roll .p-items th {
  padding: 3px 2px;
  font-size: calc(9px * var(--inv-scale));
  background: none;
  border: 0;
  border-bottom: 1px dashed #999;
}
.t-roll .p-items td { padding: 2px 2px; border: 0; }
.t-roll .p-items th + th, .t-roll .p-items td + td { border-left: 0; }
.t-roll .p-tax { display: none; }
.t-roll .p-sum { width: 100%; }
.t-roll .p-total { border-top: 1px dashed #999; border-bottom: 1px dashed #999; }
.t-roll .p-foot { text-align: center; border-top: 1px dashed #999; }
.t-roll .p-signs { display: none; }
/* On an actual roll the dashed frame is the paper's own edge. */
.p-thermal.t-roll { max-width: none; border: 0; padding: 8px 6px; }

/* ── Cash memo ────────────────────────────────────────────────────
 *
 * The pre-printed book every chemist in the country has torn a page off:
 * heavy coloured rules, the shop's name and trade across the top, the words
 * CASH MEMO in a corner, a ruled grid, and "Authorised Signatory" at the
 * foot. The colour is the shop's own accent rather than a fixed red, so a
 * shop whose book was blue gets a blue one.
 *
 * It is the most recognisable bill on this list and it was not here. */
.t-memo { border: 2px solid var(--inv-accent); padding: 0 10px; }
.t-memo > .p-head, .t-memo > .p-title { margin: 0 -10px; }
.t-memo .p-title {
  position: relative;
  padding: 4px 10px;
  font-size: calc(11px * var(--inv-scale));
  font-weight: 800;
  letter-spacing: .14em;
  text-align: right;
  color: #fff;
  background: var(--inv-accent);
}
.t-memo .p-head {
  padding: 8px 10px;
  border-bottom: 2px solid var(--inv-accent);
}
.t-memo .p-shop h2 {
  font-size: calc(17px * var(--inv-scale));
  font-weight: 800;
  letter-spacing: .02em;
  color: var(--inv-accent);
}
.t-memo .p-cust {
  padding: 5px 0;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--inv-accent);
  border-radius: 0;
}
.t-memo .p-items th {
  padding: 3px 5px;
  font-size: calc(9px * var(--inv-scale));
  color: var(--inv-accent);
  background: none;
  border-top: 1px solid var(--inv-accent);
  border-bottom: 1px solid var(--inv-accent);
}
.t-memo .p-items th + th,
.t-memo .p-items td + td { border-left: 1px solid var(--inv-accent); }
.t-memo .p-items td { border-bottom: 1px solid #e7e7e7; }
.t-memo .p-total { border-top: 2px solid var(--inv-accent); }
/* The line the counter signs over. A book always prints one. */
.t-memo .p-foot { padding-bottom: 22px; border-top: 1px solid var(--inv-accent); }

/* ── Watermark ────────────────────────────────────────────────────
 *
 * The pastel book with the shop's name ghosted across the middle of the page.
 * The watermark is the shop's own accent at a few per cent — printed, it is
 * the tint the paper came with. */
.t-mark { position: relative; border: 1px solid var(--inv-accent); }
.t-mark::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(45deg,
      color-mix(in srgb, var(--inv-accent) 5%, transparent) 0 12px,
      transparent 12px 26px);
  pointer-events: none;
}
/* Everything sits over the tint rather than under it. */
.t-mark > * { position: relative; }
.t-mark .p-head {
  padding-bottom: 8px;
  border-bottom: 2px solid var(--inv-accent);
}
.t-mark .p-title { color: var(--inv-accent); letter-spacing: .1em; }
.t-mark .p-items th {
  color: var(--inv-accent);
  background: color-mix(in srgb, var(--inv-accent) 8%, #fff);
  border-bottom: 1px solid var(--inv-accent);
}
.t-mark .p-items th + th, .t-mark .p-items td + td { border-left: 1px solid #dfe4e8; }
.t-mark .p-items td { border-bottom: 1px solid #eceff2; }
.t-mark .p-total { border-top: 2px solid var(--inv-accent); }

/* ── Statement ────────────────────────────────────────────────────
 *
 * The hospital statement: serif, dated service lines, no vertical rules at
 * all, the account details boxed at the top right. What a patient hands to an
 * insurer — and what a nursing home's pharmacy is asked for. */
.t-stmt { font-family: Georgia, "Times New Roman", serif; border: 0; padding: 20px 24px; }
.t-stmt .p-head { align-items: flex-start; padding-bottom: 10px; }
.t-stmt .p-shop h2 {
  font-size: calc(19px * var(--inv-scale));
  font-weight: 400;
  letter-spacing: -.2px;
  border-bottom: 2px solid #111;
}
.t-stmt .p-title { font-size: calc(11px * var(--inv-scale)); letter-spacing: .16em; text-align: left; }
.t-stmt .p-cust {
  padding: 6px 8px;
  background: none;
  border: 1px solid #111;
  border-radius: 0;
}
.t-stmt .p-items th {
  padding: 4px 4px;
  font-weight: 400;
  font-style: italic;
  background: none;
  border-bottom: 1px solid #111;
}
.t-stmt .p-items td { padding: 3px 4px; border-bottom: 0; }
.t-stmt .p-items th + th, .t-stmt .p-items td + td { border-left: 0; }
.t-stmt .p-total { border-top: 1px solid #111; border-bottom: 3px double #111; }

/* ── A season on the bill ─────────────────────────────────────────
 *
 * A layer over whichever template is set, never a template of its own — see
 * the note in receipt.js. Each is a border, the festival's own colour (which
 * arrives through --inv-accent, so every rule the template already draws goes
 * with it) and a greeting at the foot.
 *
 * Deliberately restrained. A tax invoice is a legal document, and a shop that
 * puts a garland across one hands its customer something an auditor looks at
 * twice. What these do is what a printed greeting card does: a coloured edge
 * and a line of good wishes. */
.p-greet {
  margin-top: 5px;
  padding-top: 4px;
  font-size: calc(10px * var(--inv-scale));
  font-weight: 600;
  font-style: italic;
  color: var(--inv-accent);
  border-top: 1px dotted var(--inv-accent);
}

/* The edge each festival is known by. A double rule, in its own colours —
 * printed on a mono laser it still reads as a border rather than as mush. */
.f-diwali { border-top: 4px double #b45309; border-bottom: 4px double #b45309; }
.f-holi { border-top: 4px solid #be185d; border-bottom: 4px solid #f59e0b; }
.f-eid { border-top: 3px solid #047857; border-bottom: 3px solid #047857; }
.f-christmas { border-top: 4px solid #b91c1c; border-bottom: 4px solid #15803d; }
.f-newyear { border-top: 3px double #1d4ed8; border-bottom: 3px double #1d4ed8; }
/* The tricolour, in order, at the top of the page. */
.f-independence {
  border-top: 6px solid;
  border-image: linear-gradient(to right, #ff9933 0 33%, #ffffff 33% 66%, #138808 66%) 1;
  border-bottom: 3px solid #138808;
}

/* On a roll there is no room for a decorated edge, and a thermal head prints
 * a solid rule as a black band. The greeting survives; the border does not. */
.p-thermal.f-diwali, .p-thermal.f-holi, .p-thermal.f-eid,
.p-thermal.f-christmas, .p-thermal.f-newyear, .p-thermal.f-independence {
  border-top: 0;
  border-bottom: 0;
  border-image: none;
}

/* The batch and expiry, under the name, on paper too narrow for a column of
 * their own. A pharmacy slip without a batch on it is not one — so on 58mm
 * they move rather than being dropped. */
.p-bx {
  display: block;
  font-size: calc(8.5px * var(--inv-scale));
  opacity: .75;
}

/* Nothing on a roll may be wider than the roll. The preview showed the item
 * table running off the side with a scrollbar under it, and a scrollbar is not
 * something a printer has. */
.p-thermal .p-items,
.p-thermal .p-items table { width: 100%; table-layout: fixed; }
.p-thermal .p-items td,
.p-thermal .p-items th { overflow-wrap: anywhere; }
.p-thermal58 .p-items th:first-child,
.p-thermal58 .p-items td:first-child { display: none; }
