.nav .ic i,.nav-drop .ic i{color:#B8BBC9;width:16px;height:16px;vertical-align:middle}.nav-item.open .nav-btn,.nav-btn.current{color:#18BDB7}.nav-drop button.on .ic i,.nav-drop a.on .ic i{color:#18BDB7}
*{box-sizing:border-box}
 /* ---------- THE SHOP'S SIZES, IN ONE PLACE ----------
    The box is 34px and the padding 5px 10px, both asked for smaller than the 34px and
    5px 10px they replace.

    THEY ARE HERE, AND NOT IN A NEW RULE, ON PURPOSE.  This file already learned that a rule
    written to set the box size loses on specificity to the two rules that really set it -
    .grid3.cap-top > div > .input at (0,.grid2.cap-top > div > .input at (0,3,1) and table.itab .input at (0,2,1) - and the first
    time that happened the height did not change while looking as though it had.  So the
    existing declarations were edited where they stand and their numbers come from here,
    which means there is one place to change them and no rule anywhere that can win on order.

    --zb-box-pad is the four sides and --zb-box-pad-y only the top and bottom, because the
    combo boxes keep their own wider right-hand padding for the arrow. */
 :root{--zb-box:34px;--zb-box-pad:5px 10px;--zb-box-pad-y:5px}
body{margin:0;font-family:'Segoe UI',Arial,sans-serif;background:#f5f6f8;color:#1f2933}
.hidden{display:none!important}
.btn{background:#fff;border:1px solid #d0d5dd;border-radius:8px;padding:9px 14px;cursor:pointer;font-weight:600;font-size:13.5px;color:#1f2933}
.btn:hover{background:#f2f4f7}
.btn-primary{background:#14b8a6;color:#fff;border-color:#14b8a6}
.btn-gold{background:#b45309;color:#fff;border-color:#b45309}
.btn-danger{background:#e11d48;color:#fff;border-color:#e11d48}
.btn-ok{background:#067647;color:#fff;border-color:#067647}
.btn-sm{padding:6px 10px;font-size:12.5px}
/* ---------- THE MODULE COLOURS, ON THE "NEW" BUTTONS ONLY ----------
   The same four colours the Reports page uses for the same four modules, so a colour means
   the same thing in both places: green is Stock, violet is Accounts, blue is Financial,
   amber is HRM.  That is the whole reason for the colour - "the green one opens a New
   Purchase" is faster than reading four buttons.

   SCOPED TO .btn-new AND NOT TO .btn, because .btn is shared by every screen and by every
   other button on them: a Delete, a Cancel and a Print all carry it, and none of them is a
   New Entry.  So the class is added by hand to the New button on each list screen, which is
   twenty-odd edits rather than one rule that would repaint the program. */
.btn-new.btn-m-stock{background:#16a34a;color:#fff;border-color:#16a34a}
.btn-new.btn-m-stock:hover{background:#15803d;border-color:#15803d}
.btn-new.btn-m-accounts{background:#7c3aed;color:#fff;border-color:#7c3aed}
.btn-new.btn-m-accounts:hover{background:#6d28d9;border-color:#6d28d9}
.btn-new.btn-m-financial{background:#2563eb;color:#fff;border-color:#2563eb}
.btn-new.btn-m-financial:hover{background:#1d4ed8;border-color:#1d4ed8}
.btn-new.btn-m-hrm{background:#d97706;color:#fff;border-color:#d97706}
.btn-new.btn-m-hrm:hover{background:#b45309;border-color:#b45309}
/* The focus ring has to follow the button, or tabbing through the program shows a blue
   outline on a green button and reads as an error. */
.btn-new:focus-visible{outline:2px solid #111827;outline-offset:2px}
.input{width:100%;padding:9px 11px;border:1px solid #d0d5dd;border-radius:8px;font-size:13.5px;background:#f2f4f7;color:#1f2933;height:43px;box-sizing:border-box}
/* ---- BOX SIZES AND SPACING, inside a form modal: Purchase, Sales, Sales Return ----

   THE GOVERNING RULES ARE ELSEWHERE IN THIS FILE and they are what set these boxes: the
   height comes from .grid3.cap-top > div > .input and from table.itab .input, which are
   (0,3,1) and (0,2,1).  A rule written here at (0,2,0) loses to both of them on
   specificity whatever order the two appear in - which is what happened the first time,
   where the gaps and the card padding took effect and the height and the padding did
   not, and the form came out at its old 32px looking like no change had been made.

   So the numbers below are NOT set by a new rule here.  They are set by editing those
   rules where they stand, which is why this block sets nothing at all.  And what those
   declarations now carry is not a number but a variable:

     .grid3.cap-top > div > .input,.select    var(--zb-box), padding var(--zb-box-pad)
     .grid3.cap-top > div .ic                 var(--zb-box)
     table.itab .input                        var(--zb-box), padding var(--zb-box-pad)
     table.itab .ic-t                         var(--zb-box)
     table.itab .rm                           var(--zb-box) tall, 34px wide

   --zb-box is 34px and --zb-box-pad is 5px 10px, both declared once at the top of this
   block, so there is one place in the file where the size lives, and no rule anywhere that
   can win on order and quietly do nothing.

   THE SAME DECLARATIONS NOW GOVERN .grid2 as well, so the Account and Item forms - the two
   the shop asked for - are laid out and sized by one set of rules and cannot drift apart
   from the Sale, Sales Return and Purchase.  No other .grid2 form was given the class:
   Task, User, Employee, Staff Advance and Leave are untouched.

   WHAT IS LEFT HERE is the one thing no rule in the file governs, because no form draws
   a multi-line box in a grid cell: a textarea gets the same padding so it does not look
   like a different control, and a minimum height rather than a fixed one, because fixing
   the height of a box meant to hold a paragraph is a way of losing what was typed in it. */
.modal textarea{min-height:var(--zb-box);padding:var(--zb-box-pad);box-sizing:border-box;width:100%}
.input:focus{outline:2px solid #d0d5dd;border-color:#111827}
.select{padding:9px 11px;border:1px solid #d0d5dd;border-radius:8px;font-size:13.5px;background:#f2f4f7;max-width:100%;color:#1f2933;height:43px;box-sizing:border-box}
label{font-size:12.5px;font-weight:700;color:#344054;display:block;margin:8px 0 3px}
/* ---------- the caption, then its box, reading left to right ----------
   English is the language the program is built in and the whole program follows
   English reading direction, on every screen.  So a field is written as its
   caption first and the box after it: the caption starts from the left, and the
   box follows it on the right.  Nothing is mirrored, in any language, ever.

   Only a wrapper holding one caption is turned this way.  A wrapper with two or
   more captions is a row of fields, where each caption must stay beside its own
   box, and a wrapper holding a table is left completely alone.

   .exp-cell is left out of it: the expense sheet lays its own, because every
   caption there has to be the same width or the boxes come out seven different
   sizes.

   .ma-row>div is left out for the same reason and it was missing.  That row holds the
   Memo and the Attachment on the Purchase, Sales and Sales Return forms, and they are
   caption-ABOVE-box like every other field on those forms.  Caught by it, they were laid
   out caption-BESIDE-box - which is why the memo came out 231px inside a 296px cell: the
   caption took 56px and the box was fitted into what was left.

   Worth knowing how this rule behaves, because it is not a specificity anyone would
   guess: :has() and :not() each take the specificity of their MOST SPECIFIC argument, so
   this selector carries the weight of every class and element inside all seven of its
   conditions.  It beats .ma-row .memo-box at (0,2,0) by a wide margin.  Making a plain
   class rule more specific cannot win against it - .ma-row .memo-box was tried, and then
   .ma-row .memo-box .input.memo, and the memo stayed 231px.  The only way past it is to
   be outside its scope, which is what :not() does here. */
div:has(>label):not(:has(>label~label)):not(.toolbar):not(.exp-cell):not(.ast-cell):not(.cap-top div):not(.ma-row>div):not(.vc-cell):not(.nt-cell):not(:has(table)),
.jn-narr,.rf-fld,.bnr-slot{
  display:flex;flex-direction:row;align-items:center;gap:9px;
  /* Pinned left-to-right. A flex row obeys the page's own direction, so this
     has to be stated: it is what stops anything ever mirroring the program. */
  direction:ltr}
div:has(>label):not(:has(>label~label)):not(.toolbar):not(.exp-cell):not(.ast-cell):not(.cap-top div):not(.ma-row>div):not(.vc-cell):not(.nt-cell):not(:has(table))>label,
.jn-narr>label,.rf-fld>label,.bnr-slot>label{
  flex:0 1 auto;min-width:0;max-width:52%;margin:0;text-align:left;
  /* the caption sits on the left of its box but still reads in its own
     direction, so a Pashto caption is not laid out backwards inside itself */
  unicode-bidi:plaintext}
div:has(>label):not(:has(>label~label)):not(.toolbar):not(.exp-cell):not(.ast-cell):not(.cap-top div):not(.ma-row>div):not(.vc-cell):not(.nt-cell):not(:has(table))>input,
div:has(>label):not(:has(>label~label)):not(.toolbar):not(.exp-cell):not(.ast-cell):not(.cap-top div):not(.ma-row>div):not(.vc-cell):not(.nt-cell):not(:has(table))>select,
div:has(>label):not(:has(>label~label)):not(.toolbar):not(.exp-cell):not(.ast-cell):not(.cap-top div):not(.ma-row>div):not(.vc-cell):not(.nt-cell):not(:has(table))>textarea,
.jn-narr>textarea,.rf-fld>input,.rf-fld>select,.bnr-slot>input{
  flex:1 1 auto;min-width:0}
/* ---------- sales and purchase: captions on top, as on the expense sheet ----------
   Two forms the shop asked for, laid out like the expense sheet.  The caption sits
   directly above its own box, small and bold and starting where the box starts.

   .pay is repeated in every selector because .grid3 > div.pay > label is the more
   specific of the two, and would otherwise keep the old size and spacing on the two
   captions that have it while every other caption on the form changed.

   The boxes fill their column, so all three across are the same width - which the
   old row layout got from a fixed caption width, and this gets from the grid. */
/* The .grid3 prefix is load-bearing, not decoration: without it these rules tie
   with .grid3 > div > label on specificity and lose to it on order, which is how
   the first attempt left the old caption size in place and the boxes a few pixels
   out of line with each other.  The .pay captions need one more class still,
   because .grid3 > div.pay > label is (0,2,2) as well. */
/* 3px, not 5px.  The eleven cells that hold an account box keep an 18px reservation
   above the box for the balance figure, so with a 5px gap those cells still read as
   visibly looser than the rest of the row.  Three is enough to separate a small bold
   caption from its box and tight enough that the caption reads as belonging to it, and
   every cell gets the same three so the rows still line up. */
/* 7px between the caption and its box - the middle of the 6-to-8 asked for.  It was
   3px, tightened earlier today because the balance reservation was putting 18px of dead
   space above EVERY box on these forms; that dead space is gone, because only the eleven
   boxes that actually show a balance keep a reservation now.  So the gap can go back to
   a comfortable 7px without the forms looking loose again. */
.grid3.cap-top > div:has(>label),.grid2.cap-top > div:has(>label){display:flex;flex-direction:column;
  align-items:stretch;gap:7px}
/* 16px, as asked for on the Sale, Sales Return and Purchase forms.  It was 11.5px, and
   11.5px on a 34px box is a caption you have to lean in to read.  Still bold, still
   uppercase and still starting where its box starts. */
.grid3.cap-top > div > label,.grid2.cap-top > div > label,.grid3.cap-top > div.pay > label,.grid2.cap-top > div.pay > label{
  flex:0 0 auto;min-width:0;max-width:none;margin:0;padding-left:1px;
  font-size:16px;font-weight:800;letter-spacing:.2px;text-transform:uppercase;
  color:#344054;text-align:left;white-space:nowrap;
  /* still reads in its own direction, so a Pashto caption is not laid out
     backwards inside itself */
  unicode-bidi:plaintext}
/* flex:none because a column flex item shrinks along the main axis, and the grid
   stretches each cell to the tallest in its row - which is what made the drop
   downs 15px tall.  One height for every box, so the boxes in a row line up. */
.grid3.cap-top > div > .input,.grid2.cap-top > div > .input,.grid3.cap-top > div > .select,.grid2.cap-top > div > .select,.grid3.cap-top > div.pay > .input,.grid2.cap-top > div.pay > .input,.grid3.cap-top > div.pay > .select,.grid2.cap-top > div.pay > .select{
  /* 34px - the middle of the 40-to-42 asked for, because a range is a tolerance and
     sitting on its boundary means one pixel of rounding on one machine puts it outside.
     5px 10px inside it, so the text is not touching the edges.  box-sizing is border-box
     on every element in this file, so 34px is the whole box.
     IT WAS 32px, which is why a select and a text box in the same row did not line up:
     a select and a text box with the same padding and the same border are not the same
     height by themselves, and a fixed height is what makes a row read as a row. */
  flex:none;width:100%;min-width:0;height:var(--zb-box);padding:var(--zb-box-pad)}
/* The purchase form wraps each combo in a div of its own, and balSlot() puts the
   figure inside that wrapper rather than beside it.  So the wrapper becomes a
   column too and the same ordering is stated inside it - otherwise the purchase
   drop downs sit 18px lower than the inputs beside them, which is what they did. */
.grid3.cap-top > div > div,.grid2.cap-top > div > div{display:flex;flex-direction:column;width:100%;min-width:0}
/* REPLACED - the figure went ABOVE its box.  These four rules said order:1 on the
   box and order:2 on the figure, and in a flex column order beats the order things
   are written in, so a slot balSlot() had deliberately placed above the box was
   painted below it.  The new rules are further down, with the whole of why. */
.grid3.cap-top > div > div > .ic,.grid2.cap-top > div > div > .ic{order:2}
/* order:1 keeps the balance ahead of the box in the caption line.  NO min-height and NO
   margin: it is positioned absolutely on the caption line, so it must not claim any
   space - that claim is what put the account boxes 18px below their neighbours. */
.grid3.cap-top > div > div > .bal-hint,.grid2.cap-top > div > div > .bal-hint{order:1}
.grid3.cap-top > div > div > .ic-ok,.grid2.cap-top > div > div > .ic-ok{order:3;margin-top:2px}
/* and here too, for the purchase form's own combo wrappers */
.grid3.cap-top > div > div > .input,.grid2.cap-top > div > div > .input,.grid3.cap-top > div > div > .select,.grid2.cap-top > div > div > .select{order:2}
/* Each account box brings a slot for the account's balance and one for the tick
   beside it.  They are inserted straight after the caption, which is right when the
   caption is BESIDE its box and wrong when it is above it - there they came out
   between the caption and the box, and pushed the drop downs 23px below the inputs
   beside them.  Sent below the box instead of hidden, so the figure is still read.
   The caption and the box carry no order of their own, so they keep the order they
   are written in and these two simply follow. */
/* same: order only, no reserved height and no margin */
.grid3.cap-top > div > .bal-hint,.grid2.cap-top > div > .bal-hint{order:1}
.grid3.cap-top > div > .ic-ok,.grid2.cap-top > div > .ic-ok{order:3;margin-top:2px}
/* and the plain boxes here, for the same reason as on the expense and asset sheets:
   the figure carries order:1, and in a flex column that only lands it ABOVE a box
   ordered 2 or later.  .ic was ordered; .input and .select were not, so they
   defaulted to 0 and were painted first - which put an empty spacer UNDER the Date,
   Invoice and Amount boxes on the sale, sales-return and purchase forms. */
.grid3.cap-top > div > .input,.grid2.cap-top > div > .input,.grid3.cap-top > div > .select,.grid2.cap-top > div > .select{order:2}
/* the account search box is measured to the same height, so the six boxes across
   these two forms are one size */
/* 34px, to match the box it sits against.  It was 32px, which is a visible step down
   beside a 34px box on the same row. */
.grid3.cap-top > div .ic,.grid2.cap-top > div .ic{width:100%;height:var(--zb-box)}
/* 34px - the same as every other box on the form.  It was 30px with a 28px line-height,
   which is what the three account pickers on the Purchase form were still showing after
   everything else had been brought up to size.  THIS rule is (0,4,1), so it beats both
   .grid3 > div .ic-t at (0,2,1) and .grid3 > div.pay .ic-t at (0,2,2): the earlier
   attempt set the height on the lower-specificity rule, lost, and the form came out at
   30px looking as though nothing had been done.

   No explicit line-height now.  With border-box, 34px less 8px of padding top and
   bottom and 1px of border leaves 23px of content, and a line-height pinned to the old
   box height is what puts the text high in a taller one.  The padding centres it. */
.grid3.cap-top > div .ic .ic-t,.grid2.cap-top > div .ic .ic-t{height:var(--zb-box);padding:var(--zb-box-pad-y) 26px var(--zb-box-pad-y) 10px}
/* THE IMPORT BUTTON, made to the height of every other box on the form so it sits in the
   row with the Memo rather than above or below it.  The shop asked for uniform box heights
   on this form, and a button that is not one of those heights breaks the row it is in. */
/* THE CAPTION ON THIS ROW, at the size the shop asked for.  This row is shared by the
   Purchase, the Sale and the Sales Return, and all three were asked for 16px - so the rule
   names .ma-row rather than the Purchase form, because a rule written for one of the three
   would leave the other two showing an 11.5px caption beside a 16px one a few pixels away. */
.ma-row>div>label{font-size:16px;font-weight:800;letter-spacing:.2px;text-transform:uppercase}
.ma-row>div>.memo,.ma-row>div>.pf-xls{height:var(--zb-box)}
.pf-xls{width:100%;height:var(--zb-box);padding:0 12px;font-size:13.5px;
  display:flex;align-items:center;justify-content:center;gap:6px;
  background:#fff;border:1px solid #d0d5dd;border-radius:8px;cursor:pointer;
  font-weight:600;color:#344054}
.pf-xls:hover{background:#f2f4f7}
.pf-xls:disabled{opacity:.6;cursor:default}
/* ---------- the journal keeps its own shape ----------
   The caption above its box, and the currency in a box of its own, is the form
   the shop knows.  The side captions are for the other forms, so the journal is
   put back here - which is where it was before the whole programme was put on
   one reading rule, and where it belongs: it is the one screen the shop has
   specified in detail, and this is the shape it asked for. */
/* The clause list is repeated on each of these on purpose.  Every :not() counts
   towards how specific a rule is, so the rule these have to beat - which grew a
   clause when the expense cells were taken out of it - is now the stronger of
   the two.  Repeated here, the journal wins outright instead of by luck of the
   order the two happen to be written in.

   Each selector is on ONE line, however long it looks.  A line break inside a
   selector is whitespace, and whitespace inside a selector is a descendant
   combinator: broken for tidiness, these asked for something that does not
   exist and matched nothing at all. */
.jn-wrap.jn-wrap div:has(>label):not(:has(>label~label)):not(.toolbar):not(.exp-cell):not(.ast-cell):not(:has(table)){display:block;direction:inherit}
.jn-wrap.jn-wrap div:has(>label):not(:has(>label~label)):not(.toolbar):not(.exp-cell):not(.ast-cell):not(:has(table))>label{display:block;float:none;max-width:none;margin:8px 0 3px;text-align:left;font-size:14px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;color:#344054;padding-left:1px}
.jn-narr.jn-narr{display:block}
.jn-narr.jn-narr .jn-wrap.jn-wrap div:has(>label):not(:has(>label~label)):not(.toolbar):not(.exp-cell):not(.ast-cell):not(:has(table))>label{display:block;max-width:none;margin:8px 0 3px;text-align:left;font-size:14px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;color:#344054;padding-left:1px}
.jn-narr.jn-narr>textarea{flex:none;width:100%}

/* ---- DARK NAVY TOP BAR: always visible, never replaced ----
   #0f172a, grey links, teal for hover and for the page you are on. */
.nav{background:#0f172a;color:#fff;position:sticky;top:0;z-index:70;display:flex;align-items:stretch;
  min-height:60px;box-shadow:0 2px 10px #0f172a33;padding:0 6px}
/* the wordmark: white, bold, italic - the brand on the bar, as asked for. */
.nav-logo{display:flex;align-items:center;gap:9px;padding:0 16px 0 10px;font-weight:800;font-style:italic;
  font-size:15.5px;letter-spacing:.6px;color:#fff;white-space:nowrap;cursor:pointer;border-right:1px solid #ffffff1f}
.nav-logo .nav-logo small{display:block;font-size:9.5px;font-weight:600;color:#94a3b8;letter-spacing:1.6px;text-transform:uppercase}
.nav-menu{display:flex;align-items:stretch;margin-left:6px}
.nav-item{position:relative;display:flex;align-items:stretch}
/* ---- ONE LOOK FOR EVERY NAME IN THE BLACK BAR ----
   Reports was drawn as an <a> while System, HRM, Accounts and Stock are <button>s, and
   the anchor inherited the browser's own link colour and its own idea of a font size.
   The result was one word in the bar in a different colour and a different size from the
   four beside it, and the bar read as though Reports belonged to somebody else.

   An anchor with class nav-btn is therefore given the button's own appearance here:
   the same slate, the same weight, the same size, the same padding, the same underline
   and the same hover and focus behaviour.  The element stays an anchor because the
   Reports link has to be a real link - middle-click and right-click have to work on it -
   so this is the anchor made to LOOK like the buttons rather than the link behaviour
   taken away.  underline:none on the resting state is the part that mattered most: a
   link is underlined by default, and the buttons never were. */
.nav-btn,.nav-btn:link,.nav-btn:visited{background:none;border:0;border-bottom:3px solid transparent;
  color:#94a3b8;text-decoration:none;font-family:inherit;font-size:14px;font-weight:600;
  padding:0 17px;cursor:pointer;display:flex;align-items:center;gap:7px}
.nav-btn:hover,.nav-btn:link:hover,.nav-btn:visited:hover{background:#2dd4bf1f;color:#2dd4bf}
.nav-btn:focus-visible,.nav-btn:link:focus-visible{outline:2px solid #2dd4bf;outline-offset:-3px;color:#2dd4bf}
.nav-drop button:focus-visible,.nav-drop a:focus-visible{outline:2px solid #1570ef;outline-offset:-2px;background:#eff8ff}
.nav-item:not(.open) .nav-drop{visibility:hidden}
.nav-item.open>.nav-btn{background:#2dd4bf24;color:#2dd4bf;border-bottom-color:#2dd4bf}
.nav-btn.current{color:#2dd4bf;border-bottom-color:#2dd4bf}
.nav-drop{display:none;position:absolute;top:100%;left:0;min-width:262px;background:#fff;
  border:1px solid #e4e7ec;border-top:0;border-radius:0 0 10px 10px;box-shadow:0 14px 34px #0b0f1926;
  padding:6px 0;z-index:75;max-height:78vh;overflow:auto}
.nav-item.open .nav-drop{display:block}
.nav-drop .dd-title{padding:9px 16px 5px;font-size:10.5px;letter-spacing:1.1px;color:#98a2b3;
  font-weight:800;text-transform:uppercase}
.nav-drop button,.nav-drop a{display:flex;text-decoration:none;color:inherit;width:100%;text-align:left;align-items:center;gap:9px;padding:9px 16px;
  background:none;border:0;color:#344054;font-family:inherit;font-size:13.5px;cursor:pointer}
.nav-drop button:hover,.nav-drop a:hover{background:#f2f4f7;color:#16a34a;font-weight:700}
.nav-drop button.on,.nav-drop a.on{background:#f2f4f7;color:#16a34a;font-weight:700;box-shadow:inset 3px 0 0 #16a34a}
.nav-drop button .ic,.nav-drop a .ic{width:20px;text-align:center}
.nav-drop button .sub,.nav-drop a .sub{display:block;font-size:11px;color:#98a2b3;font-weight:400}
/* second level: opens beside the first, on document.body so nothing clips it */
.nav-sub{position:fixed;z-index:80;display:none;background:#fff;border:1px solid #e4e7ec;border-radius:10px;min-width:280px;padding:7px 0;max-height:70vh;overflow:auto;box-shadow:0 18px 44px #0b0f1933}
.nav-sub.show{display:block}
.nav-sub button,.nav-sub a{display:flex;text-decoration:none;color:inherit;width:100%;text-align:left;align-items:center;gap:9px;
  padding:9px 16px;background:none;border:0;color:#344054;font-family:inherit;
  font-size:13.5px;cursor:pointer}
.nav-sub button:hover,.nav-sub a:hover{background:#f2f4f7;color:#111827}
.nav-sub button .ic,.nav-sub a .ic{width:20px;text-align:center}
.nav-sub button .sub,.nav-sub a .sub{display:block;font-size:11px;color:#98a2b3;font-weight:400}
.nav-sub button:focus-visible,.nav-sub a:focus-visible{outline:2px solid #1570ef;outline-offset:-2px;background:#eff8ff}
/* a row that leads to the second level */
.nav-drop .has-sub{position:relative;background:#f9fafb}
.nav-drop .has-sub:hover,.nav-drop .has-sub.on{background:#eef2f6}
.nav-right{margin-left:auto;display:flex;align-items:center;gap:8px;padding:0 8px;
  position:relative}
/* THE COMPANY SHORT NAME, on the bar itself, in teal.  It sits ahead of the icons so the
   name is read first and the buttons are still where the hand expects them. */
.nav-co{color:#2dd4bf;font-size:13px;font-weight:700;letter-spacing:.1px;white-space:nowrap;
  padding:0 8px 0 4px;max-width:340px;overflow:hidden;text-overflow:ellipsis}
.nav-company{text-align:right;line-height:1.3;margin-right:4px}
.nav-company b{display:block;font-size:12.5px;color:#e2e8f0;font-weight:700}
.nav-company small{display:block;font-size:10px;color:#94a3b8;letter-spacing:.7px;text-transform:uppercase}
.icon-btn{background:#ffffff14;border:1px solid #ffffff1f;color:#e2e8f0;width:36px;height:36px;
  border-radius:9px;cursor:pointer;font-size:15px;display:flex;align-items:center;justify-content:center}
.icon-btn:hover{background:#ffffff2e;color:#fff}
.icon-btn.on{background:#22c55e;border-color:#22c55e;color:#04121f}
/* the black bar stays put; only the area under it moves */
html,body{height:100%}
body{overflow:hidden}
#app{height:100vh;display:flex;flex-direction:column;overflow:hidden}
.nav{flex:0 0 auto;position:relative;top:auto}
/* the content area below the bar: a soft grey-blue so white cards read as cards */
.main{flex:1 1 auto;overflow:auto;min-height:0;padding:20px 22px 40px;background:#eceefb;
  scrollbar-gutter:stable}
.nav-breadcrumb{display:flex;align-items:center;gap:8px;font-size:12px;color:#667085;margin:-4px 0 12px}

/* ==================== PAGE HEADER & ADD BUTTON ==================== */
.page-header{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin:0 0 16px;padding:0 4px}
.page-header-left{display:flex;align-items:flex-start;gap:12px;flex:1;min-width:0}
.page-header h2{margin:2px 0 0;font-size:22px;font-weight:800;color:#111827;letter-spacing:-.2px}
.page-add-btn{width:40px;height:40px;border-radius:8px;background:#f59e0b;color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:24px;font-weight:700;line-height:1;box-shadow:0 2px 8px #f59e0b40;transition:background .15s,transform .1s,box-shadow .15s;flex-shrink:0}
.page-add-btn:hover{background:#d97706;transform:translateY(-1px);box-shadow:0 4px 12px #f59e0b60}
.page-add-btn:active{transform:translateY(0)}
.page-add-btn:focus-visible{outline:2px solid #f59e0b;outline-offset:2px}
@media(max-width:640px){.page-header{flex-direction:column;align-items:stretch}.page-add-btn{width:100%}}
/* the two halves of My Profile */
.sec-head{display:flex;align-items:center;gap:9px;margin:0 0 14px;padding:0 0 8px;
  border-bottom:2px solid #111827}
.sec-head .sec-ic{width:26px;height:26px;border-radius:7px;background:#111827;color:#fff;
  display:flex;align-items:center;justify-content:center;font-size:12px}
.sec-head b{font-size:12.5px;font-weight:800;letter-spacing:1.1px;text-transform:uppercase;color:#111827}
.sec-head small{font-size:11.5px;color:#98a2b3;margin-left:2px}
.sec-block{margin:0 0 26px}
.sec-block.locked .input{background:#f9fafb;color:#475467}
/* one banner row per document kind */
.bnr-row{display:grid;grid-template-columns:minmax(150px,1.1fr) 1fr 1fr;gap:14px;
  align-items:start;padding:14px 0;border-bottom:1px solid #f2f4f7}
.bnr-row:last-child{border-bottom:0}
.bnr-name{font-weight:700;color:#111827;font-size:13.5px;padding-top:22px}
.bnr-slot label{font-size:11px;font-weight:800;color:#667085;text-transform:uppercase;
  letter-spacing:.4px;margin:0 0 5px}
.bnr-pick{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.bnr-pick .file-btn{height:30px}
.bnr-have{display:flex;align-items:center;gap:7px;margin-top:7px}
.bnr-have img{max-height:46px;max-width:150px;border:1px solid #e4e7ec;border-radius:6px;
  background:#fff}
.bnr-have a{font-size:11.5px;color:#111827;text-decoration:none;border-bottom:1px dotted #98a2b3}
.bnr-none{font-size:11.5px;color:#98a2b3;margin-top:8px}
.bnr-head{display:grid;grid-template-columns:minmax(150px,1.1fr) 1fr 1fr;gap:14px;
  padding:0 0 8px;border-bottom:2px solid #111827;margin-bottom:4px}
.bnr-head span{font-size:10.5px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;
  color:#98a2b3}
/* the roles the shop defines */
.role-row{display:grid;grid-template-columns:minmax(160px,1fr) minmax(200px,1.6fr) 120px 150px;
  gap:12px;align-items:center;padding:12px 0;border-bottom:1px solid #f2f4f7}
.role-row:last-child{border-bottom:0}
.role-row .r-name{font-weight:700;color:#111827;font-size:13.5px}
.role-row .r-desc{font-size:11.5px;color:#98a2b3;display:block;margin-top:2px}
.role-mods{display:flex;flex-wrap:wrap;gap:4px}
.role-mod{font-size:10.5px;font-weight:700;background:#eef2f6;color:#344054;
  border-radius:5px;padding:3px 7px;letter-spacing:.2px}
.role-mod.all{background:#111827;color:#fff}
.role-n{font-size:12px;color:#475467}
.role-act{display:flex;gap:6px;justify-content:flex-end}
.perm-grid{border:1px solid #e4e7ec;border-radius:9px;overflow:hidden;margin-top:6px}
.perm-grid .phead{display:grid;grid-template-columns:1fr 96px 96px;gap:8px;padding:9px 12px;
  background:#f9fafb;border-bottom:1px solid #e4e7ec}
.perm-grid .phead span{font-size:10.5px;font-weight:800;letter-spacing:.5px;
  text-transform:uppercase;color:#98a2b3}
.perm-grid .phead span:nth-child(n+2){text-align:center}
.perm-grid .prow{display:grid;grid-template-columns:1fr 96px 96px;gap:8px;align-items:center;
  padding:9px 12px;border-bottom:1px solid #f2f4f7}
.perm-grid .prow:last-child{border-bottom:0}
.perm-grid .prow:hover{background:#fcfcfd}
.perm-grid .prow b{font-size:12.5px;color:#111827;font-weight:700}
.perm-grid .prow small{display:block;font-size:11px;color:#98a2b3;font-weight:400;margin-top:1px}
.perm-grid .pcell{text-align:center}
.perm-grid input{width:16px;height:16px;accent-color:#111827;cursor:pointer}
.perm-grid .nowrite{color:#c0c4cc;font-size:15px}
.perm-note{font-size:11.5px;color:#667085;background:#f9fafb;border-left:3px solid #111827;
  padding:8px 11px;border-radius:0 7px 7px 0;margin-top:10px}
.nav-breadcrumb b{color:#111827}
@media(max-width:1080px){.nav-company{display:none}.nav-co{display:none}}
@media(max-width:820px){.nav-btn{padding:0 10px;font-size:13px}.nav-logo small{display:none}}

/* ---- full-screen page heading ---- */
.page-head{margin:0 0 14px}
/* THE FULL COMPANY NAME AS THE PAGE HEADER.  A wide white card sitting immediately
   under the top bar, the name centred in it and given room above and below, so it is
   read before the eye reaches any figure.  It leads the Dashboard and leads it alone -
   every other screen keeps the page-head it has. */
.hero-card{background:#fff;border:1px solid #e4e7ec;border-radius:16px;
  box-shadow:0 6px 22px #0f172a12;padding:52px 24px;margin:0 0 18px;
  display:flex;align-items:center;justify-content:center;text-align:center}
.hero-card h1{margin:0;font-size:38px;line-height:1.25;font-weight:800;color:#0f172a;
  letter-spacing:-.6px;word-break:break-word}
@media(max-width:760px){.hero-card{padding:34px 16px}.hero-card h1{font-size:27px}}
.page-head h2{margin:0 0 4px;font-size:22px;font-weight:800;color:#111827;letter-spacing:-.2px}
.page-head p{margin:0;color:#667085;font-size:13px}

/* ---- top filter bar ---- */
.rf-bar{padding:14px 16px;margin-bottom:16px}
.rf-row{display:flex;gap:14px;align-items:flex-end;flex-wrap:wrap}
.rf-fld{min-width:150px}
.rf-fld label{margin:0 0 4px}
.rf-apply{min-width:auto}
.rf-presets{display:flex;gap:5px;flex-wrap:wrap}
.rf-presets .btn{padding:9px 11px}

/* ---- report / dashboard columns ---- */
.rgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:14px;align-items:start}
/* The reports, one after another down the page - a list to work through, not a
   wall of cards to choose between. */
.rgrid-2{grid-template-columns:repeat(auto-fit,minmax(380px,1fr))}
.rgrid-3{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.rcol{background:#fff;border:1px solid #e4e7ec;border-radius:12px;overflow:hidden;
  box-shadow:0 1px 3px #1018280f;margin-bottom:14px}
.rcol-head{display:flex;align-items:center;gap:9px;padding:12px 14px;background:#f9fafb;
  border-bottom:1px solid #e4e7ec}
.rcol-head b{font-size:14px;color:#111827;flex:1}
.rcol-ic{font-size:15px}
.rcol-n{background:#111827;color:#fff;border-radius:20px;padding:1px 9px;font-size:11.5px;font-weight:700}
.dot{width:9px;height:9px;border-radius:50%;flex-shrink:0}
.dot.grn{background:#067647}.dot.amb{background:#b45309}.dot.red{background:#b42318}
.dot.pur{background:#5925dc}.dot.teal{background:#0e7c86}

/* THE DAILY SALES & PROFIT SUMMARY.  Its own classes, so it cannot lose a fight with a
   rule written for the transaction tables - which is what happened once today when a
   (0,2,0) rule lost to (0,3,1) on the purchase form and a whole height change became a
   no-op while looking applied. */
.dsp-sum{background:#fff;border:1px solid #e4e7ec;border-radius:12px;padding:16px 18px;
  margin:0 0 16px;box-shadow:0 1px 2px rgba(16,24,40,.05)}
.dsp-sum-h{font:800 11.5px/1 'Segoe UI',Arial,sans-serif;letter-spacing:.4px;
  text-transform:uppercase;color:#667085;margin-bottom:12px}
.dsp-sum-r{display:flex;justify-content:space-between;align-items:baseline;gap:16px;
  padding:7px 0;border-bottom:1px solid #f2f4f7}
.dsp-sum-r:last-of-type{border-bottom:0}
.dsp-sum-r span{font-size:13.5px;color:#344054}
.dsp-sum-r b{font-size:14.5px;font-weight:800;color:#1f2933;text-align:right;
  direction:ltr;unicode-bidi:isolate;white-space:nowrap}
.dsp-sum-r b.grn{color:#027a48}
.dsp-sum-r b.red{color:#b42318}
.dsp-sum-r b.blu{color:#175cd3}
.dsp-sum-r b.teal{color:#0e7090}
.dsp-note{margin-top:12px;padding-top:10px;border-top:1px dashed #e4e7ec;
  font-size:11.5px;color:#667085;line-height:1.5}
@media print{.dsp-sum{box-shadow:none}}

/* ==================== DEBIT / CREDIT VOUCHER ====================
   One line against one account: date, mode, account, currency, Debit or Credit, amount,
   narration.  Saved, the form empties itself and stays exactly where it is - no redirect,
   no dashboard, so the next voucher can be typed straight away.

   THE ACCOUNT LIST IS EVERY ACCOUNT.  The Expense form's picker is filtered to money
   accounts; this one deliberately is not, because a voucher against a customer or an expense
   account is precisely what it is for.

   NO SUB-TEXT UNDER THE ACCOUNT BOX.  The "v Cash in Safe" line the account combos draw is
   hidden file-wide by a single rule, so it cannot come back on this form either.

   THE BALANCE ABOVE THE AMOUNT, in the shop's own style: 14px, bold, red, pulsing.  It is
   fetched for the account AND currency chosen - one currency bucket only, never converted,
   so the figure shown is the figure that will be posted.  It stops the moment the shop
   clicks in the Amount or types in it, because a figure that keeps pulsing after it has been
   answered is worse than one that never pulsed.

   42px, not 34px.  This form was specified at 42 to 45 and the transaction forms were
   specified smaller; they are different forms and they carry their own height. */
.vc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px 20px}
/* ---------- EVERY CAPTION ABOVE ITS OWN BOX ----------
   Two things were wrong and only one of them was visible.

   The visible one: .vc-cell was already flex-direction:column, so the caption WAS above
   its box on paper, and it still came out beside it.  div:has(>label)... in the shared
   block above sets flex-direction:ROW on any div holding exactly one label, and it
   carries the specificity of every class inside all seven of its :not() conditions - so it
   beat .vc-cell however this rule was written.  .vc-cell is now named in that rule's
   :not() list, which is the same way the expense and asset sheets are kept out of it, and
   which is the only thing that works against a selector of that weight.

   The other one is the size.  13.5px in #374151, not the 12px in #344054 this carried: a
   caption you have to lean in to read is not a caption, and #374151 is the dark grey the
   journal form was specified in.  Bold, uppercase and starting where its box starts are
   unchanged; the 7px gap is the middle of the 6-to-8 asked for, and is the same gap the
   journal's own .cap-top rule uses. */
.vc-cell{display:flex;flex-direction:column;gap:7px}
.vc-cell>label{flex:none;font-size:13.5px;font-weight:800;letter-spacing:.4px;
  text-transform:uppercase;color:#374151;margin:0;padding-left:1px;text-align:left;
  /* still reads in its own direction, so a Pashto caption is not laid out backwards
     inside itself */
  unicode-bidi:plaintext}
.vc-cell>.input,.vc-cell>.select{width:100%;height:43px;padding:8px 12px;font-size:13.5px;
  background:#fff;border:1px solid #d0d5dd;border-radius:8px}
.vc-cell.wide{grid-column:1/-1}
/* ---------- THE BUTTONS, BOTTOM RIGHT, IN THE JOURNAL'S FOOT SCALE ----------
   38px tall, 0 16px of padding.  It was a plain .btn-primary at 9px 14px, which on this
   form came out around 40px tall - taller than every box above it and the loudest thing on
   the page, on a form whose boxes are 43px.  The journal's own footer runs at 30px on a
   30px box, so 38px here is that scale at this form's size, and it is the number the shop
   asked for (36-to-40).

   ITS OWN RULES, NOT A CHANGE TO .btn.  .btn is shared by every screen in the program and
   resizing it here would resize every button in it.  Same reason .vc-foot .btn is written
   rather than .btn: this is the one form being changed. */
.vc-foot{grid-column:1/-1;display:flex;justify-content:flex-end;align-items:center;
  gap:10px;margin:4px 0 0}
.vc-foot .btn{height:38px;padding:0 16px;font-size:13px;display:inline-flex;
  align-items:center;gap:6px}
.btn-vc-save{background:#14b8a6;color:#fff;border-color:#14b8a6}
.btn-vc-save:hover{background:#0d9488;border-color:#0d9488}
/* BACK IS THE SMALLER OF THE TWO, and says so in its own rule rather than by putting a
   shared .btn-sm class on it: .vc-foot .btn above sets 38px on both, and that is the rule
   that would have to be beaten.  30px here is the height the journal's Cancel runs at, so
   the pair reads the way the journal's pair reads - Save is the one you press. */
.vc-foot .vc-back{height:30px;padding:0 12px;font-size:12.5px}
.vc-back{background:#b42318;color:#fff;border-color:#b42318}
.vc-back:hover{background:#912018;border-color:#912018}
.vc-ic{font-size:13px;line-height:1}
/* THE BALANCE, directly above the Amount box, in the shop's own CSS. */
.vc-bal{font-size:14px;font-weight:bold;color:#dc2626;margin-bottom:6px;
  animation:blink-animation 1.5s infinite}
.vc-bal.done{animation:none;opacity:.55}
@media print{.vc-bal{animation:none}}

/* ---- clickable light-gray row ---- */
.rrow{display:flex;align-items:center;gap:10px;padding:11px 14px;background:#f9fafb;
  border-bottom:1px solid #f2f4f7;cursor:pointer;font-size:13.5px;color:#344054;
  transition:background .12s,padding-left .12s}
.rrow:last-child{border-bottom:0}
.rrow:hover{background:#f2f4f7;padding-left:18px;color:#111827}
.rrow-ic{width:26px;height:26px;border-radius:7px;background:#fff;border:1px solid #e4e7ec;
  display:flex;align-items:center;justify-content:center;font-size:13px;flex-shrink:0}
.rrow-lbl{flex:1;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rrow-go{color:#98a2b3;font-size:12px;font-weight:700;white-space:nowrap}
.rrow:hover .rrow-go{color:#111827}
.rnone{padding:14px;color:#98a2b3;font-size:13px;text-align:center;background:#f9fafb}

/* ---- dashboard tiles ---- */
.dgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-bottom:16px}
.dgrid-4{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
/* The dashboard now asks one question per row, so the rows are sized to their contents
   rather than to a fixed four-across: three day's figures on one row, two stock figures
   on the next.  Same tile, same look - only the column count is different. */
.dgrid-3{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.dgrid-2{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}

/* A DAY THAT MADE A LOSS, MARKED ONCE.  Six cycles and then it stops for good: a figure
   that flashed forever would be something the shop learned to scroll past, which is worse
   than not marking it at all.  It is a nudge, not an alarm. */
@keyframes dashLoss{0%,100%{background:#fff}50%{background:#fef3f2}}
.dtile.loss{color:#b42318}
.dtile.loss .dtile-val{color:#b42318}
/* A PROFIT IS GREEN, so "the day made money" and "the day lost money" are told apart by
   the figure itself and not only by the words underneath it.  The pair of rules here and
   further down (.profit / .loss with .metric-value) are the same statement written at two
   specificities on purpose: this one holds if the heavy-weight rule is ever moved, and
   the other one holds if a tile's own colour rule is ever reintroduced above it. */
.dtile.profit .dtile-val{color:#067647}
.dtile.profit{border-left-color:#067647}
.dtile.blink-once{animation:dashLoss 1.1s ease-in-out 6;
  border-left-color:#b42318}

/* THE FINISHED ITEMS LIST.  Three columns on one line each - the code, the name, and
   the figure - so a row can be read across rather than scanned down, and the code is on
   the row because that is how the shop counts stock and orders it. */
.oos-list{display:flex;flex-direction:column}
.oos-row{display:flex;align-items:baseline;gap:10px;padding:8px 2px;
  border-bottom:1px solid #f2f4f7}
.oos-row:last-child{border-bottom:0}
.oos-code{font-size:11.5px;font-weight:700;color:#98a2b3;min-width:70px;
  font-variant-numeric:tabular-nums}
.oos-name{flex:1;font-weight:600;color:#101828;font-size:13.5px}
.oos-qty{font-size:12px;font-weight:800;color:#b42318;white-space:nowrap}
/* THE TILE ITSELF.  A white card with a dark left edge, so the row of figures reads as
   one row and each one is marked off from the next by the edge rather than by a line. */
.dtile{background:#fff;border:1px solid #e4e7ec;border-left:4px solid #111827;border-radius:10px;
  padding:13px 15px;cursor:pointer;transition:transform .12s,box-shadow .12s}
.dtile:hover{transform:translateY(-2px);box-shadow:0 6px 16px #1018281a}
.dtile.grn{border-left-color:#067647}.dtile.amb{border-left-color:#b45309}
.dtile.red{border-left-color:#b42318}.dtile.pur{border-left-color:#5925dc}
.dtile.teal{border-left-color:#0e7c86}
.dtile-top{display:flex;justify-content:space-between;align-items:center;gap:6px}
.dtile-lbl{font-size:11.5px;font-weight:700;color:#667085;text-transform:uppercase;letter-spacing:.4px}
.dtile-ic{font-size:14px;opacity:.75}
.dtile-val{font-size:20px;font-weight:800;margin:6px 0 2px;color:#111827}
.dtile.grn .dtile-val{color:#067647}.dtile.red .dtile-val{color:#b42318}
/* WHAT WENT OUT IS VIOLET, not the amber the tile's left rule still wears.  Purchases and
   inventory are the two figures that are money this shop has committed rather than money
   it has earned, so they are drawn in one colour and read as a pair; the left rule keeps
   amber so the tile is still recognisable as the purchases tile to anyone used to it. */
.dtile.amb .dtile-val{color:#5925dc}.dtile.pur .dtile-val{color:#5925dc}
.dtile.teal .dtile-val{color:#0e7c86}
.dtile-sub{font-size:11.5px;color:#98a2b3;font-weight:600}

/* ---- BOLD, NOT SHADOWED: THE FIGURES ON THIS PAGE ARE SET IN TYPE, NOT TYPED ----
   The shop asked for the metric labels and values to be read at a glance and to sit
   ON the card rather than in it: one heavy grotesque and one weight that does not
   apologise.  THE SHADOW IS GONE, which the shop then asked for twice - a figure with
   a drop shadow behind it reads as a sticker laid on top of the card rather than as
   part of it, and on a phone at arm's length the shadow is the first thing that goes
   muddy while the digits stay sharp.  Nothing else about the weight changed: the
   labels are still 800 and the figures still 900, which is what carries the type.
   The font stack stays, because the weight only reads as heavy if the face has a
   heavy to draw with.
   These rules are written at three classes so they beat the per-tile colours set
   further up (.dtile.grn .dtile-val and the rest), because the request was for ONE
   colour across every metric, not a colour per tile.  The left rule on each tile
   keeps its own colour - that is where the tile's meaning still lives - and a loss
   still blinks and still says "a loss today" underneath. */
.dtile .dtile-lbl.metric-label,.dtile .dtile-val.metric-value{
  font-family:'Inter','Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  color:#0f172a;
  text-shadow:none;
}
.dtile .dtile-lbl.metric-label{font-weight:800;letter-spacing:.5px}
.dtile .dtile-val.metric-value{font-weight:900}
/* ---- THE TWO FIGURES THE SHOP ASKED TO BE TOLD APART: PURCHASES AND NET PROFIT ----
   Every other figure on this page is one colour, so what went out and what came in
   both read as the same kind of number - and "did we sell more than we bought" and
   "did the day make money" are the two questions this page exists to answer.  So
   these two take a colour of their own and keep the heavy weight:
     money OUT = violet, the same violet as the inventory figure beside them, so the
                  two sides of a day's trading read as a pair
     PROFIT    = green, and a LOSS stays red and still blinks
   Written after the one-colour rule on purpose and at three classes, so it wins on
   order rather than on !important.  Only the VALUE takes the colour: the caption above
   it stays in the dark slate every other caption is in, because a caption is a label,
   and six labels in six colours is a page nobody can read. */
.dtile.amb .dtile-val.metric-value{color:#5925dc}
.dtile.profit .dtile-val.metric-value{color:#067647}
.dtile.loss .dtile-val.metric-value{color:#b42318}
/* THE TURN: out, swap, back in.  300ms each way inside a 3s cycle, so the figure is
   readable for most of the time and the change is seen rather than missed. */
.mrot{transition:opacity .3s ease}
.mrot.rot-fade{opacity:0}

/* ---- full screen report ---- */
/* ---------- the account ledger search box ----------
   Four boxes in a row - currency, account, the two dates - and a
   Search button.  Sized so the account box has the room it needs and the
   date boxes are exactly as wide as a date, with the button the same
   height as the boxes it lines up with. */
/* ---------- the expense form's boxes are light grey ----------
   The same quiet grey as the journal, so the figures and the words stand out
   rather than the boxes.  A box being typed in turns white, as everywhere. */
.exp-form .input,.exp-form .select,.exp-form textarea{background:#f2f4f7;
  border-color:#e4e7ec;color:#1f2933}
.exp-form .input:focus,.exp-form .select:focus,.exp-form textarea:focus{
  background:#fff;border-color:#84caff}
/* ---------- the expense sheet: captions on top, boxes all one size ----
   Two to a row, the way the paper sheet is laid out.  Every box on this form is
   the same height and the same width - text box, drop down, date, and the
   account search box alike - so the sheet reads as one grid rather than eight
   different things.  The rows have real air between them.

   Every caption sits directly above its own box and is left-aligned to that box's
   left edge.  A caption with a box beside it has to be given a fixed width or the
   boxes come out seven different sizes; a caption on top of its box needs no width
   at all, because every box is the same fraction of the same column.

   This is the same arrangement the asset sheet uses.  Both are .exp-cell and
   .ast-cell, and both are left out of the shared caption rule above - which is
   also what keeps the journal's captions above its boxes. */
.exp-form{font-family:Arial,Helvetica,sans-serif;font-size:14px}
.exp-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:22px 20px;align-items:start}
.exp-cell{display:flex;flex-direction:column;gap:6px;min-width:0}
.exp-cell.exp-wide{grid-column:1 / -1}
/* The asset sheet's Narration, on the asset sheet's own class pair.  It had the class
   in the markup and no rule anywhere, so the box sat in a quarter column with every
   other cell - the markup was right and the rendering was not, and nothing said so. */
.ast-cell.ast-wide{grid-column:1 / -1}
/* Small, bold, and starting where the box under it starts - so the caption and its
   box are visibly one thing, read down each column rather than across the row. */
.exp-cell>label{margin:0;font-size:14px;font-weight:800;letter-spacing:.4px;
  text-transform:uppercase;color:#344054;text-align:left;padding-left:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* one height for every box here, and one width: the cell fills, the box fills it */
.exp-box{flex:none;width:100%;min-width:0;height:34px;padding:0 10px;
  font-family:Arial,Helvetica,sans-serif;font-size:13px;color:#101828;
  border:1px solid #d0d5dd;border-radius:6px;background:#f2f4f7;
  line-height:32px}
select.exp-box{padding-right:30px}
.exp-box::placeholder{color:#98a2b3;font-weight:400}
.exp-box:focus{outline:none;background:#fff;border-color:#1570ef;
  box-shadow:0 0 0 3px #1570ef26}
/* the account search box is drawn by the shared widget; measured to the same
   height from here so it is not the one box of a different size */
/* The flash fades back to the box's own colour.  --jn-box is set on the journal
   for exactly this; without it here the amber would fade to white, and these two
   sheets keep their boxes grey. */
.exp-form,.ast-form{--jn-box:#f2f4f7}
.exp-form .ic{flex:none;width:100%;height:34px;border:1px solid #d0d5dd;
  border-radius:6px;background:#f2f4f7}
/* The account search box brings two note slots with it.  On the journal they sit
   above the box and are worth having; here they would take 24px of the column and
   leave this one box narrower than the six beside it, so they stay out. */
/* WAS .exp-cell>.bal-hint,.exp-cell>.ic-ok{display:none} - the figure was switched
   off on the expense sheet, so there was nothing above OR below the box to move.
   It is shown now, because all four modules were asked for. */
.exp-cell>.bal-hint{display:block;order:1;margin:0 0 3px;min-height:15px;
  line-height:15px}
.exp-cell>.ic{order:2}
.exp-cell>.ic-ok{display:block;order:3;margin-top:2px}
.exp-cell.exp-acc>.bal-hint{min-height:0;margin:0}
.exp-cell.exp-acc>.ic-ok{margin-top:0}
.exp-cell.exp-acc>.ic-ok{display:none}
.exp-cell.exp-acc{min-height:0}
/* MISSING HALF OF THE RULE, and the reason an empty spacer was landing under the
   box.  The figure has order:1, and in a flex column that only puts it above a box
   that is ordered 2 or later.  These sheets never ordered their plain boxes at all,
   so they defaulted to 0, were painted first, and left the figure - or the spacer -
   underneath.  .grid3.cap-top got this right by ordering .ic,.grid2.cap-top got this right by ordering .ic; these sheets use
   .input and .select, which nothing ordered.  Now the same order on both:
   caption 0, figure 1, box 2, tick 3. */
.exp-cell>.input,.exp-cell>.select,.exp-cell>.ic-t{order:2}
/* ---------- the asset sheet: captions on top, boxes all one size ----------
   Four to a row, two rows.  Every caption sits directly above its own box and
   is left-aligned to that box's left edge, so the eye goes down each column
   rather than across a row of words.

   The shared rule above puts a caption beside its box for every other form; the
   cells here are .ast-cell, not .exp-cell, so they are not caught by it - which
   is the same reason the journal keeps captions above its boxes. */
.ast-form{font-family:Arial,Helvetica,sans-serif;font-size:14px}
.ast-note{font-size:12.5px;color:#475467;margin:0 0 16px}
.ast-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:22px 20px;align-items:end}
.ast-cell{display:flex;flex-direction:column;gap:6px;min-width:0;position:relative}
.ast-cell>label{font-size:14px;font-weight:800;letter-spacing:.4px;
  text-transform:uppercase;color:#344054;margin:0;
  /* left-aligned to the box under it, which is what the specification asks for */
  text-align:left;padding-left:1px}
/* the red mark says required; in the same colour as everything it says nothing */
/* The required mark is the caption's own, in red - in the same colour as the
   rest of the caption it says nothing. */
.ast-req::after{content:' *';color:#d92d20;font-weight:800}
.ast-box{flex:none;width:100%;min-width:0;height:34px;padding:0 10px;
  font-family:Arial,Helvetica,sans-serif;font-size:13px;color:#101828;
  border:1px solid #d0d5dd;border-radius:6px;background:#f2f4f7;line-height:32px}
select.ast-box{padding-right:30px}
.ast-box::placeholder{color:#98a2b3;font-weight:400}
.ast-box:focus{outline:none;background:#fff;border-color:#1570ef;
  box-shadow:0 0 0 3px #1570ef26}
/* An amount figure, on either sheet, written once so the two cannot drift apart.
   Measured on the page, this is what an amount box has to come out as:

     asset af_amt   text-align left   direction ltr   unicode-bidi isolate
     expense ef_amt  text-align start  direction ltr   unicode-bidi normal   <-

   text-align:start is left in english and RIGHT in a right-to-left language, and
   unicode-bidi:normal lets a figure be reordered by whatever sits beside it.  The
   expense box had the class exp-amt and no rule, so it came out as the second one. */
.ast-amt,.exp-amt{font-weight:700;text-align:left;direction:ltr;
  unicode-bidi:isolate;font-variant-numeric:tabular-nums}
.ast-amt::-webkit-outer-spin-button,.ast-amt::-webkit-inner-spin-button,
.exp-amt::-webkit-outer-spin-button,.exp-amt::-webkit-inner-spin-button{
  -webkit-appearance:none;margin:0}
.ast-amt,.exp-amt{-moz-appearance:textfield}
/* The Paid From Account cell on the expense sheet.  A marker class with nothing
   behind it, like exp-amt was.  All it asks for is room: this shop has an account
   called NANGARHAR FABRICS and the box was cutting it off. */
.exp-cell.exp-acc .ic-t{text-align:left}
/* The two sheets the shop asked for on the Assets screen: write an asset down, and
   sell it.

   The figures at the top of each sheet are the ones the entry is built from, so they
   are set larger than the boxes below and separated from them.  A selling price means
   nothing without the book value it is measured against, and that is the whole reason
   the figure is on the sheet at all.

   THE COLOURS, and why each is what it is:
     as-book-down  a written-down asset is red.  Everywhere else a smaller figure
                   than expected is a problem; here it is the answer, so it is
                   coloured to be noticed rather than to be alarmed by.
     as-gain       green, money in.
     as-loss       red, money out.
     as-sold       a small tag on the name, so a row that has left the available
                   list is not mistaken for a row that was never there. */
.as-fig{display:flex;gap:26px;flex-wrap:wrap;margin:14px 0 20px;padding:14px 16px;
  background:#f9fafb;border:1px solid #eaecf0;border-radius:10px}
.as-fig>div{display:flex;flex-direction:column;gap:3px;min-width:0}
.as-fig label{font-size:11px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;
  color:#667085}
.as-fig b{font-size:20px;font-weight:800;color:#101828;line-height:1.15}
.as-fig .as-book-down{color:#b42318}
.as-fig .as-book{color:#101828}
/* the sentence under the boxes: what pressing Save will do, before pressing it */
.as-note{margin:4px 0 2px;padding:11px 14px;background:#fffaeb;border:1px solid #fedf89;
  border-radius:8px;font-size:13.5px;color:#93370d;min-height:20px;line-height:1.5}
.as-note b{font-weight:800}
.as-gain{color:#067647}
.as-loss{color:#b42318}
.as-worn{color:#b54708;font-weight:700}
.as-none{color:#98a2b3}
.as-book-down{color:#b42318}
.as-book{color:#101828}
/* The gain and the loss in the Asset Liquidation tables.  A GAIN OR LOSS column holding a
   bare number is read as a gain whatever its sign, so the figure carries the word in both
   cases and the colour agrees with it: green for a gain, red for a loss.  Two classes
   because the inline sentence on the form and the table cell are different markup and
   must not be able to disagree about which is which. */
.as-gain{color:#067647;font-weight:700}
.as-loss{color:#b42318;font-weight:700}
.as-lossln{color:#b42318;font-weight:700}
.as-warn{color:#b42318}
.as-sold{display:inline-block;margin-left:6px;padding:1px 6px;border-radius:4px;
  background:#fef3f2;color:#b42318;border:1px solid #fecdca;font-size:10px;
  font-weight:800;letter-spacing:.5px;vertical-align:middle}
.as-amt{font-weight:700;text-align:left;direction:ltr;unicode-bidi:isolate;
  font-variant-numeric:tabular-nums}
.as-amt::-webkit-outer-spin-button,.as-amt::-webkit-inner-spin-button{
  -webkit-appearance:none;margin:0}
.as-amt{-moz-appearance:textfield}
/* A row on the Client Balance Summary the report could not fully convert.  The shop
   is told WHICH currency had no rate, rather than being shown a total that is short
   because a figure was quietly left out.  A total that balances for the wrong reason
   is worse than one that admits it is incomplete. */
.cbs-missing{color:#b54708;font-size:12.5px;font-weight:700;white-space:nowrap}
.chk{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:#344054;
  white-space:nowrap}
.chk input{margin:0}
/* The Available Stock screen.

   The Cost Price cell is a box, not text, because it is the one figure on this
   screen the shop changes.  It is given a left edge and its own width so a column of
   them lines up, and the row says what the change is worth while it is being typed -
   the value column restates itself, so the new price can be judged against what it
   does to the stock on hand BEFORE it is saved.  Saving is still a separate press,
   because a price is not something to change by moving the cursor past a box. */
.asv-cp,.asv-sp{width:104px;text-align:left;direction:ltr;unicode-bidi:isolate;
  font-variant-numeric:tabular-nums;font-weight:700}
.asv-cp::-webkit-outer-spin-button,.asv-cp::-webkit-inner-spin-button,
.asv-sp::-webkit-outer-spin-button,.asv-sp::-webkit-inner-spin-button{
  -webkit-appearance:none;margin:0}
.asv-cp,.asv-sp{-moz-appearance:textfield}
.asv-cp.asv-changed{border-color:#f79009;background:#fffaeb}
.asv-code{color:#98a2b3;font-size:11.5px}
.asv-qty{color:#344054}
.asv-val{color:#101828}
.asv-vsp{color:#667085}
.asv-says{font-size:12px;line-height:1.45;color:#344054;min-width:210px}
.asv-says b{font-weight:800}
.asv-same{color:#98a2b3}
.asv-old{color:#98a2b3;text-decoration:line-through}
.asv-sub{color:#667085}
/* the note above the table, saying where the figures come from */
.as-note-top{margin:0 0 14px}
/* a stock value of nothing, in a column of figures, is worth noticing */
.asv-val.is-zero{color:#98a2b3}
/* ==================== THE BLINKING BALANCE GOES ABOVE ITS BOX ==================== */
/* WHY IT WAS BELOW, which is the opposite of what balSlot() intends.

balSlot() puts the slot in the DOM straight BEFORE the box:

    w.parentNode.insertBefore(slot, w);      "The figure goes ABOVE the account box"

and then two rules said otherwise:

    .grid3.cap-top > div > div > .ic,.grid2.cap-top > div > div > .ic{order:1}
    .grid3.cap-top > div > div > .bal-hint,.grid2.cap-top > div > div > .bal-hint{order:2}

In a flex column, order wins over the order things are written in.  So the figure the
code had deliberately placed above the box was painted below it, which is what the
shop reported.  The comment beside the old rule explains why it was done - the figure
had been sitting BETWEEN the caption and the box and pushing the drop downs 18px below
the inputs beside them - so it was moved the other way, and the complaint followed.

The way out of that is not to choose one or the other but to take the space the figure
needs out of the row it shares:

  - the figure is ABOVE the box again, under the caption that names it;
  - the slot has a fixed height whether or not there is anything in it, so a cell
    with a balance and a cell without one put their boxes at the SAME height and the
    row still lines up;
  - every cell in these forms gets a slot, so the reservation is the same everywhere.

That last one is why reserveBalSlots() exists: without it, the boxes in a row that
happens to have no account in it would sit higher than its neighbours, which is the
misalignment the old order was a fix for. */

/* --- the figure above the box, in the plain grid3 cap-top forms --------------- */
/* same: order only, no reserved height and no margin */
.grid3.cap-top > div > .bal-hint,.grid2.cap-top > div > .bal-hint{order:1}
.grid3.cap-top > div > .ic,.grid2.cap-top > div > .ic{order:2}
.grid3.cap-top > div > .ic-ok,.grid2.cap-top > div > .ic-ok{order:3;margin-top:2px}

/* --- and in the purchase form, which wraps each combo in a div of its own ---- */
.grid3.cap-top > div > div,.grid2.cap-top > div > div{display:flex;flex-direction:column;width:100%;min-width:0}
/* order:1 keeps the balance ahead of the box in the caption line.  NO min-height and NO
   margin: it is positioned absolutely on the caption line, so it must not claim any
   space - that claim is what put the account boxes 18px below their neighbours. */
.grid3.cap-top > div > div > .bal-hint,.grid2.cap-top > div > div > .bal-hint{order:1}
.grid3.cap-top > div > div > .ic,.grid2.cap-top > div > div > .ic{order:2}
.grid3.cap-top > div > div > .ic-ok,.grid2.cap-top > div > div > .ic-ok{order:3;margin-top:2px}

/* --- and on the expense and asset sheets, where it was switched off ----------
   These two rules hid the figure outright, so on those two sheets there was nothing
   to move: Expenses and Assets showed no balance at all.  The shop asked for all four
   modules to show it above the box, so they are shown. */
.exp-cell>.bal-hint{display:block;order:1;margin:0 0 3px;min-height:15px}
.exp-cell>.ic{order:2}
.exp-cell>.ic-ok{order:3;margin-top:2px}
.ast-cell>.bal-hint{display:block;order:1;margin:0 0 3px;min-height:15px}
.ast-cell>.ic{order:2}
.ast-cell>.ic-ok{order:3;margin-top:2px}
/* the two sheets keep their own box sizing, which is why the figure's slot is
   measured to fit rather than left to the shared rule above */
.exp-cell>.bal-hint,.ast-cell>.bal-hint{line-height:15px}

/* Every cell of these forms reserves the same height above its box, whether or not
   the cell has an account to show a balance for.  Added by reserveBalSlots() and
   only ever on a cell that has none, so a real balance is never overwritten. */
/* NO LONGER RESERVES ANYTHING.  It held 18px above the eleven account boxes so a
   balance figure would not push the box down when it appeared - and held the same 18px
   for the whole time the form was open, because a figure only appears after an account
   has been chosen.  Those boxes therefore sat 18px BELOW their neighbours, which is
   what "not in the level of Invoice No, Date, Type" describes on a form where every box
   was already the right size.  The balance is on the caption line now, so there is
   nothing to reserve and this spacer is never inserted.  Kept as a zero-height rule so
   anything that still refers to it collapses rather than opening a hole. */
.bal-slot-spacer{order:1;margin:0;height:0;min-height:0}
/* ==================== SALES RETURN, PURCHASE AND THEIR BOXES ==================== */
/* 4  WHY THE SALES RETURN FORM DID NOT MATCH THE SALES FORM.

  Every other transaction sheet - Sales, Purchase, Expenses - opens its grid as

      <div class="grid3 cap-top">

  and the Sales Return form opened its as

      <div class="grid3">

  cap-top is the class that makes the captions sit ABOVE their boxes.  Without it the
  form falls back to the shared rule, where the caption sits BESIDE the box, so the
  two forms differ in the one way the shop noticed: the label position, and with it
  the spacing and the alignment of the boxes beside each label.  Same fonts, same
  colours, same box size - and visibly a different form.  One missing word.

  Measured before the change, to be sure that was all of it:

      Sales          grid3 cap-top    gap 12px   label 12.5px/700   box 13.5px
      Sales Return   grid3            gap 12px   label 12.5px/700   box 13.5px

  Identical in every measured respect except the class.  So it is added, and nothing
  else about the form is restyled - a hand-tuned set of numbers would have been a
  guess at what the shop liked, and the shop already has a form they like.

  Purchase Return is not a separate form at all: it is a purchase_type inside the
  Purchase form, so it follows whatever the Purchase form does and needed nothing.

5  THE BOXES: LIGHT GREY, AS ASKED.

      background #f4f6f9, border 1px solid #d1d5db

  worth saying plainly, because it is not what the shop believed: EVERY box in the
  program is currently white - #fff, on .input and on .select alike - including the
  ones on the Sales form they wanted the others to match.  Measured across Sales,
  Sales Return, Purchase, Expenses and Assets: all rgb(255,255,255).

  So this does not make four forms match the rest of the program, it makes those
  four GREY and the rest still white, which is the opposite of "to match the rest of
  the software".  It is applied to the four modules named, because that is what was
  asked for, and it is scoped so it can be undone in one line or extended to the whole
  program - which is a one-word change, say the word.

  Scoped to the transaction sheets by their own grid class rather than to .input
  everywhere, because the search boxes, the report filters and the login form were
  not mentioned and turning the whole program grey on the strength of a note about
  four forms would be a change nobody asked for. */
.grid3.cap-top > div > .input,.grid2.cap-top > div > .input,.grid3.cap-top > div > .select,.grid2.cap-top > div > .select,.grid3.cap-top > div > div > .input,.grid2.cap-top > div > div > .input,.grid3.cap-top > div > div > .select,.grid2.cap-top > div > div > .select,.grid3.cap-top > div > div > .ic > .ic-t,.grid2.cap-top > div > div > .ic > .ic-t,.exp-grid .input,.exp-grid .select,.exp-grid .ic > .ic-t,.ast-grid .input,.ast-grid .select,.ast-grid .ic > .ic-t{background:#f4f6f9;border-color:#d1d5db}
.exp-grid .input:focus,
.exp-grid .select:focus,
.ast-grid .input:focus,
.ast-grid .select:focus,
.grid3.cap-top > div > .input:focus,.grid2.cap-top > div > .input:focus,.grid3.cap-top > div > .select:focus,.grid2.cap-top > div > .select:focus{background:#fff}
/* the date and number spinners are near-invisible on a tinted box and read as dirt */
.grid3.cap-top input[type=date]::-webkit-calendar-picker-indicator,.grid2.cap-top input[type=date]::-webkit-calendar-picker-indicator,.ast-grid input[type=date]::-webkit-calendar-picker-indicator,.exp-grid input[type=date]::-webkit-calendar-picker-indicator{opacity:.55}
/* the pack price, shown under the CP box when the pack is bigger than one, so the
   figure the shop thinks in - "22 per 100 GM" - is on the screen and not only in the
   item record */
.pf_cpnote{display:none;font-size:10.5px;color:#1570ef;font-weight:700;margin-top:2px;
  white-space:nowrap}
.pf_cpnote.on{display:block}

/* the cost of ONE, under the sale line's cost column: the item's own unit cost, per
   metre, per piece or per gram, so it can be read against the price list.  It does not
   move with the quantity - the row's cost is that times the quantity, which is what the
   profit and the totals work from.  Styled like the other figures on the row rather than
   like a box, because it is a figure and not something to be typed into - it comes from
   stock. */
.sf_cpline{font-size:12px;font-weight:700;color:#344054;text-align:right;
  padding:3px 6px;background:#f2f4f7;border:1px solid #e4e7ec;border-radius:6px;
  min-width:64px;cursor:default}

/* WHAT IS LEFT, under the quantity box on a sale line.  Quiet grey while the line is
   fine - it is a note, not a warning, and a warning on every line is a warning on
   none.  It turns red for the two cases that stop the sale: nothing there at all, and
   less there than the line is asking for.  That is the same distinction the save
   refusal makes, shown on the line it applies to instead of in a toast that names no
   line. */
.sf_aq{font-size:10.5px;font-weight:800;letter-spacing:.2px;color:#98a2b3;
  margin-top:3px;white-space:nowrap;text-transform:uppercase}
.sf_aq.bad{color:#b54708}
.sf_aq.none{color:#b42318}

/* the Type on the sale line: shown, not chosen, so a label and not a box that looks
   editable */
.sf_type{font-size:12px;font-weight:700;color:#344054;padding:3px 6px;
  background:#f2f4f7;border:1px solid #e4e7ec;border-radius:6px;text-align:center;
  min-width:74px;cursor:default}
.pf_type{padding:3px 6px;font-size:12px}

/* What is left, beside the item name and smaller than it.  Bold and coloured so it
   reads as information about the item rather than as more of its name.  It sits inside
   the name's <b>, so the row around it is unchanged. */
/* WHAT IS LEFT, beside the item name and smaller than it.

   The selectors name the parent because the shared rule beats this one otherwise:

       .ic-opt span   (0,1,1)   color and font-size for EVERY span in a row
       .ic-aq         (0,1,0)   one class, no element

   An element selector counts, so (0,1,1) wins and the figure came out in the shared
   grey at the shared size with no gap - measured, not read, because the rule was in
   the file the whole time and nothing said otherwise.  Naming the parent gives
   (0,2,1) and settles it in all three places the figure appears. */
.ic-opt .ic-aq,
.ic-opt b .ic-aq,
.ic-ok .ic-aq,
.search-sel .ic-opt .ic-aq{
  font-size:9px;font-weight:700;color:#1570ef;margin-left:5px;
  white-space:nowrap;letter-spacing:.1px}
/* the "selected" marker hangs off the same <b>, so it needs air from the figure
   rather than running straight on from it */
.ic-opt.on b::after{margin-left:6px}

/* the note above the Account box, from the shared asking-for-an-amount code */
/* the account search box is drawn by the shared widget; measured to this
   sheet's own height, as the expense sheet's is, or it is the one box of a
   different size on the form */
.ast-form .ic{flex:none;height:40px;border:1px solid #d0d5dd;border-radius:8px;
  background:#f2f4f7}
.ast-form .ic .ic-c{top:9px}
.ast-form .ic .ic-t{height:38px;border:0;background:transparent;font-size:14px;
  font-family:Arial,Helvetica,sans-serif;color:#101828;padding:0 10px}
.ast-form .ic .ic-t::placeholder{color:#98a2b3}
.ast-form .ic:focus-within{background:#fff;border-color:#1570ef;
  box-shadow:0 0 0 3px #1570ef26}
/* the two note slots the search box brings with it stay out of the column, or
   they take 24px and this box alone comes out narrower than the rest */
/* the same, on the asset sheet */
.ast-cell>.bal-hint{display:block;order:1;margin:0 0 3px;min-height:15px;
  line-height:15px}
.ast-cell>.ic{order:2}
.ast-cell>.ic-ok{display:block;order:3;margin-top:2px}
/* and the same on the asset sheet, for the same reason */
.ast-cell>.input,.ast-cell>.select,.ast-cell>.ic-t{order:2}
@media (max-width:1000px){
  .ast-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
/* The ledger's currency buckets.  One chip per currency the shop deals in, so a
   bucket that is not being read is still visible - reading the till in rupees and
   seeing "0.00, nothing in it" is true, but on its own it reads as though the till
   were empty of everything. */
.lg-buckets{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 4px}
.lg-buckets:empty{display:none}
.lg-bucket{display:flex;flex-direction:column;align-items:flex-start;gap:1px;
  padding:7px 11px;border:1px solid #e4e7ec;border-radius:10px;background:#fff;
  min-width:104px}
.lg-bucket.on{border-color:#1570ef;background:#eff8ff;box-shadow:0 0 0 1px #1570ef}
.lg-bucket>b{font-size:11.5px;font-weight:800;letter-spacing:.5px;color:#344054}
.lg-bucket-v{font-size:14px;font-weight:700;color:#101828;
  font-variant-numeric:tabular-nums}
.lg-bucket-n{font-size:10.5px;color:#667085}
/* THE ACCOUNT LEDGER SCREEN HAS NO PILLS, so the hover rule the shop asked for has nothing
   to attach to here.  What it has instead is this row of currency chips, and they are
   INFORMATION: they are spans, they carry no click, and a pointer cursor over something
   that cannot be pressed is a promise the page does not keep.  So they get the resting
   colour of a report pill - the same #475569 body text on #f8fafc - so the screen reads as
   part of the same family, and NO hover, because a hover on a dead chip would be the one
   place on this screen that lies about being interactive.

   The Account Ledger's own PILL on the Reports page is a normal .rpt-pill and already
   behaves exactly like Journal, Expenses and Sales - that is the consistency the shop
   asked to see, and it comes from the pill rule rather than from anything here. */
.lg-bucket{background:#f8fafc;transition:background-color .2s ease}
.lg-bucket>b{color:#475569}
/* The profit, the loss, and the two totals of a trial balance.
   Green for a profit and red for a loss, because a number that needs interpreting
   should not have to be interpreted.  The pulse is slow and gentle: enough to be
   noticed, not enough to be tiring on a figure someone reads all day. */
@keyframes finPulse{
  0%,100%{opacity:1}
  50%{opacity:.55}
}
.fin-net{animation:finPulse 2s ease-in-out infinite;font-weight:800}
.fin-profit{color:#067647;background:#ecfdf3}
.fin-loss{color:#b42318;background:#fef3f2}
.fin-total{font-weight:800;background:#f9fafb;border-top:2px solid #344054}
.fin-grand{font-weight:800;background:#f2f4f7}
.fin-check-ok{font-weight:800;color:#067647}
.fin-check-bad{font-weight:800;color:#b42318;background:#fef3f2}
.fin-warn{color:#b54708;background:#fffaeb;font-weight:700}
/* ---- THE EXPENSE BREAKDOWN, UNDER THE EXPENSES LINE ----
   Every running cost is debited to the one Expenses Module account, so the type is the
   only thing that says what the money was for - and it has to read as the DETAIL of that
   line, not as another set of accounts.  So it is indented, lighter, and set in a
   smaller weight than the account line it sits under.  The account line above it is
   marked as the head so it carries the weight, which is where the eye should start. */
.fin-break td:first-child{padding-left:26px;color:#475467}
.fin-break td{font-weight:400;font-size:13px}
.fin-break-head td{font-weight:700}
.fin-break-total td{font-weight:800;background:#f9fafb;border-top:1px solid #eaecf0}
/* A report's own figures are shown to three decimals, because that is the
   precision the shop asked for and a converted figure is rarely whole. */
.fin-row-3dp td:not(:first-child){font-variant-numeric:tabular-nums}
.exp-btns{display:flex;justify-content:flex-end;gap:10px;margin-top:18px;
  padding-top:14px;border-top:1px solid #eaecf0}
.exp-btns .btn{min-width:104px;padding:9px 18px;font-size:13.5px;font-weight:700}
@media (max-width:900px){
  .exp-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
.lg-search{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap;
  background:#fff;border:1px solid #e4e7ec;border-radius:12px;padding:14px 16px 16px}
.lg-field{display:flex;flex-direction:column;gap:5px}
.lg-field>label{font-size:10.5px;font-weight:800;letter-spacing:.5px;
  text-transform:uppercase;color:#667085}
.lg-field>label:empty{height:13px}
.lg-cur{width:104px}
.lg-acc{flex:0 0 210px;width:210px}
.lg-from,.lg-to{width:160px}
.lg-search .input,.lg-search .select{height:34px;font-size:13.5px}
/* Excel and print, on their own line under the search box */
/* the three actions, together, in one row, whatever the window is doing */
.lg-tools{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:12px 0 0}
.lg-tools .btn{height:34px;padding:0 18px;font-size:13.5px}
.lg-hint{font-size:12px;color:#98a2b3;margin-left:4px}
/* what was searched, in one line, with the currency read at a glance */
.lg-head{display:flex;align-items:center;justify-content:space-between;
  gap:14px;margin:0 0 12px;padding-bottom:11px;border-bottom:1px solid #e4e7ec}
.lg-acc-name{font-size:16px;font-weight:800;color:#101828}
.lg-period{display:block;font-size:12px;color:#667085;margin-top:2px}
.lg-cur-big{font-size:15px;font-weight:800;color:#175cd3;letter-spacing:.6px;
  background:#eef4ff;border-radius:20px;padding:5px 14px}
.lg-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:10px;margin:0 0 14px}
.lg-card{background:#fcfcfd;border:1px solid #e4e7ec;border-radius:9px;padding:10px 12px}
.lg-lbl{font-size:10px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;
  color:#667085;margin-bottom:3px}
/* the module a row came from, and the document underneath it */
.lg-mod{white-space:nowrap}
.lg-mod>b{display:block;font-size:12.5px;font-weight:800;color:#101828}
.lg-mod>span{display:block;font-size:11px;color:#98a2b3;margin-top:1px}
/* THE LEDGER IS DRAWN AS A LEDGER: a rule round every cell, so a figure can be
   followed across to its heading without the eye slipping a column - which is
   exactly what a table of debits, credits and a running balance is for.

   Scoped to .lg-table on purpose.  Every other list in the program keeps the
   single light rule under each row it has always had; only the account ledger
   asked for a grid. */
.lg-table th,.lg-table td{border:1px solid #e4e7ec}
.lg-table tfoot th{border-top:2px solid #d0d5dd;background:#f9fafb}
.lg-val{font-size:15.5px;font-weight:800;color:#101828}
.ro-bar{display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap;background:#f9fafb;
  border:1px solid #e4e7ec;border-radius:10px;padding:12px 14px;margin-bottom:14px}
.ro-bar .rf-fld{min-width:130px}
.ro-bar label{margin:0 0 3px}
/* ==================== THE REPORT HEADER AND ITS THREE BUTTONS ====================
   The three actions the shop named, always on screen, top right of every report, and the
   filter panel folded away underneath them.

   ALWAYS VISIBLE, ALWAYS THE SAME THREE, in the same colours, in the same order - so a
   report is learned once and then read without looking.  32px tall with 0 12px of padding
   and a 6px radius, side by side with an 8px gap, as specified.  They sit in the header
   rather than floating over the table because a control that moves when a scroll happens
   is a control that gets pressed by accident. */
.ro-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin:0 0 12px;flex-wrap:wrap}
.ro-acts{display:flex;align-items:center;gap:8px}
.ro-act{height:32px;padding:0 12px;border-radius:6px;border:1px solid transparent;
  font-weight:700;font-size:12.5px;color:#fff;cursor:pointer;display:inline-flex;
  align-items:center;gap:6px;line-height:1;font-family:inherit}
.ro-act:hover{filter:brightness(.94)}
.ro-act:active{filter:brightness(.88)}
.ro-act svg{width:13px;height:13px;fill:currentColor;flex:0 0 auto}
.ro-act-filter{background:#ef4444;border-color:#ef4444}
.ro-act-xls{background:#6366f1;border-color:#6366f1}
.ro-act-pdf{background:#8b5cf6;border-color:#8b5cf6}
/* The chevron says which way the panel will go, so the button is never a guess.  It is a
   separate span because the same character has to swap when the state swaps. */
.ro-chev{font-size:9px;line-height:1;opacity:.95}

/* ==================== THE FOLDED FILTER PANEL ====================
   CLOSED WHEN A REPORT OPENS.  A report is a table first and a set of controls second, and
   a strip of boxes above every table on the program pushes the figures the shop came for
   below the fold.  So the panel is collapsed by default and the shop opens it when they
   want to narrow something.

   max-height, not display:none, because the shop asked for it to SLIDE.  The value is
   generous - 420px - so a report that draws an extra box (Branch on the stock reports, the
   Account picker on the two ledgers) is never clipped part-way down its own panel. */
.ro-fpanel{max-height:0;overflow:hidden;background:#f9fafb;padding:0 20px;
  border-bottom:1px solid transparent;border-radius:10px;
  transition:max-height .3s ease,padding .3s ease,border-color .3s ease}
.ro-fpanel.open{max-height:420px;padding:20px;border-bottom:1px solid #e2e8f0}
.ro-fpanel .rf-row{display:flex;gap:14px;align-items:flex-end;flex-wrap:wrap}
.ro-fpanel .rf-fld{min-width:150px}
.ro-fpanel label{margin:0 0 5px;font-size:11.5px;font-weight:700;color:#475467;
  letter-spacing:.3px;text-transform:uppercase}
.ro-fpanel .input,.ro-fpanel .select{height:34px;border:1px solid #cbd5e1;border-radius:6px;
  padding:0 10px;font-size:13px;background:#fff}
/* The date pair sits side by side with the word between them, so "from the 3rd to the
   9th" is one object to look at rather than two boxes with no relationship drawn. */
.ro-dates{display:flex;align-items:center;gap:8px}
.ro-dates span{font-size:12.5px;color:#98a2b3;font-weight:600}
/* APPLY, in teal, at the end of the row: it is the only control on the panel that does
   anything on its own, so it is the one that is coloured. */
.ro-fapply{background:#14b8a6;color:#fff;border-color:#14b8a6}
.ro-fapply:hover{background:#0d9488;border-color:#0d9488}
.ro-fpanel .ro-fapply{height:34px;padding:0 14px;border-radius:6px;font-weight:700;
  font-size:13px;display:inline-flex;align-items:center;gap:6px;cursor:pointer}
.ro-fpanel .ro-freset{height:34px;padding:0 12px;border-radius:6px;font-weight:700;
  font-size:13px;display:inline-flex;align-items:center;gap:6px;cursor:pointer;
  background:#fff;border:1px solid #cbd5e1;color:#344054}
.ro-fpanel .ro-freset:hover{background:#f2f4f7}
@media print{.ro-fpanel,.ro-head{display:none}}

.ro-table tfoot th{background:#f9fafb;border-top:2px solid #d0d5dd;border-bottom:0;
  text-align:right;padding:9px 10px;white-space:nowrap;font-size:12.5px;color:#111827}
.ro-meta{margin-top:10px;font-size:12.5px;color:#667085;background:#f9fafb;
  border:1px solid #e4e7ec;border-radius:8px;padding:var(--zb-box-pad)}
/* THE SEARCH BOX ON A REPORT.  Styled like the other single-box inputs in the program
   (the Available Stock screen's box is the same height and the same border) so it does
   not read as a different kind of control, and the hint sits beside it rather than
   inside it - placeholder text that changes the moment you type cannot also tell you
   what the box is for once you have typed in it. */
.ro-search{display:flex;gap:10px;align-items:center;margin-bottom:12px;flex-wrap:wrap}
.ro-search .input{flex:0 1 320px;min-width:180px}
.ro-search-hint{font-size:12.5px;color:#98a2b3;font-weight:600}
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:14px;margin-bottom:20px}
.card{background:#fff;border-radius:12px;padding:16px;box-shadow:0 1px 3px #10182814;cursor:pointer;border:1px solid #e4e7ec;border-top:4px solid #111827;transition:transform .12s}
.card:hover{transform:translateY(-2px);box-shadow:0 4px 12px #1018281a}
.card .lbl{font-size:12px;color:#667085;font-weight:700;text-transform:uppercase;letter-spacing:.4px}
.card .val{font-size:22px;font-weight:800;margin-top:6px;color:#111827}
.card .afn{font-size:11.5px;color:#98a2b3;font-weight:700}
.card.grn{border-top-color:#067647}.card.grn .val{color:#067647}
.card.red{border-top-color:#b42318}.card.red .val{color:#b42318}
.card.amb{border-top-color:#b45309}.card.amb .val{color:#b45309}
.card.pur{border-top-color:#5925dc}.card.pur .val{color:#5925dc}
.card.teal{border-top-color:#0e7c86}.card.teal .val{color:#0e7c86}
.panel{background:#fff;border-radius:12px;padding:18px;box-shadow:0 1px 3px #10182814;margin-bottom:18px;border:1px solid #e4e7ec}
.panel h3{margin:0 0 14px;font-size:16.5px;color:#111827}
.table-wrap{overflow:auto;border:1px solid #d0d5dd;border-radius:10px}
table{width:100%;border-collapse:collapse;font-size:13px;border:1px solid #d0d5dd}
table.itab, table.itab th, table.itab td { border: none !important; }
th{background:#f9fafb;color:#344054;text-align:left;padding:9px 10px;border:1px solid #d0d5dd;white-space:nowrap;font-weight:700}
td{padding:8px 10px;border:1px solid #d0d5dd;white-space:nowrap}
tr:hover td{background:#f9fafb}
.empty{text-align:center;color:#98a2b3;padding:28px}
.tabs{display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap}
.tab{border:1px solid #d0d5dd;background:#fff;border-radius:8px;padding:8px 15px;font-weight:600;cursor:pointer;font-size:13.5px;color:#344054}
.tab.active{background:#111827;color:#fff;border-color:#111827}
.toolbar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:12px}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
/* 20px between columns AND 20px between rows.  It was 12px on both axes, which on a
   three-column form puts neighbouring boxes 12px apart and rows 12px apart, so the form
   reads as a single dense block with no grouping.  One gap value for both axes is what
   was asked for and it is what makes a row read as a row. */
.grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px}
.grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.totbox{background:#f9fafb;border-radius:10px;padding:12px;margin-top:12px;border:1px solid #e4e7ec}
.totline{display:flex;justify-content:flex-end;gap:18px;flex-wrap:wrap;font-size:13.5px;padding:3px 0}
/* a form opens under the black bar, which is never covered */
.modal-backdrop{display:none;position:fixed;top:60px;left:0;right:0;bottom:0;
  background:#10182888;z-index:60;align-items:flex-start;justify-content:center;
  padding:18px;overflow:auto}
.modal-backdrop.show{display:flex}
.modal{background:#fff;border-radius:14px;width:100%;max-width:860px;
  max-height:calc(100vh - 96px);overflow:auto;border:1px solid #e4e7ec}
/* a full form or report fills the whole area under the black bar, edge to edge */
.modal-backdrop.full{padding:0}
.modal-backdrop.full .modal{max-width:100%;width:100%;max-height:100%;height:100%;border-radius:0;border:0}
.modal-full{max-width:100%;max-height:100%;border-radius:0;padding:0}
.modal-head{display:flex;justify-content:space-between;align-items:center;padding:14px 18px;border-bottom:1px solid #e4e7ec;position:sticky;top:0;background:#fff}
/* 28px inside the form card - the middle of the 24-to-32 asked for, so the boxes do not
   touch the edge of the panel.  It was 18px. */
.modal-body{padding:28px}
.toast{position:fixed;bottom:20px;right:20px;z-index:99;padding:13px 18px;border-radius:10px;color:#fff;font-weight:600;max-width:340px}
.toast.ok{background:#067647}.toast.err{background:#b42318}
/* The save notice is the same toast, given room to carry three lines.  Wider than the
   plain toast because it holds a document number and an amount, and a hair taller,
   which is what makes it read as a different thing rather than as another short message
   in the corner. */
.toast-saved{max-width:420px;padding:14px 20px;line-height:1.45}
.toast-saved .ts-ref{font-weight:800;letter-spacing:.4px}
.toast-saved .ts-amt{display:inline-block;margin-top:3px;font-size:17px;font-weight:800;
  letter-spacing:.3px}
.toast-saved .ts-clear{display:block;margin-top:5px;font-size:11.5px;font-weight:600;
  opacity:.82}
.login-wrap{height:100vh;overflow:auto;display:flex;align-items:center;justify-content:center;
  background:#f5f6f8;padding:20px}
.login-card{background:#fff;border-radius:16px;padding:30px 28px;width:100%;max-width:370px;box-shadow:0 14px 40px #10182820;border:1px solid #e4e7ec}
.chip{background:#f2f4f7;padding:5px 11px;border-radius:14px;font-size:12.5px;color:#344054}
.status-badge.active{background:#067647;color:#fff}
.status-badge.inactive{background:#e5e7eb;color:#6b7280}
.status-badge:hover{filter:brightness(1.1)}
.loading{text-align:center;color:#98a2b3;padding:40px}
.ss-hint{min-height:16px;margin-top:2px}
.ss-clear{position:absolute;right:6px;top:6px;width:22px;height:22px;border:0;background:#f2f4f7;
  color:#667085;border-radius:50%;cursor:pointer;font-size:14px;line-height:1;display:flex;
  align-items:center;justify-content:center}
.ss-clear:hover{background:#e4e7ec;color:#111827}
.ss-opt{display:flex;justify-content:space-between;gap:10px;align-items:center;padding:8px 11px;
  cursor:pointer;font-size:13px;border-bottom:1px solid #f9fafb}
.ss-opt:last-child{border-bottom:0}
.ss-opt.sel{background:#f2f4f7}
.ss-opt b{font-weight:600;color:#111827}
.ss-v{color:#98a2b3;font-size:11.5px;white-space:nowrap}
.ss-none{padding:9px 11px;color:#98a2b3;font-size:12.5px}
.search-sel>input{padding-right:32px}

/* ---- invoice item selection: filter box + real list ---- */

/* ---- one invoice line, as a card (fits any window width) ---- */
.lines{display:flex;flex-direction:column;gap:7px}
.line{background:#f9fafb;border:1px solid #e4e7ec;border-radius:10px;padding:7px 9px}
.line-top{display:flex;align-items:flex-start;gap:6px}
/* the item row is the top row: font 12, compact */
.line-top .ic-t{font-size:12px;padding:5px 24px 5px 8px}
.line-top .ic-c{top:4px;width:20px;height:20px}
.line-top .ic-ok{font-size:11px;min-height:13px;margin-top:1px}
.line-top .ic-opt{font-size:12px;padding:5px 9px}
.line-top .ic-opt span{font-size:10.5px}
.line-top .ic-d .ic-opt b{font-size:12px}
.line-x{flex-shrink:0;width:24px;height:28px;border:0;background:#fee4e2;color:#b42318;
  border-radius:6px;cursor:pointer;font-size:15px;line-height:1}
.line-x:hover{background:#fecdca}
.line-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(98px,1fr));
  gap:7px;margin-top:7px}
.line-grid .input{font-size:12.5px;padding:6px 8px}
.line-grid label{font-size:10.5px}
.line-grid label{margin:0 0 2px;font-size:11px;font-weight:700;color:#667085;
  text-transform:uppercase;letter-spacing:.3px}
.line-grid .input{width:100%}
.line-calc{display:flex;align-items:flex-end;font-size:12.5px;color:#667085;
  white-space:nowrap;padding-bottom:7px}
.line-calc b{color:#111827;font-size:14px}
.line-hint{grid-column:1/-1;font-size:11.5px;color:#98a2b3;margin-top:-3px}
.line-add{width:30px;height:30px;padding:0;font-size:17px;line-height:1;font-weight:700}

/* ---- invoice top bar: small text, grouped like a real invoice ---- */
.inv-top{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;
  background:#f9fafb;border:1px solid #e4e7ec;border-radius:10px;padding:11px 13px}
.inv-top .ic-t{font-size:12px;padding:5px 24px 5px 8px}
.inv-top .ic-c{top:4px;width:20px;height:20px}
.inv-top .ic-ok{font-size:11px;min-height:13px}
.inv-top>div>label,.inv-top .lab{margin:0 0 3px;font-size:11px;font-weight:700;
  color:#667085;text-transform:uppercase;letter-spacing:.3px}
.inv-top .input,.inv-top .select{font-size:12px;padding:6px 8px}
.inv-top .auto{background:#f2f4f7;color:#475467;font-weight:600}
.inv-wide{grid-column:span 2}
/* ---- the one-time price summary, above the item list ---- */


/* ---- a short, compact field (memo, attachment) ---- */
.sm{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
/* The attachment row: a caption, a name, and a small button - one line, and as
   little of the form as it can get away with. */
/* superseded by the cell rule further down; kept only so nothing depends on the old
   figure.  The attachment is a 34px cell now and is visible whether or not a file has
   been chosen - a 0px-high control is a control you cannot find. */
.att-row{gap:7px}
.att-row>label{font-size:9.5px;letter-spacing:.5px;white-space:nowrap}
.att-row .file-btn{height:23px;padding:0 8px;font-size:10.5px;border-radius:6px}
.att-row .file-mini{height:20px;padding:0 7px;font-size:10.5px}
.att-row .file-name{font-size:11.5px;max-width:100%}
.att-row:empty{display:none}
.sm label{margin:0;font-size:11px;font-weight:700;color:#667085;text-transform:uppercase;
  letter-spacing:.3px}
.sm .input,.sm .select{font-size:12px;padding:5px 8px;height:28px}
.sm .memo{flex:1;min-width:220px;height:28px;font-size:12px;padding:5px 8px}
.file-btn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;
  border:1px solid #d0d5dd;background:#fff;border-radius:6px;cursor:pointer;font-size:12px;
  font-weight:600;color:#344054;white-space:nowrap}
.file-btn:hover{background:#f2f4f7;color:#111827}
.file-btn input{display:none}
.file-name{font-size:11.5px;color:#667085;max-width:260px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.file-name a{color:#111827}
.file-mini{height:24px;padding:0 8px;font-size:11px;border:1px solid #d0d5dd;background:#fff;
  border-radius:5px;cursor:pointer;color:#344054}
.file-mini:hover{background:#f2f4f7}
.file-mini.del{border-color:#fecdca;color:#b42318}
.file-mini.del:hover{background:#fee4e2}

/* ---- a number you can click to see the document behind it ---- */
.doc-link{color:#1570ef;font-weight:800;text-decoration:none;border-bottom:1px dashed #84caff;
  cursor:pointer;white-space:nowrap}
.doc-link:hover{color:#175cd3;border-bottom-style:solid}
/* the read-only document view */
.docview{max-width:1000px}
.docview .dv-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 14px}
.docview .dv-no{font-size:22px;font-weight:800;color:#111827;letter-spacing:.3px}
.docview .dv-title{font-size:13px;font-weight:700;color:#475467;text-transform:uppercase;
  letter-spacing:.6px}
.docview .dv-sec{margin:0 0 16px}
.docview .dv-sec h4{margin:0 0 7px;font-size:11.5px;text-transform:uppercase;letter-spacing:.7px;
  color:#667085;border-bottom:1px solid #e4e7ec;padding-bottom:5px}
.docview .kv{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:9px 16px}
.docview .kv>div{font-size:13px}
.docview .kv b{display:block;font-size:10.5px;color:#98a2b3;text-transform:uppercase;
  letter-spacing:.5px;margin-bottom:1px}
.docview .kv b.big{font-size:11.5px;color:#475467}
.docview table{width:100%;border-collapse:collapse;font-size:12.5px}
.docview table th{background:#f9fafb;padding:7px 8px;text-align:left;border:1px solid #e4e7ec;
  font-size:11px;text-transform:uppercase;letter-spacing:.4px;color:#475467}
.docview table td{padding:7px 8px;border:1px solid #eaecf0}
.docview .r{text-align:right}
.docview .tot{font-weight:800;font-size:14px;color:#111827}
.docview .ro-note{font-size:12px;color:#667085;background:#f9fafb;border:1px solid #e4e7ec;
  border-radius:8px;padding:8px 11px;margin:0 0 14px}
.docview .empty{color:#98a2b3;font-style:italic}
/* ---- the journal's status: a colour a person can read at a glance ---- */
#jnL td.jn-act{white-space:nowrap;padding:3px 6px}
#jnL td.jn-act .btn-sm{margin-right:3px}
.jn-status{display:inline-block;font-size:10.5px;font-weight:800;letter-spacing:.5px;
  text-transform:uppercase;padding:3px 9px;border-radius:20px;white-space:nowrap}
.jn-status.Posted{background:#fffaeb;color:#b54708}
.jn-status.Approved{background:#ecfdf3;color:#027a48}
.jn-status.Reversed{background:#fef3f2;color:#b42318}
.jn-status.Draft{background:#f2f4f7;color:#475467}
.jn-counts{display:flex;gap:16px;flex-wrap:wrap;margin:0 0 10px;font-size:12.5px;
  color:#475467}
.jn-counts b{color:#111827}
/* ---- the journal list, compact so it can be walked with the arrow keys ----
   Rows about a third shorter, so a screenful holds a third more journals and
   the list scrolls inside its own box instead of pushing the page about. */
#jnL{border:1px solid #e4e7ec;border-radius:10px;background:#fff}
#jnL .jn-counts{margin:0;padding:7px 12px;border-bottom:1px solid #e4e7ec;
  background:#fcfcfd;font-size:12px}
#jnL .table-wrap{border:0;border-radius:0 0 10px 10px;
  max-height:calc(100vh - 250px);overflow:auto}
#jnL table{font-size:12.5px}
#jnL th{padding:6px 9px;font-size:11px;letter-spacing:.3px}
#jnL td{padding:4px 9px;line-height:1.35}
#jnL .doc-link{font-size:12.5px}
#jnL .jn-status{font-size:9.5px;padding:2px 7px}
#jnL .btn-sm{padding:3px 8px;font-size:11.5px;border-radius:6px}
/* ---- the journal form: information on top, then two named columns ---- */
/* Kept compact on purpose: the whole form is meant to sit on one screen, so
   the narration and the Save button are both visible without scrolling. */
/* Across the page, right to the edge of the box - so each side gets half the
   screen - and short enough to sit on one screen without scrolling. */
.jn-wrap{width:100%;max-width:100%;max-height:none;overflow:visible;
  padding-right:2px}
.jn-info{border:1px solid #e4e7ec;border-radius:9px;padding:11px 16px 3px;
  background:#fcfcfd;margin:0 0 9px}
.jn-info h4{margin:0 0 8px;font-size:9.5px;font-weight:800;letter-spacing:1.1px;
  text-transform:uppercase;color:#475467}
.jn-info .jn-row{display:grid;grid-template-columns:1fr 1fr;gap:0 16px}
.jn-info .input{height:30px;font-size:12px}
/* Which side is which is in the label, not in a bar above the box. */
.jn-boxes{display:grid;grid-template-columns:48.6% 48.6%;gap:0 2.8%;
  border:1px solid #e4e7ec;border-radius:9px;background:#fff;padding:11px 16px 10px}
.jn-boxes>div{min-width:0}
.jn-cols{display:grid;grid-template-columns:1fr 1fr;gap:0 16px;align-items:end}
.jn-boxes label{display:block;font-size:12.5px;font-weight:700;color:#344054;
  text-transform:uppercase;letter-spacing:.4px;margin:8px 0 3px}
.jn-boxes .input,.jn-boxes .select{height:30px;font-size:12px;padding:0 9px}
/* The currency box is the same box as the account and the amount - the same
   width, the same height, so the two sides of the entry line up and a figure
   written into one lands in a box the size of the one beside it. */
.jn-boxes .jn-grp>.select{width:100%}
.jn-boxes .ic{width:100%}
.jn-boxes .ic-t{width:100%}
/* The account and the amount share a row, each under its own caption.  The
   amount is 12px: it is a figure, not a heading. */
.jn-boxes .input,.jn-boxes .select{font-size:12px}
/* ---------- the journal entry boxes are light grey ----------
   Every box on the form - the date, the rate, the currencies, the accounts,
   the amounts and the narration - in one quiet grey, so the writing and the
   figures are what stand out and not the boxes. */
.jn-wrap .input,.jn-wrap .select,.jn-wrap textarea,
.jn-wrap .jn-narr textarea,
.jn-wrap .ic-t{background:#f2f4f7;border-color:#e4e7ec;color:#1f2933}
.jn-wrap .input:focus,.jn-wrap .select:focus,.jn-wrap textarea:focus,
.jn-wrap .jn-narr textarea:focus,
.jn-wrap .ic-t:focus{background:#fff;border-color:#84caff}
.jn-wrap .ic{background:#f2f4f7}
.jn-wrap .ic-t::placeholder{color:#98a2b3}
/* ---- CURRENCY SETTING: THE LABEL SITS ABOVE ITS OWN BOX ----
   The rate boxes were laid out as label-beside-box, in a row 118px wide, so a label like
   "USD To AFN" was set into a fixed column and every box began at the same place whether
   its label was long or short.  On a phone that row had nowhere to go, and the label
   ended up beside rather than over its own figure - so the figure could not be read
   without counting across the gap to find which label belonged to it.

   The label is now ON TOP of its own box, full width, sitting directly above the left
   edge of the box it belongs to - the same arrangement every other form in the program
   uses, and the arrangement asked for.  The box keeps its height, its right-aligned
   figure and its greyed read-only look; only the label's position changed, and the two
   marked * still sit beside the label they belong to rather than beside the box. */
.cr-form{max-width:560px}
.cr-row{margin:0 0 13px}
.cr-row>label{display:block;flex:none;width:auto;font-size:11.5px;font-weight:800;
  letter-spacing:.5px;text-transform:uppercase;color:#475467;margin:0 0 4px;padding-left:1px}
.cr-row>.input{height:32px;font-size:14px;font-weight:700;text-align:right}
.cr-calc>.input{background:#f2f4f7;color:#475467;cursor:not-allowed}
.cr-star{color:#d92d20;font-weight:800}
.cr-chip{display:inline-block;padding:2px 9px;margin:0 4px 0 0;border-radius:20px;
  background:#eef4ff;color:#175cd3;font-size:12px;font-weight:800;letter-spacing:.4px}
.jn-boxes .jn-grp{margin:0 0 8px}
/* A figure the program writes into a box flashes, so the change is seen and
   not just read. */
/* The flash is a ring round the box, not a colour behind it, so it shows on
   a grey box as plainly as on a white one and never has to know what the box
   underneath is coloured. */
/* A thicker ring, a tint, and over a second - a thin ring on a pale grey box
   for four fifths of a second is easy to miss, and missing it means not
   knowing whether the figure was written.  The tint fades back to the box's own
   colour, so a grey box stays grey. */
.jn-wrap{--jn-box:#f2f4f7}
@keyframes jnFlash{
  0%{box-shadow:0 0 0 4px #fdb022;background-color:#fdeab7}
  30%{box-shadow:0 0 0 4px #fdb022;background-color:#fdeab7}
  100%{box-shadow:0 0 0 4px rgba(253,176,34,0);background-color:var(--jn-box,#fff)}}
/* THE INPUT NO LONGER BLINKS.  It carried a four-pixel amber ring and a cream tint, driven
   by jnFlash.  The shop asked for the TEXT to blink and the box to be left alone, so the
   animation stays defined for anything still asking for it, and nothing on a form asks. */
.jn-flash{animation:jnFlash 1.2s ease-out 1}

/* ---------- THE BLINKING LEDGER BALANCE ----------
   The shop's own CSS, applied as written: 14px, bold, red, six pixels of space under it, and
   a smooth pulse from fully opaque to 0.4 and back over a second and a half.

   THE FIGURE IS THE ONLY THING THAT MOVES.  No ring, no tint, no border and no height are
   animated, so a pulse cannot shift the box below it - which is what an animation on the input
   itself did, and the layout trouble this replaces.  opacity only: it is composited, so it is
   cheap and it cannot trigger a reflow.

   THE SHOP'S CLASS NAME IS USED AS WELL, so .ledger-balance-text is a selector in this file and
   not only a description of one.  It sits on the SAME element as bal-hint rather than beside
   it: two stacked elements would each need their height reserved, and the figure would jump
   when the other appeared. */
/* THE ACCOUNT-NAME LINE UNDER THE BOX IS GONE, ON EVERY FORM.  The shop asked for it
   removed: only the balance is to be shown, not the account name repeated under its own
   box.  It is HIDDEN rather than deleted - the combo helpers still build the element on
   six forms, and removing it would mean changing every one of them to fix code that is
   not wrong.  display:none takes no space, so nothing is reserved for it either.

   It is written here, beside the balance rule, rather than in place of the two rules
   that used to give it a line: the .grid2 duplication made those two IDENTICAL to each
   other, so matching either one finds both, and the installer reads a count of two as a
   fault.  Nothing needs to match them - one rule with !important beats both wherever
   they sit, and leaving them in place keeps the history of why they existed. */
.ic-ok{display:none !important}

/* THE SHOP'S OWN CSS, AND IT HAS TO BE ABLE TO WIN.
   Three existing rules beat the first version of this and were measured doing so - the
   figure came out 11px in grey rather than 14px in red:

     .bal-hint{font-size:12px}     (0,1,0) - the same specificity, and LATER in the file,
                                     so it won on order
     .bal-hint.recv/.pay/.cash     (0,2,0) - two classes each, so they beat a single class
                                     whatever the order.  .cash is the one the Purchase and
                                     Sales forms use, and it is where #344054 came from.

   So every competing variant is named here.  The most specific selector below is (0,2,0) and
   this rule sits after them, so it wins the tie as well as the specificity - which is the
   point the top of this style block records at length after a height that silently did not
   change while looking as though it had.

   The colour deliberately overrides the three direction classes.  That means a figure the
   shop is owed and a figure owing the shop now read the same, which is a distinction lost -
   and it is lost because the shop named one colour for both. */
.bal-hint,.bal-hint.recv,.bal-hint.pay,.bal-hint.cash,
.ledger-balance-text,.ledger-balance-text.recv,
.ledger-balance-text.pay,.ledger-balance-text.cash{
  font-size:14px;
  font-weight:bold;
  color:#dc2626;
  margin-bottom:6px;
  animation:blink-animation 1.5s infinite;
}
@keyframes blink-animation{
  0%{opacity:1}
  50%{opacity:.4}
  100%{opacity:1}
}
/* And the name the shop wrote, on its own, so a rule written against it works unchanged. */
/* The shop's class name on its own, given the same treatment so a rule written against it
   is not quietly beaten by .bal-hint.cash either. */
.ledger-balance-text,.ledger-balance-text.recv,.ledger-balance-text.pay,
.ledger-balance-text.cash{font-size:14px;font-weight:bold;color:#dc2626;margin-bottom:6px;
  animation:blink-animation 1.5s infinite}
/* 18px, as asked for, on the FLASHING AMOUNT and nothing else.
   amtAsk() flashes the box the shop still has to fill in: ef_amt on the Expense sheet and
   af_amt on the Asset sheet, which are the two classes named below.

   Not .jn-flash, which would also catch the journal's currency and rate boxes - jnFlash()
   is put on those when a currency is picked, and an 18px currency picker is not what was
   asked for.  The amount is what gets bigger.

   Room for it, checked rather than assumed: those two are .exp-box and .ast-box at 40px,
   and they are not part of the 34px family the rest of the boxes were brought down to. */
/* WAS 18px.  The amount is 14px now - it is the figure above the box that blinks, and
   this rule was setting a size on the box itself.  Left in place it would fight the new rule
   and, being the later of the two, quietly win. */
.exp-amt.jn-flash,.ast-amt.jn-flash{font-size:14px}
/* ==================== CREDIT / DEBIT NOTES ====================
   CAPTIONS ON TOP, UPPERCASE AND BOLD - the arrangement the shop asked for on the voucher
   form and set here for the same reason: a caption beside its box on a form this wide is a
   caption that has to be hunted for, and the columns here are narrow.  So each caption sits
   directly above its own box and the boxes line up in a grid.

   THE PENDING FIGURE IS THE FORM'S OWN ANSWER.  It is the one number that decides whether
   the note can be saved, so it is given the strongest of the three: red while it is
   outstanding, green when it is nothing.  Not decoration - the shop asked for the totals in
   the footer and this is the one they will watch while they work. */
.nt-wrap{display:flex;flex-direction:column;gap:16px}
.nt-head{display:flex;gap:16px;flex-wrap:wrap}
.nt-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.nt-cell{display:flex;flex-direction:column;gap:7px;min-width:0}
.nt-cell.wide{grid-column:1/-1}
.nt-cell>label{flex:none;font-size:13.5px;font-weight:800;letter-spacing:.4px;
  text-transform:uppercase;color:#374151;margin:0;padding-left:1px;text-align:left;
  unicode-bidi:plaintext}
.nt-cell>.input,.nt-cell>.select{width:100%;height:40px;padding:8px 12px;font-size:13.5px;
  background:#fff;border:1px solid #cbd5e1;border-radius:6px}
.nt-sec{border:1px solid #e4e7ec;border-radius:10px;padding:14px 16px 16px;background:#fff}
.nt-sec h4{margin:0 0 12px;font-size:11px;font-weight:800;letter-spacing:1.1px;
  text-transform:uppercase;color:#344054}
.nt-tab{width:100%}
.nt-tab td{padding:5px 6px;vertical-align:middle}
.nt-tab th{background:#f9fafb;font-size:11.5px;font-weight:800;letter-spacing:.3px;
  text-transform:uppercase;color:#475467}
.nt-tab .input,.nt-tab .select{height:38px;font-size:13px;border:1px solid #cbd5e1;
  border-radius:6px;padding:6px 10px;width:100%}
/* THE + AND THE X.  The + on every row adds another; the + on the bar under the table is
   the same action at the size of a real button, which is where a shop goes for it. */
.nt-add,.nt-del{width:28px;height:28px;border-radius:6px;cursor:pointer;font-size:14px;
  font-weight:800;line-height:1;display:inline-flex;align-items:center;
  justify-content:center;border:1px solid #cbd5e1;background:#fff;color:#344054}
.nt-add:hover{background:#14b8a6;border-color:#14b8a6;color:#fff}
.nt-del{color:#b42318;border-color:#fecdca}
.nt-del:hover{background:#b42318;border-color:#b42318;color:#fff}
.nt-addbar{display:block;width:100%;margin-top:10px;padding:11px;border-radius:8px;
  background:#14b8a6;color:#fff;border:1px solid #14b8a6;font-weight:700;font-size:13.5px;
  cursor:pointer;font-family:inherit}
.nt-addbar:hover{background:#0d9488;border-color:#0d9488}
/* A division that has an account AND an amount is marked, so a row started and not finished
   reads differently from a row not touched at all. */
.nt-tab tr.nt-done{background:#f0fdf4}
.nt-foot-tot{display:flex;gap:10px;flex-wrap:wrap;justify-content:flex-end}
.nt-tot{display:flex;align-items:center;gap:9px;background:#f9fafb;border:1px solid #e4e7ec;
  border-radius:8px;padding:9px 14px}
.nt-tot span{font-size:11.5px;font-weight:700;letter-spacing:.3px;text-transform:uppercase;
  color:#475467}
.nt-tot b{font-size:15px;color:#111827}
.nt-tot.nt-bad{border-color:#fecdca;background:#fef3f2}
.nt-tot.nt-bad b{color:#b42318}
.nt-tot.nt-ok{border-color:#a6f4c5;background:#ecfdf3}
.nt-tot.nt-ok b{color:#067647}
/* THE TWO BUTTONS, AND THEIR SIZE.  .btn-vc-save only carries a COLOUR - the size comes
   from a rule scoped to the footer that holds them, exactly as it does on the voucher form.
   Left unscoped they fall back to .btn's own 9px 14px and come out at 35px, which is a full
   size button on a form where the boxes are 40px: the loudest thing on the page.  The shop
   asked for the journal's Save size, so it is stated here: 38px and 0 16px for Save, 30px
   for Back. */
.nt-btns{display:flex;justify-content:flex-end;gap:10px;margin-top:2px}
.nt-btns .btn{height:38px;padding:0 16px;font-size:13px;display:inline-flex;align-items:center;
  gap:6px}
.nt-btns .vc-back{height:30px;padding:0 12px;font-size:12.5px}
@media (max-width:820px){.nt-grid{grid-template-columns:1fr}}

/* ---------- Advance Received: the form's own few boxes ---------- */
.arv-wide{grid-column:1/-1}
.arv-note{grid-column:1/-1;font-size:12.5px;color:#475467;min-height:17px;margin:0}
.arv-note b{color:#111827}
.arv-btns{grid-column:1/-1;justify-content:flex-end;display:flex;gap:10px;margin-top:14px}

.jn-narr{margin:0 0 3px}
.jn-narr textarea{width:100%;height:46px;min-height:38px;resize:vertical;
  font-family:inherit;font-size:12px;padding:6px 8px;border:1px solid #d0d5dd;
  border-radius:7px;background:#fff;color:#101828;line-height:1.4}
.jn-narr textarea:focus{outline:none;border-color:#84caff;box-shadow:0 0 0 3px #eff8ff}
.jn-full{margin:9px 0 0;border:1px solid #e4e7ec;border-radius:9px;padding:9px 16px;
  background:#fcfcfd}
/* the attachment line and the balance note: neither needs a box of its own */
.jn-att-row{margin:9px 0 0;padding:0 2px}
.jn-msg-row{margin:7px 0 0;padding:0 2px;min-height:16px}
.jn-foot{display:flex;justify-content:flex-end;gap:10px;margin:10px 0 0}
.jn-foot .btn{height:30px;padding:0 16px;font-size:12.5px}
@media (max-width:820px){
  .jn-wrap{width:100%}
  .jn-info .jn-row{grid-template-columns:1fr;gap:0 14px}
  .jn-boxes{grid-template-columns:1fr;gap:16px 0}
  .jn-cols{grid-template-columns:1fr;gap:0 14px}
}
/* a journal entry is two halves facing each other */
.docview .jv{display:grid;grid-template-columns:1fr 1fr;border:1px solid #e4e7ec;
  border-radius:10px;overflow:hidden;background:#fff;margin:0 0 16px}
.docview .jv-side{min-width:0}
.docview .jv-side+.jv-side{border-left:1px solid #e4e7ec}
.docview .jv-hd{font-size:11px;font-weight:800;letter-spacing:.8px;text-transform:uppercase;
  padding:9px 16px;background:#f9fafb;border-bottom:1px solid #e4e7ec;color:#475467}
.docview .jv-cr .jv-hd{background:#eff8ff;color:#175cd3}
.docview .jv-dr .jv-hd{background:#fef3f2;color:#b42318}
.docview .jv .kv{grid-template-columns:1fr;gap:11px;padding:13px 16px}
.docview .jv .kv b.big{font-size:11.5px}
.docview .jv-note{display:flex;align-items:center;gap:8px;margin:-8px 0 16px;font-size:12.5px;
  color:#475467;background:#f9fafb;border:1px solid #e4e7ec;border-radius:8px;padding:7px 12px}
.docview .jv-note.bad{background:#fef3f2;border-color:#fecdca;color:#b42318;font-weight:700}
@media (max-width:780px){
  .docview .jv{grid-template-columns:1fr}
  .docview .jv-side+.jv-side{border-left:0;border-top:1px solid #e4e7ec}
}

.grid3>div.lk-cell{display:flex;flex-direction:column;align-items:stretch;gap:4px;min-width:0}
.lk-cell>label{display:block;margin:0;font-size:11px;font-weight:700;letter-spacing:.4px;
  text-transform:uppercase;color:#344054;line-height:1.2}
/* the Module table on New Lock: all modules visible, buttons in its top band */
.lk-mods{max-height:196px;overflow:auto;border:1px solid #d0d5dd;border-radius:8px;background:#fff}
.lk-mods-head{position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  padding:5px 7px;background:#f9fafb;border-bottom:1px solid #e4e7ec}
.lk-mods-head .btn{height:24px;padding:0 9px;font-size:11px}
.lk-pickn{font-size:11px;color:#475467;font-weight:700;margin-left:auto}
.lk-pickn b{color:#111827}
.lk-mod-group{font-size:10.5px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;color:#667085;
  padding:5px 9px 2px;border-top:1px solid #f2f4f7;margin-top:2px}
.lk-mod-group:first-of-type{border-top:0;margin-top:0;padding-top:5px}
.lk-mod-row{display:flex;align-items:center;gap:7px;padding:3px 9px;cursor:pointer;
  font-size:12.5px;color:#111827;font-weight:600;text-transform:none;letter-spacing:0;margin:0}
.lk-mod-row:hover{background:#f9fafb}
.lk-mod-row.on{background:#eff8ff;color:#175cd3}
.lk-mod-row input{width:14px;height:14px;accent-color:#1570ef;cursor:pointer;margin:0}
.lk-mod-empty{padding:9px;font-size:12px;color:#b42318}
.lk-chips{margin-top:8px;display:flex;flex-wrap:wrap;gap:6px;min-height:20px}
.lk-chip{display:inline-flex;align-items:center;gap:6px;background:#eff8ff;border:1px solid #b2ddff;
  color:#175cd3;border-radius:999px;padding:3px 8px 3px 10px;font-size:12px;font-weight:700}
.lk-chip .lk-x{border:0;background:transparent;color:#175cd3;font-size:15px;line-height:1;
  cursor:pointer;padding:0 2px}
.lk-none{font-size:12px;color:#98a2b3}
/* ---- pick several rows, then delete them together ---- */
.bulk-bar{display:flex;align-items:center;gap:10px;margin:0 0 10px;padding:7px 12px;
  background:#f9fafb;border:1px solid #e4e7ec;border-radius:9px;flex-wrap:wrap}
.bulk-bar .bulk-n{font-size:12.5px;color:#475467;font-weight:600}
.bulk-bar .bulk-n b{color:#111827}
.bulk-bar .bulk-sp{flex:1}
.bulk-bar label.bulk-all{display:flex;align-items:center;gap:7px;font-size:12.5px;
  font-weight:700;color:#344054;margin:0;cursor:pointer;text-transform:none;letter-spacing:0}
table th.bulk-td,table td.bulk-td{width:38px;padding-left:10px;padding-right:0;text-align:center}
table td.bulk-td input[type=checkbox]{width:15px;height:15px;cursor:pointer;accent-color:#1570ef}
table th.bulk-td input[type=checkbox]{width:15px;height:15px;cursor:pointer;accent-color:#1570ef}
table tr.bulk-picked{background:#eff8ff}
table tr.bulk-picked:hover{background:#e1f0ff}
/* ---- one-line item row ---- */
.line-grid.one{grid-template-columns:minmax(200px,2.2fr) repeat(auto-fit,minmax(76px,1fr));
  align-items:end}
.line-grid.one>div>label{font-size:10px;text-align:center}
.line-grid.one .input{height:28px;padding:4px 6px;font-size:12px;text-align:center}
.line-grid.one .ic-t{height:28px;font-size:12px;padding:4px 22px 4px 8px;text-align:left}

/* ---- invoice item list: one line per item ---- */
.itab-wrap{overflow-x:auto;border:1px solid #e4e7ec;border-radius:9px;background:#fff}
table.itab{width:100%;border-collapse:collapse;font-size:12px;min-width:720px}
table.itab th{background:#f9fafb;color:#344054;text-align:left;padding:7px 8px;font-size:10.5px;
  font-weight:800;text-transform:uppercase;letter-spacing:.4px;
  border-bottom:1px solid #e4e7ec;white-space:nowrap}
table.itab td{padding:3px 5px;border-bottom:1px solid #f2f4f7;vertical-align:middle;white-space:nowrap}
table.itab tr:last-child td{border-bottom:0}
table.itab .c{text-align:center}
/* 34px and 5px 10px, the same as the boxes above them.  They were 26px with 3px 6px -
   a third smaller, so the items table read as belonging to a different form from the
   header sitting directly above it.  The font size stays at 12px: this is a request about
   box dimensions and not about type. */
table.itab .input,table.itab .select{height:var(--zb-box);padding:var(--zb-box-pad);font-size:12px;width:100%}
/* The Type drop down in a line is a <select>, and table.itab .input does not match it -
   so when the .input rule was given the new height the Type box was left at 30px and a
   purchase line stood a row taller than the boxes beside it.  Both elements are named
   here for that reason, and not for tidiness. */
table.itab .pf_type,table.itab .sf_type,table.itab .sr_type{
  height:var(--zb-box);padding:var(--zb-box-pad);font-size:12px;width:100%;box-sizing:border-box}
table.itab .num{text-align:right;font-weight:700;font-size:12px;padding-right:8px}
table.itab .num.pf{color:#067647}
table.itab .itemcell{width:210px;min-width:180px}
table.itab .ic{min-width:0}
table.itab .ic-t{font-size:12px;padding:var(--zb-box-pad-y) 22px var(--zb-box-pad-y) 7px;height:var(--zb-box)}
table.itab .ic-c{top:3px;width:18px;height:18px;font-size:10px}
table.itab .ic-ok{display:none}
table.itab th.del{width:38px;text-align:center}
/* 34px wide in a 34px row.  It was 28px in a 26px row and would read as a chip rather
   than a button at the end of the row the eye travels along. */
table.itab .rm{width:34px;height:var(--zb-box);border:1px solid #fecdca;background:#fee4e2;color:#b42318;
  border-radius:6px;cursor:pointer;font-size:14px;line-height:1;display:inline-flex;
  align-items:center;justify-content:center;padding:0}
table.itab .rm:hover{background:#fda29b;border-color:#f04438;color:#fff}
table.itab tr.ro td{background:#fef3f2}
table.itab tr.ro td:first-child::after{content:'not in the item list';color:#b42318;
  font-size:10px;margin-left:6px;font-weight:700}

/* ---- memo: one short line, or a bigger box when you want one ---- */
/* the memo box stays small; it never stretches across the form */
/* THE MEMO AND THE ATTACHMENT, BUILT LIKE A GRID CELL.
   They were not in the form at all: their row's parent was .modal-body rather than the
   form's grid, and they measured 24px tall and 190px wide against a grid box's 34px and
   296px, with a 10.5px grey mixed-case caption where every other caption is 11.5px,
   weight 800, uppercase.  Same geometry as a cell now - caption first in the form's own
   caption style, box beneath at 34px and the full width of its column. */
/* THE MEMO CELL, WITH ITS SELECTOR PINNED
   .ma-row .memo-box is (0,2,0) and unopposed, where the bare .memo-box at (0,1,0) was
   not: the caption line, in particular, carries properties from a later rule, and a
   property the wrong rule happens to supply is a property nobody can find.  Column
   direction puts the caption above the box, which is what every other field on the form
   does - without it the caption sat beside the box and the memo came out 231px wide in a
   296px cell, because the two shared one row. */
.ma-row .memo-box{display:flex;flex-direction:column;align-items:stretch;gap:7px;
  width:100%;min-width:0}
.ma-row .memo-box .input.memo{width:100%;height:var(--zb-box);font-size:13.5px;
  padding:var(--zb-box-pad);border-radius:8px;box-sizing:border-box;min-width:0}
/* the same pin for the attachment's file-name strip: .ma-row .file-name further down is
   (0,2,0) as well and is LATER, so it was winning with max-width:200px and
   display:inline-block on a strip that is meant to be a 34px full-width box. */
.ma-row .att-row .file-name{display:block;width:100%;max-width:100%;min-height:var(--zb-box);
  border:1px solid #e4e7ec;border-radius:8px;padding:var(--zb-box-pad);box-sizing:border-box;
  font-size:12.5px;color:#475467;background:#fff;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.ma-row .att-row .file-name:empty::before{content:'No file chosen';color:#98a2b3}
.ma-row .att-row{display:flex;flex-direction:column;align-items:stretch;gap:7px;
  width:100%;min-width:0}
.ma-row .att-row .file-btn{height:var(--zb-box);display:flex;align-items:center;
  justify-content:center;box-sizing:border-box;font-size:12.5px;padding:var(--zb-box-pad)}
.ma-row .att-row>label:first-child{margin:0;font-size:11.5px;font-weight:800;
  color:#344054;text-transform:uppercase;letter-spacing:.4px}
/* the same caption as every other field on the form */
.memo-box>label{margin:0;font-size:11.5px;font-weight:800;color:#344054;
  text-transform:uppercase;letter-spacing:.4px;
  text-transform:uppercase;letter-spacing:.4px;display:flex;align-items:center;gap:7px;padding-top:2px}
.memo-box .input.memo{width:100%;height:var(--zb-box);font-size:13.5px;padding:var(--zb-box-pad);
  border-radius:8px;box-sizing:border-box}
.memo-box textarea.memo{width:240px;height:70px;font-size:11.5px;padding:5px 7px;
  border:1px solid #d0d5dd;border-radius:6px;font-family:inherit;color:#1f2933;
  background:#fff;resize:vertical;line-height:1.45}
.memo-box textarea.memo:focus{outline:2px solid #d0d5dd;border-color:#111827}
.memo-tog{width:28px;height:28px;padding:0;display:flex;align-items:center;justify-content:center;
  border:1px solid #d0d5dd;background:#fff;border-radius:7px;cursor:pointer;
  font-size:13px;line-height:1;font-weight:800;color:#344054;flex-shrink:0}
/* Memo sits immediately in front of Attachment, both in the top right corner */
/* THE SAME THREE-COLUMN TRACK AS THE FORM, with the same 20px gap - so the memo lands
   in column one and the attachment in column two, each exactly as wide as the Invoice No
   box beside them.  It was `1fr 1fr`, which divides the full width of the card into two
   halves of 455px on a form whose columns are 296px - so the memo was a third wider than
   the box it was supposed to match.  Left aligned rather than pushed to the far edge,
   so these captions start on the same line as every other one. */
.ma-row{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;align-items:start;
  justify-content:stretch;
  flex-wrap:wrap;margin:2px 0 10px;grid-column:1/-1}
.ma-row .sm{align-items:flex-start}
.ma-row .file-name{max-width:200px;display:inline-block}
.memo-tog:hover{background:#f2f4f7;color:#111827;border-color:#b0b8c4}
.memo-tog.big{height:28px;align-self:flex-start}

/* the top header is a little shorter; payment boxes are marked .pay and keep
   their normal size, and the item table is outside .grid3 so it is untouched */
.grid3 > div > .input,.grid3 > div > .select,
/* 34px, the same as every other box on the form, and the padding the same too.  It was
   28px with 3px 8px.  The wrapper .ic has no border of its own - the INPUT is the visible
   box - so this is what the shop actually sees, and at 28px the three account pickers on
   the Purchase form stood visibly shorter than the boxes beside them.
   The right-hand padding is 26px and stays: it is what keeps the text clear of the
   little caret button. */
.grid3 > div .ic-t{height:var(--zb-box);font-size:12px;padding:var(--zb-box-pad-y) 26px var(--zb-box-pad-y) 10px}
/* the caret re-centred for the taller box: (41 - 20) / 2 is 10 */
.grid3 > div .ic-c{top:10px;width:20px;height:20px;font-size:10px}
.grid3 > div .ic-opt{font-size:12px;padding:5px 9px}
.grid3 > div > label{font-size:10.5px;margin:6px 0 2px;letter-spacing:.4px}
.grid3 > div.pay > .input,.grid3 > div.pay > .select{height:var(--zb-box);font-size:13px;padding:var(--zb-box-pad)}
.grid3 > div.pay > label{font-size:11.5px;margin:8px 0 3px;letter-spacing:.3px}
.grid3 > div.pay .ic-t{height:var(--zb-box);font-size:12.5px;padding:var(--zb-box-pad-y) 26px var(--zb-box-pad-y) 10px}
.grid3 > div.pay .ic-c{top:5px;width:20px;height:20px}

/* the account's ledger amount, centred INSIDE its own box */
/* The ledger figure, under the account box: 12px, centred, plain text.  It is
   a figure and not a heading, so it is set at the size of one. */
.bal-hint{font-size:12px;font-weight:700;letter-spacing:.2px;line-height:15px;
  margin:3px 0 0;min-height:15px;text-align:center}
/* The colour is the shop's rule for which way the money moves:
     recv  they owe the shop    - black, the figure is owed TO the shop
     pay   the shop owes them   - red, and always with a minus, because the
                                 sign is the whole point of the colour */
.bal-hint.recv{color:#101828;font-weight:800}
.bal-hint.pay{color:#b42318;font-weight:800}
.bal-hint.cash{color:#344054}          /* Cash / Bank: money on hand */
/* five seconds of blinking, then it settles */
@keyframes balBlink{0%,100%{opacity:1}50%{opacity:.15}}
.bal-hint.blink{animation:balBlink .625s ease-in-out 8}
.ic{position:relative;min-width:0;width:100%}
.ic-t{padding-right:26px}
.ic-c{position:absolute;right:4px;top:5px;width:22px;height:22px;border:0;background:#f2f4f7;
  color:#667085;border-radius:5px;cursor:pointer;font-size:11px;line-height:1}
.ic-c:hover{background:#e4e7ec;color:#111827}
/* position:fixed so the list is never clipped by a scrolling wrapper */
.ic-d{display:none;position:fixed;z-index:999;background:#fff;
  border:1px solid #d0d5dd;border-radius:8px;max-height:260px;overflow:auto;
  box-shadow:0 12px 30px #10182833}
.ic-d.show{display:block}
.ic-opt{display:flex;justify-content:space-between;gap:8px;align-items:baseline;
  padding:7px 11px;cursor:pointer;font-size:13px;border-bottom:1px solid #f9fafb}
.ic-opt:last-child{border-bottom:0}
.ic-opt:hover{background:#f2f4f7}
.ic-opt.on{background:#fef3c7;box-shadow:inset 3px 0 0 #b45309}
/* the entry the arrow is currently on */
.ic-opt.hi{background:#d1e9ff;box-shadow:inset 3px 0 0 #1570ef;color:#0b4a9e}
.ic-opt.hi b{color:#0b4a9e}
.ic-opt.on b::after{content:' \2014  selected';color:#b45309;font-weight:700;font-size:10.5px}
.ic-opt b{font-weight:600;color:#111827}
.ic-opt span{color:#98a2b3;font-size:11px;white-space:nowrap}
.ic-none{padding:9px 11px;color:#98a2b3;font-size:12.5px;display:flex;gap:8px;
  align-items:center;justify-content:space-between}
.ic-ok{margin-top:2px;font-size:11px;color:#98a2b3;min-height:14px}
.ic-yes{color:#067647;font-weight:700}
.ic-no{color:#b42318;font-weight:700}
.search-sel{position:relative}
.search-sel .ss-drop{display:none;position:absolute;top:100%;left:0;right:0;background:#fff;border:1px solid #d0d5dd;border-radius:8px;max-height:220px;overflow:auto;z-index:50;box-shadow:0 8px 20px #10182820}
.search-sel .ss-drop.show{display:block}
.search-sel .ss-opt{padding:8px 11px;cursor:pointer;font-size:13px}
.search-sel .ss-opt:hover{background:#f2f4f7}
.search-sel .ss-opt.sel{background:#f2f4f7;font-weight:700}
@media(max-width:900px){.grid2,.grid3,.grid4{grid-template-columns:1fr}.sidebar{display:none}}
/* THE BALANCE, ON THE CAPTION LINE.
   Absolutely positioned at the top right of its cell, so it occupies no vertical space:
   the caption row is one line high for every field and every box on the form sits the
   same 7px below its caption.  It is still there, still belongs to the box beside it,
   and still blinks - and because nothing is held in reserve, nothing jumps when an
   account is chosen. */
.grid3.cap-top > div,.grid2.cap-top > div{position:relative}
.grid3.cap-top > div > .bal-hint,.grid2.cap-top > div > .bal-hint,.grid3.cap-top > div > div > .bal-hint,.grid2.cap-top > div > div > .bal-hint,.grid3.cap-top > div > div > .ic-ok,.grid2.cap-top > div > div > .ic-ok,.grid3.cap-top > div > .ic-ok,.grid2.cap-top > div > .ic-ok{
  position:absolute;top:0;right:0;margin:0;min-height:0;max-width:60%;
  text-align:right;font-size:11px;line-height:1.25}

/* THE ATTACHMENT, VISIBLE WHETHER OR NOT A FILE IS CHOSEN.
   Its row collapsed to 0px x 0px until a file was picked, which is a control you cannot
   see and so cannot find - and it is why the memo and attachment were not in the level
   of the boxes above them.  Always shown, always the same 34px, with the same caption as
   every other field. */
.att-row{display:flex;flex-direction:column;align-items:stretch;gap:7px;width:100%}
.att-row>label:first-child{margin:0;font-size:11.5px;font-weight:800;color:#344054;
  text-transform:uppercase;letter-spacing:.4px}
.att-row .file-name{display:block;min-height:var(--zb-box);max-width:100%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;border:1px solid #e4e7ec;border-radius:8px;
  padding:var(--zb-box-pad);box-sizing:border-box;font-size:12.5px;color:#475467;
  background:#fff;margin:0 0 0 0}
.att-row .file-name:empty::before{content:'No file chosen';color:#98a2b3}
.att-row .file-btn{height:var(--zb-box);display:flex;align-items:center;justify-content:center;
  box-sizing:border-box;font-size:12.5px;padding:var(--zb-box-pad)}

/* THE FAULT STRIP.  Fixed to the top of the window, below the top bar, so it is seen
   without scrolling anything - a warning at the bottom of a long form is a warning that
   has not been read.  Deliberately plain: this is a message about the program failing,
   not a modal, and it must never look like something to dismiss without reading. */
.fault-strip{position:fixed;left:0;right:0;top:0;z-index:9000;
  background:#7a271a;color:#fff;font:600 13px/1.5 'Segoe UI',Arial,sans-serif;
  padding:11px 40px 11px 16px;box-shadow:0 2px 10px rgba(0,0,0,.28);
  display:flex;gap:10px;align-items:baseline;flex-wrap:wrap;direction:ltr}
.fault-strip b{font-weight:800}
.fault-strip .fault-msg{font-weight:400;opacity:.94;
  unicode-bidi:plaintext;text-align:left}
.fault-strip .fault-more{font-weight:400;opacity:.8;font-style:italic}
.fault-strip .fault-x{position:absolute;right:8px;top:6px;background:none;border:0;
  color:#fff;font-size:19px;line-height:1;cursor:pointer;opacity:.75;padding:2px 6px}
.fault-strip .fault-x:hover{opacity:1}
@media print{.fault-strip{display:none}}

/* ---- the Z-BOOKS logo: an open book in a dark rounded square ---- */
.zbmark{display:block;flex:0 0 auto}
.zbmark .zb-base{fill:#0b1220}
.zbmark .zb-edge{fill:none;stroke:#22c55e;stroke-opacity:.42;stroke-width:1.6}
.zbmark .zb-leaf-l{fill:#f8fafc}
.zbmark .zb-leaf-r{fill:#b6c2d1}
.zbmark .zb-spine{fill:#22c55e}
.zbmark .zb-rule{fill:#22c55e;fill-opacity:.55}
/* on the sign-in card */
.sign-logo{display:flex;justify-content:center;margin:0 0 13px}
.sign-logo .zbmark{width:80px;height:80px;filter:drop-shadow(0 6px 14px #0b122026)}
.sign-name{text-align:center;font-size:25px;font-weight:800;color:#0b0f19;letter-spacing:2.2px;line-height:1.1}
.sign-shop{text-align:center;font-size:14px;font-weight:600;color:#344054;margin:7px 0 20px}
/* in the black top bar */
.nav-logo .zbmark{width:32px;height:32px}
.nav-logo .nav-word{font-size:16.5px;font-weight:800;letter-spacing:1.1px;color:#fff}
.nav-logo .nav-word small{display:none}

/* The logo on a printed report: mark, then the name, then the shop underneath.  Laid
   out with flex rather than a table so the two lines stay together if the name is
   long, and given a print colour so it survives a greyscale printer - the green edge
   and the dark square are the only things distinguishing it at that point. */
.pr-brand{display:flex;align-items:center;gap:10px;margin:0 0 10px;
  padding-bottom:9px;border-bottom:2px solid #0b1220}
.pr-brand span{display:flex;flex-direction:column;line-height:1.25}
.pr-brand b{font-size:15px;letter-spacing:1.6px;color:#0b1220}
.pr-brand small{font-size:10.5px;color:#475467}
@media print{.pr-brand{-webkit-print-color-adjust:exact;print-color-adjust:exact}}

/* ---- the Period Lock and Approvals screens ---- */
.lock-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:9px}
.lock-box{display:flex;align-items:center;gap:9px;border:1px solid #e4e7ec;border-radius:9px;
  padding:9px 12px;cursor:pointer;background:#fff;font-size:13px;color:#344054;user-select:none}
.lock-box:hover{border-color:#98a2b3;background:#fcfcfd}
.lock-box.on{border-color:#111827;background:#f7f8fa;color:#111827;font-weight:700}
.lock-box input{accent-color:#111827;width:15px;height:15px;cursor:pointer}
.lock-box .lock-nm{flex:1}
.lock-box .lock-tag{font-size:9.5px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;
  background:#fef3f2;color:#b42318;border-radius:4px;padding:2px 6px}
/* the Activities list: every cell boxed, and a stripe on alternate rows */
table.act-tab{border-collapse:separate;border-spacing:0;border:1px solid #d0d5dd;
  border-radius:10px;overflow:hidden;width:100%}
table.act-tab th{background:#111827;color:#fff;text-align:left;padding:10px 11px;
  font-size:11px;font-weight:800;letter-spacing:.7px;text-transform:uppercase;
  white-space:nowrap;border:1px solid #111827}
table.act-tab td{padding:8px 11px;white-space:nowrap;
  border:1px solid #d0d5dd;vertical-align:top;font-size:12.5px;color:#344054}
table.act-tab tbody tr:nth-child(even) td{background:#f9fafb}
table.act-tab tbody tr:hover td{background:#eef2f6}
table.act-tab td.act-when{font-weight:700;color:#111827;white-space:nowrap}
table.act-tab td.act-detail{white-space:normal;min-width:220px;max-width:340px;
  word-break:break-word;color:#667085}
table.act-tab td.act-num{color:#98a2b3;font-size:11.5px}
table.act-tab th:first-child{border-start-start-radius:9px}
table.act-tab th:last-child{border-start-end-radius:9px}
table.act-tab tbody tr:last-child td:first-child{border-end-start-radius:9px}
table.act-tab tbody tr:last-child td:last-child{border-end-end-radius:9px}
.act-word{display:inline-block;margin-inline-start:7px;font-size:9.5px;font-weight:800;
  letter-spacing:.5px;text-transform:uppercase;background:#eef2f6;color:#475467;
  border-radius:4px;padding:2px 6px;white-space:nowrap}
.lock-big{font-size:16px;font-weight:800;color:#111827;margin:0 0 10px}
.lock-msg p{margin:0 0 9px;font-size:13px;color:#344054;line-height:1.55}
/* a badged Approvals entry in the Settings menu */
.nav-badge{display:inline-block;min-width:17px;height:17px;padding:0 5px;margin-inline-start:auto;
  border-radius:9px;background:#b42318;color:#fff;font-size:10.5px;font-weight:800;
  display:flex;align-items:center;justify-content:center}
.nav-drop button .badge,.nav-drop a .badge{background:#b42318;color:#fff;border-radius:9px;font-size:10.5px;
  font-weight:800;padding:1px 6px;margin-inline-start:auto}

/* the little red count on the Trash button */
.nav-right .icon-btn{position:relative}
.trash-chip{position:absolute;top:-4px;inset-inline-end:-4px;min-width:16px;height:16px;
  padding:0 4px;border-radius:8px;background:#b42318;color:#fff;font-size:10px;
  font-weight:800;display:flex;align-items:center;justify-content:center;pointer-events:none}

/* ---- the Tasks screen: the state tabs ---- */
.tsk-tabs{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0 12px}
.tsk-tab{display:flex;align-items:center;gap:7px;background:#fff;border:1px solid #d0d5dd;
  border-radius:20px;padding:7px 15px;cursor:pointer;font-family:inherit;font-size:13px;
  font-weight:700;color:#344054;transition:all .12s}
.tsk-tab:hover{border-color:#98a2b3;background:#f9fafb}
.tsk-tab b{min-width:20px;height:20px;padding:0 6px;border-radius:10px;background:#eef2f6;
  color:#344054;font-size:11.5px;display:flex;align-items:center;justify-content:center}
.tsk-tab.on{background:#111827;border-color:#111827;color:#fff}
.tsk-tab.on b{background:#ffffff26;color:#fff}
.tsk-t-pending{border-color:#b2ddff}
.tsk-t-pending.on{background:#175cd3;border-color:#175cd3}
.tsk-t-approved{border-color:#fedf89}
.tsk-t-approved.on{background:#b54708;border-color:#b54708}
.tsk-t-done{border-color:#a6f4c5}
.tsk-t-done.on{background:#067647;border-color:#067647}
.tsk-t-cancelled{border-color:#e4e7ec}
.tsk-t-cancelled.on{background:#475467;border-color:#475467}

/* ---- the Tasks screen ---- */
.tsk-tally{display:flex;gap:7px;flex-wrap:wrap;margin:12px 0}
.tsk-chip{font-size:11.5px;font-weight:700;color:#344054;background:#fff;
  border:1px solid #e4e7ec;border-radius:14px;padding:4px 11px}
.tsk-chip b{color:#111827;margin-inline-start:4px}
.tsk-chip.tsk-open{border-color:#b2ddff;background:#eff8ff;color:#175cd3}
.tsk-chip.tsk-in-progress{border-color:#fedf89;background:#fffaeb;color:#b54708}
.tsk-chip.tsk-done{border-color:#a6f4c5;background:#ecfdf3;color:#067647}
.tsk-chip.tsk-cancelled{border-color:#e4e7ec;background:#f9fafb;color:#667085}
.tsk-pri{display:inline-block;font-size:10px;font-weight:800;letter-spacing:.4px;
  text-transform:uppercase;border-radius:4px;padding:2px 7px;white-space:nowrap}
.tsk-p-low{background:#f2f4f7;color:#475467}
.tsk-p-normal{background:#eef4ff;color:#3538cd}
.tsk-p-high{background:#fef0c7;color:#b54708}
.tsk-p-urgent{background:#fee4e2;color:#b42318}
.tsk-st{display:inline-block;font-size:10px;font-weight:800;letter-spacing:.4px;
  text-transform:uppercase;border-radius:4px;padding:2px 7px;white-space:nowrap;
  background:#eef2f6;color:#475467}
.tsk-s-open{background:#eff8ff;color:#175cd3}
.tsk-s-in-progress{background:#fffaeb;color:#b54708}
.tsk-s-done{background:#ecfdf3;color:#067647}
.tsk-s-cancelled{background:#f2f4f7;color:#667085}
.tsk-late{color:#b42318;font-weight:800}
table.act-tab td input[type=checkbox]{width:16px;height:16px;accent-color:#067647;cursor:pointer}
.memo-box{margin-top:4px}
.memo-box textarea{resize:vertical;min-height:64px}

/* ---- Where your data is kept ---- */
.bk-warn{border-radius:9px;padding:11px 14px;font-size:12.5px;line-height:1.6;margin:0 0 14px}
.bk-warn b{font-size:13px}
.bk-warn.good{background:#ecfdf3;border:1px solid #a6f4c5;color:#067647}
.bk-warn.mid{background:#fffaeb;border:1px solid #fedf89;color:#b54708}
.bk-warn.bad{background:#fef3f2;border:1px solid #fecdca;color:#b42318}
.bk-where h4{font-size:12px;font-weight:800;letter-spacing:1px;text-transform:uppercase;
  color:#667085;margin:16px 0 8px}
.bk-row{display:grid;grid-template-columns:170px 1fr 240px;gap:12px;align-items:start;
  border-bottom:1px solid #f2f4f7;padding:9px 0}
.bk-row:last-child{border-bottom:0}
.bk-l{font-size:12.5px;font-weight:700;color:#344054}
.bk-p{font-size:12.5px;color:#111827;word-break:break-all;font-family:Consolas,monospace}
.bk-x{font-size:11.5px;color:#98a2b3;text-align:right;line-height:1.5}
.bk-what{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px;margin-top:14px}
.bk-card{border:1px solid #e4e7ec;border-radius:10px;padding:12px 14px;background:#fcfcfd}
.bk-card b{display:block;font-size:12.5px;color:#111827;margin:0 0 5px}
.bk-card span{font-size:12px;color:#475467;line-height:1.6}
.bk-copy{margin-top:6px}
.bk-copy label{display:block}
@media(max-width:900px){
  .bk-row{grid-template-columns:1fr}
  .bk-x{text-align:left}
}

/* on paper there is no bar to pin, and the whole report has to fit */
@media print{
  html,body{height:auto;overflow:visible}
  #app{height:auto;overflow:visible;display:block}
  .nav,.nav-right{display:none!important}
  .main{overflow:visible;min-height:0;height:auto;padding:0}
  .modal-backdrop{position:static;top:auto;background:none;padding:0}
  .modal{max-height:none;box-shadow:none;border:0}
}

/* ---- keyboard shortcuts and the jump box ---- */
.sc-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:18px}
.sc-col h4{font-size:11.5px;font-weight:800;letter-spacing:1px;text-transform:uppercase;
  color:#667085;margin:0 0 9px}
.sc-row{display:flex;align-items:center;gap:10px;padding:5px 0;font-size:13px;color:#344054}
.sc-k{min-width:82px;text-align:center;font-family:Consolas,monospace;font-size:11.5px;
  font-weight:700;color:#111827;background:#f2f4f7;border:1px solid #d0d5dd;
  border-bottom-width:2px;border-radius:6px;padding:3px 6px;white-space:nowrap}
.jump-list{max-height:46vh;overflow:auto;margin-top:10px;border:1px solid #e4e7ec;
  border-radius:9px}
.jump-row{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:none;
  border:0;border-bottom:1px solid #f2f4f7;padding:10px 13px;cursor:pointer;
  font-family:inherit;font-size:13.5px;color:#344054}
.jump-row:last-child{border-bottom:0}
.jump-row:hover{background:#f9fafb}
.jump-row.on{background:#111827;color:#fff}
.jump-ic{font-size:10px;color:#98a2b3}
.jump-row.on .jump-ic{colo#111827;word-break:break-all;font-family:Consolas,monospace}
.bk-x{font-size:11.5px;color:#98a2b3;text-align:right;line-height:1.5}
.bk-what{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:12px;margin-top:14px}
.bk-card{border:1px solid #e4e7ec;border-radius:10px;padding:12px 14px;background:#fcfcfd}
.bk-card b{display:block;font-size:12.5px;color:#111827;margin:0 0 5px}
.bk-card span{font-size:12px;color:#475467;line-height:1.6}
.bk-copy{margin-top:6px}
.bk-copy label{display:block}
@media(max-width:900px){
  .bk-row{grid-template-columns:1fr}
  .bk-x{text-align:left}
}

/* on paper there is no bar to pin, and the whole report has to fit */
@media print{
  html,body{height:auto;overflow:visible}
  #app{height:auto;overflow:visible;display:block}
  .nav,.nav-right{display:none!important}
  .main{overflow:visible;min-height:0;height:auto;padding:0}
  .modal-backdrop{position:static;top:auto;background:none;padding:0}
  .modal{max-height:none;box-shadow:none;border:0}
}

/* ---- keyboard shortcuts and the jump box ---- */
.sc-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:18px}
.sc-col h4{font-size:11.5px;font-weight:800;letter-spacing:1px;text-transform:uppercase;
  color:#667085;margin:0 0 9px}
.sc-row{display:flex;align-items:center;gap:10px;padding:5px 0;font-size:13px;color:#344054}
.sc-k{min-width:82px;text-align:center;font-family:Consolas,monospace;font-size:11.5px;
  font-weight:700;color:#111827;background:#f2f4f7;border:1px solid #d0d5dd;
  border-bottom-width:2px;border-radius:6px;padding:3px 6px;white-space:nowrap}
.jump-list{max-height:46vh;overflow:auto;margin-top:10px;border:1px solid #e4e7ec;
  border-radius:9px}
.jump-row{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:none;
  border:0;border-bottom:1px solid #f2f4f7;padding:10px 13px;cursor:pointer;
  font-family:inherit;font-size:13.5px;color:#344054}
.jump-row:last-child{border-bottom:0}
.jump-row:hover{background:#f9fafb}
.jump-row.on{background:#111827;color:#fff}
.jump-ic{font-size:10px;color:#98a2b3}
.jump-row.on .jump-ic{color:#22c55e}
.jump-lb{font-weight:700}
.jump-sb{font-size:11.5px;color:#98a2b3;margin-inline-start:auto;text-align:end}
.jump-row.on .jump-sb{color:#cbd5e1}

/* ---- the Language screen ---- */
.lang-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px;margin:0 0 16px}
.lang-card{position:relative;text-align:left;background:#fff;border:2px solid #e4e7ec;
  border-radius:12px;padding:16px 16px 14px;cursor:pointer;font-family:inherit;
  display:flex;flex-direction:column;gap:3px;transition:border-color .12s,box-shadow .12s}
.lang-card:hover{border-color:#98a2b3;box-shadow:0 6px 18px #10182814}
.lang-card.on{border-color:#111827;box-shadow:0 0 0 3px #111827 inset}
.lang-card .lang-flag{font-size:30px;line-height:1.1}
.lang-card .lang-nm{font-size:19px;font-weight:800;color:#111827}
.lang-card .lang-en{font-size:11.5px;font-weight:700;color:#667085;letter-spacing:.4px;
  text-transform:uppercase}
.lang-card .lang-sample{font-size:12.5px;color:#475467;margin-top:5px}
.lang-card .lang-tag{position:absolute;top:12px;inset-inline-end:12px;font-size:10px;
  font-weight:800;letter-spacing:.5px;text-transform:uppercase;background:#eef2f6;
  color:#475467;border-radius:5px;padding:3px 7px}
.lang-card.on .lang-tag{background:#067647;color:#fff}
.lang-now{font-size:12.5px;color:#475467}

.nav-btn{font-family:inherit}


/* ---- the page reads left to right, always ----
   A Pashto caption is written inside a sentence that runs left to right, so a
   number in one keeps its place instead of jumping to the far end of the line. */
/* ==================== THE SEARCHABLE MULTI-SELECT ====================
   White panel, a 1px #e2e8f0 border and 6px corners, the same as the other boxes on the
   forms.  The panel sits above everything: the form underneath is a modal at z-index 60 and
   this is above it, so nothing behind can show through and nothing in front can cover it. */

.ms{position:relative}

.ms-box{display:flex;align-items:center;gap:8px;cursor:pointer;background:#fff;
  border:1px solid #e2e8f0;border-radius:6px;padding:0 10px;height:var(--zb-box,43px);
  min-width:220px}
.ms-box:hover{border-color:#cbd5e1}
.ms-box:focus-visible{outline:2px solid #1570ef;outline-offset:1px}
.ms-box .ms-ph{color:#98a2b3;font-size:13.5px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;flex:1}
.ms-box .ms-caret{color:#98a2b3;font-size:11px;flex:none}
.ms-box .ms-n{flex:none;font-size:11.5px;font-weight:800;color:#1570ef;background:#eff8ff;
  border-radius:9px;padding:2px 8px;white-space:nowrap}

/* THE PANEL */
.ms-panel{display:none;position:absolute;z-index:10000;top:calc(100% + 4px);left:0;right:0;
  background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 10px 30px rgba(16,24,40,.14)}
.ms-panel.show{display:block}

/* THE SEARCH BAR, at the very top, inside the panel */
.ms-search{padding:8px;border-bottom:1px solid #eef2f6}
.ms-search input{width:100%;height:32px;border:1px solid #e2e8f0;border-radius:6px;
  padding:0 9px;font-size:13px;background:#fff;color:#111827}
.ms-search input:focus{outline:none;border-color:#1570ef}

/* SELECT ALL / DESELECT ALL, left and right */
.ms-acts{display:flex;justify-content:space-between;align-items:center;
  padding:6px 10px;border-bottom:1px solid #eef2f6;background:#f9fafb}
.ms-acts a{font-size:12px;font-weight:700;color:#1570ef;text-decoration:none;cursor:pointer;
  white-space:nowrap}
.ms-acts a:hover{text-decoration:underline}
.ms-acts a.off{color:#98a2b3}

/* THE LIST */
.ms-list{max-height:230px;overflow-y:auto}
.ms-row{display:flex;align-items:center;gap:9px;padding:7px 10px;cursor:pointer;
  border-bottom:1px solid #f9fafb}
.ms-row:hover{background:#f2f4f7}
.ms-row.on{background:#eff8ff}
.ms-row .ms-cb{width:15px;height:15px;flex:none;accent-color:#1570ef;cursor:pointer;margin:0}
.ms-row .ms-id{font-weight:700;font-size:13px;color:#111827;white-space:nowrap}
.ms-row .ms-meta{margin-inline-start:auto;font-size:11.5px;color:#667085;white-space:nowrap}
.ms-empty{padding:14px 12px;text-align:center;color:#98a2b3;font-size:12.5px}
/* ==================== THE REPORTS PAGE ====================
   No gradients, no shadows on the pills, no charts.  White page, the shop's flat tokens. */

.rpt-sub{text-align:center;font-weight:700;font-size:14px;color:#0f172a;margin:6px 0 30px}

.rpt-sec-title{text-align:center;font-weight:800;font-size:18px;text-transform:uppercase;
  color:#0f172a;margin-top:50px;margin-bottom:10px}

.rpt-div{height:1px;background:#e2e8f0;margin:0 0 18px}

.rpt-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
@media (max-width:1100px){.rpt-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:720px){.rpt-grid{grid-template-columns:1fr}}

/* ==================== REPORT PILL: RESTING AND HOVER ====================
   THE 4px BAR ON THE LEFT CARRIES THE MODULE COLOUR, and it is the only thing that does.
   The text and the chevron are one grey at rest and one near-black under the pointer, so
   what a pill says is read from the words and what module it belongs to is read from the
   bar - two jobs, two parts of the pill, and neither doing the other's.

   AT REST   text #475569, chevron the same #475569, background #f8fafc
   ON HOVER  text #0f172a, chevron the same #0f172a, background #eef2f7
   WEIGHT    unchanged on hover, deliberately.  Bolder on hover is how a menu looks BUSY
             rather than SELECTED, and the shop asked for the colour to carry it.

   THE CHEVRON IS NOT GIVEN ITS OWN COLOUR ANY MORE, and that is a reversal worth naming:
   it used to take its bar's colour, which meant five rules restating the five module
   colours for the text as well as the bar - and those sit at (0,2,0), which beats the
   plain .rpt-chev rule at (0,1,0) however it is written.  So a grey rule for the chevron
   lost to them silently, exactly as this file has sprung the same trap twice before.
   They are gone rather than overridden, because overriding is how that happens again. */
.rpt-pill{display:flex;align-items:center;gap:12px;height:42px;padding:0 14px 0 0;
  background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;cursor:pointer;
  overflow:hidden;
  /* THE FADE IS ON THE PILL for its own background, and on the label and the chevron for
     theirs - a colour set on a child does not animate off the parent's transition, so one
     rule here would fade the background and snap the text. */
  transition:background-color .2s ease}
.rpt-pill:hover{background:#eef2f7}

.rpt-bar{width:4px;height:100%;flex:none}
.rpt-grn{background:#16a34a}
.rpt-pur{background:#7c3aed}
.rpt-red{background:#dc2626}
.rpt-blu{background:#2563eb}
.rpt-amb{background:#d97706}

.rpt-lbl{flex:1;font-size:13px;font-weight:400;color:#475569;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  transition:color .2s ease, font-weight .2s ease}
.rpt-pill:hover .rpt-lbl{color:#16a34a;font-weight:700}

.rpt-chev{font-size:13px;font-weight:700;flex:none;color:#475569;
  transition:color .2s ease}
.rpt-pill:hover .rpt-chev{color:#16a34a}
/* ==================== JOURNAL: CAPTIONS ABOVE THEIR BOXES ====================
   The journal form is not built on the shared grid, so cap-top - the class that puts every
   other form's caption above its box - was never on it.  These are the same rule written for
   the two cells the journal actually uses, with the same spacing: 7px between a caption and
   its box, the caption uppercase at 10.5px.  The cells still sit side by side; only the
   caption inside each cell moves from beside the box to above it. */
.cap-top.jn-row > div, .cap-top.jn-grp {
  display:flex; flex-direction:column; align-items:stretch; gap:7px; min-width:0 }
.cap-top.jn-row > div > label, .cap-top.jn-grp > label {
  flex:none; margin:0; padding-left:1px; text-align:left;
  font-size:10.5px; font-weight:700; letter-spacing:.4px; text-transform:uppercase;
  color:#475569 }
/* the box under it keeps the height it already had */
.cap-top.jn-row > div > .input, .cap-top.jn-row > div > .select,
.cap-top.jn-grp > .input, .cap-top.jn-grp > .select {
  width:100%; min-width:0; box-sizing:border-box }


'
    +jnPrintCss()+'
'+CSS+'