/* Gasmate Depot, the plant app.

   The proportions come from the reviewed wireframes. Touch targets are large
   because this gets used outdoors, in sun, standing next to a truck.
   Computed figures sit in the pale green panels and are never inputs, so a
   staff member can see at a glance which numbers they own and which the
   system worked out.

   THE PALETTE IS BUILT FOR GLARE, and it was measured rather than chosen.
   The first version failed: secondary text sat at 4.43:1, the faintest text
   at 2.45:1, and borders at 1.50:1, which is invisible on a phone held up in
   the sun at Bacong. Five pairs failed plain AA indoors, never mind outdoors.

   Every text pair here now clears 7:1, the AAA threshold, with headroom, and
   every border clears 3:1. The values were solved for rather than picked:
   each colour keeps its hue and is darkened until it meets its target.

   Two things fell out of doing that, and both are the point. Three greys
   separated only by lightness collapsed into each other once they all had to
   be readable, so there are two now and hierarchy comes from size and weight
   instead. And the two greens landed on the same value, so they are pulled
   apart by SATURATION rather than lightness: deep is structural and quiet,
   sage is interactive and clearly green. A difference that only exists in
   lightness is the first thing glare takes away. */

:root {
  /* 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. This screen is read on a phone in the sun at
     Bacong where the floor is 7:1, and the deep blue clears it as it is:
     8.35 with white on it, 7.59 on the page, 7.10 on the pale panel. So it is
     --brand, the bar, the tiles and everything a person presses, with no
     taking down. Headings and the submit button are a dark slate, --deep,
     which differs from the blue in saturation and not only in lightness,
     which glare removes. Ocean City is taken down one step for edges and the
     sending dot, because 2.8:1 on this page is under the 3:1 a boundary needs.

     --sage was renamed --brand on 4 September. A token named for a colour it
     no longer holds is how the next person paints something green. */
  --bg: #F3F4F6;
  --paper: #FFFFFF;
  --ink: #111827;
  --deep: #333A47;
  --brand: #2A4D88;
  --pale: #E8EDF5;
  --muted: #374151;
  --line: #7C94B8;
  --edge: #6B85AC;
  --faint: #414B5A;
  --amber-bg: #FAF0D4;
  --amber-edge: #9F7F30;
  --amber-ink: #5D4A15;
  --amber-deep: #4F3F0F;
  --red: #7E3936;
  --red-ink: #7C3330;
  /* The sending state was blue when nothing else was. Now that the brand is
     blue it is taken to the turquoise end of the palette, so a queued entry
     does not read as a navy heading. */
  --blue: #6B85AC;
  --blue-ink: #2A4D88;
  /* Two shadows, the second wide and soft, which is how the references lift a
     card off the page. A shadow is not a surface anything sits on. */
  --card-shadow: 0 1px 2px rgba(17, 24, 39, 0.04), 0 8px 24px rgba(17, 24, 39, 0.06);
}

/* Dark, added 25 September 2026 to match the office: Godfrey, "I like the
   dark mode of Claude and Odoo rather than ours since ours has some tint of
   blue; make it dark gray." The same neutral warm greys as erp.css uses for
   its own dark page, card, line and text tokens, from Claude's own dark
   mode. No surface leans blue.

   This screen is still read on a phone in the sun, so the floor stays 7:1
   for text and 3:1 for a border, the same as light. A dark theme is not
   an excuse to relax the one property that was measured rather than
   picked; every pair below was solved for the same way the light ones
   were, not chosen by eye. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #262624;
  --paper: #30302E;
  --ink: #F5F4ED;
  --deep: #E3E1D7;
  /* The one accent, the deep blue lightened until it carries text: 8.07:1 on
     the page, 7.04:1 on a card, both past the 7:1 floor. */
  --brand: #A6BFE3;
  --pale: #292927;
  --muted: #C2C0B6;
  --line: #7D7B74;
  --edge: #7D7B74;
  --faint: #C0BDB3;
  --amber-bg: #2A2113;
  --amber-edge: #8A6F30;
  --amber-ink: #E4B355;
  --amber-deep: #F2CE86;
  --red: #8A423C;
  --red-ink: #F49B92;
  --blue: #7D93C2;
  --blue-ink: #A6BFE3;
  --card-shadow: none;
}

/* A handful of rules paint a literal colour rather than a token, mostly light
   washes that need their own dark reading so a table row or a tag does not
   sit as a bright patch on a dark page. .officelink also loses a border and
   a hover fill that were Glacial Salt, a blue, straight on a neutral card. */
:root[data-theme="dark"] .table td { border-bottom-color: var(--line); }
:root[data-theme="dark"] .table tr.flagged { background: var(--amber-bg); }
:root[data-theme="dark"] .tag.gone { background: var(--pale); }
:root[data-theme="dark"] .ledger .n.keep { background: var(--pale); }
:root[data-theme="dark"] .table.grid tr.lvl0 { background: var(--pale); }
:root[data-theme="dark"] .table.grid tr.worked td,
:root[data-theme="dark"] .table.grid td.worked { background: var(--pale); }
:root[data-theme="dark"] .officelink { border-color: var(--line); }
:root[data-theme="dark"] .officelink:hover { background: var(--pale); }
/* The delivery card's large icon is a fixed white glyph on --brand, which in
   dark is a light fill, so the glyph is redrawn in the dark --paper colour
   instead of moving with a token an inline data URI cannot read. */
:root[data-theme="dark"] .cards.solo .card .n {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2330302E' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='8' width='14' height='9' rx='4.5'/%3E%3Cpath d='M16 11h3l3 3v3h-6'/%3E%3Ccircle cx='6' cy='19' r='1.6'/%3E%3Ccircle cx='18' cy='19' r='1.6'/%3E%3C/svg%3E");
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
/* iPhone Safari paints a button's text in its own blue unless told the
   colour. Every sheet title on the home screen was blue on Sandra's phone on
   18 September. Buttons take the colour of what they sit in. */
button { color: inherit; }

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: 16px;
  overscroll-behavior-y: contain;
}

#app { min-height: 100%; display: flex; flex-direction: column; }
/* Staff screens are a phone held in one hand. The office screens are a
   browser on a desk, so they get room, and both live in one app. */
.screen { flex-grow: 1; display: flex; flex-direction: column; width: 100%; max-width: 520px; margin: 0 auto; }
.screen.wide { max-width: 980px; }
.grow { flex-grow: 1; }
.num { font-variant-numeric: tabular-nums; }
.hidden { display: none !important; }

/* Bars ------------------------------------------------------------------ */

.bar {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; background: var(--brand); color: var(--bg);
}
.bar h1 { font-size: 15px; font-weight: 600; margin: 0; letter-spacing: 0.2px; }
.bar .sub { font-size: 11px; color: #EEF2F8; margin-top: 1px; }
.bar { position: relative; }
.bar .who {
  display: flex; align-items: center; gap: 8px; font-size: 13px; color: inherit;
  background: none; border: 0; padding: 6px 4px 6px 10px; margin: -6px -4px -6px 0; border-radius: 10px;
  font: inherit; font-size: 13px; cursor: pointer; min-height: 44px;
}
.bar .who[aria-expanded="true"] { background: rgba(255, 255, 255, 0.14); }
/* The small menu under a person's name. What they need seldom lives here,
   so the screen keeps one visible button, Something is wrong. */
.profile {
  position: absolute; right: 10px; top: calc(100% + 6px); z-index: 40; width: min(300px, calc(100vw - 20px));
  background: var(--paper); color: var(--ink); border: 1px solid var(--line); border-radius: 14px;
  padding: 12px; display: flex; flex-direction: column; gap: 8px; box-shadow: var(--card-shadow);
}
.profilehead { display: flex; flex-direction: column; padding: 2px 4px 8px; border-bottom: 1px solid var(--line); margin-bottom: 2px; }
.profilehead span:first-child { font-size: 15px; font-weight: 600; }
.profilehead .dim { font-size: 12px; color: var(--muted); }
.profile .btn { width: 100%; }
.profile .hint { margin: 0 2px; }
/* Something is wrong, in plain sight: a warm edge so it reads as the way to
   raise a hand, not as one more grey button. */
.actions .btn.problem { border-color: var(--amber-edge); background: var(--amber-bg); color: var(--amber-deep); font-weight: 600; }
.bar .avatar {
  width: 30px; height: 30px; border-radius: 50%; background: var(--deep);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 600;
}
.back {
  background: none; border: 0; padding: 0; margin: 0;
  /* 32px in an app whose premise is large targets, used with gloves in the
     sun, on seventeen screens. Found 11 September 2026. */
  min-width: 48px; min-height: 48px; justify-content: center;
  color: var(--bg); cursor: pointer; display: flex; align-items: center;
}

.banner {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px; font-size: 13px;
  background: var(--amber-bg); color: var(--amber-deep);
  border-bottom: 1.5px solid var(--amber-edge);
}
.banner.env { background: var(--pale); color: var(--deep); border-bottom-color: var(--brand); }

/* Entries this phone is still holding. A button, because it takes you to the
   list of them, and it carries the amber of the other banners because it is
   the same kind of fact: something the person has to act on before they go
   home. One needing attention makes it red, which is the only escalation. */
.banner.waiting {
  width: 100%; border: 0; border-bottom: 1.5px solid var(--amber-edge);
  font: inherit; font-size: 13px; text-align: left; cursor: pointer;
  min-height: 48px;
}
/* There is no red ground token in this palette and inventing one is how an
   unmeasured colour gets in. The amber ground stays and the red is spent on
   the words and the rule, which is where a person reads it. */
.banner.waiting.bad { color: var(--red-ink); border-bottom-color: var(--red); }

/* Bigger text, for eyes in their fifties and sixties and for a screen read at
   arm's length in the sun. The palette already clears 7:1; size is the other
   half of legibility and no amount of contrast substitutes for it.
   One step, on the root, so every rem-based size moves together and nothing
   has to be restyled twice. Tap targets are already 48px and stay so. */
html.bigger { font-size: 19px; }
html.bigger .pagehead .big { font-size: 26px; }
html.bigger .card .t { font-size: 17px; }
html.bigger .card .s { font-size: 14.5px; }
html.bigger .lbl { font-size: 13.5px; }
html.bigger input, html.bigger select, html.bigger textarea { font-size: 17.5px; }
html.bigger .checkline { font-size: 16.5px; }
html.bigger .note, html.bigger .note-amber { font-size: 14.5px; }
/* The screens somebody presses this for. The production rows and the day
   review tables were left behind by the first version of this, which is
   exactly where an owner reading a phone at arm's length needs it. Found
   11 September 2026. */
html.bigger .table td, html.bigger .table th { font-size: 15px; }
html.bigger .prow .sku { font-size: 16px; }
html.bigger .prow .kg { font-size: 13px; }
html.bigger .hint, html.bigger .bar .sub { font-size: 13px; }
/* The unit beside the pieces box. It replaced a 17px "pcs" placeholder that
   read like a figure somebody had typed. Godfrey, 22 September. */
/* The pieces box has a fixed width, and a wider digit in a fixed box clips. */
html.bigger .prow input { min-width: 78px; width: auto; }

/* Read it over before it goes. One row per thing being sent, the figure on
   the right where the eye already goes for figures on every other screen. */
.checklines { display: flex; flex-direction: column; gap: 0; }
.checkline {
  display: flex; align-items: baseline; gap: 12px;
  padding: 11px 0; border-bottom: 1px solid var(--line);
}
.checkline:last-child { border-bottom: 0; }
.checkline .k { flex: 1; }
.checkline .v { font-weight: 600; font-variant-numeric: tabular-nums; }
.checkline.total { border-top: 2px solid var(--edge); border-bottom: 0; margin-top: 4px; }
.checkline .sub { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }

/* Type ------------------------------------------------------------------ */

.pagehead { padding: 18px 16px 8px; }
.pagehead .big { font-size: 22px; font-weight: 600; }
.pagehead .day { font-size: 14px; color: var(--muted); margin-top: 2px; }
.lbl {
  font-size: 12px; font-weight: 600; letter-spacing: 0.3px;
  color: var(--deep); margin-bottom: 7px; line-height: 1.4;
}
.section {
  padding: 20px 16px 6px; display: flex; align-items: baseline; justify-content: space-between;
}
.section .t { font-size: 13px; font-weight: 600; letter-spacing: 0.4px; color: var(--deep); }
.section .c { font-size: 12px; color: var(--muted); }
.field { padding: 18px 16px 0; }
/* A field holding nothing but a hidden note takes no room. The Production
   Report left a gap the height of a field under its rows for a note that
   shows only when a line is left blank. */
.field:has(> .hidden:only-child) { display: none; }
.row2 { display: flex; gap: 10px; align-items: stretch; }
/* Each half is a column with its control pushed to the bottom, so two boxes
   sit on one line even when one label wraps and the other does not.
   Godfrey, 22 September 2026, on a real iPhone: the vapor boxes are not
   aligned. BACONG VAPOR, PSI is one line and VAPOR BEFORE LOADING, PSI is
   two, so the second box began a whole label lower than the first. */
.row2 > * { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; }
/* The labels are made the same height, rather than the boxes being pushed to
   the bottom of their column. Pushing them down worked until one side carried
   a hint under it: the column grew, and the box on the other side sank to the
   foot of it leaving a hole under its own label. Seen on the Transfers
   Report, where the truck carries an amber note about an unregistered plate. */
.row2 > * > .lbl,
.row2 > * > .flabel { min-height: 2.5em; display: flex; align-items: flex-end; }

/* iOS Safari gives a date input an intrinsic width of its own and will not
   shrink it below that inside a flex row, whatever width is asked for. The
   box then runs over the one beside it, which is what Godfrey photographed
   on the Transfers Report: the truck box sitting on top of the date.
   Turning off the native appearance is what lets width be honoured. */
input[type="date"],
input[type="datetime-local"],
input[type="time"] {
  -webkit-appearance: none; appearance: none;
  min-width: 0; max-width: 100%;
}
/* A select has the same habit with a long option in it, and every one of
   these holds a plate number or an invoice line that is longer than the box. */
.row2 > * > select { text-overflow: ellipsis; }

/* Inputs ---------------------------------------------------------------- */

input, select, textarea {
  font: inherit; color: var(--ink); width: 100%;
  border: 1.5px solid var(--ink); border-radius: 4px; background: var(--paper);
  min-height: 48px; padding: 0 12px;
}
input:focus, select:focus, button:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 1px;
}
/* A prompt in an empty box is grey and light, never the bold of a real
   figure: beside a counted 119, a bold "not yet" read as a value. The grey is
   --faint, which still clears the 7:1 a phone in the sun needs; the weight
   and, in the big count boxes, the size are what set it apart. P2, screen
   audit of 26 September 2026. */
input::placeholder, textarea::placeholder { color: var(--faint); font-weight: 400; opacity: 1; }
/* A drop-down is a box to tap, not a value already given. It had a black
   edge and no arrow, so "Pick the tank" looked chosen. Now it has the same
   blue-grey edge as every other box and a down arrow drawn in the theme's
   own ink, and while nothing is chosen its prompt is grey and light like any
   other box's. P1. */
select {
  -webkit-appearance: none; appearance: none;
  border-color: var(--edge); padding-right: 38px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 20px) 50%, calc(100% - 14px) 50%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}
/* A list the form has locked (the truck on a transfer follows its load) is
   not something to tap, so it has no arrow. */
select:disabled { background-image: none; }
select:has(> option[value=""]:checked) { color: var(--faint); font-weight: 400; }
select option { color: var(--ink); font-weight: 400; }
.hint { font-size: 12.5px; color: var(--muted); margin-top: 8px; line-height: 1.55; }

.btn {
  min-height: 52px; width: 100%; border-radius: 4px; font: inherit; font-size: 16px;
  display: flex; align-items: center; justify-content: center; gap: 8px; cursor: pointer;
  /* An anchor can be a button here, for the blank paper sheets, which open in
     their own tab rather than replacing the count somebody is halfway through. */
  text-decoration: none; box-sizing: border-box;
}
.btn.primary { background: var(--brand); color: #FFFFFF; font-weight: 600; border: 1.5px solid var(--brand); }
.btn.plain { background: var(--paper); color: var(--ink); border: 1.5px solid var(--ink); font-size: 15px; }
.btn[disabled] { opacity: 0.45; cursor: default; }
.actions { padding: 16px; display: flex; flex-direction: column; gap: 8px; }
.actions .foot { font-size: 11px; color: var(--muted); text-align: center; line-height: 1.4; }

/* Notes and computed panels --------------------------------------------- */

.note-green {
  display: flex; align-items: flex-start; gap: 8px; margin-top: 7px;
  padding: 9px 12px; background: var(--pale); border-radius: 4px;
  font-size: 12px; color: var(--deep); line-height: 1.45;
}
.note-amber {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 11px 13px; background: var(--amber-bg); border: 1.5px solid var(--amber-edge);
  border-radius: 4px; font-size: 12px; color: var(--amber-deep); line-height: 1.45;
}
.note-amber.quiet { border: 0; padding: 9px 12px; font-size: 11px; }
/* A form given back what was typed on it before a sign-out or a restart. */
.draftnote {
  margin: 12px 16px 0; padding: 11px 13px; background: var(--pale);
  border-left: 3px solid var(--brand); border-radius: 4px;
  font-size: 13px; color: var(--deep); line-height: 1.45;
}
.draftnote p { margin: 0 0 9px; }
.draftnote .btn { width: 100%; }
.computed {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 14px; background: var(--pale); border-radius: 4px;
  border-left: 3px solid var(--brand); margin-top: 10px;
}
.computed .k { font-size: 12px; color: var(--deep); }
.computed .why { font-size: 11px; color: var(--muted); margin-top: 2px; }
.computed .v { font-size: 21px; font-weight: 600; color: var(--deep); white-space: nowrap; flex-shrink: 0; margin-left: 12px; }

/* Lists ----------------------------------------------------------------- */

.cards { display: flex; flex-direction: column; gap: 10px; padding: 8px 16px 4px; }
.card {
  display: flex; align-items: center; gap: 13px; min-height: 66px;
  padding: 0 14px; background: var(--paper); border: 1px solid var(--line);
  box-shadow: var(--card-shadow);
  border-radius: 14px; width: 100%; font: inherit; text-align: left; cursor: pointer;
}
.card:active { transform: scale(0.99); }
/* The number tile. Filled in the one blue, with white on it, so it reads from
   across the yard. One colour on purpose: the staff found the plain list dull
   and the cycling colours odd, and the references Godfrey chose use one. */
.card .n {
  width: 38px; height: 38px; border-radius: 11px; background: var(--brand);
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; font-weight: 700; color: var(--paper); flex-shrink: 0;
}
.card .t { font-size: 15px; font-weight: 600; }
.card .s { font-size: 12px; color: var(--muted); margin-top: 1px; }
/* A person whose whole job is one sheet, the drivers, gets it as one large
   card with the bullet on it rather than a short list of one. */
.cards.solo .card { min-height: 150px; padding: 22px 18px; gap: 18px; border-width: 2px; border-color: var(--brand); }
.cards.solo .card .n {
  width: 64px; height: 64px; border-radius: 18px; font-size: 0;
  background: var(--brand) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FFFFFF' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='2' y='8' width='14' height='9' rx='4.5'/%3E%3Cpath d='M16 11h3l3 3v3h-6'/%3E%3Ccircle cx='6' cy='19' r='1.6'/%3E%3Ccircle cx='18' cy='19' r='1.6'/%3E%3C/svg%3E") center / 36px no-repeat;
}
.cards.solo .card .t { font-size: 22px; line-height: 1.2; }
.cards.solo .card .s { font-size: 15px; margin-top: 6px; }
.cards.solo .card svg { width: 26px; height: 26px; }

.entries { display: flex; flex-direction: column; gap: 6px; padding: 0 16px; }
.entry {
  display: flex; align-items: center; gap: 10px; padding: 11px 12px;
  background: var(--paper); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--card-shadow);
}
.entry .what { font-size: 14px; }
button.entry { width: 100%; font: inherit; text-align: left; cursor: pointer; }
.entryday { font-size: 12px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); padding: 10px 2px 2px; }
/* Reading an entry back. A sheet over the screen, nothing on it editable. */
.scrim { position: fixed; inset: 0; background: rgba(17, 24, 39, 0.45); z-index: 60; display: flex; align-items: flex-end; justify-content: center; }
.viewsheet {
  width: 100%; max-width: 520px; max-height: 88vh; overflow-y: auto; background: var(--paper); color: var(--ink);
  border-radius: 18px 18px 0 0; padding: 18px 16px 24px; display: flex; flex-direction: column; gap: 12px;
}
.viewhead { display: flex; flex-direction: column; gap: 4px; }
.viewhead .what { font-size: 18px; font-weight: 600; }
.viewhead .detail { font-size: 13px; color: var(--muted); }
.viewrows { display: flex; flex-direction: column; }
.viewrow { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 15px; }
.viewrow .k { color: var(--muted); }
.viewrow .v { font-weight: 600; text-align: right; }
.viewrow.sub { font-size: 13px; color: var(--muted); padding-left: 12px; }
/* Which line of a sheet is being checked, on the screen shown before sending. */
.viewrow.lineno { font-size: 12px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); border-bottom: 0; padding: 14px 0 2px; }
/* The reason a person gives for cancelling their own entry, on the same sheet. */
.viewsheet .msg { font-size: 13px; color: var(--red-ink); min-height: 0; }
.viewsheet .msg:empty { display: none; }
/* The typo guard's question: a figure far from what is usually entered. */
.viewsheet .unusual { background: var(--amber-bg); border-left: 4px solid var(--amber-edge); color: var(--amber-ink); border-radius: 8px; padding: 10px 12px; }
.viewsheet .unusual .label { font-size: 13px; font-weight: 600; }
.viewsheet .unusual p { margin: 4px 0 0; font-size: 16px; line-height: 1.45; }
.entry .detail { font-size: 12px; color: var(--muted); margin-top: 1px; }
.state { display: flex; align-items: center; gap: 5px; font-size: 11px; white-space: nowrap; }
.dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.state.on_device { color: var(--amber-ink); } .state.on_device .dot { background: var(--amber-edge); }
.state.sending   { color: var(--blue-ink); }  .state.sending .dot   { background: var(--blue); }
.state.sent      { color: var(--deep); }      .state.sent .dot      { background: var(--brand); }
.state.attention { color: var(--red-ink); }   .state.attention .dot { background: var(--red); }
.empty { padding: 14px 16px; font-size: 13px; color: var(--muted); }

/* Sign in --------------------------------------------------------------- */

/* Sign in and password. A centred card rather than the old PIN pad: Gasmate
   asked for a username and a password after seeing a login they preferred.
   Kept deliberately quiet, because a sign-in screen has one job and every
   extra thing on it is something to read before you can start work. */
.signin { align-items: center; justify-content: center; padding: 24px 16px 32px; }
.mark {
  width: 52px; height: 52px; border-radius: 13px; background: var(--brand);
  display: grid; place-items: center;
}
.authcard {
  width: 100%; max-width: 360px; display: flex; flex-direction: column; align-items: stretch;
  background: var(--paper); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: var(--card-shadow);
  padding: 26px 22px 22px; gap: 0;
}
.authcard .mark { 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; line-height: 1.45; }

.field { display: block; margin-top: 18px; }
/* This rule and .row2 have the same specificity and this one is written later,
   so every .field.row2 on the plant app has been stacking instead of sitting
   side by side. Found on 3 September on the delivery form, where it put the
   BULLET label hard against the truck box with no gap above it. */
.field.row2 { display: flex; }
.field.row2 > * { display: flex; flex-direction: column; }
/* A value that is shown, not chosen: the driver's own name on his load. */
.fixedval {
  min-height: 54px; display: flex; align-items: center; padding: 0 14px; font-size: 17px; font-weight: 600;
  background: var(--paper); border: 1.5px solid var(--line); border-radius: 4px; color: var(--ink);
}
.flabel {
  display: block; font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 6px;
}
.fhint { display: block; font-size: 11.5px; color: var(--faint); margin-top: 6px; line-height: 1.4; }
.field input {
  width: 100%; font: inherit; font-size: 16px; color: var(--ink); background: var(--bg);
  border: 1px solid var(--edge); border-radius: 9px; padding: 12px 13px; min-height: 48px;
}
.field input:focus-visible { outline: 2px solid var(--deep); outline-offset: 1px; border-color: var(--deep); }
/* The drop-downs on a form take the same box as the typed boxes beside them.
   background-color only, so the arrow drawn on every select stays. P1. */
.field select {
  font-size: 16px; background-color: var(--bg);
  border: 1px solid var(--edge); border-radius: 9px; padding: 12px 38px 12px 13px; min-height: 48px;
}
.field select:focus-visible { outline: 2px solid var(--deep); outline-offset: 1px; border-color: var(--deep); }

/* The reveal sits inside the box rather than beside it, so the field keeps
   its full width on a phone held in one hand. */
.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;
}
.reveal:hover { color: var(--deep); }

.primary {
  margin-top: 20px; width: 100%; min-height: 50px; font: inherit; font-size: 15px; font-weight: 600;
  color: #FFFFFF; background: var(--deep); border: 1px solid var(--deep); border-radius: 9px;
  cursor: pointer;
}
.primary:hover { background: #1F2530; }
.primary:disabled { opacity: 0.6; cursor: default; }
.linkish {
  margin-top: 10px; background: none; border: 0; color: var(--muted); font: inherit;
  font-size: 12.5px; cursor: pointer; padding: 8px; border-radius: 7px;
}
.linkish:hover { color: var(--ink); }
/* Under the field it acts on rather than floating in a row of its own. Still a
   44px target, which is the point of the padding. */
.linkish.small { margin-top: 6px; padding: 8px 0; color: var(--brand); font-weight: 600; text-align: left; }

.signin .msg {
  font-size: 13px; color: var(--red-ink); margin-top: 14px; text-align: center;
  min-height: 18px; line-height: 1.4;
}
.signin .tip { font-size: 11.5px; color: var(--faint); margin: 14px 0 0; text-align: center; line-height: 1.45; }

/* Production rows ------------------------------------------------------- */

.tanks { display: flex; gap: 7px; margin-top: 7px; }
.tank {
  flex: 1 1 0; min-height: 46px; border-radius: 4px; font: inherit; font-size: 15px;
  font-weight: 600; border: 1.5px solid var(--edge); background: var(--paper);
  color: var(--ink); cursor: pointer;
}
.tank[aria-pressed="true"] { background: var(--deep); border-color: var(--deep); color: #FFFFFF; }
.tank:disabled { background: var(--paper); color: var(--muted); border-style: dashed; cursor: not-allowed; }

/* The shared production sheet: the tank lock, the load, the tanks so far --- */

.sheetbox:empty { display: none; }
.sheetbox { display: flex; flex-direction: column; gap: 8px; }
.sheetbox .lbl { margin-top: 4px; }
.loads { display: flex; flex-direction: column; gap: 6px; }
.tank.load { flex: none; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 8px 12px; text-align: left; }
.tank.load .loadname { font-size: 14.5px; }
.tank.load .loadsub { font-size: 12px; font-weight: 400; }
.note-red {
  padding: 11px 13px; background: var(--paper); border: 1.5px solid var(--red);
  border-radius: 4px; font-size: 12.5px; color: var(--red-ink); line-height: 1.45;
}
.sheetline { font-size: 13px; line-height: 1.45; padding: 8px 11px; background: var(--paper); border: 1.5px solid var(--edge); border-radius: 4px; }
.sheetline.open { border-color: var(--amber-edge); }

.prows { display: flex; flex-direction: column; gap: 6px; padding: 8px 16px 0; }
.prow {
  display: flex; align-items: center; gap: 10px; padding: 8px 11px;
  background: var(--paper); border: 1.5px solid var(--edge); border-radius: 4px;
}
.prow .sku { font-size: 14px; font-weight: 600; }
.prow .kg { font-size: 11px; color: var(--muted); margin-top: 1px; }
.prow input { width: 78px; min-height: 44px; text-align: center; font-size: 17px; padding: 0 4px; }
.prow .none {
  border: 1.5px solid var(--amber-edge); background: var(--paper); color: var(--amber-ink);
  border-radius: 4px; min-height: 44px; padding: 0 8px; font: inherit; font-size: 12px; cursor: pointer;
}
.prow.blank { background: var(--paper); }
.prow.blank .sku { font-weight: 400; color: var(--muted); }
/* A row with a count in it is the one worth seeing from across the screen. */
.prow.filled { background: var(--paper); border-color: var(--deep); }
.prow.unavailable { background: var(--bg); }
.prow.unavailable .sku { font-weight: 400; color: var(--muted); }
.stack { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }

/* Toast ----------------------------------------------------------------- */

#toast {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 22px;
  max-width: 340px; padding: 12px 16px; border-radius: 4px;
  background: var(--deep); color: var(--bg); font-size: 13px; line-height: 1.4;
  z-index: 20; box-shadow: 0 6px 20px rgba(30, 30, 30, 0.18);
}
#toast.warn { background: var(--amber-bg); color: var(--amber-deep); border: 1.5px solid var(--amber-edge); }

/* Office screens ---------------------------------------------------------- */

.stats { display: flex; gap: 10px; padding: 18px 16px 0; flex-wrap: wrap; }
.stat {
  flex: 1 1 150px; padding: 12px 15px; background: var(--paper);
  border: 1.5px solid var(--line); border-radius: 4px;
}
.stat.flag { border-color: var(--amber-edge); }
.stat .k { font-size: 12px; color: var(--muted); }
.stat .v { font-size: 21px; font-weight: 600; margin-top: 4px; }
.stat.flag .v { color: var(--amber-ink); }

.table {
  margin: 9px 16px 0; background: var(--paper); border: 1.5px solid var(--line);
  border-radius: 4px; overflow-x: auto;
}
.table table { width: 100%; border-collapse: collapse; min-width: 560px; }
.table th {
  text-align: left; font-size: 12px; font-weight: 600; letter-spacing: 0.3px;
  color: var(--deep); padding: 10px 15px; background: var(--pale);
  border-bottom: 1.5px solid var(--line); white-space: nowrap;
}
.table td { font-size: 13px; padding: 11px 15px; border-bottom: 1px solid #E7EAF1; vertical-align: top; }
/* A figure column reads as one column only if its heading is aligned the way
   its figures are. Without the th here a heading sits at the left of a wide
   column while its number sits at the right, and they read as two columns. */
.table th.num, .table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.table tr:last-child td { border-bottom: 0; }
.table td.dim { color: var(--muted); }
.table td.time { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.table tr.flagged { background: #FBF7EC; }
.table tr.flagged td:first-child { font-weight: 600; }
.table tr.gone td { color: var(--faint); text-decoration: line-through; }
.table tr.clickable { cursor: pointer; }
.table tr.clickable:hover { background: var(--pale); }
.tag {
  display: inline-block; font-size: 11px; padding: 2px 8px; border-radius: 3px;
  background: var(--pale); color: var(--deep); white-space: nowrap;
}
.tag.warn { background: var(--amber-bg); color: var(--amber-ink); }
.tag.gone { background: #E7EAF1; color: var(--muted); }

.cardgrid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px; padding: 10px 16px 0;
}
.figure { padding: 14px 15px; background: var(--paper); border: 1.5px solid var(--line); border-radius: 4px; }
.figure .k { font-size: 12px; color: var(--muted); }
.figure .v { font-size: 23px; font-weight: 600; margin-top: 6px; }
.figure.absent .v { color: var(--faint); font-size: 18px; font-weight: 400; }
.figure .from { font-size: 11px; color: var(--faint); margin-top: 4px; line-height: 1.35; }
.figure .flag {
  display: inline-block; font-size: 10px; margin-top: 7px; padding: 2px 7px;
  border-radius: 3px; background: var(--amber-bg); color: var(--amber-ink);
}

.callout {
  display: flex; align-items: flex-start; gap: 12px; margin: 18px 16px 0;
  padding: 15px 18px; background: var(--amber-bg); border: 1.5px solid var(--amber-edge);
  border-radius: 4px;
}
.callout .t { font-size: 14px; font-weight: 600; color: var(--amber-deep); }
.callout .b { font-size: 13px; color: var(--amber-deep); margin-top: 4px; line-height: 1.45; }
.observed {
  margin: 14px 16px 0; padding: 13px 16px; background: var(--paper);
  border: 1.5px dashed var(--edge); border-radius: 4px;
  font-size: 13px; color: var(--muted); line-height: 1.5;
}
.asks { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 7px; padding: 10px 16px 0; }
.ask {
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 13px;
  background: var(--paper); border: 1.5px solid var(--line); border-radius: 4px;
}
.ask .dot { margin-top: 5px; background: var(--edge); }
.ask.blocking .dot { background: var(--amber-edge); }
.ask .q { font-size: 12px; line-height: 1.35; }
.ask .w { font-size: 11px; color: var(--muted); margin-top: 3px; line-height: 1.35; }
.footnote { padding: 16px; font-size: 12px; color: var(--muted); border-top: 1px solid var(--line); line-height: 1.5; }

/* Correction -------------------------------------------------------------- */

.record {
  margin-top: 8px; padding: 14px 16px; background: var(--paper);
  border: 1.5px solid var(--line); border-radius: 4px;
}
.record .head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.record .title { font-size: 15px; font-weight: 600; }
.record .meta { font-size: 12px; color: var(--muted); margin-top: 3px; }
.record .big { font-size: 25px; font-weight: 600; text-align: right; }
.record .unit { font-size: 11px; color: var(--muted); text-align: right; }
.record .foot {
  margin-top: 12px; padding-top: 11px; border-top: 1px dashed var(--line);
  font-size: 12px; color: var(--muted);
}
.arrowrule { display: flex; align-items: center; gap: 12px; padding: 16px 16px 0; }
.arrowrule .line { flex-grow: 1; height: 1px; background: var(--line); }
.chips { display: flex; gap: 7px; margin-top: 8px; flex-wrap: wrap; }
.chip {
  padding: 7px 13px; border: 1px solid var(--edge); border-radius: 14px;
  background: var(--paper); font: inherit; font-size: 12px; color: var(--muted); cursor: pointer;
}
.chip:hover { border-color: var(--brand); }
.ledger { display: flex; flex-direction: column; gap: 7px; margin-top: 9px; }
.ledger .row { display: flex; align-items: center; gap: 11px; }
.ledger .n {
  width: 22px; height: 22px; border-radius: 4px; display: flex; align-items: center;
  justify-content: center; font-size: 11px; font-weight: 600; flex-shrink: 0;
}
.ledger .n.keep { background: #E7EAF1; color: var(--muted); }
.ledger .n.rev { background: var(--amber-bg); color: var(--amber-ink); }
.ledger .n.new { background: var(--pale); color: var(--deep); }
.ledger .text { flex-grow: 1; font-size: 13px; }
.ledger .amt { font-size: 13px; }
.ledger .amt.rev { color: var(--amber-ink); }
.ledger .amt.new { color: var(--deep); }
.ledger .amt.keep { color: var(--muted); }
textarea { min-height: 66px; padding: 12px 14px; line-height: 1.45; resize: vertical; }

/* The plant station -------------------------------------------------------
   Confirmed 25 August: entry happens on a Windows computer with a mouse and
   keyboard at the plant, and on the office machines. Not on personal phones.

   The layout stays a phone layout underneath, because the screens were built
   that way and a narrow window must keep working. Everything below only
   applies once there is room, so nothing here can break the small case.

   Two things change on a real screen. The production sheet stops scrolling
   and shows all thirteen sizes at once, the way the paper does, because a
   person checking their work against a sheet should not have to remember what
   is above the fold. And the vertical rhythm tightens, because a mouse
   pointer does not need a thumb's worth of room. */

@media (min-width: 760px) {
  .screen { max-width: 640px; }

  /* The one screen that genuinely wants the width. */
  #screen-production { max-width: 940px; }
  #screen-production .prows {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px 12px;
    align-content: start;
  }
  /* The blank-count warning and the running total belong under both columns,
     not squeezed into one. */
  #screen-production .field,
  #screen-production .section,
  #screen-production .actions { grid-column: 1 / -1; }

  .prow { padding: 7px 11px; }
  .prow input { min-height: 38px; }
  .prow .none { min-height: 38px; }
  .card { min-height: 54px; }
  .btn { min-height: 46px; }
  .key { min-height: 54px; }

  /* Submitting is the one irreversible act on these screens, so it keeps its
     size when everything else shrinks. */
  .actions .btn.primary { min-height: 52px; font-size: 16px; }
}

/* Who is entering, said at the moment it is recorded. On a shared station the
   person at the keyboard is not necessarily the person signed in, and the
   record carries whoever is. Naming them on the button is the cheapest
   possible guard against a whole tank being entered under the wrong name. */
.btn .as {
  font-weight: 400;
  opacity: 0.85;
}

/* Idle warning. A shared station left signed in is an attribution problem, so
   it signs out, but never without saying so first. */
#idle-warning {
  position: fixed; left: 50%; transform: translateX(-50%); top: 16px;
  max-width: 420px; padding: 14px 18px; border-radius: 4px; z-index: 30;
  background: var(--amber-bg); color: var(--amber-deep);
  border: 1.5px solid var(--amber-edge); font-size: 14px; line-height: 1.45;
  box-shadow: 0 6px 20px rgba(30, 30, 30, 0.18);
}
#idle-warning button {
  margin-top: 10px; min-height: 40px; padding: 0 18px; font: inherit;
  font-size: 14px; font-weight: 600; border-radius: 4px; cursor: pointer;
  background: var(--deep); color: var(--bg); border: 0;
}

/* A keyboard is the fast way in at a station, so the focused field has to be
   obvious without hunting for it. */
.prow input:focus {
  outline: 2px solid var(--deep);
  outline-offset: 1px;
  background: var(--pale);
}

/* Stock report grid ---------------------------------------------------------
   A counted sheet is wide and numeric. The row label stays pinned while the
   columns scroll, because a figure whose row you cannot see is not a figure.
   A blank cell is drawn blank: on these sheets a zero is a count of none and
   an empty cell is nobody having looked, and the screen must not merge them. */

.table.grid table { min-width: 760px; }
.table.grid th, .table.grid td { padding: 7px 10px; font-size: 12px; }
.table.grid th.rowhead, .table.grid td.rowhead {
  position: sticky; left: 0; z-index: 1; background: var(--paper);
  white-space: nowrap; min-width: 210px;
}
.table.grid th.rowhead { background: var(--pale); }
.table.grid th.n, .table.grid td.n { text-align: right; font-variant-numeric: tabular-nums; }
.table.grid td.blank { color: var(--faint); }
.table.grid td.tot { font-weight: 600; border-left: 1px solid var(--line); }
.table.grid tr.lvl0 td.rowhead { font-weight: 600; }
.table.grid tr.lvl0 { background: #F3F4F6; }
.table.grid tr.lvl1 td.rowhead { padding-left: 26px; }
.table.grid tr.lvl2 td.rowhead { padding-left: 42px; color: var(--muted); }
.table.grid tr.stated td.rowhead { font-style: italic; }
.table.grid td.gap { background: var(--amber-bg); color: var(--amber-ink); font-weight: 600; }

.check {
  display: flex; flex-direction: column; gap: 4px; padding: 12px 14px;
  background: var(--amber-bg); border: 1.5px solid var(--amber-edge); border-radius: 4px;
}
.check .h { font-size: 13px; font-weight: 600; color: var(--amber-deep); }
.check .b { font-size: 12px; color: var(--amber-deep); line-height: 1.45; }
.check .w { font-size: 11px; color: var(--amber-ink); line-height: 1.4; }

/* A worked out row on a movement sheet. Marked so an Ending is never read as
   a figure somebody wrote down, which is the whole distinction the daily
   depot sheet turns on. */
.table.grid tr.worked td { background: #F3F4F6; font-style: italic; }
.table.grid tr.worked td.rowhead { font-style: italic; color: var(--deep); }
.table.grid td.worked { background: #F3F4F6; font-style: italic; color: var(--deep); }

/* A total that does not cover every line on its row. The daily depot sheet
   can be counted in part, and a partial total sitting silently next to a
   complete one is read as a shortfall that does not exist. */
.table.grid td.partial .part {
  display: block; font-size: 9px; font-weight: 400; color: var(--amber-ink);
  white-space: nowrap; margin-top: 1px;
}

/* Depot entry grid. Same table shape the read-only stock report uses, with a
   plain number input filling each cell instead of a static figure. */
.table.grid input {
  width: 100%; min-width: 56px; text-align: right; padding: 3px 5px;
  font-size: 12px; border: 1px solid var(--line); border-radius: 3px;
  background: var(--paper); font-variant-numeric: tabular-nums;
}
.table.grid input:focus { outline: 2px solid var(--brand); outline-offset: -1px; }

/* Office and owner have a desktop application at /erp. The plant app stays
   theirs too, because corrections are made here. */
.officelink {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: 14px 16px 0; padding: 13px 15px; border-radius: 10px;
  background: var(--pale); border: 1px solid #B1BBC8; color: var(--deep);
  font-size: 14px; font-weight: 600; text-decoration: none;
}
.officelink:hover { background: #DCE3EE; }

/* Residual. Four narrow columns rather than the wide counted sheet, so the
   grid does not need its 760px minimum: a phone should show the whole row.
   The residual column is worked out as you type and never sent, which is why
   it is drawn as text rather than as a field. */
#screen-residual .table.grid table { min-width: 0; }
#screen-residual .table.grid th, #screen-residual .table.grid td { padding: 6px 8px; }
#screen-residual .table.grid input.code { text-align: left; min-width: 56px; }
#screen-residual .table.grid td.residualout {
  font-variant-numeric: tabular-nums; text-align: right; font-weight: 600;
  color: var(--deep); white-space: nowrap; min-width: 58px;
}
#screen-residual .table.grid td.residualout.bad { color: var(--amber-ink); font-weight: 700; }

/* M&R. Three drop downs and a count per line. The selects take the same
   shape as the grid inputs so a row reads as one row. */
#screen-mr .table.grid table { min-width: 0; }
#screen-mr .table.grid th, #screen-mr .table.grid td { padding: 6px 3px; }
#screen-mr .table.grid th:last-child, #screen-mr .table.grid td:last-child { padding-right: 6px; }
#screen-mr .table.grid select {
  width: 100%; min-width: 78px; padding: 5px 22px 5px 2px; font-size: 12px;
  border: 1px solid var(--line); border-radius: 3px; background-color: var(--paper);
  background-position: calc(100% - 12px) 50%, calc(100% - 7px) 50%; background-size: 5px 5px, 5px 5px;
}
#screen-mr .table.grid select:focus { outline: 2px solid var(--brand); outline-offset: -1px; }
#screen-mr .table.grid input.num { min-width: 46px; width: 46px; }

/* Counting one cylinder at a time -----------------------------------------
   The paper form is a grid and this screen was a copy of it, which on a phone
   is a spreadsheet scrolled sideways with 12px boxes in it. A person counting
   walks the floor by cylinder type and reads one column of that paper top to
   bottom, so that is what this asks for: same rows, same order, one column at
   a time, in boxes big enough to hit with a thumb. */
.pills {
  display: flex; gap: 8px; overflow-x: auto; padding: 12px 16px 4px;
  scrollbar-width: none; -ms-overflow-style: none;
}
.pills::-webkit-scrollbar { display: none; }
.pill {
  flex: none; display: inline-flex; align-items: center; gap: 7px;
  min-height: 46px; padding: 0 16px; border-radius: 24px;
  border: 1.5px solid var(--ink); background: var(--paper);
  font: inherit; font-size: 15px; font-weight: 600; color: var(--ink); cursor: pointer;
  white-space: nowrap;
}
.pill[aria-pressed="true"] { background: var(--deep); border-color: var(--deep); color: #FFFFFF; }
/* A cylinder somebody has already put a figure against. Not a claim that it is
   finished, only that it has been started, which is what the count beside the
   heading says too. */
.pilldot { width: 8px; height: 8px; border-radius: 50%; background: var(--brand); flex: none; }
.pill[aria-pressed="true"] .pilldot { background: #FFFFFF; }

.counthead {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 16px 16px 2px;
}
.counttitle { font-size: 21px; font-weight: 600; letter-spacing: -0.01em; }
.countof { font-size: 12px; color: var(--muted); }

.countcard {
  margin: 12px 16px 0; background: var(--paper);
  border: 1.5px solid var(--ink); border-radius: 4px; overflow: hidden;
}
.countcard h2 {
  margin: 0; padding: 11px 14px; font-size: 14px; font-weight: 600;
  background: var(--pale); border-bottom: 1.5px solid var(--ink);
}
.countgroup { display: block; font-size: 11px; font-weight: 600; letter-spacing: 0.4px;
              text-transform: uppercase; color: var(--muted); margin-bottom: 2px; }
.countrow {
  display: flex; align-items: center; gap: 12px; padding: 9px 14px;
  border-bottom: 1px solid var(--line);
}
.countrow:last-child { border-bottom: 0; }
/* The count as tiles: two by two, label above the figure, and the worked out
   ending under them. The paper is a grid, and this is the grid one cylinder
   at a time rather than a column of rows. */
.countgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; padding: 10px 12px 4px; }
.counttile {
  display: flex; flex-direction: column; gap: 4px; padding: 8px 10px 10px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--paper);
}
.counttile .cl { font-size: 11px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
/* The box sits at the foot of its tile, so three boxes in a row line up when
   one label wraps and another does not. SERIAL NUMBER and TARE WEIGHT take two
   lines on a phone and TOTAL KGS takes one, which set its box higher. */
.counttile input, .counttile select { margin-top: auto; }
.counttile input {
  width: 100%; min-height: 50px; text-align: left; font-size: 22px; font-weight: 600;
  font-variant-numeric: tabular-nums; border: 0; border-bottom: 2px solid var(--edge); border-radius: 0; padding: 4px 2px; background: transparent;
}
.counttile input:focus-visible { outline: 0; border-bottom-color: var(--brand); }
/* The prompt in a big count box is smaller than the figure it waits for, as
   well as grey and light, so an empty box never reads as a count. P2. */
.counttile input::placeholder, .countrow input::placeholder { font-size: 16px; }
/* A worked out figure, not a box: read from production and M&R, so it has no
   underline to type on and says where it came from under the figure. */
.counttile.worked { background: var(--bg); border-style: dashed; }
.counttile.worked .wv { margin-top: auto; min-height: 36px; font-size: 20px; font-weight: 600; color: var(--deep); font-variant-numeric: tabular-nums; }
.counttile.worked .wf { font-size: 12px; color: var(--muted); line-height: 1.35; }
.countending { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px 12px; font-size: 14px; }
.countending .k { color: var(--muted); }
.countending .v { font-size: 18px; font-weight: 600; color: var(--deep); }
/* A worked out figure that cannot be worked out yet says "not yet" in grey,
   light type, the way an empty box's prompt does, so it never sits on the
   screen looking like a figure (P2). A real figure keeps its weight. */
.countending .v.none, .computed .v.none, .residualout.none { color: var(--faint); font-weight: 400; font-size: 15px; }
.countending .tag { margin-left: auto; }
.countgrid.three { grid-template-columns: 1fr 1fr 1fr; }
.countgrid.three .counttile input { font-size: 19px; }
/* A line of a sheet as a card: residual and M&R, one steel or one batch each. */
.linecards { display: flex; flex-direction: column; gap: 10px; padding: 8px 16px 0; }
.linecard { background: var(--paper); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--card-shadow); }
.linehead { font-size: 13px; font-weight: 600; color: var(--muted); padding: 10px 14px 0; letter-spacing: 0.03em; text-transform: uppercase; }
.linecard .countgrid { padding: 8px 12px 4px; }
.counttile select {
  width: 100%; min-height: 50px; font: inherit; font-size: 16px; font-weight: 600; color: var(--ink);
  border: 0; border-bottom: 2px solid var(--edge); border-radius: 0; padding: 4px 26px 4px 2px; background-color: transparent;
  background-position: calc(100% - 13px) 50%, calc(100% - 7px) 50%;
}
.counttile select:focus-visible { outline: 0; border-bottom-color: var(--brand); }
.countending .residualout.bad { color: var(--amber-ink); }
.countrow .cl { flex: 1 1 auto; min-width: 0; font-size: 15px; }
.countrow input {
  flex: 0 0 116px; width: 116px; min-height: 54px;
  text-align: center; font-size: 20px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* A tablet or a desk has room for the three conditions side by side. Still one
   cylinder at a time: the matrix is what was wrong, not the width. */
/* The Canister Inventory Form. The small line under a box says the Beginning
   was carried and from which day, and the line under the Canister Production
   check says it is a check only. REFILLING and CRIMPING fold their boxes away
   behind one line, because the paper gives them boxes nobody has said are
   used. */
.cinote { display: block; font-size: 11.5px; color: var(--muted); line-height: 1.35; }
.countcard > .cinote, .cifold > .cinote { padding: 0 14px 12px; }
.cifold > summary { padding: 11px 14px; font-size: 13px; color: var(--muted); cursor: pointer; }
/* C11, 26 September 2026. A row folds to its name and its typed figures, one
   row open at a time, and the whole row name is the thing to tap. The worked
   out Ending sits under the boxes as the check on the typed one, in smaller
   type, so the two never read as two answers to one question. */
.cirow { scroll-margin-top: 8px; }
.countcard h2:has(> .cihead) { padding: 0; }
.cirow:not(.open) > h2 { border-bottom: 0; }
.cirow:not(.open) .cibody, .cirow.open .cityped { display: none; }
.cihead {
  position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 3px;
  width: 100%; min-height: 52px; padding: 11px 42px 11px 14px; text-align: left; cursor: pointer;
  background: none; border: 0; font: inherit; font-size: 14px; font-weight: 600; color: var(--ink);
}
.cihead::after {
  content: ''; position: absolute; right: 18px; top: 50%; width: 8px; height: 8px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: translateY(-70%) rotate(45deg);
}
.cihead[aria-expanded="true"]::after { transform: translateY(-20%) rotate(-135deg); }
.cihead:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.cityped {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px;
  font-size: 13px; font-weight: 400; color: var(--muted); font-variant-numeric: tabular-nums;
}
.cityped .none { color: var(--faint); }
.cicheck {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px;
  padding: 6px 14px 12px; font-size: 12.5px; color: var(--muted);
}
.cicheck .v { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.cicheck .v.none { color: var(--faint); font-weight: 400; }
.cicheck .why { flex-basis: 100%; line-height: 1.35; }
.cinext { margin: 2px 12px 12px; width: calc(100% - 24px); min-height: 48px; }

@media (min-width: 720px) {
  #de-sheet, #ae-sheet, #ci-sheet {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 12px; margin: 0 16px;
  }
  .countcard { margin: 12px 0 0; }
  /* The open row of the Canister Inventory Form takes the width, its boxes
     in one line where they fit; the folded rows sit two or three across. */
  #ci-sheet { align-items: start; }
  #ci-sheet .cirow.open { grid-column: 1 / -1; }
  #ci-sheet .cirow.open .countgrid { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
}

/* Small grey unit beside an entry box, so the box holds only the figure. */
.stack .unit { font-size: 11px; color: var(--muted); font-weight: 600; }

/* Photographing the paper. -------------------------------------------------
   The button is deliberately not the primary blue: taking a photo is never
   required and a control that looks like the submit button reads as a step
   somebody has to complete. */
.photoslot { padding: 18px 16px 0; }
.photofield { display: flex; flex-direction: column; gap: 8px; }
.photoinput {
  /* Off screen rather than display:none, so the label still opens it and a
     screen reader still finds it. */
  position: absolute; width: 1px; height: 1px; opacity: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
.photobtn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 0 18px; cursor: pointer; align-self: flex-start;
  font-size: 15px; font-weight: 600; color: var(--deep);
  background: var(--paper); border: 1.5px solid var(--edge); border-radius: 10px;
}
.photobtn:active { background: var(--pale); }
.photobtn::before {
  content: ''; width: 18px; height: 18px; flex: none;
  background: currentColor;
  -webkit-mask: center / contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5A1.5 1.5 0 0 1 4.5 7h2.8l1.4-2h6.6l1.4 2h2.8A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z'/%3E%3Ccircle cx='12' cy='13' r='3.4'/%3E%3C/svg%3E");
  mask: center / contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5A1.5 1.5 0 0 1 4.5 7h2.8l1.4-2h6.6l1.4 2h2.8A1.5 1.5 0 0 1 21 8.5v9A1.5 1.5 0 0 1 19.5 19h-15A1.5 1.5 0 0 1 3 17.5z'/%3E%3Ccircle cx='12' cy='13' r='3.4'/%3E%3C/svg%3E");
}
.photopreview { display: flex; align-items: flex-start; gap: 12px; }
.photopreview img {
  width: 108px; height: 108px; object-fit: cover;
  border-radius: 10px; border: 1px solid var(--line);
}
.photoagain {
  font: inherit; font-size: 14px; font-weight: 600; color: var(--deep);
  background: var(--paper); border: 1.5px solid var(--edge); border-radius: 10px;
  min-height: 44px; padding: 0 14px; cursor: pointer;
}
.photomsg { font-size: 12.5px; color: var(--muted); line-height: 1.5; }

/* The tank blocks of the Transfers Report. One load into A and C is two
   blocks, each with its own readings, and a rule between them so the second
   tank's totalizer is never read as the first tank's. Joie, 24 September
   2026. With one tank there is no heading and the sheet reads as before. */
.tblock + .tblock { border-top: 1px solid var(--line); margin-top: 18px; }
.tblock-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 18px 16px 0;
}
.tblock-title { font-size: 13px; font-weight: 600; letter-spacing: 0.4px; color: var(--deep); text-transform: uppercase; }
.tblock-head .linkish.small { margin-top: 0; }
/* Which app this phone is running, in the menu that holds the seldom things. */
#shell-line { padding: 10px 2px 2px; font-size: 11.5px; color: var(--muted); line-height: 1.5; }
#shell-line.stale { color: var(--amber-ink); font-weight: 600; }

/* 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; }
