/* ===========================================================================
   Bake — Bryan's Cake House
   Dressed from the shop's own hiring poster: a strong red band across the top
   carrying the pattern, gold for the small labels on it, brown for everything
   that is read, and white paper underneath.
   Red is the BAND, never the text — because red inside the page is still
   reserved for money that needs attention, and a page painted red everywhere
   would say nothing when a figure turns red.
   =========================================================================== */

:root{
  --ground:#F4EDEA; --panel:#FFFFFF; --sunk:#F7EFEB; --row:#FDFAF9;
  --line:#E6D8D2; --line2:#D3BFB7;
  --ink:#2E1512; --dim:#77574F; --faint:#8F7466;
  --accent:#3E1B15; --accent-ink:#FFFFFF; --accent-soft:#F4E6E1;
  --gold:#FDC147; --gold-deep:#8A5A0C; --brandred:#D6293A;
  /* the poster's red band, and what sits on it */
  --band:#D6293A; --band-deep:#AF2230; --band-ink:#FFFFFF;
  --berry:#8E3A63; --ok:#2F6B4F; --ok-soft:#E2F0E8;
  --warn:#8A5A0C; --warn-soft:#FBEFD5;
  --crit:#CA3747; --crit-soft:#FBE3E5;
  --shadow:0 10px 40px -12px rgba(46,21,18,.28);
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --ground:#141010; --panel:#1E1817; --sunk:#191413; --row:#221B1A;
  --line:#332826; --line2:#4B3B36;
  --ink:#F3E9E5; --dim:#BCA49B; --faint:#93796F;
  --accent:#FDC147; --accent-ink:#2A1310; --accent-soft:#3A2A16;
  --gold:#FDC147; --gold-deep:#FDC147; --brandred:#F0736F;
  --band:#8E1B26; --band-deep:#6E141D; --band-ink:#FFF3F1;
  --berry:#E894BC; --ok:#63C08C; --ok-soft:#16291F;
  --warn:#E5913C; --warn-soft:#2E2113;
  --crit:#F0736F; --crit-soft:#331A18;
  --shadow:0 10px 40px -12px rgba(0,0,0,.8);
}}
:root[data-theme="dark"]{
  --ground:#141010; --panel:#1E1817; --sunk:#191413; --row:#221B1A;
  --line:#332826; --line2:#4B3B36;
  --ink:#F3E9E5; --dim:#BCA49B; --faint:#93796F;
  --accent:#FDC147; --accent-ink:#2A1310; --accent-soft:#3A2A16;
  --gold:#FDC147; --gold-deep:#FDC147; --brandred:#F0736F;
  --band:#8E1B26; --band-deep:#6E141D; --band-ink:#FFF3F1;
  --berry:#E894BC; --ok:#63C08C; --ok-soft:#16291F;
  --warn:#E5913C; --warn-soft:#2E2113;
  --crit:#F0736F; --crit-soft:#331A18;
  --shadow:0 10px 40px -12px rgba(0,0,0,.8);
}

*{box-sizing:border-box}
[hidden]{display:none !important}
body{margin:0;background:var(--ground);color:var(--ink);
  font-family:Inter,system-ui,-apple-system,"Segoe UI",sans-serif;font-size:13px;line-height:1.45;
  -webkit-font-smoothing:antialiased}
.mono{font-family:"IBM Plex Mono",ui-monospace,monospace}
.num{font-variant-numeric:tabular-nums}
h1,h2,h3{font-family:Fraunces,Georgia,serif;font-weight:700;letter-spacing:-.01em;margin:0}

/* ------------------------------------------------------------- chrome ---- */
/* Just enough room to breathe under the last box — 40px of it was pushing
   a busy order into a scroll on a 1600-wide counter screen. */
.app{padding:0 14px 20px}
/* The poster's red band. The pattern is the shop's own artwork, laid under a
   red wash so the bakery icons show through a shade darker — the same trick the
   poster uses, rather than a flat rectangle of colour. */
.bar{display:flex;align-items:center;gap:12px;padding:12px 14px;flex-wrap:wrap;
  border-bottom:3px solid var(--gold);border-radius:0 0 6px 6px;
  color:var(--band-ink);
  background-color:var(--band);
  background-image:url("assets/pattern.jpg");
  background-size:340px auto;background-position:center;
  /* multiply, not a wash: the artwork is pale icons on white, so white leaves
     the red alone and the icons come through a shade deeper — which is what the
     poster's band actually does. */
  background-blend-mode:multiply}

.brand{display:flex;align-items:center;gap:9px}
.brand img{height:32px;width:auto;display:block}
.brand .btxt{display:flex;flex-direction:column;line-height:1}
.brand .bname{font-family:Fraunces,Georgia,serif;font-weight:700;font-size:20px}
.bar .brand .bname{color:var(--band-ink)}
.brand .bname i{font-style:normal;color:var(--brandred)}
/* On the red band the full stop has to be the gold, not the red it is sitting on. */
.bar .brand .bname i{color:var(--gold)}
.brand .bsub{font-family:"IBM Plex Mono",monospace;font-size:8px;letter-spacing:.15em;
  text-transform:uppercase;color:var(--faint);margin-top:4px;white-space:nowrap}
.bar .brand .bsub{color:rgba(255,255,255,.72)}
@media(max-width:760px){.brand .bsub{display:none}}

.nav{display:flex;gap:2px;background:var(--sunk);border:1px solid var(--line);border-radius:4px;padding:2px}
.nav a{font:inherit;font-size:12.5px;color:var(--dim);padding:5px 11px;border-radius:3px;
  text-decoration:none;cursor:pointer}
.nav a:hover{color:var(--ink)}
.nav a.on{background:var(--panel);color:var(--ink);box-shadow:0 1px 2px rgba(0,0,0,.12);font-weight:600}
/* The nav in the band: white pill on red, exactly as the poster puts white type
   on its red. Everything else is the band's own ink. */
.bar .nav{background:rgba(0,0,0,.16);border-color:rgba(255,255,255,.22)}
.bar .nav a{color:rgba(255,255,255,.82)}
.bar .nav a:hover{color:#FFF}
.bar .nav a.on{background:#FFF;color:var(--band);box-shadow:0 1px 3px rgba(0,0,0,.28)}
.spacer{flex:1}
/* ---- today against its target, in the band ---------------------------- */
/* A single gold pill in the shop's own yellow, sitting on the red band the way
   the poster's gold sits on it. What it replaced was a two-tone bar that filled
   up across the middle of its own text — half gold, half dark, the money
   straddling the join — which read as a broken progress widget rather than as a
   figure. Here the number is the thing and the small track beside it is the
   glance. */
.tgt{display:flex;align-items:center;height:34px;padding:0 4px 0 14px;
  border-radius:999px;background:var(--gold);
  border:1px solid rgba(62,27,21,.18);
  box-shadow:0 1px 0 rgba(255,255,255,.45) inset, 0 2px 8px -4px rgba(0,0,0,.45);
  color:#3E1B15;white-space:nowrap}
.tgt:empty{display:none}
.tgt-face{display:flex;align-items:center;gap:9px}
.tgt-out{font-family:"IBM Plex Mono",monospace;font-size:8.5px;letter-spacing:.14em;
  text-transform:uppercase;opacity:.66}
.tgt-now{font-family:Fraunces,Georgia,serif;font-size:17px;line-height:1;
  font-variant-numeric:tabular-nums}
.tgt-of{font-style:normal;font-size:11px;opacity:.7}
/* The glance: how far along, in one small rounded track. */
.tgt-track{width:46px;height:6px;border-radius:999px;overflow:hidden;
  background:rgba(62,27,21,.2)}
.tgt-fill{display:block;height:100%;border-radius:999px;background:#3E1B15;
  transition:width .5s ease}
.tgt-pct{font-family:"IBM Plex Mono",monospace;font-size:10.5px;font-weight:700;
  font-variant-numeric:tabular-nums;
  background:rgba(62,27,21,.12);border-radius:999px;padding:4px 9px}
.tgt-party{font-size:14px;line-height:1}
/* Beaten: the track is full and the percentage stops being a quiet chip. */
.tgt.hit{background:#FFD97A}
.tgt.hit .tgt-pct{background:#3E1B15;color:var(--gold)}
@media(max-width:1180px){.tgt-track,.tgt-of{display:none}}
@media(max-width:980px){.tgt{padding-left:10px}.tgt-out{display:none}}

/* ---- beating it ------------------------------------------------------- */
.party{position:fixed;left:50%;top:82px;transform:translateX(-50%);z-index:60;
  display:flex;align-items:center;gap:13px;padding:14px 20px;border-radius:8px;
  background:var(--panel);border:1px solid var(--ok);box-shadow:var(--shadow);
  animation:party-in .45s cubic-bezier(.2,1.4,.4,1)}
.party.go{opacity:0;transition:opacity .9s ease}
.party-pop{font-size:30px;animation:party-pop 1.1s ease-in-out 2}
.party b{display:block;font-family:Fraunces,Georgia,serif;font-size:17px}
.party span{font-size:12.5px;color:var(--dim)}
@keyframes party-in{from{opacity:0;transform:translate(-50%,-14px) scale(.94)}
  to{opacity:1;transform:translate(-50%,0) scale(1)}}
@keyframes party-pop{0%,100%{transform:scale(1) rotate(0)}
  30%{transform:scale(1.25) rotate(-12deg)}65%{transform:scale(1.1) rotate(10deg)}}

.confetti{position:fixed;inset:0;z-index:59;pointer-events:none;overflow:hidden}
.confetti i{position:absolute;top:-16px;width:8px;height:13px;border-radius:1px;
  animation:confetti-fall 3.4s linear forwards}
@keyframes confetti-fall{
  0%{opacity:0;transform:translateY(0) rotate(0)}
  8%{opacity:1}
  100%{opacity:0;transform:translateY(102vh) rotate(760deg)}}
/* Nobody should be made dizzy by a sales figure. */
@media (prefers-reduced-motion:reduce){
  .confetti{display:none}
  .party,.party-pop{animation:none}
}
.who{text-align:right;line-height:1.2}
.who b{display:block;font-size:12.5px}
.who i{font-style:normal;font-size:9.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--faint)}
.bar .who b{color:var(--band-ink)}
.bar .who i{color:var(--gold)}
.bar button.ghost{color:rgba(255,255,255,.88);border-color:rgba(255,255,255,.34)}
.bar button.ghost:hover{color:#FFF;background:rgba(255,255,255,.14);border-color:#FFF}

/* ------------------------------------------------------------ controls --- */
button,.btn{font:inherit;font-size:12.5px;font-weight:600;padding:6px 14px;border-radius:4px;
  border:1px solid var(--line2);background:var(--panel);color:var(--ink);cursor:pointer}
button:hover,.btn:hover{border-color:var(--accent)}
button.primary{background:var(--accent);color:var(--accent-ink);border-color:var(--accent)}
button.primary:disabled{opacity:.45;cursor:not-allowed;border-color:var(--line2)}
button.ghost{background:transparent;border-color:transparent;color:var(--dim)}
button.ghost:hover{color:var(--ink)}
/* A checkbox must never be stretched by the width:100% below — that is what
   pushes its label halfway across the row. */
input[type=checkbox],input[type=radio]{width:auto;margin:0;accent-color:var(--accent);cursor:pointer}
.tickrow{display:flex;align-items:center;gap:20px;flex-wrap:wrap}
/* One line of narrow numeric fields — the whole of a cake's money in a glance. */
.cakerow{display:flex;gap:8px;align-items:flex-end;flex-wrap:wrap}
/* The collection rows: a few fixed-width controls, the rest sharing what is left. */
.colrow{display:flex;gap:8px;align-items:flex-end;flex-wrap:wrap}
.cakerow input,.cakerow select{padding:6px 6px}
.cakerow label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tickrow label{display:inline-flex;align-items:center;gap:7px;margin:0;
  text-transform:none;letter-spacing:0;font-family:inherit;font-size:12.5px;
  font-weight:500;color:var(--ink);cursor:pointer}
input,select,textarea{width:100%;font:inherit;font-size:13px;color:var(--ink);background:var(--panel);
  border:1px solid var(--line2);border-radius:4px;padding:6px 8px}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent);outline-offset:-1px;border-color:var(--accent)}
input::placeholder{color:var(--faint)}
label{display:block;font-size:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--faint);margin-bottom:3px;font-family:"IBM Plex Mono",monospace}
kbd{font-family:"IBM Plex Mono",monospace;font-size:10px;background:var(--sunk);border:1px solid var(--line);
  border-bottom-width:2px;border-radius:3px;padding:1px 4px;color:var(--dim)}

/* ------------------------------------------------------------- panels ---- */
.grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:14px;margin-top:14px;align-items:start}
@media(max-width:980px){.grid{grid-template-columns:1fr}}
/* Both columns end on the same line: the shorter one stretches, and whatever it
   marks .fill is pushed to the foot of it. */
.grid.level{align-items:stretch}
.grid.level>*{display:flex;flex-direction:column;min-width:0}
.grid.level .fill{margin-top:auto}
/* Who and where · how they paid · what it comes to. Three narrow columns beat
   two wide ones here: the page stops scrolling and no box is wider than the
   longest thing in it. */
.grid3{display:grid;
  grid-template-columns:minmax(0,1.35fr) minmax(0,1fr) minmax(0,1fr);
  gap:14px;align-items:stretch}
.grid3>*{display:flex;flex-direction:column;min-width:0}
.grid3 .fill{margin-top:auto}
@media(max-width:1280px){.grid3{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
@media(max-width:860px){.grid3{grid-template-columns:1fr}}
/* A row you can open. */
tbody tr.clickable{cursor:pointer}
tbody tr.clickable:hover td{background:var(--accent-soft)}
/* The banner that says which bill is open for correction. */
.note-edit{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;
  padding:8px 11px;border-radius:4px;font-size:12.5px;
  background:var(--warn-soft);border:1px solid var(--warn);color:var(--warn)}
.note-edit b{color:var(--ink)}
/* Four boxes across: decoration · customer and delivery · money · payment.
   Money and payment are the narrowest of the four — a label and a figure need
   far less room than a name, an address and a phone number do. */
.grid4{display:grid;
  grid-template-columns:minmax(0,1.05fr) minmax(0,1.4fr) minmax(0,.85fr) minmax(0,.9fr);
  gap:14px;align-items:stretch}
.grid4>*{display:flex;flex-direction:column;min-width:0}
.grid4 .fill{margin-top:auto}
@media(max-width:1300px){.grid4{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
@media(max-width:900px){.grid4{grid-template-columns:1fr}}
/* One payment mode per line — a row of them wrapped badly and read as a jumble. */
.paycol{display:flex;flex-direction:column;gap:6px}
.paycol button{width:100%;text-align:left}
.panel{background:var(--panel);border:1px solid var(--line);border-radius:5px;margin-top:12px}
.phead{display:flex;align-items:center;gap:8px;padding:8px 12px;border-bottom:1px solid var(--line);
  background:var(--sunk);border-radius:5px 5px 0 0}
.phead h2{font-size:10.5px;font-weight:600;letter-spacing:.13em;text-transform:uppercase;
  color:var(--faint);font-family:"IBM Plex Mono",monospace}
.phead .r{margin-left:auto;font-size:11px;color:var(--faint)}
.pbody{padding:12px}
.row{display:grid;gap:8px}
.r2{grid-template-columns:1fr 1fr}
.r3{grid-template-columns:1fr 1fr 1fr}
.stack{display:flex;flex-direction:column;gap:10px}
.hint{font-size:11px;color:var(--faint);padding:8px 2px 0}

/* ------------------------------------------------- the wide cake row ----- */
/* Everything true about one cake belongs on one line. On a narrow screen that
   line is wider than the screen, so it scrolls sideways inside its own box —
   the page itself never does. */
.xscroll{overflow-x:auto;overflow-y:visible;margin:0 -12px;padding:0 12px}
/* Fixed layout, so every column is the width it was given rather than the width
   the longest value happens to want — otherwise one long message squeezes the
   quantity down to nothing. The one column with no width set, Additional info,
   takes whatever room is left over on a wide screen. */
.cakes{table-layout:fixed;width:100%;min-width:1626px}
.cakes thead th{padding:6px 5px;overflow:hidden;text-overflow:ellipsis}
.cakes tbody td{padding:5px;height:auto;vertical-align:middle}
.cakes tbody tr:nth-child(even) td{background:transparent}
.cakes tbody tr:hover td{background:transparent}
.cakes input,.cakes select{padding:5px 6px;font-size:12.5px}
/* The spinner arrows are useless on a counter and steal a third of a narrow
   column — enough to hide the digit that is in it. */
/* Date, Time and Cake stay put while the rest of the row scrolls, so you can
   never be typing a message into a line without knowing which cake it is.
   The offsets are measured from the real header cells after layout, not
   hardcoded — a wide screen hands the spare width to the columns and a guessed
   offset would park the Cake cell on top of the Size one. */
.cakes th:nth-child(1),.cakes td:nth-child(1){position:sticky;left:0}
.cakes th:nth-child(2),.cakes td:nth-child(2){position:sticky;left:var(--c2,126px)}
.cakes th:nth-child(3),.cakes td:nth-child(3){position:sticky;left:var(--c3,214px);
  box-shadow:1px 0 0 var(--line2)}
/* A sticky cell must be opaque or the columns sliding beneath it show through.
   The extra :nth-child(n) is only there to out-specify the zebra striping. */
.cakes tbody tr:nth-child(n) td:nth-child(-n+3),
.cakes tbody tr:hover td:nth-child(-n+3){background:var(--panel);z-index:2}
.cakes th:nth-child(-n+3){z-index:4}
.cakes input[type=number]{-moz-appearance:textfield}
.cakes input[type=number]::-webkit-outer-spin-button,
.cakes input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.cakes td.tc,.cakes th.tc{text-align:center}
/* The cake is chosen in the row itself. Its list of matches is fixed-positioned
   off the body, because anything inside .xscroll is clipped by it. */
.picker{position:fixed;z-index:200;max-height:290px;overflow:auto;
  background:var(--panel);border:1px solid var(--line2);border-radius:5px;
  box-shadow:var(--shadow);padding:0 0 3px}
.picker .grp{position:sticky;top:0;background:var(--sunk);color:var(--faint);
  font-family:"IBM Plex Mono",monospace;font-size:9px;letter-spacing:.13em;
  text-transform:uppercase;font-weight:600;padding:6px 10px 4px;
  border-bottom:1px solid var(--line)}
.picker .opt{display:grid;grid-template-columns:56px minmax(0,1fr) auto;gap:8px;
  align-items:center;padding:6px 10px;cursor:pointer;border-bottom:1px solid var(--line)}
.picker .opt b{color:var(--accent);font-size:11.5px}
.picker .opt .sub{color:var(--faint);font-size:11px;margin-left:7px}
.picker .opt:hover,.picker .opt.on{background:var(--accent-soft)}
/* A label sitting inline in a panel heading, next to its control. */
.hlbl{font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.13em;
  text-transform:uppercase;font-weight:600;color:var(--faint)}
/* Ready cake / Order cake, per line — a cake for next Saturday cannot be one
   that is on the shelf now, so the row says which it is. */
.chip{display:inline-block;flex:0 0 auto;font-family:"IBM Plex Mono",monospace;
  font-size:8.5px;letter-spacing:.08em;text-transform:uppercase;font-weight:600;
  padding:2px 6px;border-radius:3px;border:1px solid var(--line2);
  color:var(--faint);text-decoration:none;cursor:pointer;white-space:nowrap}
.chip:hover{border-color:var(--accent);color:var(--ink)}
.chip.chip-on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
/* A cake being MADE for this order, as against one lifted off the display. The
   same dark the day board uses for the same fact. */
/* On the order form the chip sits beside the cake box and is a control in its
   own right, so it stands the same height and is read at the same distance. */
.chip.chip-lg{display:inline-flex;align-items:center;font-size:11px;
  padding:0 12px;border-radius:4px;letter-spacing:.06em}
.chip.chip-order{background:var(--ink);border-color:var(--ink);color:var(--panel)}
.chip.chip-order:hover{border-color:var(--accent);color:var(--panel)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .chip.chip-on{color:var(--gold)}}
:root[data-theme="dark"] .chip.chip-on{color:var(--gold)}

/* -------------------------------------------------------------- table ---- */
.scroll{overflow:auto;max-height:calc(100vh - 250px)}
table{border-collapse:separate;border-spacing:0;width:100%;font-size:12.5px}
thead th{position:sticky;top:0;z-index:3;background:var(--sunk);font-family:"IBM Plex Mono",monospace;
  font-size:9px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--faint);
  text-align:left;padding:7px 8px;border-bottom:1px solid var(--line2);white-space:nowrap}
tbody td{padding:0 8px;height:32px;border-bottom:1px solid var(--line);white-space:nowrap;vertical-align:middle}
tbody tr:nth-child(even) td{background:var(--row)}
tbody tr:hover td{background:var(--accent-soft)}
.tr{text-align:right}
td.cake{white-space:normal;min-width:180px}
td.cake b{color:var(--accent);font-family:"IBM Plex Mono",monospace;font-size:11.5px}
tfoot td{position:sticky;bottom:0;z-index:3;background:var(--sunk);border-top:2px solid var(--line2);
  font-weight:600;padding:8px;font-variant-numeric:tabular-nums;white-space:nowrap}
.empty{padding:34px 12px;text-align:center;color:var(--faint)}
.empty b{display:block;font-family:Fraunces,Georgia,serif;font-size:20px;color:var(--ink);margin-bottom:4px}

.pill{font-family:"IBM Plex Mono",monospace;font-size:9px;letter-spacing:.05em;text-transform:uppercase;
  padding:2px 5px;border-radius:3px;border:1px solid currentColor}
.pill.ok{color:var(--ok)} .pill.wait{color:var(--warn)} .pill.due{color:var(--crit)}
.pill.cash{color:var(--berry)} .pill.bank{color:var(--accent)} .pill.ctr{color:var(--faint)}

/* --------------------------------------------------------------- signin -- */
/* The poster in one screen: the red ground with the pattern in it, a white card
   on top, a gold rule under the name. */
.signin{min-height:100vh;display:grid;place-items:center;padding:20px;
  background-color:var(--band);
  background-image:url("assets/pattern.jpg");
  background-size:420px auto;background-blend-mode:multiply}
.card{width:360px;max-width:100%;background:var(--panel);border:1px solid var(--line);
  border-top:5px solid var(--gold);
  border-radius:8px;box-shadow:0 26px 60px -18px rgba(0,0,0,.45);padding:26px 24px 22px}
.card .brand{justify-content:center;margin-bottom:18px}
.card .brand img{height:52px}
.card .brand .bname{font-size:26px}

/* --------------------------------------------------------------- toast --- */
#toast{position:fixed;right:16px;bottom:16px;z-index:90;display:flex;flex-direction:column;gap:8px}
.toast{background:var(--panel);border:1px solid var(--line2);border-left:4px solid var(--crit);
  border-radius:4px;padding:9px 14px;box-shadow:var(--shadow);max-width:380px;font-size:12.5px;
  transition:opacity .3s, transform .3s}
.toast.good{border-left-color:var(--ok)}
.toast.out{opacity:0;transform:translateY(6px)}

.loading{padding:40px;text-align:center;color:var(--faint)}

/* =========================================================== the thermal bill ==
   80mm paper, 72mm of printable strip, one monospaced font at a size where 42
   characters fit the width. Everything is text: no image to smudge, nothing that
   depends on the printer's own graphics mode.
   ============================================================================ */
.bill{width:72mm;margin:0 auto;padding:2mm 0 0;
  font-family:"IBM Plex Mono",ui-monospace,"Courier New",monospace;
  font-size:11px;line-height:1.42;color:#000;background:#fff;
  -webkit-font-smoothing:none}
.bill .b-name{text-align:center;font-size:15px;font-weight:700;letter-spacing:.02em}
.bill .b-mid{text-align:center}
.bill .b-title{text-align:center;font-weight:700;letter-spacing:.22em}
.bill .b-rule{border-top:1px dashed #000;margin:4px 0;height:0}
.bill .b-rule.hard{border-top-style:solid;border-top-width:2px}
.bill .b-pair{display:flex;justify-content:space-between;gap:6px}
.bill .b-pair span:last-child{white-space:nowrap}
.bill .b-bold{font-weight:700;font-size:13px}
.bill .b-item{font-weight:700;word-break:break-word}
.bill .b-note{font-style:italic;padding-left:5mm}
.bill .b-sub{padding-left:5mm}
/* Thermal cutters take the paper a few millimetres above the head. */
.bill .b-feed{height:14mm}

/* On screen it is a preview: a paper-coloured slip on the page ground. */
.bill-preview{background:#fff;color:#000;border:1px solid var(--line2);
  border-radius:3px;box-shadow:var(--shadow);padding:4mm 3mm;width:78mm}

@media print{
  @page{size:80mm auto;margin:0}
  html.printing body>*{display:none !important}
  html.printing body>#printarea{display:block !important}
  #printarea{position:static;width:80mm}
  .bill{width:72mm;font-size:11px}
}

/* ------------------------------------------------------- the day board ---- */
/* Fixed columns: the cake name is the one that wants to run away with the width,
   and every figure column has to stay under its heading. */
.board{table-layout:fixed;width:100%;min-width:1540px}
.board thead th{overflow:hidden;text-overflow:ellipsis}
.board td.cake{white-space:normal;min-width:0;line-height:1.3}
.board td.wrap{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  color:var(--dim);font-size:12px}
/* A pill you press: the counter's handover tick. */
.pill.tick{text-decoration:none;cursor:pointer;display:inline-block}
.pill.tick:hover{background:var(--accent-soft)}

/* ============================================================== day end ====
   Counting up. Two shapes: the running tally and the note grid. */

/* The tally reads as a sum on paper — labels left, figures in a column that
   lines up, and one ruled total. */
.tally{display:flex;flex-direction:column;gap:2px}
.tl{display:flex;align-items:baseline;gap:10px;padding:3px 0;font-size:12.5px}
.tl span{color:var(--dim)}
.tl span i{font-style:normal;color:var(--faint);font-size:11px;margin-left:6px}
.tl b{margin-left:auto;font-weight:500;white-space:nowrap}
.tl.sum{border-top:1px solid var(--line);margin-top:5px;padding-top:7px}
.tl.sum span{color:var(--ink)}
.tl.sum b{font-weight:700}

/* The verdict line. Green when it tallies, red when it does not — and "over"
   is not reassuring, so it is coloured too. */
.gap{margin-top:10px;border-top:1px solid var(--line);padding-top:8px}
.gap .tl.ok b{color:var(--ok)}
.gap .tl.over b,.gap .tl.short b{color:var(--crit)}
.gap .tl.over span,.gap .tl.short span{color:var(--crit);font-weight:600}

/* The count sheet. One column, ₹500 down to ₹1, the way a drawer is actually
   counted — you work down the notes in order, not across a grid. Each row shows
   what that bundle comes to, so a miscount shows itself while it is being typed. */
.notes{display:flex;flex-direction:column;gap:2px;padding:3px 0 1px}
.notes label{display:flex;align-items:center;gap:10px;margin:0}
.notes label .mono{width:40px;flex:0 0 40px;color:var(--dim);font-size:11.5px;text-align:right}
.notes label .x{color:var(--faint);font-size:10px}

/* At close the sheet carries two columns: what was counted this morning, and
   what is being counted now. The morning figure is a fact, not a field — it is
   set in the same tabular figures so the two line up down the page. */
.notes.two label{gap:0}
.notes.two label .mono{flex:0 0 42px}
.notes.two .was{flex:0 0 62px;text-align:right;padding-right:14px;
  font-variant-numeric:tabular-nums;font-size:12px;color:var(--dim)}
.notes.two .was.nil{color:var(--faint)}
.notes.two label input{margin-left:0}
.nhead{display:flex;align-items:baseline;gap:0;padding:0 0 3px;
  font-family:"IBM Plex Mono",monospace;font-size:8.5px;letter-spacing:.11em;
  text-transform:uppercase;color:var(--faint)}
.nhead span:nth-child(1){flex:0 0 42px}
.nhead span:nth-child(2){flex:0 0 62px;text-align:right;padding-right:14px}
.nhead span:nth-child(3){flex:0 0 74px;text-align:right;padding-right:7px}
.notes.two .nsum .was{flex:0 0 62px;padding-right:14px;font-weight:400}
.notes.two .nsum b:not(.was){flex:0 0 74px;text-align:right;margin-left:0;padding-right:7px}
.notes label input{width:74px;flex:0 0 74px;padding:4px 7px;font-size:12.5px;text-align:right}
.notes label i{font-style:normal;font-size:11px;color:var(--faint);
  margin-left:auto;white-space:nowrap;font-variant-numeric:tabular-nums}
/* The running total of the sheet, ruled off like the tally above it. */
.notes .nsum{display:flex;align-items:baseline;gap:10px;
  border-top:1px solid var(--line);margin-top:5px;padding-top:6px;font-size:12.5px}
.notes .nsum b{margin-left:auto;font-weight:700}

/* A quiet list inside a panel: the accounts that are not yours to tally. */
.lines{width:100%;border-collapse:collapse;margin-top:8px}
.lines td{padding:4px 5px;border-bottom:1px solid var(--line);font-size:12.5px;
  vertical-align:middle}
.lines tr:last-child td{border-bottom:0}
.lines .sub{color:var(--faint);font-size:11px;margin-left:7px}

/* A term of the sum you type rather than count: cash sent to the office. */
.tl .minus{color:var(--faint);margin-right:5px}
.tl b input{text-align:right}

/* Something is missing that everything below depends on. Not an error — the
   screen still works — but it must not read as a number. */
.warnline{background:var(--warn-soft);color:var(--warn);border:1px solid var(--line);
  border-radius:4px;padding:8px 10px;font-size:11.5px;line-height:1.45;margin-bottom:10px}

/* ============================================================== reports ====
   A register: many rows, one total at the foot that has to be right. Narrower
   and quieter than the day board — nothing here is being acted on, it is being
   read down a column. */
.board.report{min-width:860px}
.board.report tbody td{font-size:12.5px}
.board.report tfoot td{border-top:2px solid var(--line2);font-size:12.5px;
  background:var(--sunk)}
.board.report .sub{color:var(--faint);font-size:11px;margin-left:7px}
/* A row that opens its bill. The day board earns its pointer the same way. */
/* Dark carries the states the day board is really about: a cake being MADE for
   the order, a cake that IS baked, a cake handed over. Green was doing the same
   job as the amber next to it and reading as decoration rather than as a state. */
.pill.made{background:var(--ink);color:var(--panel);border-color:var(--ink)}
.pill.tick.made:hover{background:var(--accent);border-color:var(--accent)}
/* The Time heading is a control, not a label: the board is in the order the
   orders were taken, and sometimes the question is what is due this morning. */
.board th.timehead{cursor:pointer;user-select:none}
.board th.timehead:hover{color:var(--ink)}
.board th.timehead.on{color:var(--accent)}
.board th.timehead i{font-style:normal;font-size:9px}
.board tr.go{cursor:pointer}
.board tr.go:hover td{background:var(--accent-soft)}

/* ======================================================= taking a balance ====
   A small panel hanging off the Due figure on the day board. Deliberately not a
   dialog: the row it belongs to stays visible behind it, because the thing you
   are about to do is to THAT bill. */
.due-take{font-variant-numeric:tabular-nums;color:var(--crit);font-weight:600;
  text-decoration:none;border-bottom:1px dashed var(--crit);cursor:pointer}
.due-take:hover{background:var(--accent-soft);border-bottom-style:solid}
.take{position:fixed;z-index:220;width:326px;background:var(--panel);
  border:1px solid var(--line2);border-radius:5px;
  box-shadow:0 10px 30px rgba(0,0,0,.24)}
.take-head{display:flex;align-items:baseline;gap:8px;padding:9px 12px;
  border-bottom:1px solid var(--line);background:var(--sunk);
  border-radius:5px 5px 0 0;font-size:12.5px}
.take-head b{font-family:"IBM Plex Mono",monospace;font-size:12px}
.take-head .r{margin-left:auto;color:var(--crit);font-weight:600;white-space:nowrap}
.take-body{padding:11px 12px;display:flex;flex-direction:column;gap:9px}
.take-body label{display:flex;align-items:center;gap:10px;margin:0;font-size:12px;
  color:var(--dim)}
.take-body label>span:first-child{flex:0 0 52px;color:var(--faint);
  font-family:"IBM Plex Mono",monospace;font-size:9px;letter-spacing:.12em;
  text-transform:uppercase}
.take-body input{flex:1;text-align:right;padding:5px 8px}
.take-body select{flex:1;min-width:0;padding:5px 6px;font-size:12.5px}
.take-body input[type=date]{flex:1;min-width:0;text-align:left;padding:4px 7px}
.take-body .sub{font-size:11.5px;color:var(--faint);min-height:16px}
.take-foot{display:flex;align-items:center;gap:8px;padding:9px 12px;
  border-top:1px solid var(--line);background:var(--sunk);border-radius:0 0 5px 5px}
/* A column you can sort by. Only the number columns — sorting by name is a
   question nobody asks of a sales report. */
.board.report th.sortable{cursor:pointer;user-select:none}
.board.report th.sortable:hover{color:var(--ink)}

/* ================================================== filtering a register ====
   Every heading sorts and filters. The metaphor is the spreadsheet they came
   from: click the heading, get sort at the top and a filter under it. */
.board.report th.headcell{cursor:pointer;user-select:none}
.board.report th.headcell:hover{color:var(--ink)}
.board.report th.headcell i{font-style:normal;font-size:9px}
.board.report th.filtered{color:var(--accent)}
.board.report th.filtered .dot{color:var(--accent)}

.headmenu{position:fixed;z-index:230;width:236px;background:var(--panel);
  border:1px solid var(--line2);border-radius:5px;overflow:hidden;
  box-shadow:0 10px 30px rgba(0,0,0,.24);font-size:12.5px}
.hm-sort{display:flex;flex-direction:column;border-bottom:1px solid var(--line)}
.hm-sort a{padding:7px 12px;color:var(--dim);text-decoration:none}
.hm-sort a:hover{background:var(--accent-soft);color:var(--ink)}
.hm-sort a.on{color:var(--accent);font-weight:600}
.hm-head{display:flex;align-items:baseline;gap:8px;padding:7px 12px 4px;
  font-family:"IBM Plex Mono",monospace;font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint)}
.hm-head a{color:var(--accent);text-decoration:none;letter-spacing:0;
  font-family:inherit;font-size:9px}
.hm-head .r{margin-left:auto}
.hm-list{max-height:210px;overflow:auto;padding:0 6px 8px}
.hm-list label{display:flex;align-items:center;gap:8px;margin:0;padding:4px 6px;
  border-radius:3px;cursor:pointer}
.hm-list label:hover{background:var(--sunk)}
.hm-list label span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;color:var(--ink)}
.hm-list label i{font-style:normal;color:var(--faint);font-size:11px;
  font-variant-numeric:tabular-nums}
.hm-text{padding:9px 10px}
.hm-text input{width:100%}
.hm-nums{padding:9px 10px;display:flex;flex-direction:column;gap:7px}
.hm-nums label{display:flex;align-items:center;gap:9px;margin:0;color:var(--dim)}
.hm-nums label span{flex:0 0 62px;font-size:11.5px}
.hm-nums input{flex:1;min-width:0;text-align:right;padding:4px 7px}

/* What the filter is hiding, said out loud under the table. */
.filterbar{display:flex;align-items:center;gap:10px;padding:7px 2px 0;
  font-size:11.5px;color:var(--faint)}
.filterbar a{color:var(--accent);text-decoration:none}
.filterbar a:hover{text-decoration:underline}

/* ================================================================= shelf ====
   Counting the display down at night. Narrow, because it is read one line at a
   time with a cake in your other hand. */
.board.shelf{min-width:400px}
.board.shelf tbody td{vertical-align:top}
/* Code, cake and size on ONE line, in the order the counter says it out loud.
   Stacked, the size sat under the name — where the eye had to go looking for
   the one thing that tells two otherwise identical rows apart. */
.board.shelf .shelf-code{font-family:"IBM Plex Mono",monospace;font-size:11px;
  color:var(--accent)}
.board.shelf .shelf-item{font-size:12.5px}
.board.shelf .shelf-size{font-family:"IBM Plex Mono",monospace;font-size:11.5px;
  background:var(--accent-soft);color:var(--accent);border:1px solid var(--line2);
  border-radius:3px;padding:1px 5px;white-space:nowrap}
/* The counts are the point of the screen; they were the smallest thing on it. */
.board.shelf input{width:100%;text-align:right;padding:5px 6px;font-size:14px;
  font-weight:600;font-variant-numeric:tabular-nums;
  /* Chrome reserves room for the spinner even when it is hidden, which is what
     was clipping a two-digit count down to a bracket. */
  -moz-appearance:textfield}
.board.shelf input::-webkit-outer-spin-button,
.board.shelf input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.board.shelf tbody td{vertical-align:middle}
.board.shelf tbody td{padding:5px 6px}
.board.shelf .sub{color:var(--faint);font-size:11px;margin-left:7px}
/* A cake that was due before today and still has not come. */
/* ------------------------------------------------------------- the shelf --
   Three jobs, three equal columns, side by side. Each table was cut down to
   fit a third of the screen: without its own min-width a .board insists on
   1540px and the last column — the tick, the difference — falls off the edge
   where nobody will ever drag to find it. */
.shelfcols{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:12px;align-items:start}

.shelfcols>.panel{margin-top:12px;min-width:0}
/* Below this there is no room for three of anything; they stack instead. */
@media (max-width:1180px){ .shelfcols{grid-template-columns:1fr} }
/* In a narrow panel margin-left:auto throws the count to the far corner, away
   from the heading it belongs to. Keep it beside its own title. */
.shelfcols .phead{flex-wrap:wrap;row-gap:2px}
.shelfcols .phead .r{margin-left:0;color:var(--dim)}
.shelfcols .phead .r::before{content:'·';margin:0 7px 0 1px;color:var(--line2)}
.board.arrivals{min-width:330px}
.board.arrivals tbody td{padding:5px 6px;vertical-align:top}
.board.arrivals .sub{color:var(--faint);font-size:11px;margin-left:7px}
/* Bill, customer and the unit's word on it — read once, per row, never scanned
   as a column, so they sit under the cake rather than beside it. */
.board.arrivals .sub2{color:var(--faint);font-size:11px;margin-top:2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.board.arrivals tr.late td{background:var(--warn-soft)}
/* ---- the day report --------------------------------------------------- */
/* One table: the date pinned at the left, then three sections beside it, so a
   day is a row you read straight across instead of the same date found three
   times in three places. */
.board.dayreport{min-width:1040px;table-layout:auto}
.board.dayreport td,.board.dayreport th{padding:5px 8px;font-size:12.5px;
  white-space:nowrap}
.board.dayreport th{padding:6px 8px}
/* The section headings sit above their own columns and are the only thing on
   the page allowed to be bigger than the column names under them. */
.board.dayreport tr.grouprow th{font-size:10px;color:var(--accent);
  border-bottom:1px solid var(--line);letter-spacing:.14em;text-align:center;
  height:26px}
.board.dayreport tr.grouprow th.dt{text-align:left}
/* Two header rows both pinned to top:0 land on top of each other and the
   section names vanish. The second one has to stack UNDER the first. */
.board.dayreport thead tr.grouprow th{top:0}
.board.dayreport thead tr:nth-child(2) th{top:26px}
/* A hairline where one section ends and the next begins — three sections need
   to be three sections at a glance, not twelve columns in a row. */
.board.dayreport .grp{border-left:2px solid var(--line2)}
/* Pinned: the date stays put however far right you scroll. */
.board.dayreport .dt{position:sticky;left:0;z-index:2;background:var(--panel);
  text-align:left;box-shadow:1px 0 0 var(--line)}
.board.dayreport thead .dt{background:var(--sunk);z-index:3;vertical-align:bottom}
.board.dayreport tfoot .dt{background:var(--sunk);font-weight:600}
.board.dayreport tbody tr:nth-child(even) .dt{background:var(--row)}
.board.dayreport tr.shut .dt{background:var(--sunk)}
/* Cash transfer is the same table with three columns instead of thirteen, so it
   does not need the day report's width to hold itself open. */
.board.dayreport.transfer{min-width:0}
/* A day nothing came up on: present, and visibly not a transfer. */
.board.dayreport.transfer tr.quiet td{color:var(--faint);background:var(--sunk)}
.board.dayreport.transfer tr.quiet .dt{background:var(--sunk)}
/* What the office counted, typed straight into the row it belongs to. */
.board.dayreport.transfer input.gotbox{width:100%;min-width:86px;text-align:right;
  padding:3px 6px;font-size:12.5px;font-weight:600;font-variant-numeric:tabular-nums;
  -moz-appearance:textfield}
.board.dayreport.transfer input.gotbox::-webkit-outer-spin-button,
.board.dayreport.transfer input.gotbox::-webkit-inner-spin-button{
  -webkit-appearance:none;margin:0}
.board.dayreport.transfer tr.quiet input.gotbox{background:var(--panel)}
.board.dayreport.transfer .dt{min-width:120px}
/* Today. On a month-long range it is one row in thirty, and it is the row
   somebody opened the report to read. Marked, not shouted at — the loud colours
   on this table are reserved for money that is wrong. */
.board.dayreport tbody tr.now td{background:var(--accent-soft);
  border-top:1px solid var(--accent);border-bottom:1px solid var(--accent)}
.board.dayreport tbody tr.now .dt{background:var(--accent-soft);font-weight:700;
  box-shadow:1px 0 0 var(--accent)}
.board.dayreport tbody tr.now .todaymark{margin-left:7px;font-size:8.5px;
  letter-spacing:.13em;text-transform:uppercase;color:var(--accent);font-weight:600}
.board.report td.dim{color:var(--faint)}
.board.report tr.shut td{background:var(--sunk);color:var(--faint)}
.board.report td.dim{color:var(--faint)}
.board.report tr.shut td{background:var(--sunk);color:var(--faint)}

/* ===========================================================================
   The oven board — one tile per cake, five to a row.
   A baker reads this across a room, so the two things that decide what happens
   next are the biggest: the hour it has to be out, and whether it is done.
   =========================================================================== */
.ovengrid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:10px;
  margin-top:12px;align-items:stretch}
/* Five holds all the way down to a 1024-wide screen — a counter monitor is
   often 1366, and dropping to four there would be four when five was asked for.
   Below that there is genuinely not room. */
@media (max-width:1000px){.ovengrid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:760px){.ovengrid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:520px){.ovengrid{grid-template-columns:1fr}}

/* Two things happen to a cake here and they are different facts, so they are
   two targets: the body of the tile is BAKED, the foot is HANDED OVER. */
.oven{display:flex;flex-direction:column;border:1px solid var(--line);
  border-left:3px solid var(--line2);border-radius:5px;background:var(--panel);
  color:var(--ink);overflow:hidden;transition:opacity .12s,border-color .12s}
.oven:hover{border-color:var(--accent)}
.oven-bake{display:flex;flex-direction:column;gap:6px;text-align:left;font:inherit;
  flex:1 1 auto;padding:10px 11px 9px;border:0;border-radius:0;background:none;
  color:inherit;cursor:pointer}
.oven-bake:hover{background:var(--accent-soft)}
.oven-bake:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
/* The second click, and only where the unit is the collection point. */
.oven-hand{font:inherit;font-size:10.5px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;font-family:"IBM Plex Mono",monospace;
  padding:6px 10px;border:0;border-top:1px solid var(--line);border-radius:0;
  background:var(--sunk);color:var(--dim);cursor:pointer;text-align:center}
.oven-hand:hover{background:var(--accent);color:var(--accent-ink)}
.oven-hand.on{background:var(--ink);color:var(--panel)}
.oven-hand.on:hover{background:var(--accent);color:var(--accent-ink)}
/* Gone: the customer has it, and it is no longer anybody's job. */
.oven.gone{opacity:.45;border-left-color:var(--ink)}
/* Eggless changes what goes in the bowl, so it marks the whole tile — but the
   two that change where the cake GOES, or how much work it is, outrank it. */
.oven.eggless{border-left-color:var(--ok)}
.oven.hot{border-left-color:var(--crit)}
.oven.deliver{border-left-color:var(--berry);
  background:color-mix(in srgb, var(--berry) 5%, var(--panel))}
.oven.done{opacity:.5;border-left-color:var(--ok);background:var(--sunk)}

.oven-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.oven-time{font-family:"IBM Plex Mono",monospace;font-size:15px;font-weight:600;
  font-variant-numeric:tabular-nums}
.oven-time.early{color:var(--crit)}
/* Empty until it is baked: an empty circle is the thing left to do. */
.oven-tick{width:22px;height:22px;flex:0 0 auto;border-radius:50%;
  border:1.5px solid var(--line2);display:grid;place-items:center;
  font-size:13px;font-weight:700;color:transparent}
.oven-tick.on{background:var(--ok);border-color:var(--ok);color:#FFF}

.oven-cake{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}
.oven-code{font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--accent)}
.oven-name{font-family:Fraunces,Georgia,serif;font-size:15px;font-weight:700;
  line-height:1.15;flex:1 1 auto;min-width:0}
.oven-of{font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint)}
/* What actually gets piped onto the cake, in the face the shop writes in. */
.oven-msg{font-family:Fraunces,Georgia,serif;font-size:14px;line-height:1.3;
  color:var(--ink)}
.oven-pills{display:flex;gap:4px;flex-wrap:wrap}
.oven-pills:empty{display:none}
.oven-info{font-size:11.5px;color:var(--dim);background:var(--sunk);
  border-left:2px solid var(--line2);border-radius:3px;padding:4px 7px;
  white-space:normal}
.oven-foot{margin-top:auto;padding-top:2px;font-size:10.5px;color:var(--faint)}

/* ---- at the counters: one tile per cake, same idea as the oven board ----- */
.stockgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));
  gap:8px}
.stock{display:flex;flex-direction:column;gap:3px;padding:9px 10px;
  border:1px solid var(--line);border-left:3px solid var(--line2);
  border-radius:5px;background:var(--panel)}
.stock.out{border-left-color:var(--crit);background:var(--crit-soft)}
.stock-top{display:flex;align-items:center;justify-content:space-between;gap:6px}
.stock-code{font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--accent)}
.stock.out .stock-code{color:var(--crit)}
.stock-size{font-family:"IBM Plex Mono",monospace;font-size:10.5px;
  background:var(--accent-soft);color:var(--accent);border:1px solid var(--line2);
  border-radius:3px;padding:1px 5px;white-space:nowrap}
.stock-name{font-family:Fraunces,Georgia,serif;font-size:13.5px;font-weight:700;
  line-height:1.2}
/* The quantity decides whether somebody bakes more, so it is the biggest thing
   on the tile — and a zero says the words rather than showing a small 0. */
.stock-qty{display:flex;align-items:baseline;gap:7px;margin-top:auto;padding-top:4px}
.stock-qty b{font-family:Fraunces,Georgia,serif;font-size:24px;line-height:1}
.stock-out{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--crit);font-weight:700}
.stock-sold{font-size:10.5px;color:var(--faint)}

/* ===========================================================================
   Office cash — the tin, what leaves it, and the notes counted against it.
   Two four-column tables side by side, and a note pad along the foot. Nothing
   here is wide: the whole point of dropping the per-day count was that four
   columns fit in half the screen and two books can be read together.
   =========================================================================== */
/* Four figures across the top, in the order the arithmetic runs. Read left to
   right they are a sentence: had this, got this, paid that, so this is left. */
.tin{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px;
  margin:14px 0 0}
.tinbit{background:var(--panel);border:1px solid var(--line);border-radius:8px;
  padding:9px 13px;display:flex;flex-direction:column;gap:2px}
.tinbit span{font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--faint)}
.tinbit b{font-size:19px;font-variant-numeric:tabular-nums;letter-spacing:-.01em}
.tinbit.up b{color:var(--ok)}
.tinbit.down b{color:var(--crit)}
/* The one the pad below is checked against. */
.tinbit.now{background:var(--accent-soft);border-color:var(--accent)}
.tinbit.now span{color:var(--accent)}
.tinbit.now b{font-size:21px}

/* The two books. Equal halves — they are the same shape and are read across. */
.twoup{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;
  align-items:start;margin-top:14px}
@media (max-width:1000px){.twoup{grid-template-columns:minmax(0,1fr)}}
.twoup .panel.half{margin-top:0;min-width:0}
/* Both lists can run to a month. Scrolling them inside the panel keeps the pad
   at the foot on screen, which is where the answer is. */
.scroll.tall{max-height:460px;overflow-y:auto}

/* .board carries a 1540px floor for the thirteen-column day board. These two
   have four columns each and live in half the width; inheriting that floor
   pushed the balance off the right-hand edge into a scroll nobody would drag. */
.board.tinbook,.board.spends{min-width:0;table-layout:auto}
.board.tinbook .dt,.board.spends .dt{width:70px;white-space:nowrap}
.board.tinbook td,.board.spends td{padding-top:5px;padding-bottom:5px}
.board.tinbook th.tr,.board.tinbook td.tr{width:33%}
.board.spends td.what{white-space:normal;line-height:1.35}
.board.spends th:nth-child(3),.board.spends td:nth-child(3){width:92px;white-space:nowrap}
.board.spends th:nth-child(4),.board.spends td:nth-child(4){width:30px}
.board .sub{color:var(--faint);font-size:11.5px;display:block}
.board .sub.crit{color:var(--crit)}
.board tbody tr.quiet td{color:var(--faint)}
/* An × rather than the word "cancel": the word was wider than the amount. */
.xout{background:none;border:0;padding:0 2px;font:inherit;font-size:15px;line-height:1;
  color:var(--line2);cursor:pointer}
.xout:hover{color:var(--crit)}

/* Recording a payment: one line, so it never reads as a form to fill in. */
.spendrow{display:flex;flex-wrap:wrap;gap:7px;align-items:center;
  padding:10px 0 9px;border-bottom:1px solid var(--line)}
.spendrow input[type=text]{flex:1 1 100px;min-width:90px}
.spendrow select{flex:1 1 150px;min-width:140px}
.spendrow button{margin-left:auto}

/* ------------------------------------------------------------- the note pad --
   A calculator, not a report: nine cells in a row, the total and the verdict
   under them. It is checked against "Should be there" above — the tin is
   counted on a random Tuesday, so there is no per-day column for it. */
.padpanel{margin-top:14px}
.padcells{display:grid;grid-template-columns:repeat(9,minmax(0,1fr));gap:8px;
  padding:14px 0 4px}
@media (max-width:820px){.padcells{grid-template-columns:repeat(3,minmax(0,1fr))}}
.padcell{display:flex;flex-direction:column;gap:3px;margin:0;min-width:0}
.padcell .mono{font-size:11.5px;color:var(--dim);text-align:center}
.padcell input{width:100%;text-align:center;padding:7px 4px;font-size:15px;
  font-variant-numeric:tabular-nums;-moz-appearance:textfield}
.padcell input::-webkit-outer-spin-button,
.padcell input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.padcell i{font-style:normal;font-size:11px;color:var(--faint);text-align:center;
  min-height:15px;font-variant-numeric:tabular-nums}
.padfoot{display:flex;flex-wrap:wrap;align-items:center;gap:14px;
  padding-top:11px;border-top:1px solid var(--line);margin-top:6px}
.padfoot .ct{display:flex;align-items:baseline;gap:9px;font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.padfoot .ct b{font-size:21px;letter-spacing:-.01em;color:var(--ink);
  font-variant-numeric:tabular-nums;text-transform:none;letter-spacing:normal}
.padsay{font-size:14px;color:var(--dim)}
.padsay b{font-weight:700}
.padgo{margin-left:auto;display:flex;align-items:center;gap:8px}

/* ===========================================================================
   Deliveries — the fee beside what the driver cost.
   =========================================================================== */
.board.runs{min-width:0;table-layout:auto}
.board.runs .dt{width:74px;white-space:nowrap}
.board.runs td.ref,.board.runs th:nth-child(2){width:160px;white-space:nowrap;
  font-size:12px;color:var(--dim)}
.board.runs td.what{white-space:normal;line-height:1.35;min-width:220px}
.board.runs th:nth-child(4),.board.runs td:nth-child(4){width:96px;white-space:nowrap}
.board.runs th:nth-child(5),.board.runs td:nth-child(5){width:104px}
.board.runs th:nth-child(6),.board.runs td:nth-child(6){width:126px}
.board.runs th:nth-child(7),.board.runs td:nth-child(7){width:110px;white-space:nowrap}
.board.runs td{padding-top:6px;padding-bottom:6px}
/* Typed straight into the row it belongs to, like the office's receipts. */
.board.runs input.costbox{width:100%;text-align:right;padding:3px 6px;
  font-size:12.5px;font-weight:600;font-variant-numeric:tabular-nums;
  -moz-appearance:textfield}
.board.runs input.costbox::-webkit-outer-spin-button,
.board.runs input.costbox::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.board.runs input.whobox{width:100%;padding:3px 6px;font-size:12.5px}
.board.runs tr.quiet td{color:var(--faint);background:var(--sunk)}
/* Why the three figures in the strip do not subtract to each other. */
.tinbit .onlyon{font-style:normal;font-size:11px;color:var(--faint);
  text-transform:none;letter-spacing:normal;margin-top:1px}

/* ===========================================================================
   Admin — reference data. Dense tables, one editor panel above them.
   =========================================================================== */
.adminbar{display:flex;flex-wrap:wrap;gap:8px;align-items:center;
  padding:12px 0 11px;border-bottom:1px solid var(--line);margin-bottom:2px}
/* Inputs in this app stretch by default; on a one-line bar they have to not. */
.adminbar > input,.adminbar > select{flex:0 0 auto}
.adminbar .field,.prodform .field,.setprices .field{display:flex;align-items:center;gap:6px}
.adminbar label.tick,.prodform label.tick{display:flex;align-items:center;gap:6px;
  font-size:13px;color:var(--dim);white-space:nowrap;margin:0}
.adminbar label.tick input,.prodform label.tick input{width:auto;margin:0}

.board.cat{min-width:0;table-layout:auto}
.board.cat td,.board.cat th{padding-top:6px;padding-bottom:6px}
.board.cat td.code{width:130px;white-space:nowrap;font-size:12.5px}
.board.cat td.code .half{font-style:normal;color:var(--faint);font-size:11px;
  margin-left:7px}
.board.cat tbody tr.quiet td{color:var(--faint)}
.odd{font-style:normal;font-size:10px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--warn);margin-left:7px}
.per{font-style:normal;font-size:10.5px;color:var(--faint);margin-left:2px}
.queued{font-size:10px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--warn)}

/* The one product being worked on, above the list it came from. */
.editor{background:var(--sunk);border:1px solid var(--line2);border-radius:8px;
  padding:4px 14px 14px;margin:12px 0 4px}
.phead.thin{padding-top:12px}
.prodform{display:flex;flex-wrap:wrap;gap:9px;align-items:center;padding:6px 0 12px;
  border-bottom:1px solid var(--line)}
.prodform button{margin-left:auto}
.prodform input,.prodform select{background:var(--panel)}

.board.pricetab{min-width:0;table-layout:auto}
.board.pricetab .dt{width:150px;white-space:nowrap}
.board.pricetab td,.board.pricetab th{padding-top:5px;padding-bottom:5px}
.setprices{display:flex;flex-wrap:wrap;gap:10px;align-items:center;padding:12px 0 4px}
.setprices button{margin-left:auto}
.setprices input{background:var(--panel)}
.setprices input[type=number]{-moz-appearance:textfield}
.setprices input[type=number]::-webkit-outer-spin-button,
.setprices input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.adminbar input[type=number]{-moz-appearance:textfield}
.adminbar input[type=number]::-webkit-outer-spin-button,
.adminbar input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}

/* What the per-kg rate works out to, every rung editable so a cake is still
   allowed an odd price at 2.5 kg. */
.ladderwrap{display:flex;align-items:flex-start;gap:11px;padding:6px 0 2px;flex-wrap:wrap}
.ladder{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:7px;flex:1 1 400px}
@media (max-width:820px){.ladder{grid-template-columns:repeat(4,minmax(0,1fr))}}
.rung{display:flex;flex-direction:column;gap:3px;margin:0;min-width:0}
.rung .mono{font-size:11px;color:var(--faint);text-align:center}
.rung input{width:100%;text-align:center;padding:5px 4px;font-size:13px;
  background:var(--panel);font-variant-numeric:tabular-nums;-moz-appearance:textfield}
.rung input::-webkit-outer-spin-button,
.rung input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.rung input.edited{border-color:var(--accent);font-weight:600}

input.inline{width:100%;max-width:280px;padding:3px 6px;font-size:13px;
  background:transparent;border-color:transparent}
input.inline:hover,input.inline:focus{background:var(--panel);border-color:var(--line2)}

.note.warn{background:var(--warn-soft);border:1px solid var(--warn);
  border-radius:8px;padding:10px 13px;margin:12px 0 2px;font-size:13.5px;
  color:var(--warn)}
.note.warn b{display:block;font-size:14px;margin-bottom:2px}
/* A verb that reads as a link rather than a button: "retire" is a rare, quiet
   action at the end of a row, not something to invite a click on. */
.linky{background:none;border:0;padding:0;font:inherit;font-size:11.5px;
  color:var(--faint);cursor:pointer;text-decoration:underline}
.linky:hover{color:var(--crit)}
/* Sortable headings on the catalogue, the same gesture as the registers. */
.board.cat th.sortable{cursor:pointer;user-select:none;white-space:nowrap}
.board.cat th.sortable:hover{color:var(--ink)}
.board.cat th.sortable.on{color:var(--accent)}
.board.cat th.sortable i{font-style:normal;font-size:9px}
.adminbar .r{margin-left:auto}
.adminbar .found{font-size:12px;white-space:nowrap}
/* Closing an editor without saving. */
.phead .xout.close{margin-left:12px;font-size:19px;color:var(--faint)}
.phead .xout.close:hover{color:var(--crit)}
/* The name a number is saved under. Shown, never typed — BCH's customer list
   is kept against phone numbers. */
input.shown{background:var(--sunk);color:var(--dim);cursor:default}
input.shown:focus{outline:none;border-color:var(--line)}

/* ===========================================================================
   Which bill? Two documents come off the Print button and only the person at
   the window knows which moment it is.
   =========================================================================== */
.askback{position:fixed;inset:0;z-index:60;background:rgba(20,10,8,.45);
  display:grid;place-items:center;padding:20px}
.askcard{background:var(--panel);border:1px solid var(--line2);border-radius:12px;
  box-shadow:0 18px 60px -20px rgba(0,0,0,.5);padding:20px;width:min(420px,100%);
  display:flex;flex-direction:column;gap:10px}
.askcard h2{margin:0 0 4px;font-size:17px}
.billpick{display:flex;flex-direction:column;align-items:flex-start;gap:3px;
  text-align:left;padding:13px 15px;border:1px solid var(--line2);border-radius:9px;
  background:var(--sunk);cursor:pointer;font:inherit;color:var(--ink);width:100%}
.billpick:hover,.billpick:focus-visible{border-color:var(--accent);
  background:var(--accent-soft);outline:none}
.billpick b{font-size:15px}
.billpick span{font-size:12.5px;color:var(--dim);line-height:1.4}
.askcard .ghost{align-self:flex-end;margin-top:2px}
/* What the number will actually dial. Sits under the saved-contact line. */
.hint.dial{font-size:11.5px;line-height:1.4;margin-top:2px}

/* ===========================================================================
   Taking a report away — the bar under it, and what the printer sees.
   =========================================================================== */
.takeaway{display:flex;flex-wrap:wrap;align-items:center;gap:9px;
  padding:14px 0 4px;margin-top:12px;border-top:1px solid var(--line)}
.takeaway .note{font-size:11.5px;color:var(--faint);margin-left:auto}
/* Pills. Three ways out of the same report, so they read as one set of three
   rather than as three unrelated buttons — same size, same shape, side by side,
   and round enough that nothing about them looks like the primary action on the
   screen. Saving a copy never is. */
.takeaway button{border-radius:999px;padding:7px 16px;font-size:12.5px;
  font-weight:500;border:1px solid var(--line2);background:var(--panel);
  color:var(--dim);cursor:pointer;white-space:nowrap;
  transition:border-color .12s,color .12s,background .12s}
.takeaway button:hover{border-color:var(--accent);color:var(--accent);
  background:var(--accent-soft)}
.takeaway button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.takeaway button:active{transform:translateY(1px)}
.printcap{display:none}

@media print{
  /* Everything that is a control rather than a figure. A printed report is
     read on paper, where a date picker is a grey box that means nothing. */
  html.printing-report .bar,
  html.printing-report .panel > .phead,
  html.printing-report .takeaway,
  html.printing-report .headmenu,
  html.printing-report .toast,
  html.printing-report .party{display:none !important}

  html.printing-report .printcap{display:block;margin:0 0 10px}
  html.printing-report .printcap b{display:block;font-size:15px}
  html.printing-report .printcap span{font-size:12px;color:#444}
  html.printing-report .printcap i{font-style:normal;font-size:12px;color:#444;
    margin-left:10px}

  /* On screen the long tables scroll inside their panel. On paper there is no
     scrolling — the rest of the rows would simply be missing. */
  html.printing-report .scroll,
  html.printing-report .scroll.tall{max-height:none !important;overflow:visible !important}
  html.printing-report .panel{border:0;box-shadow:none;padding:0;margin:0 0 14px;
    background:#fff;break-inside:auto}
  html.printing-report .twoup{display:block}
  html.printing-report .tin{break-inside:avoid}

  /* The heading repeats at the top of every page, and no row is cut in half. */
  html.printing-report table{width:100% !important;min-width:0 !important;
    font-size:10px;border-collapse:collapse}
  html.printing-report thead{display:table-header-group}
  html.printing-report tfoot{display:table-footer-group}
  html.printing-report tr{break-inside:avoid}
  html.printing-report td,html.printing-report th{padding:3px 5px}
  /* A typed figure has to print as a figure, not as an empty box outline. */
  html.printing-report input{border:0 !important;background:transparent !important;
    padding:0 !important;color:#000 !important;font-size:10px}
  html.printing-report button{display:none !important}
}
/* Bill numbers are BCH/YEY/2026/00001 now — long, and never to be wrapped in
   the middle, because half a bill number is not a bill number. */
.board.report td.ref,.board.runs td.ref{white-space:nowrap;font-size:11.5px;
  overflow:hidden;text-overflow:ellipsis}

/* ===========================================================================
   On a phone.
   =========================================================================== */
/* Bake is desktop software and stays desktop software — the counters work on a
   monitor and that is what the layout is for. This is the OWNER's phone: a call
   comes in, an order goes on, and the day gets looked at. Two screens, not
   seven, and the same code underneath so the half-kg premium and the eggless
   charge cannot drift between the two.
   =========================================================================== */
@media (max-width: 760px){

  /* ------------------------------------------------------------- the band --
     Seven tabs will not fit across a phone and wrapping them costs three lines
     of a small screen. So the strip scrolls sideways, and everything else on
     the band sits above it on one line. */
  .bar{flex-wrap:wrap;padding:8px 10px;gap:8px}
  /* min-width:0 is the whole trick. A flex item will not shrink below the
     width of its contents however much overflow it is given, so without this
     the seven tabs push the band — and the page — wider than the phone. */
  .bar nav.nav{order:3;width:100%;min-width:0;max-width:100%;overflow-x:auto;
    flex-wrap:nowrap;-webkit-overflow-scrolling:touch;scrollbar-width:none;
    padding-bottom:2px}
  .bar>*{min-width:0}
  .bar nav.nav::-webkit-scrollbar{display:none}
  .bar nav.nav a{flex:0 0 auto;white-space:nowrap}
  /* The two a phone is for, first. Nothing is hidden — the strip scrolls and
     everything else is still behind it — but taking an order and looking at the
     day are what somebody opens this on a phone to do, and they should not have
     to swipe to find either. */
  .bar nav.nav a[href^="#/order"]{order:-2}
  .bar nav.nav a[href^="#/board"]{order:-1}
  /* Room for the home bar on a phone with no button. */
  body{padding-bottom:env(safe-area-inset-bottom)}
  .bar .tgt{order:2;margin-left:auto}
  .bar .who{font-size:11px}
  main{padding:0 10px 30px}
  .panel{padding:10px}

  /* -------------------------------------------------- a cake, on a phone --
     The cake table is fifteen columns and 1626px wide. On a phone that is not a
     table that needs scrolling, it is a form that cannot be filled in: the size
     and the quantity are off the right-hand edge, so an order literally cannot
     be completed. Each row becomes a card instead, two fields across. */
  .xscroll{overflow:visible;margin:0;padding:0}
  .cakes{min-width:0;table-layout:auto;display:block}
  .cakes colgroup,.cakes thead{display:none}
  .cakes tbody{display:block}
  .cakes tbody tr{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:9px 10px;position:relative;
    background:var(--panel);border:1px solid var(--line);border-radius:9px;
    padding:12px 12px 13px;margin:0 0 10px}
  /* Every sticky offset is meaningless once there are no columns to scroll. */
  .cakes th:nth-child(1),.cakes td:nth-child(1),
  .cakes th:nth-child(2),.cakes td:nth-child(2),
  .cakes th:nth-child(3),.cakes td:nth-child(3){position:static;left:auto;box-shadow:none}
  .cakes tbody tr:nth-child(n) td:nth-child(-n+3){background:transparent;z-index:auto}
  .cakes tbody td{display:block;padding:0;height:auto;border:0;white-space:normal}
  /* A column with nothing in it — a pastry has no shape, no topper, no message —
     takes no room rather than leaving a labelled hole. */
  .cakes tbody td:empty,.cakes tbody td.nix{display:none}
  .cakes tbody td::before{content:attr(data-label);display:block;
    font-family:"IBM Plex Mono",monospace;font-size:9px;letter-spacing:.11em;
    text-transform:uppercase;color:var(--faint);margin-bottom:3px}
  .cakes tbody td:not([data-label])::before{content:none}
  .cakes input,.cakes select{font-size:16px;padding:9px 10px;width:100%}
  /* 16px is not a taste: anything smaller and iOS zooms the whole page in when
     the box is tapped, and never zooms back out. */
  .cakes td.tc{text-align:left}
  .cakes td.tc input[type=checkbox]{width:auto;transform:scale(1.3);
    transform-origin:left center;margin:5px 0 0}
  /* The ones that need the whole width to be readable. */
  .cakes td[data-label="Cake"],
  .cakes td[data-label="Message on cake"],
  .cakes td[data-label="Dietary"],
  .cakes td[data-label="Additional info"]{grid-column:1 / -1}
  /* Remove-this-line, out of the way in the corner rather than in the flow. */
  .cakes tbody td:not([data-label]){position:absolute;top:6px;right:8px;
    grid-column:auto;width:auto}
  .cakes tbody td:not([data-label]) button{font-size:19px;padding:2px 8px}

  /* ------------------------------------------------- the rest of the form --
     The four panels are side by side on a monitor and stack on a phone, which
     the grid already does. What it does not do is make the boxes thumb-sized. */
  .grid,.grid3,.grid4,.grid.level{grid-template-columns:minmax(0,1fr)}
  .panel input,.panel select,.panel textarea{font-size:16px;padding:9px 10px}
  .picker{max-height:52vh}
  .picker .opt{padding:10px}
  /* The keyboard shortcut strip is a line of things a phone has no keys for. */
  .keys{display:none}

  /* ---------------------------------------------------------- the day board
     It already dropped to four columns and scrolled the rest away sideways,
     which meant the phone could not see whether a cake was ready or collected —
     the two things the board is opened to find out. */
  .board{min-width:0;table-layout:auto;font-size:13px}
  .board thead th{padding:6px 4px;font-size:9px}
  .board tbody td{padding:7px 4px}
  .board td.cake{min-width:0}

  /* Two thumbs, one screen. A save button that shares a line with "Start again"
     is a save button somebody misses. */
  .savebar{position:sticky;bottom:0;background:var(--ground);padding:8px 0;
    border-top:1px solid var(--line);z-index:5}
  .savebar button{padding:14px;font-size:15px}
  .savebar button.primary{flex:1 1 auto}
  /* Where the cake is baked sits beside the panel heading and its longest
     option — "Yeyyadi oven — cakes up to 1 kg only" — is wider than the phone.
     On its own line under the heading, full width. */
  .phead{flex-wrap:wrap;gap:6px}
  /* The wrapper is pushed to the right of the heading by margin-left:auto,
     which on a phone means it starts 37px in and runs off the end. Its own line
     instead, full width. */
  .phead>span:has(.bakedrow){width:100%;min-width:0;margin-left:0}
  .bakedrow{width:100%;min-width:0}
  .bakedrow select{flex:1 1 auto;width:100%;min-width:0}
}
