/* Gasmate Depot, the office and owner application.
   
   A desktop ERP rather than the phone-first plant app, because Sandra and Alma
   sit at a computer and the two jobs are different shapes. The palette is the
   plant app's, so the two read as one system.

   The rule the dashboard is built around, and the reason several cards here
   deliberately show no number: no figure appears without a path down to the
   entries behind it and the person who made them. A card that cannot offer one
   says what is missing instead of showing something plausible. */

:root {
  /* Structure and density came from the system Sandra recorded on 28 August:
     white sidebar, light-tinted table headers, pastel status pills on white.

     The hue is the four blues Godfrey chose on 18 September: Deep Blue
     #2A4D88, Ocean City #7C94B8, Glacial Salt #B1BBC8 and Concerto #D9D9D8,
     on white cards over a light grey page. The deep blue carries white at
     8.35:1 and sits on white at the same, so it is the one accent in both
     applications: links, the chart, the phone's bar and tiles. Ocean City
     is the current page pill and the input edge, at 3.1:1 on white, which is
     the floor for a boundary and not enough for a word, so the pill carries
     the ink. Glacial Salt is the chart fill and the greeting corner, Concerto
     the dividers. The primary button is a dark slate, --deep, because the
     plant app shares it and needs its buttons to differ from its headings by
     more than lightness.

     The three values the two applications share, the page ground, the primary
     and the pale panel, are the plant's own byte for byte, and a test holds
     them equal. Contrast here is held to AA rather than the AAA the plant app
     needs: this is read at a desk indoors, not on a phone in the sun. */
  --bg: #F3F4F6;
  --paper: #FFFFFF;
  /* The right-edge scroll hint on a wide table (P4, finding 3). */
  --table-fade-shadow: rgba(17, 24, 39, 0.16);
  --ink: #111827;
  --deep: #333A47;
  /* What sits on top of --deep. White in light; in dark the primary fill has
     to be light enough to read as an accent, so the label goes dark. */
  --on-deep: #FFFFFF;
  --deeper: #1F2530;
  --deep-wash: #EEF1F6;
  --brand: #2A4D88;
  --pale: #E8EDF5;
  --muted: #4B5563;
  --line: #D9D9D8;
  --edge: #6B85AC;
  --faint: #5B6472;
  --amber-bg: #FDF3E7;
  --amber-edge: #F3CFAB;
  --amber-ink: #9A6216;
  --red-bg: #FCEDEE;
  --red-edge: #E8BABC;
  --red-ink: #A33B41;
  --green-bg: #E6F9F0;
  --green-edge: #A5EBC9;
  --green-ink: #1B7A52;
  --blue-ink: #2A4D88;
  --card-brand: #2A4D88;
  --card-violet: #5B7398;
  --card-green: #0F7F7E;
  --card-red: #BF4133;
  --card-slate: #5C6480;
  --accent: #B1BBC8;
  /* The sidebar. White in light and dark chrome in dark, so it has tokens
     of its own: nothing on it is painted in the page colours.

     The current page pill is Ocean City with the ink on it, 5.7:1, and 3.1:1
     against the panel, which is the 3:1 a state carried in colour needs. The
     focus ring is the ink, because it has to clear 3:1 against both the panel
     and the pill and nothing lighter does. The three washes are Ocean City on
     purpose: white over white is a hover nobody sees.

     --side-line is deliberately not held to 3:1. A divider is decoration, not
     a control somebody must find; the focus ring and the pill are, and those
     are the two that clear 3:1. Do not "fix" it. */
  --side-bg: #FFFFFF;
  --side-ink: #111827;
  --side-muted: #4B5563;
  --side-faint: #5B6472;
  --side-active: #7C94B8;
  --side-on-active: #111827;
  --side-line: #D9D9D8;
  --side-focus: #111827;
  --side-hover: rgba(124, 148, 184, 0.08);
  --side-raise: rgba(124, 148, 184, 0.12);
  --side-press: rgba(124, 148, 184, 0.18);
  /* The top of the production chart's fill. It fades to --paper, the card
     itself, rather than to transparent, so the chart carries no glass. Held
     at least 1.2:1 from --paper by a test so it cannot quietly vanish. */
  --area-top: #B1BBC8;
  /* Two shadows in light, the second wide and soft, which is how the
     reference lifts a card off the page. None in dark: a drop shadow on a
     dark page is a smudge, and the border already separates. */
  --card-shadow: 0 1px 2px rgba(16, 24, 40, 0.04), 0 10px 28px rgba(16, 24, 40, 0.06);
  /* The greeting band. Its own pair, because in dark the primary is a light
     accent and a whole band of it was a block of cyan at the top of every
     page. Godfrey asked for a calmer dark on 8 September. */
  --hero-bg: #1E3A63;
  --hero-ink: #FFFFFF;
  --side: 248px;
  --rail: 68px;
}

/* Dark, solved the same way the light palette was: foregrounds lightened
   until they clear their target against the surface they sit on. A dark
   theme picked by eye is where contrast work goes to die.

   Godfrey, 25 September 2026: "I like the dark mode of Claude and [Odoo]
   rather than ours since ours has some tint of blue; make it like Claude or
   like them, dark gray combo." The navy grounds are gone. Every surface,
   line and word is a warm neutral grey, from Claude's own dark mode: page
   #262624, sidebar #1F1E1D, cards #30302E, lines #3D3D3A, text #F5F4ED,
   secondary #C2C0B6, faintest #9C9A92. No surface leans blue, and a test
   says so channel by channel.

   The one accent is still the deep blue, #2A4D88 at the same hue and
   saturation, lightened only until it carries text on a card: #779AD5 is
   4.64:1 on #30302E, and one step darker is 4.48:1, under AA. It is the
   links, the bars of a chart and the sending dot, nothing that fills an area.
   The primary button and the chart line are --deep, the slate of the light
   theme, and the dark counterpart of a slate is a warm light grey, not a
   blue. Green, amber and red are the states and are as they were.

   The pale panel and the table wash sit a shade below the card rather than
   above it, the way the light theme's sit below white, so the faintest text
   still clears 5:1 on a row under the pointer. Body text 12:1, secondary
   7.2:1, the faintest 4.7:1, input edges 3.1:1. */
:root[data-theme="dark"] {
  /* Native controls, the date boxes, the selects and the scrollbars, drawn
     dark too, rather than as white boxes on a dark page. */
  color-scheme: dark;
  --bg: #262624;
  --paper: #30302E;
  --table-fade-shadow: rgba(0, 0, 0, 0.55);
  --ink: #F5F4ED;
  --deep: #E3E1D7;
  --on-deep: #1F1E1D;
  --deeper: #F5F4ED;
  --deep-wash: #2B2B29;
  --brand: #779AD5;
  --pale: #292927;
  --muted: #C2C0B6;
  --line: #3D3D3A;
  --edge: #7D7B74;
  --faint: #9C9A92;
  --amber-bg: #2A2113;
  --amber-edge: #6A5423;
  --amber-ink: #BC8523;
  --red-bg: #2B1817;
  --red-edge: #6B3833;
  --red-ink: #E4675C;
  --green-bg: #12271F;
  --green-edge: #22543F;
  --green-ink: #2AA678;
  --blue-ink: #779AD5;
  /* The five stat chips keep their colours: each is a small square with a
     white glyph in it, a mark rather than a surface. */
  --card-brand: #2A4D88;
  --card-violet: #5B7398;
  --card-green: #0F7F7E;
  --card-red: #A83E33;
  --card-slate: #4E5670;
  /* The greeting's corner. A neutral lift in dark; see the dark .hello rule. */
  --accent: #6E6C66;
  /* The sidebar in dark, a shade below the page as Claude's is. The current
     page pill is a mid grey carrying white: 3.17:1 against the panel, which
     is the 3:1 a state carried in colour needs, and 5.25:1 for its label and
     for the white focus ring. A blue pill cannot do both: light enough to be
     found on the panel, it is too light for a white ring to be seen on it.
     The washes are the text colour at low strength, so a hover is a lift of
     the same grey rather than a tint; the raised panels at 0.08 come out at
     the card colour. */
  --side-bg: #1F1E1D;
  --side-ink: #F5F4ED;
  --side-muted: #C2C0B6;
  --side-faint: #9C9A92;
  --side-active: #6E6C66;
  --side-on-active: #FFFFFF;
  --side-line: #3D3D3A;
  --side-focus: #FFFFFF;
  --side-hover: rgba(245, 244, 237, 0.05);
  --side-raise: rgba(245, 244, 237, 0.08);
  --side-press: rgba(245, 244, 237, 0.12);
  --area-top: #4A4945;
  --card-shadow: none;
  /* The greeting band, a card without its border: the navy band of 8
     September was the largest blue area on any page. */
  --hero-bg: #30302E;
  --hero-ink: #F5F4ED;
}

* { box-sizing: border-box; }
/* Hidden means hidden, whatever display a class gives the element. Without
   this a button styled as flex stayed on screen when hidden, and a draft
   invoice offered "Cancel it" beside "Post". */
[hidden] { display: none !important; }

html, body {
  margin: 0; height: 100%;
  background: var(--bg); color: var(--ink);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 14px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.hidden { display: none !important; }
a { color: inherit; }
/* iPhone Safari paints a button's text in its own blue unless told the colour. */
button { color: inherit; }

/* Sign in ----------------------------------------------------------------- */
.signin-wrap { min-height: 100%; display: grid; place-items: center; padding: 24px; }
.authcard {
  width: 100%; max-width: 372px; display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid var(--line); border-radius: 16px;
  padding: 28px 24px 22px; box-shadow: var(--card-shadow);
}
/* The mark is filled with the chip blue rather than the link blue. In light
   the two are the same #2A4D88, so nothing there moves; in dark the link blue
   is lightened to be read as text, and a white glyph on it was 2.9:1. */
.mark {
  width: 52px; height: 52px; border-radius: 13px; background: var(--card-brand); color: #FFFFFF;
  display: grid; place-items: center; align-self: center;
}
.authtitle { font-size: 20px; font-weight: 600; margin: 14px 0 0; text-align: center; }
.authsub { font-size: 13px; color: var(--muted); margin: 4px 0 0; text-align: center; }
.field { display: block; margin-top: 18px; }
.flabel {
  display: block; font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 6px;
}
.field input {
  width: 100%; font: inherit; font-size: 15px; color: var(--ink); background: var(--bg);
  border: 1px solid var(--edge); border-radius: 9px; padding: 11px 13px; min-height: 44px;
}
.field input:focus-visible { outline: 2px solid var(--deep); outline-offset: 1px; border-color: var(--deep); }
.withreveal { position: relative; display: block; }
.withreveal input { padding-right: 62px; }
.reveal {
  position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
  background: none; border: 0; color: var(--brand); font: inherit; font-size: 12.5px;
  font-weight: 600; cursor: pointer; padding: 10px 8px; border-radius: 7px;
}
.primary {
  margin-top: 20px; width: 100%; min-height: 46px; font: inherit; font-size: 15px; font-weight: 600;
  color: var(--on-deep); background: var(--deep); border: 1px solid var(--deep); border-radius: 9px; cursor: pointer;
}
.primary:hover { background: var(--deeper); }
.primary:disabled { opacity: 0.6; cursor: default; }
.msg { font-size: 13px; color: var(--red-ink); margin-top: 14px; text-align: center; min-height: 18px; }
.tip { font-size: 11.5px; color: var(--faint); margin: 14px 0 0; text-align: center; }

/* Shell ------------------------------------------------------------------- */
.shell { display: grid; grid-template-columns: var(--side) 1fr; min-height: 100vh; }
.shell.railed { grid-template-columns: var(--rail) 1fr; }

/* The sidebar is painted only in its own --side-* tokens, because in dark the
   page colours do not work on it: --ink on that ground measures 1.00:1 and
   --muted 2.32:1, so any rule that reaches for them paints an invisible word.

   Every state below, including every hover, sets its foreground as well as
   its ground. The first draft only swapped backgrounds, and the two labels
   that would have vanished, the theme switch and the rail toggle, vanished
   only under the pointer, where no screenshot looks. */
.side {
  background: var(--side-bg); color: var(--side-ink); display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; border-right: 1px solid var(--side-line);
}
.brand { display: flex; align-items: center; gap: 10px; padding: 16px 12px 12px 16px; }
.brandmark {
  width: 32px; height: 32px; border-radius: 9px; background: var(--card-brand); color: #FFFFFF;
  display: grid; place-items: center; flex: none;
}
/* The mark and the avatar are --deep everywhere else, which on this ground is
   1.57:1 and would vanish. Both the fill and the glyph are set, because the
   fill alone leaves the dark glyph at 3.72:1 on the pill, under AA. The global
   rules stay as they are: the top bar avatar and the sign in mark use them. */
.side .brandmark, .side .avatar { background: var(--side-active); color: var(--side-on-active); }
.brandtext { display: flex; flex-direction: column; min-width: 0; }
.brandname { font-size: 14px; font-weight: 600; letter-spacing: -0.01em; }

/* Collapse to an icon rail. Sub items stay on the rail rather than being
   hidden behind an expand, because a page you cannot reach while collapsed is
   a page somebody stops using. */
.railtoggle {
  margin-left: auto; flex: none; width: 28px; height: 28px; display: grid; place-items: center;
  background: none; border: 1px solid transparent; border-radius: 7px;
  color: var(--side-muted); cursor: pointer;
}
.railtoggle:hover { background: var(--side-hover); border-color: var(--side-line); color: var(--side-ink); }
.railtoggle svg { width: 16px; height: 16px; }

.nav { flex: 1; overflow-y: auto; padding: 4px 10px 10px; }

/* A group is a button now rather than a caption, so the whole sidebar can be
   folded down to the part somebody is working in. */
.navgroupbtn {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: none; border: 0; color: var(--side-muted); font: inherit; font-size: 12.5px;
  font-weight: 600; padding: 9px 10px; border-radius: 9px; cursor: pointer; margin-top: 4px;
}
.navgroupbtn:hover { color: var(--side-ink); background: var(--side-hover); }
.navchev { margin-left: auto; flex: none; width: 15px; height: 15px; color: var(--side-faint);
           transition: transform 0.15s ease; }
.navgroupbtn[aria-expanded="false"] .navchev { transform: rotate(-90deg); }
.navgroupbtn.later { color: var(--side-faint); }
.navgroupbtn.later:hover { color: var(--side-muted); }

.navico { flex: none; width: 18px; height: 18px; display: block; }
/* A name too long for the sidebar wraps onto a second line rather than losing
   its end. Measured 25 September 2026: Daily Transaction Report, Chart of
   accounts and Opening balances all lost their last letters, and Profit and
   loss, balance sheet read as Profit and lo. A menu nobody can read in full
   is a menu people guess at. */
.navlabel { min-width: 0; overflow-wrap: anywhere; line-height: 1.3; }

.navitem {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: none; border: 0; color: var(--side-muted); font: inherit; font-size: 13px;
  padding: 8px 10px; border-radius: 9px; cursor: pointer; position: relative;
}
.navitem:hover { background: var(--side-hover); color: var(--side-ink); }
/* The current page is a filled pill. A raised white card was the device on
   the light panel; on navy the raised thing is the fill, and it needs no
   shadow. The icon is stroke: currentColor, so it takes the label's colour
   without a rule of its own. */
.navitem[aria-current="page"] {
  background: var(--side-active); color: var(--side-on-active); font-weight: 600;
}

/* An open group is shown by indent alone. The reference drew a tree line into
   it; that is two more strokes on a panel that reads better with fewer, and
   only one group is open at a time, so nothing is ambiguous without it. */
.navsub { padding-left: 28px; margin: 2px 0 6px; }
.navsub.closed { display: none; }

/* Counts are real or they are absent. The reference shows a badge on nearly
   every row; here only a figure the system can actually produce gets one, and
   a count of zero shows nothing rather than a reassuring nought. It keeps the
   page's amber chip colours: self grounded, already measured, and the one warm
   thing on the navy, which is what a count needing attention should be. */
.navcount {
  margin-left: auto; flex: none; font-size: 10.5px; font-weight: 700; line-height: 1;
  padding: 3px 7px; border-radius: 20px;
  background: var(--amber-bg); color: var(--amber-ink); border: 1px solid var(--amber-edge);
}
.navsoon {
  margin-left: auto; flex: none; font-size: 9.5px; color: var(--side-faint);
  border: 1px solid var(--side-line); border-radius: 4px; padding: 1px 4px;
}
.navitem.later { color: var(--side-faint); }
.navitem.later:hover { background: var(--side-hover); color: var(--side-muted); }

/* Workspace at the top and the person at the bottom, the shape every one of
   the reference dashboards uses. Here the workspace is the plant, because a
   figure entered against the wrong terminal is the mistake worth designing
   against. The four raised sub panels are the one place the sidebar is glass:
   a white wash over a ground that is known and solid, never over content. */
.plantpick {
  display: flex; align-items: center; gap: 9px; margin: 0 10px 4px; padding: 9px 10px;
  background: var(--side-raise); border: 1px solid var(--side-line); border-radius: 10px;
}
.plantpick .brandmark { width: 26px; height: 26px; border-radius: 8px; }
.planttext { display: flex; flex-direction: column; min-width: 0; }
.plantname { font-size: 12.5px; font-weight: 600; }
.plantsub { font-size: 10.5px; color: var(--side-muted); }
.usercard {
  display: flex; align-items: center; gap: 9px; padding: 9px 10px; margin-bottom: 9px;
  background: var(--side-raise); border: 1px solid var(--side-line); border-radius: 10px;
}
.avatar {
  width: 30px; height: 30px; border-radius: 50%; background: var(--deep); color: var(--on-deep);
  display: grid; place-items: center; font-size: 12px; font-weight: 600; flex: none;
}
.usertext { display: flex; flex-direction: column; min-width: 0; }
.username { font-size: 12.5px; font-weight: 600; }
.userrole { font-size: 10.5px; color: var(--side-muted); text-transform: capitalize; }

/* One theme control, and it says which one is on rather than making somebody
   click to find out. It replaced an icon in the top bar and an item in the
   user menu, which were two controls for one setting. The pressed option is
   the same filled pill as the current page, so the sidebar has one way of
   saying "this is on". */
.themeswitch {
  display: grid; grid-template-columns: 1fr 1fr; gap: 3px; padding: 3px; margin-bottom: 9px;
  background: var(--side-raise); border: 1px solid var(--side-line); border-radius: 10px;
}
.themeopt {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  background: none; border: 0; border-radius: 8px; padding: 7px 4px;
  font: inherit; font-size: 12px; color: var(--side-muted); cursor: pointer;
}
.themeopt:hover { color: var(--side-ink); }
.themeopt[aria-pressed="true"] { background: var(--side-active); color: var(--side-on-active); font-weight: 600; }
.themeopt svg { width: 14px; height: 14px; flex: none; }

.sidefoot { padding: 8px 12px 14px; border-top: 1px solid var(--side-line); display: flex; flex-direction: column; }
/* Administration lives here, above Sign out (S1, 28 September 2026). It does
   not grow with the menu: past two fifths of the window it scrolls on its
   own, so Sign out is always in reach and nothing overlaps at any height. */
.navfoot { flex: none; max-height: 40vh; overflow-y: auto; padding: 0 0 8px; }
.navfoot .navgroupbtn { margin-top: 0; }
.navfoot .navsub { margin-bottom: 2px; }
.envtag {
  font-size: 10.5px; color: var(--amber-ink); background: var(--amber-bg);
  border: 1px solid var(--amber-edge);
  border-radius: 7px; padding: 6px 8px; margin-bottom: 9px; line-height: 1.35;
}
.sideout {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; background: var(--side-raise); border: 1px solid var(--side-line); color: var(--side-muted);
  font: inherit; font-size: 12.5px; padding: 8px; border-radius: 8px; cursor: pointer;
}
.sideout:hover { background: var(--side-press); color: var(--side-ink); }
a.sideout { text-decoration: none; margin-bottom: 8px; }
.sideout svg { width: 15px; height: 15px; flex: none; }

/* Keyboard focus. There was none: the browser default is a dark ring that
   does not show on navy. Offset so the ring lands on the ground, where it is
   10.39:1 against the panel and 3.07:1 against the active pill. */
.navitem:focus-visible, .navgroupbtn:focus-visible, .railtoggle:focus-visible,
.themeopt:focus-visible, .sideout:focus-visible {
  outline: 2px solid var(--side-focus); outline-offset: 2px;
}

/* The rail is 68px wide, so the browser's default scrollbar takes a fifth of
   it. Thin, and only as dark as a divider. */
.nav::-webkit-scrollbar { width: 6px; }
.nav::-webkit-scrollbar-thumb { background: var(--side-line); border-radius: 3px; }
.nav::-webkit-scrollbar-track { background: transparent; }
.nav { scrollbar-width: thin; scrollbar-color: var(--side-line) transparent; }

/* Collapsed. Labels go, icons and the tooltip on each stay. The rail is a
   desktop affordance: below 900px the sidebar is already a wrapped row and
   these rules would hide every label in it. */
@media (min-width: 901px) {
  .shell.railed .navlabel,
  .shell.railed .navchev,
  .shell.railed .navcount,
  .shell.railed .navsoon,
  .shell.railed .brandtext,
  .shell.railed .planttext,
  .shell.railed .usertext,
  .shell.railed .envtag,
  .shell.railed .themeopt span { display: none; }
  /* The mark, then the toggle under it, both centred inside the rail. Until
     28 September the toggle hung 13px over the page beside the mark, half
     out of the rail (Godfrey: "so weird right now"). */
  .shell.railed .brand { flex-direction: column; gap: 8px; padding: 14px 0 10px; }
  .shell.railed .railtoggle { margin: 0; width: 36px; height: 30px; border-color: var(--side-line); }
  .shell.railed .side { position: sticky; }
  .shell.railed .plantpick,
  .shell.railed .usercard { justify-content: center; padding: 9px 0; }
  .shell.railed .navitem,
  .shell.railed .navgroupbtn { justify-content: center; padding: 10px 0; }
  .shell.railed .navsub { padding-left: 0; }
  .shell.railed .themeswitch { grid-template-columns: 1fr; }
  .shell.railed .sideout { width: 40px; margin: 0 auto; padding: 9px 0; }
}

/* The rail, second block, kept apart for the length the test allows. On the
   rail a group is its icon with the group's name as the tooltip, and a thin
   line above each group says where one ends and the next begins. The foot's
   group needs no line of its own: the foot's top border is that line. */
@media (min-width: 901px) {
  .shell.railed .navgroupbtn { position: relative; margin-top: 10px; }
  .shell.railed .navgroupbtn::before {
    content: ''; position: absolute; top: -6px; left: 12px; right: 12px; height: 1px;
    background: var(--side-line);
  }
  .shell.railed .navfoot .navgroupbtn { margin-top: 0; }
  .shell.railed .navfoot .navgroupbtn::before { display: none; }
  .shell.railed .sidefoot { padding: 8px 6px 12px; }
  .shell.railed .navfoot { padding-bottom: 6px; }
}

.main { min-width: 0; display: flex; flex-direction: column; }
.crumb h1 { font-size: 20px; font-weight: 600; margin: 0; letter-spacing: -0.01em; }
.crumbsub { font-size: 12.5px; color: var(--muted); margin: 3px 0 0; }
.range { display: flex; gap: 10px; }
.rangefield { display: flex; flex-direction: column; gap: 3px; }
.rangefield span {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted);
}
.rangefield input {
  font: inherit; font-size: 12.5px; color: var(--ink); background: var(--bg);
  border: 1px solid var(--edge); border-radius: 7px; padding: 6px 8px;
}
.who { display: flex; flex-direction: column; align-items: flex-end; }
.whoname { font-size: 13px; font-weight: 600; }
.whorole { font-size: 11px; color: var(--muted); text-transform: capitalize; }

.body { padding: 30px 34px 64px; }

/* Dashboard ------------------------------------------------------------- */
.hello h2 { font-size: 16px; font-weight: 600; margin: 0; letter-spacing: -0.01em; }
.hello p { font-size: 12.5px; color: var(--muted); margin: 3px 0 0; }

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 20px; }
/* Five cards filled edge to edge with colour, which is what this was, is a
   dashboard shouting five things at once. The colour still carries the same
   meaning and now carries it in one small square: the card is paper, the
   figure is ink, and the eye lands on the number rather than on the panel
   behind it. */
.stat {
  background: var(--paper); border: 1px solid var(--line); border-radius: 16px;
  padding: 20px 22px 22px; display: flex; flex-direction: column; color: var(--ink);
  box-shadow: var(--card-shadow);
}

.stathead { display: flex; align-items: center; gap: 11px; }
/* The one place colour is filled. White has to clear AA on it, which is what
   the card tokens were solved for and what the tests still measure. */
.staticonwrap {
  width: 36px; height: 36px; border-radius: 11px; flex: none;
  display: grid; place-items: center; color: #FFFFFF;
}
.stat.tone-sage   .staticonwrap { background: var(--card-brand); }
.stat.tone-violet .staticonwrap { background: var(--card-violet); }
.stat.tone-green  .staticonwrap { background: var(--card-green); }
.stat.tone-red    .staticonwrap { background: var(--card-red); }
.stat.tone-slate  .staticonwrap { background: var(--card-slate); }
.staticon { width: 18px; height: 18px; flex: none; }
.statlabel {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--muted);
}
.statvalue { display: flex; align-items: baseline; gap: 7px; margin-top: 18px; }
.bignum { font-size: 30px; font-weight: 600; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.unit { font-size: 12.5px; font-weight: 500; color: var(--muted); }
.statsub { font-size: 11.5px; margin-top: 8px; line-height: 1.5; color: var(--muted); }
/* The two buttons a card can carry, on one row so every card ends the same
   way and the label above keeps the full width of the card. */
/* Pushed to the bottom so the buttons line up across a row of cards whose
   text runs to different lengths. */
.statfoot { display: flex; align-items: center; gap: 8px; margin-top: auto; padding-top: 16px; flex-wrap: wrap; }
.statfoot .statlink { margin-top: 0; }
/* Always visible, so a figure carrying a caveat says so at a glance. */
.statmark {
  flex: none; font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer;
  background: var(--amber-bg); color: var(--amber-ink); border: 1px solid var(--amber-edge);
  border-radius: 8px; padding: 7px 12px;
}
.statmark:hover { border-color: var(--amber-ink); }
.statwarn { font-size: 11.5px; margin-top: 14px; line-height: 1.55; color: var(--amber-ink); }
.statwarn p { margin: 0 0 7px; }
.statwarn p:last-child { margin-bottom: 0; }
/* One button style for every card and panel. It used to be white glass, which
   works on a filled card and is invisible on the white panels the same class
   is used on. */
.statlink {
  align-self: flex-start; margin-top: 16px; background: var(--paper);
  border: 1px solid var(--edge); border-radius: 8px; padding: 7px 12px;
  font: inherit; font-size: 11.5px; font-weight: 600; color: var(--ink); cursor: pointer;
}
.statlink:hover { border-color: var(--deep); color: var(--deep); }

/* Drawn only where a day by day figure exists behind it. */
.spark { width: 88px; height: 24px; margin-left: auto; flex: none; align-self: center; }
.spark polyline { fill: none; stroke: var(--edge); stroke-width: 1.8;
                  stroke-linecap: round; stroke-linejoin: round; }

/* Earned, not decorative: it appears only when one specific thing needs a
   person, and it says what that thing is. */
.attention {
  display: flex; align-items: center; gap: 14px; margin-bottom: 20px;
  background: var(--amber-bg); border: 1px solid var(--amber-edge);
  border-radius: 12px; padding: 15px 18px;
}
.attentiontext { font-size: 12.5px; color: var(--amber-ink); line-height: 1.5; }
/* These two were written as light theme literals and were the only colours in
   this file the contrast test could not see, because its hex guard reads
   app.css alone. In dark the bold word sat at 2.00:1 on the amber ground and
   the hover painted a near white rectangle under amber text at 3.18:1. Found
   by a styling audit on 11 September 2026. Tokens, so both themes follow. */
.attentiontext strong { color: var(--ink); }
.attentionbtn {
  margin-left: auto; flex: none; font: inherit; font-size: 12px; font-weight: 600;
  background: var(--paper); color: var(--amber-ink); border: 1px solid var(--amber-edge);
  border-radius: 8px; padding: 7px 13px; cursor: pointer;
}
.attentionbtn:hover { background: var(--amber-bg); border-color: var(--amber-ink); }

/* The dashboard, 26 September 2026: the figures and charts in the wide
   column, Needs attention in a rail beside them, a quarter of the width.
   It was one long column again, and five tall items came before any
   figure did. Under 1180px the rail drops below the charts (see the media
   rule after .split). */
.dashgrid {
  display: grid; grid-template-columns: minmax(0, 1fr) 260px;
  gap: 20px; margin-top: 20px; align-items: start;
}
.dashgrid.norail { grid-template-columns: minmax(0, 1fr); }
.dashmain { min-width: 0; }
.dashmain > .sectionhead:first-child { margin-top: 0; }
.dashrail { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.split { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 20px; margin-top: 20px; }
.panel {
  background: var(--paper); border: 1px solid var(--line); border-radius: 16px; padding: 20px 22px 22px;
  box-shadow: var(--card-shadow);
  /* A panel wider than its column scrolls inside itself at every width. This
     was set only below 640px, so a tablet in portrait clipped a wide table
     with no way to reach the rest of it, and the monthly page pushed the
     whole page sideways instead. Found 11 September 2026. */
  overflow-x: auto;
}
/* The dashboard's full width panels follow the two banded rows. */
.dashgrid ~ .panel { margin-top: 20px; }
/* The quick buttons sit in the narrow column beside the chart now. Stacked
   one under another they ran three times the chart's height, so in the rail
   each button is a row, icon beside name, and two of them share a line. */
.dashrail .quickbtn { flex-direction: row; align-items: center; gap: 10px; padding: 10px 12px; }
.stats + .split, .attention + .stats { margin-top: 20px; }
.dashrail > * { margin: 0; }
.panelhead { display: flex; align-items: baseline; justify-content: space-between; gap: 4px 14px; flex-wrap: wrap; margin-bottom: 16px; }
.panelhead h2 { font-size: 14px; font-weight: 600; margin: 0; }
.panelsub { font-size: 11.5px; color: var(--faint); }

.chart { width: 100%; height: auto; display: block; }
.chart .grid { stroke: var(--line); stroke-width: 1; }
.chart .axis { fill: var(--faint); font-size: 9.5px; font-family: inherit; }
/* The area is a gradient from --area-top down to --paper, defined in the SVG
   itself so it can reach the tokens. The line and the dots are the primary;
   every dot carries its date and figure as a title, so a day can be read. */
.chart .line { fill: none; stroke: var(--deep); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart .dot { fill: var(--paper); stroke: var(--deep); stroke-width: 2; }
.chart .dot:hover { fill: var(--deep); }

/* Discrepancy trends' bars. Glacial Salt for a shortfall, Concerto for a
   group that came out over: both fills, never the one accent, per the
   palette rule that only the deep blue carries text. Look at this is a
   pointer, so it takes the warm amber a state gets, drawn as an outline
   rather than a second fill. */
.chart .bar { fill: var(--accent); }
.chart .bar.over { fill: var(--line); }
.chart .bar.lookat { stroke: var(--amber-ink); stroke-width: 2; }
.chart .zero { stroke: var(--edge); stroke-width: 1; }

/* The figures with no number. The part of this dashboard the whole system is
   built around, so it reads as a list of open questions rather than as four
   blank cards pretending to be the same kind of thing as a figure. */
.unres { padding: 14px 0; border-top: 1px solid var(--line); }
.unres:first-of-type { border-top: 0; padding-top: 0; }
.unrestop { display: flex; align-items: center; gap: 10px; }
.unresname { font-size: 13px; font-weight: 600; }
.unreswhy {
  margin-left: auto; flex: none; font: inherit; font-size: 11.5px; font-weight: 600;
  background: none; border: 0; padding: 2px 0; color: var(--brand); cursor: pointer;
}
.unreswhy:hover { text-decoration: underline; }
.unresdetail { margin-top: 10px; }
.unresnote { font-size: 11.5px; color: var(--muted); margin: 0; line-height: 1.55; }
.blockers { margin: 9px 0 0; padding: 0 0 0 16px; font-size: 11.5px; color: var(--muted); line-height: 1.55; }
.blockers li { margin-bottom: 6px; }

.rulebar {
  margin-top: 16px; background: var(--pale); border: 1px solid var(--edge); border-radius: 10px;
  padding: 12px 15px; font-size: 12.5px; color: var(--muted); line-height: 1.5;
}

.loading, .empty { color: var(--muted); font-size: 13px; padding: 30px 0; text-align: center; }
/* A failure is not an empty state. They shared the muted grey rule above, so
   "could not be loaded" read exactly like "nothing has happened yet", which is
   the opposite of what it means. Found by a styling audit, 11 September 2026. */
.failed {
  color: var(--red-ink); background: var(--red-bg); border: 1px solid var(--red-edge);
  border-radius: 12px; font-size: 13.5px; line-height: 1.55; padding: 16px 18px;
}
.errorbox {
  background: var(--red-bg); border: 1px solid var(--red-edge); color: var(--red-ink);
  border-radius: 10px; padding: 14px 16px; font-size: 13px;
}

.placeholder {
  background: var(--paper); border: 1px dashed var(--edge); border-radius: 12px;
  padding: 28px 24px; max-width: 620px;
}
.placeholder h2 { font-size: 15px; margin: 0 0 8px; }
.placeholder p { font-size: 13px; color: var(--muted); margin: 0 0 8px; line-height: 1.55; }

.toast {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
  background: var(--deep); color: var(--on-deep); font-size: 13px; padding: 11px 16px;
  border-radius: 9px; max-width: 460px; z-index: 40;
}
.toast.warn { background: var(--amber-ink); }

/* A newer office build is on the server than the one in this window. It stays
   until the reload, in the corner, clear of the toast in the middle. */
.newbuild {
  position: fixed; right: 16px; bottom: 16px; z-index: 45; max-width: 420px;
  display: flex; align-items: center; gap: 12px;
  background: var(--paper); color: var(--ink); border: 1px solid var(--edge); border-radius: 12px;
  padding: 12px 12px 12px 16px; font-size: 13px; line-height: 1.45; box-shadow: var(--card-shadow);
}
.newbuildbtn {
  flex: none; min-height: 40px; padding: 8px 14px; border-radius: 9px; cursor: pointer;
  font: inherit; font-weight: 600; color: var(--on-deep); background: var(--deep); border: 1px solid var(--deep);
}
.newbuildbtn:hover { background: var(--deeper); }
.newbuildbtn:focus-visible { outline: 2px solid var(--deep); outline-offset: 2px; }
@media (max-width: 620px) {
  .newbuild { left: 16px; max-width: none; }
}


@media (max-width: 1180px) {
  .split, .dashgrid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 900px) {
  .shell, .shell.railed { grid-template-columns: 1fr; }
  .side { position: static; height: auto; flex-direction: row; align-items: center; flex-wrap: wrap; }
  /* The menu takes a row of its own under the brand and the footer. Sharing
     their row left it whatever width the three of them did not take, about
     80px on a tablet, so all seventeen items stacked in one narrow column and
     the dashboard began 900px down the page. */
  .nav { display: flex; flex-wrap: wrap; gap: 4px; padding: 4px 8px 8px; flex-basis: 100%; order: 1; }
  /* Groups fold the menu on a desktop. At this width the whole menu is one
     wrapped row, so the headers go and their items come up a level. A closed
     group still shows its items here, because the control that would reopen
     it is the header that just went. */
  .navgroupbtn, .railtoggle { display: none; }
  /* .navitem is full width in the column layout, which in a wrapped row puts
     one item on every line. */
  .navitem { width: auto; }
  .navsub, .navsub.closed { display: contents; }
  .sidefoot {
    border-top: 0; padding: 8px 14px; margin-left: auto;
    display: flex; flex-direction: row; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px;
  }
  /* The foot's group has no header at this width, like the others, so its
     items sit in the footer's row beside Sign out. */
  .navfoot { display: contents; }
  .themeswitch, .usercard { margin-bottom: 0; }
  .sideout { width: auto; }
  .envtag { display: none; }
  .topbar { flex-direction: column; align-items: flex-start; gap: 12px; }
}

/* A phone. The wrapped row above still put seventeen items and the footer
   above the page, so the dashboard began a screen and a half down. Here the
   sidebar is one row, brand and a Menu button, and the menu drops down as a
   single column when asked for and folds away when a page is chosen. */
.menubtn { display: none; }
@media (max-width: 640px) {
  .menubtn {
    display: inline-flex; align-items: center; gap: 6px; margin-left: auto; flex: none;
    font: inherit; font-size: 12.5px; font-weight: 600; color: var(--side-ink);
    background: var(--side-raise); border: 1px solid var(--side-line); border-radius: 8px;
    padding: 7px 11px; cursor: pointer; min-height: 36px;
  }
  .menubtn:focus-visible { outline: 2px solid var(--side-focus); outline-offset: 2px; }
  .menubtn svg { width: 16px; height: 16px; }
  .brand { width: 100%; padding: 12px 14px; }
  .plantpick, .nav, .sidefoot { display: none; }
  .shell.menuopen .plantpick { display: flex; width: calc(100% - 20px); }
  /* The whole panel scrolls (S1): a footer pinned below a scrolling menu left a short phone no menu at all. */
  .shell.menuopen .nav { display: flex; flex-direction: column; flex-wrap: nowrap; gap: 2px; padding: 6px 10px 10px; flex: none; overflow: visible; }
  .shell.menuopen .navitem { width: 100%; }
  .shell.menuopen .sidefoot {
    display: flex; flex-direction: column; align-items: stretch; width: 100%;
    margin-left: 0; padding: 4px 12px 14px; border-top: 1px solid var(--side-line);
    /* A wrapping column in the fixed-height panel wraps sideways, off the phone. */
    flex-wrap: nowrap; justify-content: flex-start;
  }
  /* Menu first, then the footer, on a phone. */
  .shell.menuopen .sidefoot { order: 2; }
  .shell.menuopen .navfoot { display: flex; max-height: none; padding: 0; order: 0; } /* order 1 from the tablet .nav rule put Sign out above it */
  .shell.menuopen .themeswitch, .shell.menuopen .usercard { margin-bottom: 8px; }
  .shell.menuopen .sideout { width: 100%; }
  .topbar { padding: 10px 14px; gap: 8px; }
  .search { width: 100%; }
  .body { padding: 16px 14px 48px; }
  .pagehead { padding: 16px 14px 14px; flex-direction: column; align-items: stretch; gap: 10px; }
  .stats { grid-template-columns: 1fr; }
  .hero { padding: 18px 16px; }
  .herokpis { grid-template-columns: 1fr; }
  .panel, .stat, .tablewrap { border-radius: 12px; }
  .panel { padding: 14px 14px 16px; }
  .tabletools { flex-wrap: wrap; }
  .tabletools .search { flex-basis: 100%; }
  /* A wide table scrolls inside its card; the page never scrolls sideways. */
  .panel, .tablewrap { overflow-x: auto; }
}

/* The phone, second block, kept apart so neither runs past the length the
   test allows. The top bar and the menu, from Sandra's iPhone on 18 September. */
@media (max-width: 640px) {
  /* One row: the bell and the person on the right, the search folded to the
     row beneath, the clock gone because the phone shows one. Until 18
     September this stacked into three rows on Sandra's iPhone. */
  .topbar { padding: 10px 14px; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
  /* Written with the bar's own name in front, because the base rules for
     the search and the clock sit later in this file and would win otherwise. */
  .topbar .searchwrap { order: 3; flex: 0 0 100%; max-width: none; }
  .topbar .clock { display: none; }
  .search { width: 100%; }
  /* The open menu covers the page rather than pushing it a screen down. */
  .shell.menuopen .side {
    position: fixed; inset: 0; z-index: 60; overflow-y: auto; height: 100vh;
    flex-direction: column; align-items: stretch; flex-wrap: nowrap;
  }
  .shell.menuopen .brand { position: sticky; top: 0; z-index: 1; background: var(--side-bg); border-bottom: 1px solid var(--side-line); }
}

/* The phone, third block: the header in one row and the Menu in groups. C7,
   26 September 2026. Measured at 390 that day, the header still took three
   rows before the page's name (logo and Menu; theme, bell and person; search)
   and the Menu was one flat list of 49 rows. Now the row is the logo, the
   page's name, a search button and the Menu, and it stays at the top while
   the page scrolls. The theme, the bell and the person sit at the top of the
   open Menu (startPhoneHeader in erp.js). The page's heading stays for a
   screen reader and is not drawn a second time under the header. */
.phonetitle, .searchbtn, .phonetools { display: none; }
@media (max-width: 640px) {
  .side { position: sticky; top: 0; z-index: 25; border-right: 0; border-bottom: 1px solid var(--side-line); }
  .brand { gap: 10px; padding: 8px 12px; }
  .brandname { display: none; }
  .brandtext { flex: 1 1 auto; }
  .phonetitle {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
    font-size: 15px; font-weight: 600; line-height: 1.25; overflow-wrap: anywhere; color: var(--side-ink);
  }
  .searchbtn {
    display: grid; place-items: center; flex: none; width: 42px; height: 40px; cursor: pointer;
    color: var(--side-ink); background: var(--side-raise); border: 1px solid var(--side-line); border-radius: 8px;
  }
  .searchbtn svg { width: 18px; height: 18px; }
  .searchbtn:focus-visible { outline: 2px solid var(--side-focus); outline-offset: 2px; }
  .searchbtn[aria-expanded="true"] { border-color: var(--side-ink); }
  .menubtn { margin-left: 0; position: relative; min-height: 40px; }
  .menubtn .badge { top: -6px; right: -6px; }
  /* The search is a row of its own only when the search button asks for it.
     Written with .shell in front, because the base rules for the top bar and
     the page head sit later in this file and would win otherwise: they had
     been setting the phone's page head right aligned since it was written. */
  .shell .topbar { display: none; }
  .shell.searchopen .topbar { display: flex; top: 57px; }
  .shell .topbar .kbd { display: none; }
  .shell .pagehead h1 {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  .shell .pagehead .crumbsub { margin: 0; }
  .shell .pagehead .crumbsub:empty { display: none; }
  .shell .pagehead { padding: 12px 14px; flex-direction: column; align-items: stretch; gap: 10px; }
}

/* The phone, fourth block, kept apart for the length the test allows: the
   open Menu, its tools strip and its groups. */
@media (max-width: 640px) {
  .shell.menuopen .phonetools { display: block; background: var(--paper); border-bottom: 1px solid var(--side-line); }
  .phonetools .topright { margin-left: 0; justify-content: flex-end; padding: 8px 12px; }
  .phonetools .clock { display: none; }
  .phonetools .menu { left: 12px; right: 12px; min-width: 0; }
  /* The Menu in the desktop sidebar's groups, each folding, the page you are
     on unfolded. Every row a thumb's height. */
  .shell.menuopen .navgroupbtn { display: flex; min-height: 46px; font-size: 14px; }
  .shell.menuopen .navsub { display: block; padding-left: 18px; }
  .shell.menuopen .navsub.closed { display: none; }
  .shell.menuopen .navitem { min-height: 44px; font-size: 14px; }
}

/* Data tables. The reference system reads as rows rather than cards for
   anything that is a list, so lists here do too: white rows, a light indigo
   header, and the status carried as a coloured pill rather than as a word
   nobody scans. */
.tablewrap {
  border: 1px solid var(--line); border-radius: 16px;
  /* A table wider than its card scrolls inside the card at every width, not
     only on the phone: the phone rule above sits earlier in this file, so a
     plain overflow: hidden here used to clip the last columns, the Open
     buttons among them, on a 1024 pixel tablet. */
  overflow-x: auto; overflow-y: hidden;
  box-shadow: var(--card-shadow);
  /* A soft fade at the right edge while the table can still scroll
     sideways, gone once scrolled to the end (P4, finding 3). Two layers:
     a cover the colour of the card that scrolls with the table and hides
     the shadow once it reaches the table's true right edge, and the shadow
     itself, held to the card's own right edge. Both CSS only, no listener. */
  background-color: var(--paper);
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0), var(--paper) 70%),
    linear-gradient(to right, rgba(0, 0, 0, 0), var(--table-fade-shadow));
  background-repeat: no-repeat, no-repeat;
  background-position: 100% 0, 100% 0;
  background-size: 40px 100%, 14px 100%;
  background-attachment: local, scroll;
}
.body > .panel + .panel, .body > .split + .panel { margin-top: 14px; }
.tabletools {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  border-bottom: 1px solid var(--line);
}
.search {
  flex: 1; max-width: 320px; font: inherit; font-size: 13px; color: var(--ink);
  background: var(--bg); border: 1px solid var(--edge); border-radius: 8px; padding: 8px 11px;
}
.search:focus-visible { outline: 2px solid var(--deep); outline-offset: 1px; }
.count { margin-left: auto; font-size: 12px; color: var(--muted); }

table { width: 100%; border-collapse: collapse; }
thead th {
  background: var(--deep-wash); text-align: left; font-size: 10px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted);
  padding: 10px 16px; white-space: nowrap;
}
/* Denser than it was, and the density comes from the padding alone. The
   type stays at 13px: the owners reading this are in their fifties and
   sixties, and CLAUDE.md asks for legible type before it asks for anything. */
tbody td { padding: 11px 16px; border-top: 1px solid var(--line); font-size: 13px; vertical-align: middle; }
tbody tr:hover { background: var(--deep-wash); }
/* The header takes the same alignment as the figures under it. Without the
   th here the class alignHeaders adds does nothing, which is exactly what
   happened: BEGINNING sat at the left of its column and its figure at the
   right, a hundred pixels apart, reading as two different columns. */
/* A figure and its unit stay on one line (U6, 28 September: the Transfers
   totalizers wrapped "30950902.3" over "kg"). The words columns beside them,
   Continuity and Recorded by, are the ones that may wrap instead. */
td.num { text-align: right; font-variant-numeric: tabular-nums; font-size: 13px; white-space: nowrap; }
thead th.num { text-align: right; }
/* W3, 28 September 2026: every office table reads cleanly (public/table_cells.js).
   A date never wraps, and neither does a short label: a bullet or tank name,
   a plate, a first name, a status, a document number. Long free text is the
   one thing that wraps, and it takes the width these give up. */
td.date, th.date, td.label, th.label, span.date { white-space: nowrap; }
/* A button in a row says its word on one line: "Type BOL", not "Type" over "BOL". */
td .rowbtn { white-space: nowrap; }
/* Nothing entered is a dim dash, never a nought and never a word repeated
   down a column. The note under a table says once what the dashes mean. */
.dash { color: var(--faint); }
.tablenote { margin: 8px 16px 0; font-size: 12px; color: var(--muted); }
td.dim { color: var(--muted); }
.rowtitle { font-weight: 600; }
/* A row title that opens something, read as a link rather than a heading.
   Trucks, the plate opens its loads (Godfrey, 26 September 2026). Deep blue
   is the one accent that can carry text (palette, 18 September). */
.platelink {
  font: inherit; font-weight: 600; color: var(--brand); background: none;
  border: 0; padding: 0; cursor: pointer; text-align: left;
}
.platelink:hover { text-decoration: underline; }
.platelink:focus-visible { outline: 2px solid var(--deep); outline-offset: 2px; border-radius: 4px; }

/* A figure that opens to the entries behind it, golden rule 3. It has to read
   as a number first and a control second, so it keeps the cell's type and
   alignment and carries a dotted rule underneath rather than a button's box.
   A real button, not a click handler on the cell, so it can be tabbed to. */
.cellopen {
  font: inherit; font-size: 13px; font-variant-numeric: tabular-nums;
  color: var(--ink); background: none; border: 0; padding: 0; cursor: pointer;
  border-bottom: 1px dotted var(--edge);
}
.cellopen:hover { color: var(--deep); border-bottom-color: var(--deep); }
.cellopen:focus-visible { outline: 2px solid var(--deep); outline-offset: 2px; }

/* The submission's own facts above a history: who entered the sheet, when it
   left the phone, when it reached the server. A list rather than a table,
   because there is one of each. */
.facts { margin: 0 0 12px; padding: 0 0 0 18px; font-size: 12.5px; color: var(--muted); }
.facts li { margin: 2px 0; }

/* A status pill, the reference's. The dot is currentColor, so it takes the
   pill's ink and no new pair has to be measured. One class covers reports,
   trust receipts, orders, residual and the unresolved panel. */
.tag {
  display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600;
  border-radius: 999px; padding: 3px 10px 3px 8px; white-space: nowrap; line-height: 1.4;
}
.tag::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.tag.ok { background: var(--green-bg); color: var(--green-ink); border: 1px solid var(--green-edge); }
.tag.warn { background: var(--amber-bg); color: var(--amber-ink); border: 1px solid var(--amber-edge); }
.tag.bad { background: var(--red-bg); color: var(--red-ink); border: 1px solid var(--red-edge); }
.tag.plain { background: var(--pale); color: var(--muted); border: 1px solid var(--edge); }

.rowbtn {
  font: inherit; font-size: 12px; font-weight: 600; color: var(--deep); background: var(--paper);
  border: 1px solid var(--edge); border-radius: 7px; padding: 6px 11px; cursor: pointer;
  /* An anchor can be one, for the blank paper sheets, which open in their own
     tab rather than replacing the page somebody is working on. */
  text-decoration: none; display: inline-flex; align-items: center;
}
.rowbtn:hover { background: var(--pale); border-color: var(--deep); }
.rowbtns { display: flex; flex-wrap: wrap; gap: 6px; }
/* Three buttons in a sheet's foot overflow a 375px phone, and the office app
   is opened on one. Found by a styling audit on 11 September 2026. */
.sheetfoot { flex-wrap: wrap; }
/* The month name has to stay readable while the figures scroll beside it. A
   six column table on a phone otherwise puts the label out of reach. */
.periodrow .rowtitle { min-width: 9rem; }
.rowbtn + .rowbtn { margin-left: 6px; }
.rowbtn.solid { background: var(--deep); border-color: var(--deep); color: var(--on-deep); }
.rowbtn.solid:hover { background: var(--deeper); }
.rowbtn:disabled { opacity: 0.5; cursor: default; }

/* Print and Excel, everywhere: one icon button each, side by side, never
   stacked, at least 40 px square for older eyes and gloves (C4, 26 September
   2026). The name lives in the title attribute and the accessible name, since
   the icon carries no text. */
.iconbtn {
  width: 40px; height: 40px; padding: 0; display: inline-flex; align-items: center;
  justify-content: center; border: 1px solid var(--edge); border-radius: 7px;
  background: var(--paper); color: var(--deep); cursor: pointer; flex: none;
}
.iconbtn:hover { background: var(--pale); border-color: var(--deep); }
.iconbtn:disabled { opacity: 0.4; cursor: default; }
.iconbtn:disabled:hover { background: var(--paper); border-color: var(--edge); }
.iconbtnsvg { width: 20px; height: 20px; }
.rowacts.rowbtns, td.rowacts { display: flex; gap: 6px; }

/* A row's own name, made a real button so Tab reaches it and Enter opens the
   record, with the whole row clickable too (item 4, 26 September). It reads
   as plain text, not as a button, until it has focus or a pointer over it. */
.rowlink {
  font: inherit; font-weight: inherit; color: inherit; background: none; border: none;
  padding: 0; margin: 0; cursor: pointer; text-align: left;
}
.rowlink:hover, .rowlink:focus-visible { text-decoration: underline; }

/* Detail sheet, the reference's modal. */
.scrim {
  position: fixed; inset: 0; background: rgba(27, 36, 52, 0.42); display: grid;
  place-items: center; padding: 26px; z-index: 30;
}
/* The shade in light is a navy one. Over a dark grey page it is plain black. */
:root[data-theme="dark"] .scrim { background: rgba(0, 0, 0, 0.55); }
.sheet {
  background: var(--paper); border-radius: 14px; width: min(1080px, 100%);
  max-height: 100%; display: flex; flex-direction: column; overflow: hidden;
}
.sheethead {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
  padding: 18px 22px 14px; background: linear-gradient(180deg, var(--deep-wash), var(--paper));
  border-bottom: 1px solid var(--line);
}
.sheetkind { font-size: 10px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase; color: var(--deep); }
.sheethead h2 { font-size: 17px; margin: 3px 0 2px; }
.sheetsub { font-size: 12px; color: var(--muted); margin: 0; }
.sheetbody { padding: 18px 22px; overflow: auto; }
.sheetfoot {
  display: flex; justify-content: flex-end; gap: 8px; padding: 13px 22px;
  border-top: 1px solid var(--line); background: var(--bg);
}
.closex {
  background: var(--paper); border: 1px solid var(--edge); border-radius: 50%; width: 30px; height: 30px;
  font-size: 15px; line-height: 1; color: var(--muted); cursor: pointer; flex: none;
}
.closex:hover { color: var(--ink); border-color: var(--deep); }
.sheetnote {
  background: var(--amber-bg); border: 1px solid var(--amber-edge); color: var(--amber-ink);
  border-radius: 9px; padding: 10px 13px; font-size: 12.5px; margin-bottom: 14px; line-height: 1.5;
}

/* A rule nobody has settled, said on the page rather than left to be inferred
   from a blank column. These screens carry more of these than they carry
   figures, which is the honest state of the paperwork rather than a gap in the
   build. */
.notice {
  background: var(--amber-bg); border: 1px solid var(--amber-edge); color: var(--amber-ink);
  border-radius: 10px; padding: 11px 14px; font-size: 12.5px; line-height: 1.55; margin-bottom: 14px;
}
.sheetbody .notice { margin-bottom: 14px; }
.panel .notice { margin: 0 0 12px; }

/* The daily closing message, ready to copy. Read only: nothing is typed
   here, it only holds words this page composed from figures typed elsewhere. */
.closingtext {
  width: 100%; min-height: 220px; font: inherit; font-size: 13px; line-height: 1.6;
  color: var(--ink); background: var(--bg); border: 1px solid var(--edge); border-radius: 10px;
  padding: 12px 14px; resize: vertical; margin-bottom: 14px; white-space: pre-wrap;
}
/* CANISTER / CYLINDER, inside the line by line table below the message. */
tr.grouprow td {
  font-weight: 600; font-size: 11.5px; letter-spacing: 0.04em; color: var(--muted);
  padding-top: 16px; border-top: 1px solid var(--line);
}
tr.grouprow:first-child td { padding-top: 6px; border-top: none; }

/* A cell in a row where the three counts disagree. Marked, never resolved. */
td.conflict { color: var(--red-ink); font-weight: 600; }
tr.voided td { color: var(--faint); text-decoration: line-through; }
tr.voided td:last-child { text-decoration: none; }

.totals {
  display: flex; flex-wrap: wrap; gap: 26px; margin-top: 16px; padding-top: 14px;
  border-top: 1px solid var(--line);
}
.totalpair { display: flex; flex-direction: column; gap: 2px; }
.totallabel {
  font-size: 10px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted);
}
.totalvalue { font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* The top bar ------------------------------------------------------------- */
.topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 11px 22px; background: var(--paper); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 20;
}
.searchwrap { position: relative; flex: 1; max-width: 460px; }
.searchicon {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; color: var(--faint); pointer-events: none;
}
.globalsearch {
  width: 100%; font: inherit; font-size: 13px; color: var(--ink); background: var(--bg);
  border: 1px solid var(--edge); border-radius: 9px; padding: 9px 34px 9px 34px;
}
.globalsearch:focus-visible { outline: 2px solid var(--deep); outline-offset: 1px; border-color: var(--deep); }
.kbd {
  position: absolute; right: 9px; top: 50%; transform: translateY(-50%);
  font: inherit; font-size: 10.5px; color: var(--faint); background: var(--paper);
  border: 1px solid var(--edge); border-radius: 5px; padding: 1px 6px; pointer-events: none;
}
.results {
  position: absolute; top: calc(100% + 7px); left: 0; right: 0; z-index: 30;
  background: var(--paper); border: 1px solid var(--edge); border-radius: 11px;
  box-shadow: 0 12px 34px rgba(15, 25, 40, 0.18); overflow: hidden; max-height: 60vh; overflow-y: auto;
}
.rgroup {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--faint); padding: 9px 13px 4px;
}
.rhit {
  display: flex; align-items: baseline; gap: 9px; width: 100%; text-align: left;
  background: none; border: 0; font: inherit; font-size: 13px; color: var(--ink);
  padding: 8px 13px; cursor: pointer;
}
.rhit:hover, .rhit[aria-selected="true"] { background: var(--pale); }
.rhit .rwhat { font-weight: 600; }
.rhit .rwhere { font-size: 11.5px; color: var(--muted); margin-left: auto; }
.rempty { padding: 16px 13px; font-size: 12.5px; color: var(--muted); }
.rheading { padding: 10px 13px 2px; font-size: 12.5px; font-weight: 600; color: var(--muted); }
.rhit.rsee .rwhat { font-weight: 500; color: var(--accent); }

.topright { display: flex; align-items: center; gap: 8px; margin-left: auto; position: relative; }
.clock { display: flex; flex-direction: column; align-items: flex-end; margin-right: 4px; }
.clocktime { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.clockdate { font-size: 10.5px; color: var(--muted); }

.iconbtn {
  position: relative; width: 34px; height: 34px; display: grid; place-items: center;
  background: none; border: 1px solid transparent; border-radius: 9px;
  color: var(--muted); cursor: pointer;
}
.iconbtn:hover { background: var(--pale); color: var(--ink); border-color: var(--line); }
.iconbtn svg { width: 17px; height: 17px; }
.ic-moon { display: none; }
:root[data-theme="dark"] .ic-sun { display: none; }
:root[data-theme="dark"] .ic-moon { display: block; }
.badge {
  position: absolute; top: 3px; right: 3px; min-width: 15px; height: 15px; padding: 0 3px;
  border-radius: 8px; background: var(--card-red); color: #FFFFFF; font-size: 9.5px;
  font-weight: 700; display: grid; place-items: center; line-height: 1;
}

.userbtn {
  display: flex; align-items: center; gap: 8px; background: none; border: 1px solid transparent;
  border-radius: 10px; padding: 4px 7px 4px 4px; cursor: pointer; color: inherit; font: inherit;
}
.userbtn:hover { background: var(--pale); border-color: var(--line); }
.userbtn .who { display: flex; flex-direction: column; align-items: flex-start; }
.userbtn .chev { width: 14px; height: 14px; color: var(--faint); }
.avatar.sm { width: 28px; height: 28px; font-size: 11px; }

.menu {
  position: absolute; top: calc(100% + 9px); right: 0; z-index: 30; min-width: 268px;
  background: var(--paper); border: 1px solid var(--edge); border-radius: 12px;
  box-shadow: 0 14px 40px rgba(15, 25, 40, 0.2); overflow: hidden;
}
.menuhead { padding: 12px 14px 10px; border-bottom: 1px solid var(--line); }
.menuname { font-size: 13.5px; font-weight: 600; }
.menusub { font-size: 11.5px; color: var(--muted); }
.menuitem {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: none; border: 0; font: inherit; font-size: 13px; color: var(--ink);
  padding: 10px 14px; cursor: pointer;
}
.menuitem:hover { background: var(--pale); }
.menuitem.danger { color: var(--red-ink); }
.menuline { height: 1px; background: var(--line); }
.noticeitem { padding: 11px 14px; border-bottom: 1px solid var(--line); }
.noticeitem:last-child { border-bottom: 0; }
.noticetitle { font-size: 12.5px; font-weight: 600; }
.noticebody { font-size: 11.5px; color: var(--muted); margin-top: 2px; line-height: 1.5; }
.noticego {
  background: none; border: 0; padding: 0; margin-top: 5px; font: inherit; font-size: 11.5px;
  font-weight: 600; color: var(--deep); cursor: pointer;
}

/* Saved views beside a list's search box (C10): the same .menu a bell or a
   user button opens, positioned in script under its own small "Views"
   button (listViewsMenu, public/erp.js) rather than by this button's own
   position, since a card that scrolls a wide table sideways clips anything
   below it and the menu needs to float clear of that. */
.viewsbox { display: inline-flex; }
/* Clamped in script (listViewsMenu's place()) to whatever room the window
   actually has above or below the button, so it scrolls its own list rather
   than running off the screen with Save this view out of reach. */
.viewsmenu { overflow-y: auto; }
.viewsrow { display: flex; align-items: center; gap: 6px; padding: 0; }
.viewsopen {
  flex: 1; text-align: left; background: none; border: 0; font: inherit; font-size: 13px;
  color: var(--ink); padding: 10px 0 10px 14px; cursor: pointer;
}
.viewsopen:hover { color: var(--deep); }
.viewsdel {
  background: none; border: 0; padding: 4px 14px; font-size: 15px; line-height: 1;
  color: var(--faint); cursor: pointer;
}
.viewsdel:hover { color: var(--red-ink); }

.pagehead {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 20px;
  padding: 24px 34px 20px; border-bottom: 1px solid var(--line); background: var(--paper);
}

/* The gradient Godfrey liked, used once, on the greeting. Kept to one place so
   it reads as a welcome rather than as decoration sprayed over the data. */
.hello {
  position: relative; overflow: hidden; border-radius: 16px; padding: 15px 20px;
  /* Carried over on 5 September when the runaway media query was closed. This
     margin lived in a second .hello rule that the query had swallowed, so below
     901px it was never applied at all. */
  margin-bottom: 20px;
  border: 1px solid var(--line);
  background:
    radial-gradient(120% 160% at 0% 0%, color-mix(in srgb, var(--card-brand) 13%, transparent), transparent 60%),
    radial-gradient(120% 160% at 100% 0%, color-mix(in srgb, var(--accent) 15%, transparent), transparent 62%),
    var(--paper);
}
/* In dark the blue corner goes and the neutral one stays. Godfrey, 25
   September 2026, wanted no tint of blue; a blue glow behind the greeting is
   exactly that, however faint. */
:root[data-theme="dark"] .hello {
  background:
    radial-gradient(120% 160% at 100% 0%, color-mix(in srgb, var(--accent) 15%, transparent), transparent 62%),
    var(--paper);
}

/* Period. Two date boxes are the right control for a report and the wrong one
   for a dashboard: they ask a question before showing anything. The presets
   answer it, and Custom brings the boxes back for the case that needs them. */
.oneday {
  font: inherit; font-size: 13px; color: var(--ink); background: var(--paper);
  border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px;
}
.period { display: flex; align-items: center; gap: 6px; }
.periodbtn {
  font: inherit; font-size: 12px; color: var(--muted); background: var(--paper);
  border: 1px solid var(--edge); border-radius: 8px; padding: 6px 11px; cursor: pointer;
}
.periodbtn:hover { color: var(--ink); border-color: var(--deep); }
.periodbtn[aria-pressed="true"] {
  background: var(--deep); border-color: var(--deep); color: var(--on-deep); font-weight: 600;
}
.range.hidden { display: none; }

/* Alerts on the dashboard. Sandra asked to see what is wrong without going
   looking for it. Each one is something the system can actually tell. They
   were three full width tinted banners above the figures, which is a lot of
   colour and a lot of height for three sentences. In the rail the dot carries
   the level and the panel carries the rest. */
.alertrow { display: flex; align-items: flex-start; gap: 11px; padding: 14px 0; border-top: 1px solid var(--line); }
.alertrow:first-of-type { border-top: 0; padding-top: 0; }
.alertdot { width: 8px; height: 8px; border-radius: 50%; background: var(--amber-ink); margin-top: 5px; flex: none; }
.alertrow.bad .alertdot { background: var(--red-ink); }
.alertrow.info .alertdot { background: var(--blue-ink); }
.alertrow strong { display: block; font-size: 13px; font-weight: 600; margin-bottom: 3px; }
.alertrow p { font-size: 11.5px; color: var(--muted); line-height: 1.55; margin: 0; }
.alertrow .statlink { margin-top: 11px; }

/* From the reference dashboards, where this is a grid of create buttons. Only
   the first of ours creates anything, because everything else is entered at
   the plant. */
.quick { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.quickbtn {
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
  padding: 14px; background: var(--paper); border: 1px solid var(--line);
  border-radius: 11px; cursor: pointer; text-align: left; font: inherit;
}
.quickbtn:hover { border-color: var(--deep); }
.quickico {
  width: 32px; height: 32px; border-radius: 10px; flex: none;
  background: var(--pale); color: var(--deep); display: grid; place-items: center;
}
.quickglyph { width: 17px; height: 17px; display: block; }
.quickname { font-size: 12px; font-weight: 600; color: var(--ink); line-height: 1.35; }

/* Every reference table ends with a line saying how much of the whole you are
   looking at. */
.tablefoot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--line);
  font-size: 11.5px; color: var(--muted);
}

.periodselect {
  font: inherit; font-size: 12.5px; color: var(--ink); background: var(--paper);
  border: 1px solid var(--edge); border-radius: 8px; padding: 7px 10px; cursor: pointer;
  min-width: 148px;
}
.periodselect:focus-visible { outline: 2px solid var(--deep); outline-offset: 1px; }

/* The two closing figures on the discrepancy panel. Two, never one, because a
   load still emptying belongs in one of them and Gasmate has not said which.
   Question 67. */
.runbar { display: flex; flex-wrap: wrap; gap: 12px; padding: 14px; }
.runfig {
  flex: 1; min-width: 200px; padding: 12px 14px;
  background: var(--bg); border: 1px solid var(--line); border-radius: 10px;
}
.runlabel {
  font-size: 10px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--faint);
}
.runsub { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
/* Words where a figure would be, small and dim, never figure size (U5, 28 Sept 2026). */
.runnone { font-size: 13px; color: var(--muted); padding: 8px 0; }
.bignum.isdown { color: var(--red-ink); }
.bignum.isup { color: var(--green-ink); }
.tinynote {
  font-size: 11px; color: var(--faint); line-height: 1.45; margin: 0; padding: 10px 14px 14px;
}

/* The discrepancy report, load by load, 25 September 2026: every load listed,
   their sheet's figures in their own shaded columns beside ours, and a plain
   line at the top saying what holds the figures back. The shading is the page
   ground, so her figures read as a quieter column than ours without a second
   accent; the group heading above says whose they are in words as well. */
.loadheadline { font-size: 13.5px; font-weight: 600; color: var(--ink); margin: 0 0 4px; line-height: 1.45; }
.loadbecause { font-size: 12.5px; color: var(--muted); margin: 0 0 14px; line-height: 1.5; }
.loadtable th.group {
  text-align: center; font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--muted); border-bottom: 1px solid var(--line);
}
.loadtable td.theirs { background: var(--bg); }
.loadtable td.whycell { min-width: 190px; }
.whyempty { display: block; font-size: 12px; color: var(--muted); line-height: 1.4; white-space: normal; }
.kgsigned { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.kgsigned.short { color: var(--red-ink); }
.kgsigned.over { color: var(--green-ink); }
.loadtable tr.disagree td {
  font-size: 12px; color: var(--amber-ink); background: var(--amber-bg); line-height: 1.45;
}
.loadtable tr.totalrow td { font-weight: 600; border-top: 1px solid var(--edge); }
.totalwords { display: block; font-size: 11.5px; font-weight: 400; color: var(--muted); white-space: normal; }

/* The small forms on the starting figures sheets. Three rows and a button, so
   this is a stacked label and control rather than the grid the entry screens
   use: a two column form for three fields reads as a table with nothing in it. */
.formrows { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
.formrow { display: flex; flex-direction: column; gap: 5px; width: min(420px, 100%); }
.formlabel { font-size: 12px; font-weight: 600; color: var(--ink); }
.formrow input {
  font: inherit; font-size: 13px; color: var(--ink); background: var(--paper);
  border: 1px solid var(--edge); border-radius: 7px; padding: 8px 10px; width: 100%;
}
.formrow input:focus-visible { outline: 2px solid var(--deep); outline-offset: 1px; }
/* A long form needs saying where you are in it. */
.formhead {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--muted); margin: 18px 0 2px;
}
.formrows > .formhead:first-child { margin-top: 0; }
.formmsg { font-size: 12px; color: var(--red-ink); margin: 0; }

/* The DTR. Petron's page, so the density is theirs: twenty piece columns plus
   five, which scrolls sideways inside the panel rather than squeezing the
   labels into two characters each. */
.dtrruns { display: flex; flex-wrap: wrap; gap: 26px; padding: 16px 18px 18px; }
.dtrfig { min-width: 150px; }
.tablescroll { overflow-x: auto; }
.dtrgrid { min-width: 1180px; }
.dtrgrid th.colhead { font-size: 10px; line-height: 1.25; white-space: normal; min-width: 52px; }
.dtrgrid td.nocol { background: var(--pale); }
.dtrgrid td.missing { background: var(--amber-bg); }
.dtrgrid tr.subrow td { padding-top: 0; }
.dtrgrid tr.totalrow td { font-weight: 700; border-top: 2px solid var(--edge); }
.blockrow { padding: 12px 18px; border-top: 1px solid var(--line); }
.blocktitle { font-weight: 650; font-size: 13px; color: var(--ink); }
.blockwhy { font-size: 12px; color: var(--muted); margin: 3px 0 7px; }

/* The trust receipt form's line grid, and the return box on an open receipt. */
.linegrid { width: 100%; border-collapse: collapse; margin: 6px 0 10px; }
.linegrid th { text-align: left; font-size: 11px; color: var(--muted); padding: 4px 6px; }
.linegrid td { padding: 3px 6px; }
.linegrid input { width: 100%; font: inherit; font-size: 13px; padding: 6px 8px; border: 1px solid var(--edge); border-radius: 6px; background: var(--paper); color: var(--ink); }
.qtyin { width: 64px; font: inherit; font-size: 13px; padding: 5px 7px; border: 1px solid var(--edge); border-radius: 6px; margin-right: 6px; background: var(--paper); color: var(--ink); }
/* An amount typed against an invoice or a bill: wide enough for 1,000,000.00,
   and marked when it is blank, nought, or more than is open. */
.qtyin.money { width: 116px; text-align: right; }
.qtyin.bad { border-color: var(--red-ink); }

/* ---------------------------------------------------------------------------
   An entry table worked like their Excel sheet (public/sheet_grid.js).
   Godfrey, 26 September: "format it like an Excel sheet or a Smartsheet...
   since that's what they have been doing for the last 10 years." Thin cell
   lines and no box inside a box; figures right-aligned in even-width digits;
   the header row and the row names stay put while the sheet scrolls, with a
   darker line where they are frozen, as Excel draws it; the chosen cell is
   outlined in the one accent. A grey cell is added up, not typed. */
.sheetbar {
  display: flex; align-items: center; gap: 12px; min-height: 34px;
  margin: 12px 14px 8px; padding: 6px 10px; font-size: 13px;
  background: var(--paper); border: 1px solid var(--line); border-radius: 6px;
}
.sheetbarname { font-weight: 700; color: var(--ink); min-width: 200px; padding-right: 12px; border-right: 1px solid var(--line); white-space: nowrap; }
.sheetbartext { color: var(--muted); font-variant-numeric: tabular-nums; }
.sheetbarname:empty { display: none; }
.sheetwrap {
  margin: 0 14px; overflow: auto; max-height: max(360px, calc(100vh - 300px));
  background: var(--paper); border: 1px solid var(--edge); border-radius: 6px;
  scroll-padding-top: 44px; scroll-padding-left: 200px;
}
table.sheetgrid {
  border-collapse: separate; border-spacing: 0; font-size: 13px;
  border-top: 1px solid var(--line); border-left: 1px solid var(--line);
}
.sheetwrap > table.sheetgrid { width: max-content; min-width: 100%; border: 0; }
table.sheetgrid th, table.sheetgrid td {
  height: 30px; padding: 0; border-top: 0;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
table.sheetgrid tr:hover { background: transparent; }
table.sheetgrid th {
  background: var(--deep-wash); color: var(--ink); font-size: 12px; font-weight: 700;
  text-transform: none; letter-spacing: 0; text-align: left; padding: 6px 8px; line-height: 1.25;
}
table.sheetgrid th.num { text-align: right; }
.sheetwrap table.sheetgrid thead th {
  position: sticky; top: 0; z-index: 2; min-width: 64px; max-width: 84px;
  white-space: normal; text-align: center; vertical-align: bottom;
  border-bottom: 1px solid var(--edge);
}
table.sheetgrid th.rowhead {
  position: sticky; left: 0; z-index: 1; min-width: 190px; max-width: 320px;
  background: var(--paper); font-weight: 400; text-align: left; white-space: nowrap;
  border-right: 1px solid var(--edge);
}
.sheetwrap table.sheetgrid thead th.rowhead { z-index: 3; left: 0; text-align: left; background: var(--deep-wash); }
.rownum { display: inline-block; min-width: 2em; font-weight: 700; }
.sheetwrap table.sheetgrid thead th.offpaper { color: var(--muted); font-weight: 400; font-style: italic; }
table.sheetgrid tr.status > *, table.sheetgrid tr.foot > * { background: var(--pale); font-weight: 700; }
table.sheetgrid tr.sub > th, table.sheetgrid tr.sub > td.sum { background: var(--deep-wash); font-weight: 600; }
table.sheetgrid td.sum, table.sheetgrid td.blankcell {
  padding: 0 8px; text-align: right; color: var(--muted); background: var(--bg);
  font-variant-numeric: tabular-nums; cursor: pointer; min-width: 64px;
}
table.sheetgrid td.blankcell { cursor: default; }
table.sheetgrid td:not(:has(input, select, textarea)):not(.sum):not(.blankcell) { padding: 0 8px; }
table.sheetgrid td:has(> button) { padding: 2px 6px; }
table.sheetgrid td input, table.sheetgrid td select, table.sheetgrid td textarea {
  display: block; width: 100%; height: 100%; min-height: 30px; min-width: 64px; box-sizing: border-box;
  margin: 0; padding: 0 8px; border: 0; border-radius: 0; box-shadow: none; outline: none;
  background: transparent; color: var(--ink); font: inherit; font-size: 13px;
}
table.sheetgrid td input[inputmode="numeric"], table.sheetgrid td input[inputmode="decimal"],
table.sheetgrid td input[type="number"] { text-align: right; font-variant-numeric: tabular-nums; }
table.sheetgrid td input[type="number"] { appearance: textfield; -moz-appearance: textfield; }
table.sheetgrid td input[type="number"]::-webkit-inner-spin-button,
table.sheetgrid td input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
table.sheetgrid td input:not(:focus)::placeholder { color: transparent; }
table.sheetgrid td input:disabled { color: var(--ink); -webkit-text-fill-color: var(--ink); }
table.sheetgrid td:focus-within { outline: 2px solid var(--brand); outline-offset: -2px; background: var(--paper); }
.gridfoot p, .gridnote { margin: 8px 14px 0; font-size: 12px; color: var(--muted); }
.gridnote.warn { color: var(--amber-ink); background: var(--amber-bg); border: 1px solid var(--amber-edge); border-radius: 6px; padding: 8px 10px; font-size: 13px; }
@media (max-width: 640px) {
  table.sheetgrid th.rowhead { min-width: 140px; white-space: normal; }
  .sheetbarname { min-width: 0; }
}

/* ---------------------------------------------------------------------------
   The dashboard, rebuilt on 4 September to the format Godfrey chose: a dark
   hero band carrying the day's figures, stat cards with a progress row, two
   bands of a wide column beside a narrow one, and a closing row of tinted
   cards for what needs a person.

   Two devices in that reference are not reproduced, and the omission is the
   point. Every card there carries a percentage against yesterday, and a
   "vs last month" figure under the bar. Setting a figure against an earlier
   period means rebuilding what was true then, which this system does not do,
   so the slots carry what the figure is and how much of the range was entered.
   --------------------------------------------------------------------------- */

.hero {
  background: var(--hero-bg);
  color: var(--hero-ink);
  border-radius: 18px;
  padding: 22px 24px;
  margin-bottom: 18px;
}
.herotop { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.herotitle { font-size: 25px; font-weight: 650; margin: 0; letter-spacing: -0.01em; color: var(--hero-ink); }
.herosub { margin: 4px 0 0; font-size: 13.5px; color: var(--hero-ink); opacity: 0.82; }
.herochip {
  font-size: 12px; font-weight: 600; white-space: nowrap;
  padding: 6px 12px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.16); color: var(--hero-ink);
}
.herokpis {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-top: 20px;
}
.herokpi { background: rgba(255, 255, 255, 0.12); border-radius: 11px; padding: 13px 15px; }
.herokpihead {
  display: flex; align-items: center; gap: 8px;
  font-size: 11.5px; font-weight: 600; color: var(--hero-ink); opacity: 0.86;
}
.heroicon { width: 15px; height: 15px; flex: none; }
.herokpival {
  font-size: 22px; font-weight: 680; margin-top: 7px; color: var(--hero-ink);
  font-variant-numeric: tabular-nums; letter-spacing: -0.015em;
}
.herokpifoot { font-size: 11px; margin-top: 2px; color: var(--hero-ink); opacity: 0.74; }

/* The activity feed on the dashboard: one line per sheet entered, newest
   first, each opening the sheet. Replaced a four column table on 8 September. */
.feed { display: flex; flex-direction: column; }
.feedrow { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 11px 0; border-top: 1px solid var(--line); }
.feedrow:first-child { border-top: 0; padding-top: 4px; }
.feedico { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; background: var(--pale); color: var(--deep); font-size: 11px; font-weight: 700; letter-spacing: 0.04em; }
.feedline { font-size: 13.5px; min-width: 0; }
.feedline b { font-weight: 600; }
.feedmeta { font-size: 11.5px; color: var(--faint); margin-top: 1px; }

/* The three figures behind an M&R still out, one per line, so 1,048 sent,
   210 back and 18 scrapped are three numbers and not one run together. */
.mrline { display: flex; justify-content: space-between; gap: 10px; font-size: 12px; color: var(--muted); white-space: nowrap; }
.mrline b { color: var(--ink); font-variant-numeric: tabular-nums; font-weight: 600; }

/* Sortable table headings on the report list. */
th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { color: var(--ink); }
th.sortable .dir { margin-left: 4px; color: var(--deep); }
.tabletools select { font: inherit; font-size: 12.5px; color: var(--ink); background: var(--paper); border: 1px solid var(--edge); border-radius: 8px; padding: 6px 10px; }

/* The progress row on a stat card. */
.statbar { margin-top: 12px; }
.statbarhead {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 11.5px; color: var(--faint); margin-bottom: 5px;
}
.statbarpct { font-weight: 650; color: var(--muted); font-variant-numeric: tabular-nums; }
.stattrack { height: 6px; border-radius: 999px; background: var(--pale); overflow: hidden; }
.statfill { height: 100%; border-radius: 999px; background: var(--deep); }
.statbarfoot { font-size: 11px; color: var(--faint); margin-top: 6px; }
.statstate {
  margin-left: auto; font-size: 10.5px; font-weight: 650; padding: 3px 8px;
  border-radius: 999px; white-space: nowrap;
}
.statstate.warn { background: var(--amber-bg); color: var(--amber-ink); border: 1px solid var(--amber-edge); }

/* The ranked list. */
.ranklist { display: flex; flex-direction: column; }
.rankrow {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-bottom: 1px solid var(--line);
}
.rankrow:last-child { border-bottom: none; }
/* The bullet truck that carries the rank. The tank and the cab are the tone,
   the window is paper, the wheels are ink, and the number is white on the
   tone, a pair the stat chip tests already hold above AA. */
.ranktruck { width: 76px; height: 34px; flex: none; display: block; }
.ranktruck .body { fill: var(--card-slate); }
.ranktruck.tone-red .body { fill: var(--card-red); }
.ranktruck.tone-amber .body { fill: var(--card-violet); }
.ranktruck .glass { fill: var(--paper); }
.ranktruck .wheel { fill: var(--ink); }
.ranktruck .hub { fill: var(--paper); }
.ranktruck .rank { fill: #FFFFFF; font-size: 12.5px; font-weight: 700; font-family: inherit; }
.rankwho { flex: 1; min-width: 0; }
.rankname { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.ranksub { font-size: 11.5px; color: var(--faint); margin-top: 2px; }
.rankfig { text-align: right; flex: none; }
.ranknum { font-size: 14px; font-weight: 650; color: var(--ink); font-variant-numeric: tabular-nums; }

/* The closing row of tinted cards. */
.pendcount {
  font-size: 11.5px; font-weight: 650; padding: 4px 10px; border-radius: 999px;
  background: var(--pale); color: var(--deep);
}
.pendrow { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 14px; }
.pend { border-radius: 16px; padding: 16px 17px; border: 1px solid; }
.pend.tone-red { background: var(--red-bg); border-color: var(--red-edge); }
.pend.tone-amber { background: var(--amber-bg); border-color: var(--amber-edge); }
.pend.tone-blue { background: var(--pale); border-color: var(--edge); }
.pendicon { display: block; width: 30px; height: 30px; border-radius: 9px; margin-bottom: 11px; }
.pend.tone-red .pendicon { background: var(--card-red); }
.pend.tone-amber .pendicon { background: var(--card-violet); }
.pend.tone-blue .pendicon { background: var(--card-brand); }
.pendtitle { font-size: 14px; font-weight: 650; color: var(--ink); line-height: 1.35; }
.penddetail { font-size: 12.5px; color: var(--muted); margin-top: 6px; line-height: 1.5; }
.pendbtn {
  margin-top: 13px; width: 100%; padding: 9px 12px; border-radius: 9px;
  border: 1px solid var(--edge); background: var(--paper); color: var(--ink);
  font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.pendbtn:hover { background: var(--deep-wash); }

@media (max-width: 1080px) {
  .herokpis { grid-template-columns: repeat(2, 1fr); }
  .pendrow { grid-template-columns: 1fr; }
}
@media (max-width: 620px) {
  .herokpis { grid-template-columns: 1fr; }
  .herotitle { font-size: 21px; }
}
.ranknum.isshort { color: var(--red-ink); }
.ranknum.isover, .divnum.over { color: var(--green-ink); }

/* What a peso figure rests on, said under the figures rather than in a tooltip
   nobody opens. */
.valbar {
  margin-top: 14px; padding: 14px 16px; border-radius: 10px;
  background: var(--deep-wash); border: 1px solid var(--line);
  font-size: 13px; color: var(--muted);
}
.valbar strong { display: block; color: var(--ink); font-size: 13.5px; margin-bottom: 5px; }
.valbar p { margin: 0 0 6px; line-height: 1.55; }
.valbar p:last-child { margin: 0; }
.valbar .dim { color: var(--faint); font-size: 12.5px; }
.pesosub { font-size: 12px; color: var(--faint); margin-top: 3px; font-variant-numeric: tabular-nums; }

/* The plant's own things: trucks, bullets, tanks. They were a grey sentence
   with middots between them, which read as prose rather than as a list of
   objects somebody maintains. Godfrey, 22 September. */
.thinglist { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.thing {
  font-size: 12.5px; font-weight: 600; color: var(--ink); background: var(--pale);
  border: 1px solid transparent; border-radius: 4px; padding: 5px 10px; line-height: 1.4;
}

/* Settings, one line per rule. Godfrey, 26 September 2026: each rule wrapped
   its name and explanation into five lines, the date broke over three, and
   Change sat on top of History. The explanation now folds under an arrow
   beside the name, the date is short and never wraps, and the actions sit
   side by side. The same arrow folds each panel's note and the page's own. */
/* Plain inline flow inside the button, so on a name that wraps the arrow
   follows its last word rather than standing at the far edge of the cell. */
.settoggle {
  font: inherit; color: inherit; background: none; border: 0; margin: 0; padding: 3px 0;
  text-align: left; cursor: pointer;
}
.settoggle:hover > span { text-decoration: underline; }
.setnobr { white-space: nowrap; }
.settoggle:focus-visible { outline: 2px solid var(--deep); outline-offset: 2px; border-radius: 4px; }
.setchev {
  width: 15px; height: 15px; margin-left: 6px; vertical-align: -3px;
  color: var(--faint); transition: transform 0.12s ease;
}
.settoggle[aria-expanded="true"] .setchev { transform: rotate(180deg); }
.setnote { font-size: 12.5px; color: var(--muted); line-height: 1.55; margin: -8px 0 14px; max-width: 78ch; }
.sethow { margin: 0 0 12px; }
.sethow > .settoggle { font-size: 12.5px; font-weight: 600; color: var(--brand); }
.sethow > .setnote { margin: 2px 0 0; }
.settable tbody td { padding-top: 7px; padding-bottom: 7px; }
.setval, .setsince, .setacts { white-space: nowrap; }
.settable td.setval { padding-left: 8px; }
.setval .tag { font-size: 11px; padding: 1px 8px 1px 6px; }
.setval > span + .tag { margin-left: 6px; }
.setwords, .setlater {
  display: block; white-space: normal; max-width: 16.5rem; margin-left: auto; line-height: 1.45;
}
.setlater { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.setsince { color: var(--muted); }
/* Beginning figures: a phrase, not a date, in the third column, so it wraps
   rather than running the row wide. Godfrey, 26 September 2026. */
.setsrc { color: var(--muted); white-space: normal; max-width: 22rem; }
.setacts { width: 1%; text-align: right; }
.setacts .rowbtn { padding: 4px 10px; }
.setlink {
  font: inherit; font-size: 12px; font-weight: 600; color: var(--brand); background: none;
  border: 0; padding: 5px 2px; margin-left: 10px; cursor: pointer;
}
.setlink:first-child { margin-left: 0; }
.setlink:hover { text-decoration: underline; }
.setlink:focus-visible { outline: 2px solid var(--deep); outline-offset: 2px; border-radius: 4px; }
.settable .setwhatrow td { border-top: 0; padding-top: 0; padding-bottom: 10px; }
.setwhat { font-size: 12.5px; color: var(--muted); line-height: 1.55; margin: 0 0 4px; max-width: 78ch; }

/* A phone: stacked, still compact. The name on its own line, then the value
   with the actions beside it, then the date. */
@media (max-width: 640px) {
  .settable thead { display: none; }
  .settable, .settable tbody { display: block; }
  .settable tr {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
    gap: 2px 12px; padding: 9px 0; border-top: 1px solid var(--line);
  }
  .settable tbody tr:first-child { border-top: 0; }
  .settable tr[hidden] { display: none; }
  .settable tbody td { padding: 0; border-top: 0; }
  .settable td.setname { grid-column: 1 / -1; }
  .settable td.setval { grid-column: 1; grid-row: 2; text-align: left; white-space: normal; padding-left: 0; }
  .settable td.setsince { grid-column: 1; grid-row: 3; font-size: 12px; }
  .settable td.setsince:not(:empty)::before { content: 'since '; }
  .settable td.setsrc { grid-column: 1; grid-row: 3; font-size: 12px; white-space: normal; max-width: none; }
  .settable td.setacts { grid-column: 2; grid-row: 2 / span 2; width: auto; }
  .settable tr.setwhatrow { display: block; padding-top: 0; border-top: 0; }
  .settable tr.setwhatrow[hidden] { display: none; }
  .setwords, .setlater { margin-left: 0; max-width: none; }
  .settoggle { min-height: 34px; }
  /* The measurement contract: the question beside its reference, its state
     under it, rather than a column two words wide. */
  .setcontract thead { display: none; }
  .setcontract, .setcontract tbody { display: block; }
  .setcontract tr {
    display: grid; grid-template-columns: 2.6rem minmax(0, 1fr); gap: 4px 8px;
    padding: 9px 0; border-top: 1px solid var(--line);
  }
  .setcontract tbody tr:first-child { border-top: 0; }
  .setcontract tbody td { padding: 0; border-top: 0; }
  .setcontract td:nth-child(n + 3) { grid-column: 2; }
  .setcontract td:empty { display: none; }
  .setcontract td:nth-child(4)::before { content: 'Blocks the calculation '; font-size: 12px; color: var(--muted); }
}

/* A paragraph that justifies a figure, folded until somebody doubts the
   figure. Screens were opening with three of them before the first number.
   Godfrey, 22 September: there are still words blocking the app. */
.why { margin-top: 10px; border-top: 1px solid var(--line); padding-top: 8px; }
.why > summary {
  cursor: pointer; font-size: 12.5px; font-weight: 600; color: var(--deep);
  list-style: none; display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 0; user-select: none;
}
.why > summary::-webkit-details-marker { display: none; }
.why > summary::marker { content: ''; }
/* The Settings arrow after the words, turning over when open. M2, 26 September. */
.why > summary { color: var(--brand); gap: 0; }
.why > summary .setchev { margin-left: 6px; vertical-align: 0; }
.why[open] > summary .setchev { transform: rotate(180deg); }
.why > summary:hover { text-decoration: underline; }
.why > summary:focus-visible { outline: 2px solid var(--deep); outline-offset: 2px; border-radius: 4px; }
.why .whybody { font-size: 12.5px; color: var(--muted); line-height: 1.55; margin: 7px 0 0; max-width: 78ch; }
.panel > .why { padding-left: 16px; padding-right: 16px; padding-bottom: 12px; }

/* One short line, the rest folded under it. Where a paragraph, often amber,
   stood above a page or a panel. */
.brief { margin: 0 0 14px; }
.briefline { font-size: 13px; color: var(--muted); line-height: 1.5; margin: 0; max-width: 90ch; }
.brief > .why { margin-top: 2px; border-top: 0; padding-top: 0; }
.panel > .brief { padding: 10px 16px 0; margin-bottom: 10px; }
.panel .brief > .why { padding: 0; }
.sheetbody .brief { margin-bottom: 14px; }
/* A warning's own explanation, folded inside the amber box in its own ink. */
.notice > .why { margin-top: 4px; border-top: 0; padding-top: 0; }
.notice > .why > summary { color: var(--amber-ink); }
.notice > .why .whybody { color: var(--amber-ink); }
.flagline { margin: 0 0 10px; }
.panel > .flagline { padding: 0 16px; }

/* ===========================================================================
   The dashboard, rebuilt 22 September 2026.

   What it replaced: a greeting band carrying four small tiles, two of which
   read "not yet, waiting on a decision", above a row of five stat cards, one
   of which repeated the kilograms from the band, above a chart, a quick
   actions panel, a ranked rail, a panel headed "six figures this dashboard
   will not show", and a rule at the foot. Godfrey showed it to the staff on
   22 September: confusing, and it does not look worth what it costs.

   The shape now is the shape of the job. Two figures Gasmate is paid on, a
   quiet row of the rest, then the one ranked answer the plant needs, which is
   which bullet keeps running short.
   =========================================================================== */

/* The two figures that matter, side by side. ------------------------------ */
/* Three across on a desk monitor, stacking on a narrow one. auto-fit rather
   than a fixed count so a card is never squeezed into a column too narrow for
   a peso figure. */
.payband {
  display: grid; gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
}
.paycard {
  background: var(--paper); border: 1px solid var(--line); border-radius: 14px;
  padding: 22px 24px 18px; display: flex; flex-direction: column; min-width: 0;
  box-shadow: 0 1px 2px rgba(17, 24, 39, 0.04);
}
.paycardhead { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.paytitle {
  font-size: 12px; font-weight: 700; letter-spacing: 0.6px; text-transform: uppercase;
  color: var(--muted); margin: 0;
}
/* The dates live on the card, not only in the page heading. Godfrey's
   question about the old band was: produced when, today, last week. */
.paydates { font-size: 11.5px; color: var(--faint); white-space: nowrap; }
.payvalue { display: flex; align-items: baseline; gap: 8px; margin-top: 12px; }
.paynum {
  font-size: 42px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.05;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.paynum.short { color: var(--red-ink); }
.payunit { font-size: 16px; font-weight: 600; color: var(--muted); }
.payfoot { font-size: 12.5px; color: var(--muted); margin-top: 7px; line-height: 1.5; }
.billlines { margin-top: 10px; display: grid; gap: 6px; }
.billline { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font-size: 13.5px; }
.billwhat { display: flex; flex-direction: column; min-width: 0; }
.billlabel { color: var(--ink); font-weight: 600; }
.billqty { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.billamt { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.billnote { color: var(--muted); font-size: 12px; }
.paynone {
  font-size: 13.5px; color: var(--muted); margin-top: 14px; line-height: 1.55;
  padding: 14px 0; border-top: 1px solid var(--line);
}
/* What the office sheet says, when this system worked nothing out.
   Quieter than a computed figure on purpose: the source is named above the
   number, the number is a third the size of a real one, and the whole block
   sits inside a rule so it reads as a quotation from a document rather than
   as an output of this system. No colour of its own; it borrows the page. */
.declared {
  margin-top: 4px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 8px;
}
.declaredhead {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
}
.declaredsrc {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--muted);
}
.declareddates { font-size: 11px; color: var(--muted); white-space: nowrap; }
.declaredline { display: flex; align-items: baseline; gap: 6px; margin-top: 6px; }
.declarednum {
  font-size: 22px; font-weight: 600; letter-spacing: -0.01em;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.declarednum.short { color: var(--red-ink); }
.declaredunit { font-size: 12.5px; font-weight: 600; color: var(--muted); }
.declaredcount { font-size: 12.5px; color: var(--muted); margin-top: 6px; line-height: 1.5; }
.declaredrank { margin-top: 10px; border-top: 1px solid var(--line); padding-top: 9px; }
.declaredranktitle {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 6px;
}
.declaredrankrow {
  display: flex; align-items: baseline; gap: 10px;
  font-size: 12.5px; padding: 3px 0;
}
.declaredrankwho { font-weight: 600; color: var(--ink); min-width: 74px; }
.declaredrankcount { color: var(--muted); flex: 1; }
.declaredrankkg { color: var(--ink); font-variant-numeric: tabular-nums; }
.declaredrankkg.short { color: var(--red-ink); }
.declaredrankkg.over { color: var(--green-ink); }
.declared .why { margin-top: 10px; }

.kindpick {
  font: inherit; font-size: 12.5px; color: var(--ink); background: var(--paper);
  border: 1px solid var(--line); border-radius: 6px; padding: 4px 8px;
}
.rowacts { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
tr.clickable { cursor: pointer; }
tr.clickable:hover { background: var(--page); }

.paylink {
  align-self: flex-start; margin-top: auto; padding-top: 14px;
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--brand);
  background: none; border: 0; cursor: pointer; text-decoration: none;
}
.paylink:hover { text-decoration: underline; }
.paycard .why { margin-top: 12px; }

/* A column for each day that was entered. A day nobody entered is a gap. */
.daychart {
  display: flex; align-items: flex-end; gap: 2px; height: 68px; margin-top: 16px;
  padding-top: 6px; border-bottom: 1px solid var(--line);
}
.daycol { flex: 1 1 0; height: 100%; display: flex; align-items: flex-end; min-width: 2px; }
.daybar { width: 100%; background: var(--brand); border-radius: 2px 2px 0 0; }
.daybar:hover { background: var(--deeper); }
.gapbadges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 16px; }

/* The quiet row: everything else that has a real number. ------------------ */
.figrow {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px; margin-top: 20px;
}
.figcard {
  font: inherit; text-align: left; cursor: pointer;
  background: var(--paper); border: 1px solid var(--line); border-radius: 11px;
  padding: 15px 16px; display: flex; flex-direction: column; gap: 9px; min-width: 0;
}
.figcard:hover { border-color: var(--edge); }
/* The plus box that ends the figures: a place to add one, not a figure. */
.figcard.figadd { align-items: center; justify-content: center; min-height: 96px; color: var(--ink); }
.figcard.figadd .figplus { font-size: 44px; line-height: 1; font-weight: 300; }
.figcard.figadd:hover { border-color: var(--blue-ink); color: var(--blue-ink); }
.fighead { display: flex; align-items: center; gap: 8px; min-width: 0; }
.figicon { width: 15px; height: 15px; flex: none; color: var(--brand); }
.figlabel {
  font-size: 11.5px; font-weight: 600; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.figvalue { display: flex; align-items: baseline; gap: 5px; flex-wrap: wrap; }
/* Proportional figures on a standalone value: equal width digits make a
   big number look loose. Tabular stays for columns that line up. */
.fignum { font-size: 22px; font-weight: 600; color: var(--ink); }
.fignum.short { color: var(--red-ink); }
.figunit { font-size: 12px; font-weight: 600; color: var(--muted); }

/* Where the gas is going. ------------------------------------------------- */
.grouptabs { display: flex; gap: 6px; padding: 0 16px 4px; flex-wrap: wrap; }
.grouptab {
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
  color: var(--muted); background: none; border: 1px solid transparent;
  border-radius: 999px; padding: 5px 12px;
}
.grouptab:hover { color: var(--ink); }
.grouptab.on { color: var(--ink); background: var(--pale); border-color: var(--line); }
/* An invoice or bill list's views, Open, Overdue, Paid, Drafts and All, each
   with its count. */
.doctabs { padding: 10px 16px 6px; border-top: 1px solid var(--line); }
.doccount { margin-left: 6px; font-weight: 500; color: var(--muted); font-variant-numeric: tabular-nums; }
.grouptab.on .doccount { color: var(--ink); }
/* A second row of tabs under a first (U6, 28 September): the delivery
   notes' two statements under the Billing tabs, the Open, Overdue and Paid
   views under an accounting page's tabs. Drawn as a segmented control, one
   pill holding the choices, the chosen one filled with the primary and its
   label in the primary's own text colour, indented and a size smaller than
   the page tabs above it, so it reads as a choice within the page rather
   than a second set of pages. */
.grouptabs.segtabs {
  display: inline-flex; flex-wrap: nowrap; gap: 0; align-self: flex-start;
  margin: 2px 16px 10px 28px; padding: 2px; border: 1px solid var(--edge);
  border-radius: 999px; background: var(--paper); max-width: calc(100% - 44px); overflow-x: auto;
}
.grouptabs.segtabs.doctabs { border-top: 1px solid var(--edge); }
.segtabs .grouptab { font-size: 12px; padding: 4px 12px; border-color: transparent; white-space: nowrap; }
.segtabs .grouptab.on { background: var(--deep); color: var(--on-deep); border-color: transparent; }
.segtabs .grouptab.on .doccount { color: var(--on-deep); }
/* Include inactive, beside a list of names. */
.inactivebox { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink); cursor: pointer; min-height: 32px; }
.inactivebox input { width: 16px; height: 16px; margin: 0; }
.groupchart { padding: 8px 16px 4px; }

.diverge { display: flex; flex-direction: column; }
.divrow {
  display: grid; grid-template-columns: 7.5rem minmax(0, 1fr) 6rem 9rem;
  align-items: center; gap: 12px; padding: 9px 0;
  border-bottom: 1px solid var(--line);
  /* A button now (C9): it opens the loads behind its bar. Reset to the
     plain row it was, so the click target is the whole row and nothing
     about it looks like a button. */
  width: 100%; text-align: left; background: none; border: 0; border-bottom: 1px solid var(--line);
  font: inherit; cursor: pointer;
}
.divrow:last-child { border-bottom: 0; }
.divrow:hover .divname { color: var(--deep); }
.divname {
  font-size: 13px; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* The zero line sits at the middle of every track, so the eye follows one
   vertical rather than hunting for where each row started. */
.divtrack { position: relative; height: 18px; background: var(--bg); border-radius: 4px; }
.divtrack::before {
  content: ''; position: absolute; left: 50%; top: -3px; bottom: -3px;
  width: 1px; background: var(--line);
}
.divbar { position: absolute; top: 3px; bottom: 3px; border-radius: 3px; }
.divbar.short { background: var(--card-red); border-radius: 3px 0 0 3px; }
.divbar.over { background: var(--card-green); border-radius: 0 3px 3px 0; }
.divnum {
  font-size: 13px; font-weight: 600; text-align: right;
  font-variant-numeric: tabular-nums; color: var(--green-ink);
}
.divnum.short { color: var(--red-ink); }
.divsub { font-size: 11.5px; color: var(--faint); text-align: right; white-space: nowrap; }

/* Needs a person. -------------------------------------------------------- */
.todo { display: flex; gap: 10px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.todo:last-child { border-bottom: 0; }
.tododot { width: 7px; height: 7px; border-radius: 50%; flex: none; margin-top: 6px; }
.todo.bad .tododot { background: var(--card-red); }
.todo.warn .tododot { background: var(--amber-ink); }
/* Needs attention only: a settled item gets a plain statement, not a colour
   nobody needs to read twice. */
.todo.ok .tododot { background: var(--card-green); }
.todoname { font-size: 13px; font-weight: 600; color: var(--ink); }
.todobody { font-size: 12.5px; color: var(--muted); margin-top: 3px; line-height: 1.5; }

@media (max-width: 1080px) {
  .payband { grid-template-columns: minmax(0, 1fr); }
  .divrow { grid-template-columns: 6rem minmax(0, 1fr) 5.5rem; }
  .divsub { display: none; }
}
@media (max-width: 640px) {
  .paycard { padding: 18px 16px 14px; }
  .paynum { font-size: 34px; }
  .divrow { grid-template-columns: 5.5rem minmax(0, 1fr); }
  .divnum { display: none; }
}

/* Needs attention in the rail: one line a thing, a dot, a few words and
   where to go. The whole line is the button, so the target is the width of
   the column and at least 44px tall, not one small word. */
.railpanel { padding: 18px 18px 8px; }
.railpanel .panelhead { margin-bottom: 8px; }
.railline {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 44px;
  font: inherit; font-size: 13px; line-height: 1.4; text-align: left; color: var(--ink);
  background: none; border: 0; border-top: 1px solid var(--line); padding: 10px 0;
}
button.railline { cursor: pointer; }
.railline .tododot { margin-top: 0; }
.railline.bad .tododot { background: var(--card-red); }
.railline.warn .tododot { background: var(--amber-ink); }
.railline.ok .tododot { background: var(--card-green); }
.railtext { flex: 1; min-width: 0; }
.railgo { flex: none; font-size: 12.5px; font-weight: 600; color: var(--deep); }
button.railline:hover .railgo, button.railline:focus-visible .railgo { text-decoration: underline; }
/* The settings still to choose: said once, quietly, under the things to do. */
.railline.quiet { font-size: 12.5px; color: var(--muted); }
/* Beside the rail the wide column is three quarters of the page, so the
   small boxes come down to 170px to keep four to a row on a 1366px laptop,
   which puts the first chart on the first screen. */
@media (min-width: 1181px) {
  .dashgrid:not(.norail) .figrow.metrics { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }
}
/* PHP goes in front of its figure, kg after it. */
.figunit.pre { align-self: baseline; }
/* The photograph, opened. Fitted to the sheet rather than scaled up, because
   a 1600px long edge blown up to a desktop width is a blurred serial number
   that looks like a bad photo rather than a small one. */
.bigphoto {
  display: block; max-width: 100%; max-height: 62vh; margin: 0 auto 16px;
  border-radius: 10px; border: 1px solid var(--line); background: var(--bg);
}
/* When a photograph was taken against when it arrived, in words, under the
   buttons that open it. Muted like every other fact on the row: it says what
   happened and leaves the meaning to the office. 25 September 2026. */
.photogap { font-size: 12px; color: var(--muted); line-height: 1.45; margin-top: 6px; max-width: 36ch; }

/* The dashboard, 24 September 2026: small boxes, then charts. ------------- */
.sectionhead {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin: 24px 0 12px;
}
.sectionhead h2 { margin: 0; font-size: 17px; color: var(--ink); }
.sectionactions { display: flex; gap: 8px; flex-wrap: wrap; }
.figrow.metrics { margin-top: 0; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.figcard:disabled { cursor: default; }
.figfoot { font-size: 12px; color: var(--muted); line-height: 1.4; }
.fignone { font-size: 12.5px; color: var(--muted); line-height: 1.4; }
.figdeclared {
  font-size: 12px; color: var(--muted); line-height: 1.4;
  border-top: 1px solid var(--line); padding-top: 7px;
}

.chartgrid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
}
.chartgrid > .panel { margin: 0; min-width: 0; }
.chartgrid > .wide { grid-column: 1 / -1; }
.chartbody { padding: 4px 16px 16px; }

/* Columns: thin, rounded at the top, square at the baseline. */
.colchart { display: flex; flex-direction: column; gap: 6px; }
.colscale { font-size: 11.5px; color: var(--muted); }
.colplot {
  height: 170px; display: flex; align-items: flex-end; gap: 2px;
  border-bottom: 1px solid var(--line);
}
.colcol { flex: 1; height: 100%; display: flex; align-items: flex-end; justify-content: center; min-width: 0; }
.colbar { width: 100%; max-width: 24px; background: var(--brand); border-radius: 4px 4px 0 0; }
.colbar:hover, .colbar:focus-visible { background: var(--deeper); outline: none; }
.colaxis { display: flex; justify-content: space-between; font-size: 11.5px; color: var(--muted); }

/* Bars: one colour, the amount at the end. */
.hbars { display: grid; gap: 12px; }
.hbar { display: grid; grid-template-columns: minmax(96px, 140px) 1fr auto; align-items: center; gap: 12px; }
.hbarname { font-size: 13px; color: var(--ink); font-weight: 600; }
.hbartrack { height: 16px; min-width: 0; }
.hbarfill { height: 16px; background: var(--brand); border-radius: 0 4px 4px 0; }
.hbarval { font-size: 13px; color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.hbartotal { font-size: 12.5px; color: var(--muted); border-top: 1px solid var(--line); padding-top: 10px; }
@media (max-width: 520px) {
  .hbar { grid-template-columns: 1fr auto; }
  .hbartrack { grid-column: 1 / -1; order: 3; }
}

/* Manage metrics: a list of ticks. */
.tickgroup { margin: 14px 0 6px; font-size: 12px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.tickgroup:first-child { margin-top: 0; }
.tickrow { display: flex; align-items: center; gap: 10px; padding: 7px 0; font-size: 14px; color: var(--ink); cursor: pointer; }
.tickrow input { width: 18px; height: 18px; accent-color: var(--brand); }
/* The same tick, sized for a table's own toolbar rather than a sheet: Users,
   "Include switched off", the QuickBooks "Include inactive" pattern.
   Godfrey, 26 September 2026. */
.tickrow.inline { padding: 0; gap: 7px; font-size: 12.5px; white-space: nowrap; }
.tickrow.inline input { width: 15px; height: 15px; }

/* Manage: one button per row opening a sheet of the actions that used to
   stack four buttons tall on every row (Users, Godfrey, 26 September 2026).
   Full width and roomy, so a finger on a phone does not miss. */
.managelist { display: flex; flex-direction: column; gap: 8px; }
.managebtn {
  font: inherit; font-size: 14px; font-weight: 600; color: var(--ink); background: var(--paper);
  border: 1px solid var(--edge); border-radius: 8px; padding: 12px 14px; text-align: left; cursor: pointer;
}
.managebtn:hover { background: var(--pale); border-color: var(--deep); }

/* A figure stays on one line with its unit, even in a half width card. */
.chartbody td.num { white-space: nowrap; }

/* Two small boxes to a row on a phone, so the figures stay on one screen. */
@media (max-width: 520px) {
  .figrow.metrics { grid-template-columns: 1fr 1fr; gap: 10px; }
  .figrow.metrics .figcard { padding: 12px; }
  .figrow.metrics .fignum { font-size: 18px; }
}

/* The Overview, 25 September 2026: Hostaway's bar of views, dates and
   chips above the figures. Tokens only, so it follows the theme. The
   controls are 38px tall at least: the owners read this at a desk and on a
   tablet, and a small target is a missed one. */
.ovbar {
  background: var(--paper); border: 1px solid var(--line); border-radius: 12px;
  padding: 14px 16px; margin-bottom: 18px; display: flex; flex-direction: column; gap: 12px;
}
.ovviewstop { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.ovtabs, .ovgroup { display: flex; flex-wrap: wrap; gap: 6px; }
.ovtab, .ovgroup .grouptab { min-height: 38px; font-size: 13px; }
.ovtab.on, .ovgroup .grouptab.on { border-color: var(--edge); }
.ovfirst {
  margin-left: 7px; font-size: 11px; font-weight: 600; color: var(--muted);
  border-left: 1px solid var(--line); padding-left: 7px;
}
.ovnew { color: var(--brand); }
.ovstate { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-top: 10px; border-top: 1px solid var(--line); }
.ovstate .rowbtn { min-height: 36px; }
.ovstate .rowbtn + .rowbtn { margin-left: 0; }
.ovchanged { font-size: 13px; font-weight: 600; color: var(--amber-ink); margin-right: 4px; }
.ovfilters { display: flex; align-items: flex-end; gap: 12px 16px; flex-wrap: wrap; }
.ovfield { display: flex; flex-direction: column; gap: 3px; }
.ovlabel {
  font-size: 9.5px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--muted);
}
.ovfield .periodselect { min-height: 38px; font-size: 13.5px; }
.ovstep { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ovstep .rowbtn { min-height: 38px; }
.ovstep .rowbtn + .rowbtn { margin-left: 0; }
.ovstepname { font-size: 14px; font-weight: 600; color: var(--ink); min-width: 8rem; text-align: center; }
.ovday {
  font: inherit; font-size: 13px; color: var(--ink); background: var(--paper);
  border: 1px solid var(--edge); border-radius: 8px; padding: 7px 9px; min-height: 38px;
}
.ovfilters .rangefield input { min-height: 38px; }
.ovchips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ovchip {
  display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; font-weight: 600;
  color: var(--ink); background: var(--pale); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 6px 4px 12px; min-height: 32px;
}
.ovchipx {
  font: inherit; font-size: 16px; line-height: 1; color: var(--muted); background: none;
  border: 0; border-radius: 999px; width: 26px; height: 26px; cursor: pointer;
}
.ovchipx:hover { color: var(--ink); background: var(--paper); }
.ovreset {
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--brand); background: none;
  border: 0; padding: 6px 4px; cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
}
.ovcontent > .panel + .panel, .ovcontent > .figrow + .panel,
.ovcontent > .notice + .panel { margin-top: 14px; }
.ovcontent > .figrow { margin-bottom: 18px; }
.ovrowopen {
  font: inherit; font-size: 13px; font-weight: 600; color: var(--brand); background: none;
  border: 0; padding: 4px 0; cursor: pointer; text-align: left;
  text-decoration: underline; text-underline-offset: 3px;
}
.tickhint { display: block; font-size: 12px; color: var(--muted); margin-top: 1px; }

/* The Overview on a phone: every row of the bar full width, one per line. */
@media (max-width: 640px) {
  .ovbar { padding: 12px; }
  .ovviewstop, .ovfilters { flex-direction: column; align-items: stretch; }
  .ovfield .periodselect, .ovday { width: 100%; }
  .ovstep { justify-content: space-between; }
  .ovstepname { min-width: 0; flex: 1; }
}

/* Delivery notes, under Billing, 26 September 2026. The paste box takes what
   Excel copies, so it is wide and plain; the size boxes sit in a grid rather
   than a column of six; a row the paste left out reads quieter than one that
   will be saved, and the reasons beside each row keep the warning colours. */
.dnpaste {
  font: inherit; font-size: 12.5px; font-family: ui-monospace, Menlo, Consolas, monospace;
  width: 100%; min-height: 140px; color: var(--ink); background: var(--paper);
  border: 1px solid var(--edge); border-radius: 8px; padding: 9px 11px; resize: vertical;
}
.dnpaste:focus-visible { outline: 2px solid var(--deep); outline-offset: 1px; }
.formrows > .dnpaste { width: 100%; }
.formrow select {
  font: inherit; font-size: 13px; color: var(--ink); background: var(--paper);
  border: 1px solid var(--edge); border-radius: 7px; padding: 8px 10px; width: 100%;
}
.formrow select:focus-visible { outline: 2px solid var(--deep); outline-offset: 1px; }
.dnchecks { margin: 8px 0 0; padding-left: 16px; font-size: 12px; line-height: 1.45; }
.dnchecks li { margin: 2px 0; }
.dnchecks .bad { color: var(--red-ink); }
.dnchecks .warn { color: var(--amber-ink); }
tr.dnleftout td { color: var(--faint); }
.dnwhen { white-space: nowrap; }
.dnacts { display: flex; gap: 6px; flex-wrap: nowrap; align-items: center; }
.dnacts .rowbtn + .rowbtn { margin-left: 0; }
/* Where a refilling statement's rows come from, under its name beside Print. */
.dnsource { margin-top: 5px; font-size: 12px; line-height: 1.5; color: var(--muted); max-width: 560px; white-space: normal; }
.dnsource .tag { margin-right: 4px; }

/* Accounting home, docs/48: the reference application's own flow, our own
   boxes. A box is a button when its page works today, and a plain, dimmer
   div with a Coming tag when it does not, so the two are never confused by a
   hover state that promises a click that fails. The arrow is a character,
   not an image, so it reads the same in light and dark without a second
   asset. */
.accthome-group { margin: 0 0 26px; }
.accthome-group h3 {
  font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--muted); margin: 0 0 10px;
}
.accthome-row { display: flex; align-items: stretch; flex-wrap: wrap; gap: 10px 4px; }
.accthome-box {
  display: flex; align-items: center; gap: 8px; min-width: 150px;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--ink); text-align: left;
  background: var(--paper); border: 1px solid var(--edge); border-radius: 10px;
  padding: 12px 14px; box-shadow: var(--card-shadow); cursor: pointer;
}
.accthome-box:hover { border-color: var(--deep); }
.accthome-box.coming { color: var(--muted); border-style: dashed; box-shadow: none; cursor: default; }
.accthome-box.beside { margin-left: 8px; }
.accthome-name { flex: 1; }

/* The snake (H1, 29 September 2026): steps two to a row, the second row
   right to left, a short arrow straight down between them. Inline SVG,
   stroked with the muted text token so they read in both themes, and they
   stretch with the layout. Each item carries its place in --r and --c. */
.accthome-snake {
  display: grid; grid-template-columns: minmax(150px, 220px) 44px minmax(150px, 220px);
  gap: 10px 4px; align-items: stretch;
}
.accthome-snake > * { grid-row: var(--r); grid-column: var(--c); }
.accthome-link { display: flex; align-items: center; justify-content: center; color: var(--muted); }
.accthome-svgarrow { fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; display: block; }
.accthome-svgarrow.right, .accthome-svgarrow.left { width: 40px; height: 16px; }
.accthome-svgarrow.down { width: 16px; height: 24px; }
.accthome-link .narrow { display: none; }

/* Boxes that come after nothing: one quiet line of links under the
   section, each with its icon and tag. */
.accthome-shortcuts {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px;
  margin: 10px 0 0; font-size: 13px; color: var(--muted);
}
.accthome-shortcut {
  display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: 13px;
  color: var(--deep); background: none; border: 0; padding: 4px 0; cursor: pointer;
}
.accthome-shortcut:hover .accthome-name { text-decoration: underline; }
.accthome-shortcut.coming { color: var(--muted); cursor: default; }
.accthome-shortcut .accthome-icon { width: 22px; height: 22px; }
.accthome-shortcut .tag { font-size: 11px; padding: 0 6px; }
.accthome-keys { font-size: 12px; color: var(--muted); margin: -6px 0 14px; }

@media (max-width: 760px) {
  .accthome-snake { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .accthome-snake > * { grid-row: auto; grid-column: auto; }
  .accthome-link { justify-content: flex-start; padding-left: 18px; }
  .accthome-link .wide { display: none; }
  .accthome-link .narrow { display: block; }
}

@media (max-width: 640px) {
  .accthome-row { flex-direction: column; align-items: stretch; }
}

/* The Accounting home's money figures above the flows, and the column
   beside them: each bank and cash account, then the reminders (X1 B2, B3).
   A figure is a button when it opens something, so it looks like one card
   among the boxes and the hover says so. Overdue is red and due this week
   amber, the states only; everything else is the ink. */
.acctfigs { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin: 0 0 24px; }
.acctfig {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-width: 0;
  font: inherit; color: var(--ink); text-align: left;
  background: var(--paper); border: 1px solid var(--edge); border-radius: 10px;
  padding: 14px 16px; box-shadow: var(--card-shadow);
}
button.acctfig { cursor: pointer; }
button.acctfig:hover { border-color: var(--deep); }
.acctfig-label {
  font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted);
}
.acctfig-value { font-size: 22px; font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.acctfig-value.none { font-size: 16px; font-weight: 600; color: var(--muted); }
.acctfig-sub { display: flex; flex-direction: column; gap: 2px; font-size: 12.5px; line-height: 1.45; color: var(--muted); font-variant-numeric: tabular-nums; }
.acctfig-sub .late { color: var(--red-ink); font-weight: 600; }
.acctfig-sub .soon { color: var(--amber-ink); font-weight: 600; }
.acctfig-opens { margin-top: auto; padding-top: 4px; font-size: 12px; font-weight: 600; color: var(--muted); }
button.acctfig:hover .acctfig-opens { text-decoration: underline; }

.accthome-body { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 24px; align-items: start; }
.accthome-side { display: flex; flex-direction: column; gap: 16px; }
.accthome-side:empty { display: none; }
.accthome-panel {
  background: var(--paper); border: 1px solid var(--edge); border-radius: 10px;
  padding: 14px 16px; box-shadow: var(--card-shadow);
}
.accthome-panel h3 {
  font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--muted); margin: 0 0 4px;
}
.accthome-panel .tinynote { margin: 6px 0 0; padding: 0; }
.accthome-line {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; min-height: 44px;
  font: inherit; font-size: 13px; color: var(--ink); text-align: left;
  background: none; border: 0; border-top: 1px solid var(--line); padding: 8px 0; cursor: pointer;
}
.accthome-panel h3 + .accthome-line { border-top: 0; }
.accthome-linename { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.accthome-lineamt { flex: none; font-weight: 600; font-variant-numeric: tabular-nums; }
.accthome-lineamt.none { font-weight: 400; color: var(--muted); }
.accthome-line:hover .accthome-linename { text-decoration: underline; }

@media (max-width: 1180px) {
  .acctfigs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* One column: the balances and reminders come before the flows, so a
     phone shows what needs doing without scrolling past every box. */
  .accthome-body { grid-template-columns: minmax(0, 1fr); }
  .accthome-side { order: -1; }
}
@media (max-width: 640px) {
  .acctfigs { grid-template-columns: minmax(0, 1fr); gap: 10px; }
}

/* Customer Center and Vendor Center (B7): the names on the left, the one
   chosen on the right. One column on a tablet or phone, names first. */
/* The three figures over a centre's list: the home's small boxes, three across. */
.acctfigs.center-figs { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-bottom: 16px; }
.center { display: grid; grid-template-columns: minmax(240px, 320px) minmax(0, 1fr); gap: 16px; align-items: start; }
.center-left { padding-bottom: 8px; }
.center-left .tabletools { flex-wrap: wrap; }
.center-names { max-height: 70vh; overflow-y: auto; }
.center-namecell { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.center-name { background: none; border: 0; padding: 4px 0; font: inherit; color: var(--brand); text-align: left; cursor: pointer; min-height: 32px; }
.center-name:hover { text-decoration: underline; }
.center-name.on { color: var(--ink); font-weight: 600; }
.center-name:focus-visible { outline: 2px solid var(--deep); outline-offset: 2px; }
.center-detail .panel + .panel { margin-top: 16px; }
/* A date or a number kept on one line; the table scrolls sideways instead. */
.center-detail td:nth-child(-n+4), .qr td:nth-child(-n+3) { white-space: nowrap; }
@media (max-width: 900px) {
  .acctfigs.center-figs { grid-template-columns: minmax(0, 1fr); }
  .center { grid-template-columns: minmax(0, 1fr); }
  .center-names { max-height: 40vh; }
}
/* Reports page (B11): the star that puts a report in Favorites. */
.starbtn { background: none; border: 0; font-size: 18px; line-height: 1; color: var(--muted); cursor: pointer; min-width: 32px; min-height: 32px; }
.starbtn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; vertical-align: middle; }
.starbtn.on { color: var(--brand); }
.starbtn.on svg { fill: currentColor; }
.starbtn:focus-visible { outline: 2px solid var(--deep); outline-offset: 2px; }

/* Overview: the one line said instead of a year-earlier line in every cell. */
.ovnoearlier { margin: 0 0 12px; }

/* An empty day on the DTR, said plainly rather than in amber. */
.dtrnone { padding: 12px 16px 14px; }

/* Q5, 26 September 2026: the QBD date keys, the New button, Find a
   transaction and Compact rows. */

/* The QBD date box (B13): a text input where the browser's picker was, the
   typed or jumped-to date shown back in words underneath. */
.qbdatebox { display: block; }
.qbdatewords { display: block; font-size: 12px; color: var(--muted); margin-top: 3px; min-height: 15px; }

/* The Accounting home's own row for the New button, Find and Compact rows
   (B12, B15). */
.accthome-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 14px; }
.newtxn { position: relative; display: inline-block; }
.newtxnmenu {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 20; min-width: 200px;
  background: var(--paper); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: var(--card-shadow); padding: 6px; display: flex; flex-direction: column; gap: 2px;
}
.newtxnmenu.hidden { display: none; }
.newtxnitem {
  font: inherit; font-size: 13px; text-align: left; color: var(--ink);
  background: none; border: 0; border-radius: 6px; padding: 8px 10px; cursor: pointer;
}
.newtxnitem:hover { background: var(--deep-wash); }

.compactswitch { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink); cursor: pointer; }
.compactswitch input { width: auto; margin: 0; }

/* Compact rows itself (B15): the same 13px type, less padding, about 32px
   a row. */
.compact-rows tbody td, .compact-rows thead th { padding: 8px 16px; }

/* Find a transaction's own search fields (B12). */
.fieldgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 0 16px; }
.fieldgrid .field { margin-top: 12px; }

/* The accounting home tiles' icon (U6, 28 September): a round chip at the
   left of every tile, the same size on each, with a line icon from the
   sidebar's own set. The chip is a wash with the deep blue on it, an icon
   rather than a word, so it needs no text pair of its own. */
.accthome-icon {
  flex: none; width: 28px; height: 28px; border-radius: 50%;
  background: var(--deep-wash); color: var(--brand);
  display: inline-flex; align-items: center; justify-content: center;
}
.accthome-ico { width: 16px; height: 16px; display: block; }
.accthome-box.coming .accthome-icon { color: var(--muted); }

/* An opened production report (U6, 28 September): its tank cards and the
   Report total sit on one row at one height, Report total last. On a phone
   the row folds to one card a line, like the dashboard's grid. */
.stats.onerow { display: flex; align-items: stretch; gap: 16px; }
.stats.onerow > .stat { flex: 1 1 0; min-width: 0; }
@media (max-width: 720px) {
  .stats.onerow { flex-direction: column; }
}
/* The sheet's Kg per piece cell: figure and its factor date on one line. */
td.factorcell { white-space: nowrap; }
.factorsince { color: var(--muted); }

/* The statement dropdown in the delivery notes card header (28 Sept 2026). */
.panelhead .notepick { font: inherit; font-size: 14px; padding: 7px 30px 7px 12px; border: 1px solid var(--edge);
  border-radius: 9px; background-color: var(--paper); color: var(--ink); min-width: 0; max-width: 100%; }

/* The search box's See all filter over a list (S3, 28 September 2026): what
   the list is kept to, in the brand ink on its pale wash, and a cross that
   clears it, 40 px square for older eyes. Tokens only, so it follows the
   theme. */
.foundchip {
  display: inline-flex; align-items: center; gap: 6px; margin: 0 0 10px;
  padding: 2px 2px 2px 12px; border: 1px solid var(--edge); border-radius: 999px;
  background: var(--pale); color: var(--brand); font-weight: 600;
}
.foundclear {
  min-width: 40px; min-height: 40px; border: 0; border-radius: 999px;
  background: transparent; color: var(--brand); font-size: 20px; line-height: 1; cursor: pointer;
}
.foundclear:hover, .foundclear:focus-visible { background: var(--paper); }

/* "+ New" (H1, 29 September 2026): the same .rowbtn height and corner as
   Find a transaction beside it, filled with the primary. Its menu is
   grouped Customers, Vendors, Other. */
.rowbtn.newtxn-btn { background: var(--deep); border-color: var(--deep); color: var(--on-deep); gap: 6px; }
.rowbtn.newtxn-btn:hover { background: var(--deeper); border-color: var(--deeper); }
.newtxn-plus { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.newtxngroup {
  font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--muted); padding: 8px 10px 2px;
}
.newtxnitem { display: flex; align-items: center; gap: 8px; }
.newtxnitem:focus-visible { background: var(--deep-wash); outline: 2px solid var(--deep); outline-offset: -2px; }
.newtxnitem .tag { font-size: 11px; padding: 0 6px; margin-left: auto; }
/* The feedback sheet, F1 (29 September 2026), public/feedback.js. */
.fbsheet-back {
  position: fixed; inset: 0; z-index: 90; background: rgba(17, 24, 39, 0.45);
  display: flex; align-items: flex-start; justify-content: center; padding: 48px 16px; overflow-y: auto;
}
.fbsheet {
  background: var(--paper); color: var(--ink); border: 1px solid var(--line); border-radius: 14px;
  width: 100%; max-width: 520px; padding: 20px 22px; display: flex; flex-direction: column; gap: 8px;
}
.fbtitle { font-size: 20px; margin: 0 0 6px; }
.fblabel { font-weight: 600; font-size: 15px; }
.fbwords { width: 100%; font: inherit; font-size: 16px; padding: 10px; border: 1px solid var(--edge); border-radius: 8px; background: var(--paper); color: var(--ink); box-sizing: border-box; }
.fbhint { font-size: 13px; color: var(--muted); }
.fbkinds { border: 0; padding: 0; margin: 4px 0; display: flex; flex-direction: column; gap: 6px; }
.fbkind { display: flex; align-items: center; gap: 10px; min-height: 40px; font-size: 16px; }
.fbkind input { width: 20px; height: 20px; }
.fbpic { font-size: 15px; min-height: 40px; }
.fbmsg { color: var(--red-ink); min-height: 1em; }
.fbactions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 6px; }
.fbsheet .btn { min-height: 44px; padding: 0 18px; border-radius: 8px; cursor: pointer; font: inherit; font-size: 16px; }
.fbsheet .btn.plain { background: var(--paper); color: var(--ink); border: 1.5px solid var(--edge); }
.fbsheet .btn.primary { background: var(--deep); color: var(--paper); border: 1.5px solid var(--deep); font-weight: 600; }
/* The Feedback button beside the bell: the word on wide screens, the icon alone below. */
.iconbtn.fbbtn { width: auto; padding: 0 10px; gap: 6px; }
.iconbtn.fbbtn svg { width: 20px; height: 20px; }
@media (max-width: 1180px) { .iconbtn.fbbtn { width: 40px; padding: 0; } .fbbtn .fbword { display: none; } }
.fbrow { border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; margin-bottom: 10px; background: var(--paper); }
.fbrow .fbmeta { font-size: 13px; color: var(--muted); }
.fbrow .fbtext { white-space: pre-wrap; margin: 8px 0; font-size: 15px; }
.fbrow img { max-width: 100%; max-height: 360px; border: 1px solid var(--line); border-radius: 8px; }
.fbrow .fbctl { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 8px; }
.fbrow .fbctl input { flex: 1; min-width: 180px; min-height: 36px; padding: 0 8px; }
.fbfilters { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.fbfilters select { min-height: 36px; }
