/* ============================================================================
   Forecourt control panel — SK Saad Filling Station
   ----------------------------------------------------------------------------
   The look is taken from the site itself: the deep slate of an underground tank,
   the fluorescent white of a canopy at night, and three product colours that are
   never used decoratively. Amber is petrol, green-gold is octane, copper is
   diesel — everywhere, on every chart, gauge and nozzle, without exception.
   ========================================================================= */

@font-face {
  font-family: 'Archivo';
  src: url('/fonts/archivo-2.woff2') format('woff2');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: 'Archivo';
  src: url('/fonts/archivo-1.woff2') format('woff2');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('/fonts/instrument-2.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('/fonts/instrument-1.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Martian Mono';
  src: url('/fonts/martian-2z.woff2') format('woff2');
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}
@font-face {
  font-family: 'Martian Mono';
  src: url('/fonts/martian-1.woff2') format('woff2');
  font-weight: 200 800;
  font-display: swap;
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Bangla prose. The Latin faces above are unicode-range limited to Latin, so Bengali
   codepoints fall through to this one automatically — no per-language font switching and no
   second stylesheet. Same file as the taka face, declared separately because a family called
   'Taka' has no business setting body copy. */
@font-face {
  font-family: 'Bangla';
  src: url('/fonts/notobengali.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+0980-09FE, U+200C-200D, U+25CC;
}

/* The taka sign lives outside every Latin subset, so it falls through to Bengali. */
@font-face {
  font-family: 'Taka';
  src: url('/fonts/notobengali.woff2') format('woff2');
  font-weight: 400 700;
  font-display: swap;
  unicode-range: U+09F2-09F3, U+0980-09FE;
}

:root {
  --ink-900: #081115;
  --ink-850: #0A161B;
  --ink-800: #0D1A20;
  --ink-750: #102128;
  --ink-700: #12242C;
  --ink-600: #17303A;
  --line: #1C333D;
  --line-2: #29505F;
  --haze: #7C9AA6;
  --haze-2: #A8C2CC;
  --paper: #E8F2F4;

  --petrol: #F2A93B;
  --octane: #C6E04A;
  --diesel: #E2643C;
  --water: #3D8FD1;
  --alarm: #FF4D5E;
  --ok: #2FD1A5;
  --warn: #F2A93B;

  --rail-w: 224px;
  --bar-h: 60px;
  --gap: 18px;
  --r: 4px;
  --r-lg: 8px;

  --display: 'Archivo', 'Bangla', system-ui, sans-serif;
  --body: 'Instrument Sans', 'Bangla', system-ui, sans-serif;
  --data: 'Martian Mono', 'Bangla', ui-monospace, monospace;

  --ease: cubic-bezier(.22, 1, .36, 1);
  color-scheme: dark;
}

/* ---------------------------------------------------------------- light theme
   Chosen per viewer from the switch in the top bar and kept in a cookie, so the server puts
   data-theme on <html> before the first paint and nothing flashes dark first. Every surface
   and ink is a token, so the panel turns over by redefining them.

   The light theme is the same forecourt by day: the dark theme's teal night becomes a cool
   sunlit floor, white cards under one soft shadow, and the side menu stays in the deep teal
   of the canopy's shade — the one dark block on the page, where the amber brand mark and
   the orange of the active item carry the colour. Product colours are tuned so they hold as
   text on white and still read as the pump's own colours; prices sit on a wash of their own
   colour, and the nozzle cards' idle bar is sky rather than navy. */
:root[data-theme="light"] {
  --ink-900: #EBF1F5;          /* the floor */
  --ink-850: #F4F7F9;          /* top bar, KPI tape */
  --ink-800: #FFFFFF;          /* cards */
  --ink-750: #EEF3F6;          /* hover, quiet buttons */
  --ink-700: #E1E9EE;          /* inset wells */
  --ink-600: #CFDBE2;
  --line: #D9E3E9;
  --line-2: #AFC2CC;
  --haze: #5E7682;
  --haze-2: #3A5461;
  --paper: #0F2A33;

  --petrol: #D9880E;
  --octane: #6E9112;
  --diesel: #D5471C;
  --water: #1F6FB8;
  --alarm: #D3243A;
  --ok: #0B9B72;
  --warn: #D9880E;
  color-scheme: light;
}
/* Grade colours arrive inline as --c straight from the controller's configuration, so they
   cannot be retuned as tokens; where one is used as TEXT it is darkened on the spot. As fills,
   dots and borders they read fine on white and are left alone. */
:root[data-theme="light"] :is(.totem__code, .totem__price, .tank__no, .chip--grade, .tank__pct) {
  color: color-mix(in srgb, var(--c) 62%, #0F1E24);
}
:root[data-theme="light"] .modal::backdrop { background: rgba(15, 30, 36, .45); }

/* Daylight on the floor: a touch brighter at the top of the page. */
:root[data-theme="light"] body { background: linear-gradient(180deg, #F3F7F9 0, var(--ink-900) 360px); }

/* The side menu keeps the canopy's shade. Its children read the same tokens, so they are
   re-pointed here and nothing inside needs its own rule. The brand mark, already an
   amber-to-orange tile, is the warm spot on it; the active item carries the amber bar. */
:root[data-theme="light"] .rail {
  --ink-850: #10303A; --ink-800: #143944; --ink-750: #1A4551; --ink-700: #1F5160; --ink-600: #27606F;
  --line: #22515F; --line-2: #3B7183; --haze: #8FB0BC; --haze-2: #C5DAE1; --paper: #F0F7F9;
  border-right-color: #0C252D;
  box-shadow: inset -1px 0 0 rgba(255, 255, 255, .04);
  color: var(--paper);   /* re-resolved here: the page's dark ink would otherwise be inherited */
}
:root[data-theme="light"] .rail a.nav.is-active { background: rgba(255, 255, 255, .07); }
:root[data-theme="light"] .rail a.nav:hover { background: rgba(255, 255, 255, .05); }
:root[data-theme="light"] .rail__resize::before { background: #0C252D; }
:root[data-theme="light"] .rail__resize::after { background: #3B7183; }

/* One shadow level for everything that floats on the floor, so cards sit on it rather than
   being drawn on it. */
:root[data-theme="light"] :is(.panel, .ncard, .shiftcard, .totem, .tape) {
  box-shadow: 0 1px 2px rgba(15, 42, 51, .05), 0 10px 28px -18px rgba(15, 42, 51, .22);
}
:root[data-theme="light"] .bar { background: rgba(255, 255, 255, .86); }
:root[data-theme="light"] .tape { background: var(--ink-800); }
:root[data-theme="light"] .tape__cell:not(:last-child) { border-right-style: solid; }

/* Prices on a wash of their own colour — the forecourt's price board, by product. */
:root[data-theme="light"] .totem__cell {
  background: linear-gradient(180deg, color-mix(in srgb, var(--c) 11%, #fff), color-mix(in srgb, var(--c) 3%, #fff));
}
/* Nozzle cards: the idle bar is sky, not navy; fuelling stays green and offline red. */
:root[data-theme="light"] .ncard__state { --nz-idle: #DCE9F4; }
:root[data-theme="light"] .ncard.is-dispensing .ncard__state { color: #fff; }
:root[data-theme="light"] .ncard.is-offline .ncard__state { color: #fff; }
:root[data-theme="light"] .ncard__head { background: linear-gradient(180deg, color-mix(in srgb, var(--c) 7%, #fff), #fff); }
:root[data-theme="light"] .ncard__meta { background: #fff; }
/* Chips and the bridge pill take a tint of their own colour instead of a bare outline. */
:root[data-theme="light"] .chip--ok { background: color-mix(in srgb, var(--ok) 10%, #fff); }
:root[data-theme="light"] .chip--warn { background: color-mix(in srgb, var(--warn) 12%, #fff); }
:root[data-theme="light"] .chip--live { background: color-mix(in srgb, var(--octane) 12%, #fff); }
:root[data-theme="light"] .chip--grade { background: color-mix(in srgb, var(--c) 12%, #fff); }
:root[data-theme="light"] .pulse.is-online { background: color-mix(in srgb, var(--ok) 10%, #fff); border-color: color-mix(in srgb, var(--ok) 40%, transparent); }
:root[data-theme="light"] .shiftcard.is-live { background: color-mix(in srgb, var(--octane) 9%, #fff); }
/* Tables: a tinted header row and a faint zebra, so long lists stay readable in daylight. */
:root[data-theme="light"] .tbl thead th { background: #F4F7F9; }
:root[data-theme="light"] .tbl tbody tr:nth-child(even) td { background: #FAFCFD; }
:root[data-theme="light"] .btn--primary { color: #fff; }
:root[data-theme="light"] .btn--primary:hover { background: color-mix(in srgb, var(--petrol) 88%, #000); }

/* ---------------------------------------------------------------- reset */

*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
/* The browser's own [hidden] rule loses to any author display rule — a chip is inline-flex, a
   panel is grid — so anything toggled with el.hidden needs this to actually go away. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--ink-900);
  color: var(--paper);
  font-family: var(--body);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }
table { border-collapse: collapse; width: 100%; }
svg { display: block; }

:focus-visible {
  outline: 2px solid var(--octane);
  outline-offset: 2px;
  border-radius: 2px;
}

/* Scrollbars wear the page's own colours: the track IS the surface behind it, the thumb a
   shade deeper so it still reads as a bar (client 10-13) — in both themes, from the tokens.
   --scroll-thumb is set per theme below; Chrome 121+/Firefox use the standard properties,
   older Chromium the ::-webkit ones. */
:root { --scroll-thumb: color-mix(in srgb, var(--line-2) 80%, var(--ink-900)); --scroll-thumb-hover: var(--haze); }
:root[data-theme="light"] { --scroll-thumb: color-mix(in srgb, var(--line-2) 75%, var(--haze)); }
* { scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) transparent; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: 6px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); background-clip: padding-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* ---------------------------------------------------------------- type */

.taka { font-family: 'Taka', var(--data); }

/* Bengali glyphs carry a headline stroke and descend further than Latin, so at the sizes this
   panel uses they need a touch more line height or the rail labels touch each other. Applied
   on the root so it costs nothing in English. */
.lang-bn body { line-height: 1.62; }
.lang-bn h1, .lang-bn h2, .lang-bn h3 { line-height: 1.3; }

/* The eyebrow style is built for Latin small caps: wide tracking and uppercase. Bengali has
   no case, so the transform does nothing, but the tracking pulls conjunct ligatures apart —
   "সাইন ইন করা আছে" comes out looking like loose syllables. Both are dropped for Bangla. */
.lang-bn .eyebrow {
  letter-spacing: normal;
  text-transform: none;
  font-family: var(--body);
  font-size: 10.5px;
}

/* ------------------------------------------------------------- language switch */

.lang-switch { display: flex; align-items: center; gap: 2px; padding: 0 4px; }
/* Light / dark, as a pair of glyphs in the same pill shape as the language switch beside it. */
.theme-switch { display: flex; align-items: center; gap: 2px; padding: 0 4px; }

/* ---------------------------------------------------------------- payment board
   Two ledgers at the foot of the overview: money still owed per sale, and money in. The owed
   total carries the petrol amber the panel uses for "needs attention", the received total the
   same green as a paid chip; nothing else on the board is coloured but the product dots. */
.collect { display: grid; gap: var(--gap); }
.collect__head { flex-wrap: wrap; }
.panel__head.collect__head h2 { flex: none; white-space: nowrap; }  /* beats .panel__head h2 { flex: 1 } further down */
.collect__sum { margin-right: auto; font-size: 12px; color: var(--haze); display: flex; align-items: baseline; gap: 6px; }
/* "All sales →" sits just left of the day's received total and opens /sales. */
.collect__all { margin-left: auto; white-space: nowrap; }
.collect__all + .collect__sum { margin-right: 0; }
.collect__sum b { color: var(--paper); font-family: var(--data); font-variant-numeric: tabular-nums; }
.collect__amt { margin-left: 8px; font-size: 14px; color: var(--petrol) !important; }
.collect__amt--ok { color: var(--ok) !important; }
.collect__search { width: 180px; padding: 5px 9px; font-size: 12px; }
.collect__scroll { max-height: 460px; overflow: auto; }
.collect__tbl thead th { position: sticky; top: 0; z-index: 1; background: var(--ink-800); }
.collect__tbl td { white-space: nowrap; }
.collect__tbl .strong { font-weight: 700; color: var(--paper); }
.collect__time { text-align: left !important; }
.collect__act { width: 1%; text-align: right; }
.collect__act form { display: inline; }
.collect__act { white-space: nowrap; }
.collect__act > * + * { margin-left: 6px; }
.collect__tbl [data-receive]:hover { border-color: var(--ok); color: var(--ok); }
.collect__empty { padding: 26px 16px; text-align: center; color: var(--haze); font-size: 13px; }
.btn--quiet { background: none; border-color: transparent; color: var(--haze); }
.btn--quiet:hover { color: var(--paper); border-color: var(--line-2); }
/* A ticked row leaves the owed list the way a slip comes off a spike — quickly, once. */
.collect tr.is-leaving td { transition: opacity .25s, background .25s; opacity: 0; background: color-mix(in srgb, var(--ok) 18%, transparent); }
.collect tr.is-new td { animation: collect-new 1.6s ease-out; }
@keyframes collect-new { from { background: color-mix(in srgb, var(--petrol) 16%, transparent); } }
@media (prefers-reduced-motion: reduce) { .collect tr.is-leaving td, .collect tr.is-new td { transition: none; animation: none; } }
@media (max-width: 640px) { .collect__search { width: 100%; } }

/* Tank name on Settings: a short box and its button on one line inside a table cell. */
.tank-name { display: flex; align-items: center; gap: 6px; }
/* Qualified by type so it outranks the global text-input rule further down, whose width:100%
   collapsed this box to a sliver inside the flex row. */
.tank-name input[type=text] {
  flex: 0 0 120px; width: 120px; padding: 5px 8px; font-size: 12px;
}
/* Colour chooser (Shared/_ColourPick): swatches + the browser's full picker, no hex to type. */
.cpick { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.cpick__sw {
  width: 24px; height: 24px; padding: 0; border-radius: 50%; cursor: pointer;
  background: var(--c); border: 2px solid var(--ink-800);
  box-shadow: 0 0 0 1px var(--line-2); transition: transform .15s var(--ease);
}
.cpick__sw:hover { transform: scale(1.12); }
.cpick__sw[aria-pressed=true] { box-shadow: 0 0 0 2px var(--paper); transform: scale(1.12); }
.cpick__more {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  padding: 3px 8px 3px 4px; border: 1px solid var(--line-2); border-radius: 14px;
  font-size: 12px; color: var(--haze-2);
}
.cpick__more:hover { color: var(--paper); }
.cpick__more input[type=color] {
  width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%;
  background: none; cursor: pointer; flex: none;
}
.cpick__more input[type=color]::-webkit-color-swatch-wrapper { padding: 0; }
.cpick__more input[type=color]::-webkit-color-swatch { border: 0; border-radius: 50%; }
.cpick__more input[type=color]::-moz-color-swatch { border: 0; border-radius: 50%; }
.colourrow { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }
.colourrow__name { flex: 1 1 140px; min-width: 0; }
.colourrow__pick { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.theme-switch__opt {
  display: grid; place-items: center;
  width: 26px; height: 24px; border-radius: 3px;
  color: var(--haze); border: 1px solid transparent;
  transition: background .14s, color .14s, border-color .14s;
}
.theme-switch__opt svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
.theme-switch__opt:hover { color: var(--paper); background: var(--ink-750); }
:root:not([data-theme="light"]) .theme-switch__opt[data-theme-set="dark"],
:root[data-theme="light"] .theme-switch__opt[data-theme-set="light"] {
  color: var(--paper); background: var(--ink-700); border-color: var(--line-2); pointer-events: none;
}
.lang-switch__opt {
  font-size: 11px;
  padding: 3px 7px;
  border-radius: 3px;
  color: var(--haze);
  border: 1px solid transparent;
  transition: background .14s, color .14s, border-color .14s;
}
.lang-switch__opt:hover { color: var(--paper); background: var(--ink-750); }
.lang-switch__opt.is-on {
  color: var(--paper);
  background: var(--ink-700);
  border-color: var(--line-2);
  font-weight: 600;
  pointer-events: none;
}

.display {
  font-family: var(--display);
  font-variation-settings: 'wdth' 108;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
}

.eyebrow {
  font-family: var(--data);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--haze);
}

.data { font-family: var(--data); font-variant-numeric: tabular-nums; }
.num { font-family: var(--data); font-weight: 500; font-variant-numeric: tabular-nums; letter-spacing: -0.03em; }

h1, h2, h3 { font-family: var(--display); font-weight: 600; letter-spacing: -0.015em; line-height: 1.15; }
h1 { font-size: 24px; font-variation-settings: 'wdth' 105; }
h2 { font-size: 17px; }
h3 { font-size: 14px; }

.muted { color: var(--haze); }
.dim { color: var(--haze); font-size: 12px; }

/* ---------------------------------------------------------------- shell */

/* --rail-open-w is the width dragged by hand (inline on <html>, from a cookie); "mini" folds the
   menu to an icon strip. Both are per browser and drawn by the server, so no page flickers. */
:root { --rail-w: var(--rail-open-w, 224px); }
:root[data-rail-mode="mini"] { --rail-w: 60px; }
.shell { display: grid; grid-template-columns: var(--rail-w) 1fr; min-height: 100vh; }
.shell { transition: grid-template-columns .2s var(--ease); }
:root.rail-dragging .shell { transition: none; }
:root.rail-dragging, :root.rail-dragging * { cursor: col-resize !important; user-select: none; }

.rail__resize {
  position: fixed; top: 0; bottom: 0; left: var(--rail-w); width: 7px; z-index: 40;  /* just outside the menu, clear of its scrollbar */
  cursor: col-resize; touch-action: none;
}
/* The edge reads as a strip: the menu's colour a shade deeper, with a grip in the middle, so
   it is plain that it can be dragged. */
.rail__resize::before {
  content: ""; position: absolute; inset: 0 2px 0 0;
  background: color-mix(in srgb, var(--ink-850) 82%, var(--line-2));
  transition: background .15s;
}
:root[data-theme="light"] .rail__resize::before { background: color-mix(in srgb, var(--ink-850) 70%, var(--line-2)); }
.rail__resize::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 2px; height: 26px; translate: -50% -50%;
  border-radius: 2px; background: var(--line-2); transition: background .15s;
}
/* Hover/drag: the same colour one step deeper again — never the yellow accent (client 10-13). */
.rail__resize:hover::before, :root.rail-dragging .rail__resize::before { background: color-mix(in srgb, var(--ink-850) 55%, var(--line-2)); }
.rail__resize:hover::after, :root.rail-dragging .rail__resize::after { background: var(--haze); }

.rail__who { display: flex; align-items: center; gap: 8px; }
.rail__user { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rail__out { display: inline-flex; align-items: center; gap: 6px; }
.rail__out svg { display: none; }

.rail-fold {
  display: grid; place-items: center; width: 32px; height: 32px; flex: none;
  border: 1px solid var(--line-2); border-radius: var(--r); color: var(--haze-2);
}
.rail-fold:hover { color: var(--paper); border-color: var(--haze); }
.rail-fold__arrow { transition: transform .2s var(--ease); transform-origin: 9.7px 8px; }
:root[data-rail-mode="mini"] .rail-fold__arrow { transform: scaleX(-1); }

/* Folded: icons only, names on hover (title). */
:root[data-rail-mode="mini"] .rail { overflow-x: hidden; }
:root[data-rail-mode="mini"] .rail__brand { padding: 14px 0 12px; justify-content: center; }
:root[data-rail-mode="mini"] .rail__brand > div:not(.rail__mark) { display: none; }
:root[data-rail-mode="mini"] .rail__label { font-size: 0; padding: 0 0 6px; margin: 0 14px; border-bottom: 1px solid var(--line); }
:root[data-rail-mode="mini"] .rail__group { padding-top: 10px; }
:root[data-rail-mode="mini"] .rail a.nav { justify-content: center; padding: 9px 0; position: relative; }
:root[data-rail-mode="mini"] .nav__icon { width: 18px; height: 18px; }
:root[data-rail-mode="mini"] .nav__text, :root[data-rail-mode="mini"] .rail__signed, :root[data-rail-mode="mini"] .rail__user { display: none; }
:root[data-rail-mode="mini"] .nav__count { position: absolute; top: 3px; right: 10px; margin: 0; font-size: 9px; padding: 0 4px; }
:root[data-rail-mode="mini"] .rail__foot { padding: 12px 0; }
:root[data-rail-mode="mini"] .rail__who { justify-content: center; }
:root[data-rail-mode="mini"] .rail__out { padding: 6px; }
:root[data-rail-mode="mini"] .rail__out svg { display: block; }

.rail {
  background: var(--ink-850);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.rail__brand {
  padding: 16px 18px 14px;
  border-bottom: 1px solid var(--line);
  display: flex;
  gap: 11px;
  align-items: center;
}

.rail__mark {
  width: 30px; height: 30px;
  border-radius: 3px;
  background: linear-gradient(150deg, var(--petrol), var(--diesel));
  display: grid; place-items: center;
  font-family: var(--display);
  font-variation-settings: 'wdth' 120;
  font-weight: 800;
  font-size: 15px;
  color: var(--ink-900);
  flex: none;
}
/* An uploaded logo replaces the initials; white tile so a dark-on-transparent logo still reads. */
.rail__mark--logo { background: #fff; padding: 2px; overflow: hidden; }
.rail__mark--logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
.logo-preview {
  width: 160px; height: 110px; flex: none;
  display: grid; place-items: center;
  border: 1px dashed var(--line-2); border-radius: var(--r); background: #fff; padding: 8px;
}
.logo-preview .dim { color: #667; }
.logo-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* Settings ▸ Invoice page setup: the form, and a to-scale sketch of the chosen paper. */
.pagesetup { display: flex; flex-wrap: wrap; gap: 22px; align-items: flex-start; }
.pagesetup__form { display: flex; flex-direction: column; gap: 12px; flex: 1; min-width: 260px; max-width: 560px; }
.pagesetup__custom { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.pagesetup__custom[hidden] { display: none; }
.field.pagesetup__check { flex-direction: row; align-items: center; gap: 8px; align-self: end; padding-bottom: 8px; }
.pagesetup__check input { width: 16px; height: 16px; accent-color: var(--brand, currentColor); }
.pagesetup__preview { width: 170px; min-height: 170px; flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; }
.pagesetup__sheet { background: #fff; border: 1px solid var(--line-2); border-radius: 2px; box-shadow: 0 2px 10px rgba(0,0,0,.25); transition: width .2s, height .2s, padding .2s; }
.pagesetup__sheet.is-roll { border-bottom: 2px dashed var(--line-2); border-radius: 2px 2px 0 0; }
.pagesetup__ink { width: 100%; height: 100%; background: repeating-linear-gradient(#d5dbde 0 2px, transparent 2px 7px); opacity: .8; }

.rail__name { font-family: var(--display); font-weight: 700; font-size: 13.5px; letter-spacing: -0.01em; }
.rail__place { font-size: 10.5px; color: var(--haze); }

.rail__group { padding: 14px 0 4px; }
.rail__label { padding: 0 18px 7px; }

.rail a.nav {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 18px;
  font-size: 13px;
  color: var(--haze-2);
  border-left: 2px solid transparent;
  transition: background .14s, color .14s, border-color .14s;
}
.rail a.nav:hover { background: var(--ink-750); color: var(--paper); }
.rail a.nav.is-active {
  background: var(--ink-700);
  color: var(--paper);
  border-left-color: var(--petrol);
  font-weight: 600;
}
.nav__icon { width: 15px; height: 15px; flex: none; opacity: .75; }
.nav.is-active .nav__icon { opacity: 1; }
.nav__count {
  margin-left: auto;
  font-family: var(--data);
  font-size: 10px;
  padding: 1px 5px;
  border-radius: 20px;
  background: var(--alarm);
  color: #fff;
  font-weight: 600;
}

.rail__foot { margin-top: auto; padding: 14px 18px; border-top: 1px solid var(--line); font-size: 11.5px; }

/* ---------------------------------------------------------------- top bar */

.main { display: flex; flex-direction: column; min-width: 0; }

.bar {
  height: var(--bar-h);
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--ink-850) 88%, transparent);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 0 22px;
  position: sticky;
  top: 0;
  z-index: 30;
}

.bar__title { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.bar__spacer { flex: 1; }
.bar__cell { display: flex; flex-direction: column; gap: 1px; align-items: flex-end; }
.bar__cell .v { font-family: var(--data); font-size: 13px; font-weight: 600; letter-spacing: -0.02em; }

.pulse {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--data); font-size: 10.5px; letter-spacing: .04em;
  padding: 4px 9px 4px 8px;
  border: 1px solid var(--line-2);
  border-radius: 20px;
  color: var(--haze-2);
}
.pulse__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); flex: none; }
.pulse.is-online .pulse__dot { animation: breathe 2.4s var(--ease) infinite; }
.pulse.is-offline { border-color: color-mix(in srgb, var(--alarm) 50%, transparent); color: var(--alarm); }
.pulse.is-offline .pulse__dot { background: var(--alarm); }

@keyframes breathe {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 60%, transparent); }
  60% { box-shadow: 0 0 0 6px transparent; }
}

/* ---------------------------------------------------------------- page */

.page { padding: var(--gap) 22px 44px; display: flex; flex-direction: column; gap: var(--gap); }

.page__head { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.page__head p { color: var(--haze); font-size: 13px; max-width: 62ch; margin-top: 4px; }

/* Panels size to their content: a half-empty panel padded out to match its
   neighbour reads as missing data. */
.grid { display: grid; gap: var(--gap); align-items: start; }
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid--forecourt { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }
.grid--split { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
/* Rows whose panels should end on one line: every panel takes the row's height. */
.grid--fill { align-items: stretch; }
/* A panel that follows its neighbour's height instead of setting it: size containment keeps
   its own content out of the row's height, and its body scrolls within what it is given. */
.panel--follow { contain: size; }
.panel--follow > .panel__body { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
.panel--follow .ticket-list { flex: 1; max-height: none; min-height: 0; }
@media (max-width: 1180px) {
  .panel--follow { contain: none; }
  .panel--follow .ticket-list { max-height: 430px; }
}

/* ---------------------------------------------------------------- panel */

.panel {
  background: var(--ink-800);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
}

.panel__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
}
.panel__head h2 { flex: 1; min-width: 0; }
.panel__head .eyebrow { flex: 1; }
.panel__body { padding: 16px; flex: 1; min-width: 0; }
.panel__body--flush { padding: 0; }
.panel__foot {
  padding: 10px 16px;
  border-top: 1px solid var(--line);
  font-size: 11.5px;
  color: var(--haze);
  display: flex;
  gap: 16px;
  align-items: center;
}

/* ---------------------------------------------------------------- shift card foot
   One cluster per product: litres and taka at the same weight so the money reads as
   easily as the volume (owner, 10-13), and a cluster never breaks across lines. The
   cash hand-in is one slim row at the foot's own height, not a stacked form field. */
.panel__foot--sum { flex-wrap: wrap; gap: 6px 16px; min-height: 42px; }
.gsum { display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.gsum .dot { align-self: center; }
.gsum__p { margin-right: 1px; }
.gsum__v { font-size: 12.5px; font-weight: 700; color: var(--paper); }
.gsum__tk { padding-left: 8px; border-left: 1px solid var(--line-2); }
.gsum__end { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.handin { display: inline-flex; align-items: center; gap: 8px; }
.handin__l { color: var(--haze); }
.handin__in.data {
  width: 12ch; padding: 3px 8px; font-size: 12.5px; line-height: 1.4; text-align: right;
  -moz-appearance: textfield;
}
.handin__in::-webkit-outer-spin-button, .handin__in::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
@media (max-width: 720px) { .gsum__end { margin-left: 0; flex-basis: 100%; } }

/* ---------------------------------------------------------------- price totem
   The roadside sign is the first thing anyone sees at a filling station, and it
   is the one number the owner checks before anything else. It opens the panel. */

.totem {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.totem__cell {
  background: var(--ink-800);
  padding: 15px 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  position: relative;
  overflow: hidden;
  container-type: inline-size;
}
.totem__cell::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--c);
}
.totem__cell::after {
  content: '';
  position: absolute;
  inset: -60% -40% auto auto;
  width: 180px; height: 180px;
  background: radial-gradient(circle, color-mix(in srgb, var(--c) 16%, transparent), transparent 70%);
  pointer-events: none;
}

/* ---------------------------------------------------------------- stock column
   The fourth cell of the price row: litres in the ground per product. Rows, not tiles, so the
   figures line up down one edge and read as a ledger; each opens with a dipstick — the one
   object on a forecourt that says "how much is left" — filled to how full the product is. */
.totem--stock { grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)) minmax(310px, 1fr); }
/* Two by two, and the day's figure up in the title line, so the column is no taller than a
   price cell: the prices keep their own natural rhythm instead of being stretched to match. */
.totem__stock { gap: 10px; }
.totem__stock::before, .totem__stock::after { display: none; }
.stock__head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.stock__title { font-family: var(--display); font-size: 13px; font-weight: 700; }
.stock__day { font-size: 11px; color: var(--haze); white-space: nowrap; }
.stock__day b { font-family: var(--data); font-size: 12px; color: var(--paper); margin-left: 4px; font-variant-numeric: tabular-nums; }
.stock {
  list-style: none; padding: 0; margin: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 18px;
}
.stock li {
  display: grid; grid-template-columns: 7px minmax(0, 1fr); grid-template-rows: auto auto;
  column-gap: 9px; align-items: center;
}
.dipstick {
  grid-row: 1 / 3; align-self: stretch;
  position: relative; width: 7px; min-height: 30px; border-radius: 2px; overflow: hidden;
  background: color-mix(in srgb, var(--c) 16%, var(--ink-700));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c) 35%, transparent);
}
.dipstick > i {
  position: absolute; inset: auto 0 0 0; height: var(--p, 0%);
  background: var(--c); transition: height .6s var(--ease);
}
.stock__n { font-size: 11.5px; line-height: 1.2; color: var(--haze-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stock__v { display: flex; align-items: baseline; gap: 7px; min-width: 0; white-space: nowrap; }
.stock__l {
  font-family: var(--display); font-variation-settings: 'wdth' 108; font-weight: 700; font-size: 16px; line-height: 1.2;
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}
.stock__p { font-family: var(--data); font-size: 10.5px; color: var(--haze); font-variant-numeric: tabular-nums; }
@media (max-width: 1180px) {
  .totem--stock { grid-template-columns: repeat(var(--n, 3), minmax(0, 1fr)); }
  .totem__stock { grid-column: 1 / -1; }
  .stock { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .totem--stock { grid-template-columns: minmax(0, 1fr); }
  .stock { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (prefers-reduced-motion: reduce) { .dipstick > i { transition: none; } }

.totem__grade { display: flex; align-items: center; gap: 8px; }
.totem__grade b { font-family: var(--display); font-size: 13px; font-weight: 700; letter-spacing: .01em; }
.totem__code {
  font-family: var(--data); font-size: 9.5px; font-weight: 600;
  padding: 1px 5px; border-radius: 2px;
  background: color-mix(in srgb, var(--c) 18%, transparent);
  color: var(--c);
}

.totem__price {
  font-family: var(--display);
  font-variation-settings: 'wdth' 118;
  font-weight: 800;
  font-size: clamp(30px, 3.4vw, 44px);
  font-size: clamp(26px, 14cqi, 44px);   /* sized to its own cell, so four prices still fit */
  line-height: .95;
  letter-spacing: -0.035em;
  color: var(--c);
  display: flex;
  align-items: baseline;
  gap: 4px;
}
.totem__price .cur { font-size: .48em; font-weight: 600; opacity: .72; font-family: 'Taka', var(--display); }
.totem__price .unit { white-space: nowrap; font-family: var(--data); font-size: 10px; font-weight: 500; color: var(--haze); letter-spacing: 0; margin-left: 3px; }

.totem__note { font-size: 11px; color: var(--haze); display: flex; align-items: center; gap: 6px; }
.totem__delta { font-family: var(--data); font-size: 10.5px; font-weight: 600; }
/* LPG only: the rate is fixed on the panel, so its cell carries the one button that sets it. */
.totem__set {
  margin-left: auto; position: relative; z-index: 1;
  font: 600 10.5px var(--data); padding: 2px 8px; border-radius: 3px; cursor: pointer;
  color: var(--c); background: color-mix(in srgb, var(--c) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--c) 40%, transparent);
}
.totem__set:hover { background: color-mix(in srgb, var(--c) 24%, transparent); }
.totem__delta.up { color: var(--alarm); }
.totem__delta.down { color: var(--ok); }

/* ---------------------------------------------------------------- shift tape
   Styled after the till roll the attendant tears off at handover. */

.tape {
  background: var(--ink-850);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  overflow: hidden;
}
.tape__cell {
  padding: 12px 16px;
  border-right: 1px dashed var(--line);
  display: flex; flex-direction: column; gap: 5px;
}
.tape__cell:last-child { border-right: none; }
.tape__v {
  font-family: var(--display);
  font-variation-settings: 'wdth' 100;
  font-weight: 700;
  font-size: 21px;
  letter-spacing: -0.03em;
  line-height: 1;
  display: flex; align-items: baseline; gap: 5px;
}
.tape__v .taka { font-size: .72em; opacity: .7; }
.tape__d { font-family: var(--data); font-size: 10.5px; font-weight: 600; display: flex; align-items: center; gap: 4px; }
.tape__d.up { color: var(--ok); }
.tape__d.down { color: var(--alarm); }
.tape__d.flat { color: var(--haze); }

/* ------------------------------------------------------- shift band
   Three trading shifts and the day they add up to. The running shift is the one the owner
   is actually asking about, so it carries the colour and the clock; the rest are quiet. */

.shiftband {
  display: grid;
  gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.shiftcard {
  background: var(--ink-800);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 12px 14px 11px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  position: relative;
  overflow: hidden;
}

.shiftcard__top { display: flex; align-items: center; gap: 7px; min-height: 20px; flex-wrap: wrap; }
.shiftcard__top b { font-family: var(--display); font-size: 13px; font-weight: 700; }
.shiftcard__win { margin-left: auto; }

/* The attendant who signed on. It reads as part of the shift's name, so it sits against it
   rather than in the figures below. */
.shiftcard__who {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--haze-2);
  max-width: 12ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.shiftcard__who::before { content: '· '; color: var(--haze); }

/* Litres and takings per product. Three fixed lines whatever sold, so the eye can run down
   the row of cards and compare the same grade in the same place. */
.shiftcard__grades { display: flex; flex-direction: column; gap: 3px; }
.gline {
  display: grid;
  grid-template-columns: 7px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 4px 7px;
  column-gap: 5px;
  font-family: var(--data);
  font-size: 11px;
  font-weight: 600;
}
.gline__n { color: var(--haze-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gline__l { color: var(--haze); }
.gline__m { min-width: 10ch; text-align: right; }
/* Two decimals on litres and takings make the figures long enough to squeeze the name on a
   laptop-width card; below 1500px the figures drop a size so "Diesel" still reads in full. */
@media (max-width: 1500px) { .gline { font-size: 10.5px; letter-spacing: -0.02em; } }
.gline__m .taka { font-size: .85em; opacity: .6; margin-right: 1px; }
.gline.is-nil { opacity: .38; }

.shiftcard__v {
  font-family: var(--display);
  font-variation-settings: 'wdth' 108;
  font-weight: 800;
  font-size: clamp(24px, 2.4vw, 32px);
  line-height: 1;
  letter-spacing: -0.035em;
  display: flex; align-items: baseline; gap: 4px;
}
.shiftcard__v .taka { font-size: .5em; font-weight: 600; opacity: .6; }

.shiftcard__sub {
  font-family: var(--data);
  font-size: 11px;
  font-weight: 600;
  color: var(--haze);
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
}
.shiftcard__sub .sep { opacity: .45; }

/* How far through the window the shift has run. It is a clock, not a target: the bar filling
   up says the handover is near, never that the shift is doing well. */
.shiftcard__bar {
  height: 3px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--octane) 16%, transparent);
  overflow: hidden;
  margin-top: 1px;
}
.shiftcard__bar i { display: block; height: 100%; width: var(--p); background: var(--octane); }

.shiftcard.is-live {
  border-color: color-mix(in srgb, var(--octane) 45%, transparent);
  background: color-mix(in srgb, var(--octane) 5%, var(--ink-800));
}
.shiftcard.is-live .shiftcard__v { color: var(--octane); }

.shiftcard--total {
  background: var(--ink-850);
  border-style: dashed;
}
.shiftcard--total .shiftcard__sub a { color: var(--haze); }
.shiftcard--total .shiftcard__sub a:hover { color: var(--paper); }

.livedot {
  width: 5px; height: 5px; border-radius: 50%;
  background: currentColor; flex: none;
  animation: livedot 2.4s var(--ease) infinite;
}

@keyframes livedot {
  0%, 100% { opacity: 1; }
  55% { opacity: .25; }
}

/* ---------------------------------------------------------------- tanks */

.tanks { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

.tank {
  background: var(--ink-850);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 13px 14px 11px;
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}

.tank__top { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 9px; }
.tank__no {
  font-family: var(--data); font-size: 10px; font-weight: 700;
  width: 22px; height: 22px; border-radius: 3px;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--c) 20%, transparent);
  color: var(--c);
  flex: none;
}
.tank__grade { font-family: var(--display); font-weight: 700; font-size: 13px; white-space: nowrap; }
/* What is in the ground, on a line of its own under the name. It used to share the header with
   the name and the status chips and wrapped differently on every card (and clipped on some); a
   single unbroken baseline reads the same on all of them. The figure is the card's whole job,
   so it is the one large thing; capacity is quiet beside it, and how full the tank is sits on
   the right in the product's colour, the only colour on the line. */
.tank__read {
  display: flex; align-items: baseline; gap: 8px;
  margin: 10px 0 0; white-space: nowrap; min-width: 0;
}
.tank__litres {
  font-family: var(--display); font-variation-settings: 'wdth' 112;
  font-weight: 800; font-size: 26px; line-height: 1; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums; color: var(--paper);
}
.tank__litres small { font-size: 13px; font-weight: 600; letter-spacing: 0; margin-left: 2px; color: var(--haze-2); }
.tank__cap { font-size: 12px; color: var(--haze); overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.tank__pct {
  margin-left: auto; flex: none;
  font-family: var(--data); font-size: 13px; font-weight: 700; color: var(--c);
  font-variant-numeric: tabular-nums;
}

.tank__gauge { position: relative; }
.tank__meta {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  font-size: 11px;
}
.tank__meta div { display: flex; flex-direction: column; gap: 2px; }
.tank__meta b { font-family: var(--data); font-size: 11.5px; font-weight: 500; }

/* the liquid surface: a slow swell, not a cartoon wave.

   Two waves travel against each other at different speeds. One wave on its own reads as a
   rigid sheet sliding about; two out of step read as a surface. Each slides by exactly one
   wavelength — 120 user units, a 60-unit crest plus a 60-unit trough — which is what makes
   the loop seamless. Any other distance visibly snaps back at the end of each cycle, and
   the timing has to stay linear for the same reason: an ease would show the turn.

   --phase is set per tank so the farm does not swell in unison; it is a negative delay,
   which starts each tank part way through its cycle rather than making it wait. */
.wave { will-change: transform; }
.wave--front,
.wave--crest { animation: drift-left 9s linear infinite; animation-delay: var(--phase, 0s); }
.wave--back { animation: drift-right 14s linear infinite; animation-delay: var(--phase, 0s); }

@keyframes drift-left {
  from { transform: translateX(0); }
  to { transform: translateX(-120px); }
}
@keyframes drift-right {
  from { transform: translateX(-120px); }
  to { transform: translateX(0); }
}

/* A gentle rise and fall over the travel, kept on its own group so it does not fight the
   level transition below — that transform belongs to the reading, not to the animation. */
.wave-bob { will-change: transform; }
.wave-bob--a { animation: bob 6.5s ease-in-out infinite; animation-delay: var(--phase, 0s); }
.wave-bob--b { animation: bob 9.5s ease-in-out infinite reverse; animation-delay: var(--phase, 0s); }

@keyframes bob {
  0%, 100% { transform: translateY(.5px); }
  50% { transform: translateY(-1.1px); }
}

/* An empty tank holds still. */
.tank-svg.is-still .wave,
.tank-svg.is-still .wave-bob { animation: none; }

.tank-level { transition: transform 1.1s var(--ease); }

/* Booking a purchase from the tank card. The card holds only the button — the form itself is
   one dialog shared by every card on the page, so the gauges are never buried by it. */
.tank__add { border-top: 1px solid var(--line); padding-top: 9px; display: flex; gap: 7px; flex-wrap: wrap; }

/* Two ways to say the same thing, shown as one control so it reads as a choice between them
   rather than as two unrelated fields. */
.segmented { display: flex; gap: 0; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.segmented label { flex: 1; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }
.segmented span {
  display: block; text-align: center; cursor: pointer;
  padding: 7px 10px; font-size: 12px; color: var(--haze);
  background: var(--ink-800);
  transition: background .14s, color .14s;
}
.segmented label + label span { border-left: 1px solid var(--line); }
.segmented span:hover { color: var(--paper); }
.segmented input:checked + span { background: var(--ink-600); color: var(--paper); font-weight: 600; }
.segmented input:focus-visible + span { outline: 2px solid var(--octane); outline-offset: -2px; }

/* ---------------------------------------------------------------- modal */

.modal {
  border: none;
  padding: 0;
  background: transparent;
  color: var(--paper);
  max-width: 100vw;
  max-height: 100vh;
  /* The reset at the top of this file zeroes every margin, which also wipes the margin:auto
     the UA stylesheet uses to centre an open dialog — without this it pins to the top left. */
  margin: auto;
}
.modal::backdrop { background: rgba(4, 12, 16, .74); }

.modal__card {
  width: min(600px, calc(100vw - 28px));
  max-height: calc(100vh - 48px);
  display: flex;
  flex-direction: column;
  background: var(--ink-850);
  border: 1px solid var(--line-2);
  border-radius: var(--r-lg);
  box-shadow: 0 24px 64px rgba(0, 0, 0, .55);
  overflow: hidden;
}

.modal__head {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 15px 16px 13px;
  border-bottom: 1px solid var(--line);
}
.modal__head h2 { font-size: 16px; }
.modal__head p { margin: 3px 0 0; }
.modal__x {
  margin-left: auto; font-size: 22px; line-height: 1;
  color: var(--haze); padding: 0 4px;
}
.modal__x:hover { color: var(--paper); }

.modal__body { padding: 15px 16px; overflow-y: auto; }
.modal__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  align-items: end;
}
.modal--wide { grid-column: 1 / -1; }

/* The figure the owner signs off on. Set apart from the inputs because it is the one number
   on this form nobody types — it is what the form has worked out. */
.modal__total {
  display: flex; align-items: baseline; gap: 10px;
  margin-top: 14px; padding: 11px 13px;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  background: var(--ink-800);
}
.modal__total b {
  margin-left: auto;
  font-family: var(--data); font-size: 19px; font-weight: 600; letter-spacing: -0.03em;
  color: var(--petrol);
}

.modal__foot {
  display: flex; align-items: center; gap: 9px;
  padding: 12px 16px;
  border-top: 1px solid var(--line);
  background: var(--ink-800);
}
.modal__foot .dim { margin-right: auto; }

@media (max-width: 520px) {
  .modal__grid { grid-template-columns: 1fr; }
  .modal__foot { flex-wrap: wrap; }
  /* On a phone the station's name is already in the drawer; in the bar it wrapped to three
     lines and pushed the page title out underneath. The title alone fits on one line. */
  .bar__title .eyebrow { display: none; }
  .bar__title strong { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* The bridge pill keeps its coloured dot — green online, red silent — and drops the words. */
  .pulse > span:not(.pulse__dot) { display: none; }
  /* Like the theme button: only the language you can switch to. */
  .lang-switch__opt.is-on { display: none; }
  .bar { gap: 8px; }
}

/* The full purchase form on the delivery log. Wider than the tank-card version because this
   is where a load is entered off the paperwork, with every field the note carries. */
.buyform {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  align-items: end;
}
.buyform--wide { grid-column: 1 / -1; }
.buyform button { white-space: nowrap; }

/* ---------------------------------------------------------------- forecourt */

.court { padding: 10px; background:   /* same breath as the gap between the cards: no void under the heading (owner, 10-13) */
  radial-gradient(ellipse 80% 60% at 50% 0%, color-mix(in srgb, var(--paper) 4%, transparent), transparent 70%),
  var(--ink-850); }

.islands { display: grid; grid-template-columns: repeat(auto-fit, minmax(178px, 1fr)); gap: 12px; }

.island {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--ink-800);
  padding: 9px 10px 10px;
  display: flex; flex-direction: column; gap: 8px;
}
.island__label { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.island__id { display: flex; flex-direction: column; gap: 1px; min-width: 0; }

/* The fueling-position names this island covers. Truncated: the grade chip beside it must
   never be pushed out of the card, and the full list is on the title. */
.island__pos {
  font-size: 10px; color: var(--haze);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}

.nozzle {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 9px;
  padding: 7px 8px;
  border-radius: 3px;
  background: var(--ink-750);
  border: 1px solid transparent;
  transition: border-color .2s, background .2s, transform .2s var(--ease);
}
.nozzle:hover { background: var(--ink-700); transform: translateX(1px); }
.nozzle.is-dispensing {
  border-color: color-mix(in srgb, var(--c) 55%, transparent);
  background: color-mix(in srgb, var(--c) 8%, var(--ink-750));
}
.nozzle.is-offline { opacity: .42; }

.nozzle__lamp {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--c);
  flex: none;
  opacity: .35;
}
.nozzle.is-dispensing .nozzle__lamp { opacity: 1; animation: flow 1.15s ease-in-out infinite; }
.nozzle.is-offline .nozzle__lamp { background: var(--haze); opacity: .3; }

@keyframes flow {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--c) 70%, transparent); }
  70% { box-shadow: 0 0 0 7px transparent; }
}

.nozzle__id { font-family: var(--data); font-size: 11px; font-weight: 600; }
.nozzle__sub { font-size: 10px; color: var(--haze); }

/* min-width:0 is what lets the attendant name ellipsis inside the grid column. */
.nozzle__who { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.nozzle__sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.nozzle__val {
  font-family: var(--data); font-size: 11px; text-align: right; letter-spacing: -0.03em;
  display: flex; flex-direction: column; gap: 1px; white-space: nowrap;
}
.nozzle__litres { font-weight: 600; }
.nozzle__money { color: color-mix(in srgb, var(--c) 62%, var(--paper)); }
.nozzle__fills { font-size: 10px; }

/* A number that has just rolled gets a brief lift, so a change is noticed on a wall
   display rather than only by whoever happened to be looking at that row. */
.is-rolling { color: var(--paper); }

/* ---------------------------------------------------------------- live tape */

.ticket-list { display: flex; flex-direction: column; max-height: 430px; overflow-y: auto; }

/* ---------------------------------------------------------------- attendants
   Each person on the day is a block that shares the panel's height with the others; the bar
   under them is their share of the day's takings, in the colour the staff chart gives them. */
.crew { display: flex; flex-direction: column; }
.crew__row {
  flex: 1; display: flex; flex-direction: column; justify-content: center; gap: 6px;
  padding: 12px 16px; border-bottom: 1px solid var(--line); min-height: 72px;
}
.crew__row:last-child { border-bottom: none; }
.crew__top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.crew__name { font-family: var(--display); font-weight: 700; font-size: 15px; }
.crew__amt { font-family: var(--display); font-variation-settings: 'wdth' 108; font-weight: 700; font-size: 16px; font-variant-numeric: tabular-nums; }
.crew__sub { display: flex; justify-content: space-between; gap: 10px; font-family: var(--data); font-size: 10.5px; color: var(--haze); }
.crew__bar { position: relative; height: 18px; border-radius: 3px; background: var(--ink-700); overflow: hidden; }
.crew__bar > i { position: absolute; inset: 0 auto 0 0; background: color-mix(in srgb, var(--c) 70%, transparent); border-radius: 3px; }
.crew__bar > b {
  position: absolute; right: 7px; top: 50%; transform: translateY(-50%);
  font-family: var(--data); font-size: 10px; color: var(--paper);
}
.ticket {
  display: grid;
  grid-template-columns: 46px 1fr auto;
  gap: 11px;
  align-items: center;
  padding: 9px 16px;
  border-bottom: 1px solid var(--line);
  font-size: 12px;
}
.ticket:last-child { border-bottom: none; }
.ticket.is-new { animation: arrive .55s var(--ease); }
@keyframes arrive {
  from { opacity: 0; transform: translateY(-8px); background: color-mix(in srgb, var(--octane) 10%, transparent); }
  to { opacity: 1; transform: none; }
}
.ticket__time { font-family: var(--data); font-size: 10.5px; color: var(--haze); }
.ticket__who { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.ticket__who b { font-size: 12px; font-weight: 600; }
.ticket__amt { text-align: right; }
.ticket__amt b { font-family: var(--data); font-size: 12.5px; font-weight: 600; letter-spacing: -0.03em; }

/* ---------------------------------------------------------------- chips */

.chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--data); font-size: 9.5px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
  padding: 3px 7px; border-radius: 3px;
  border: 1px solid var(--line-2);
  color: var(--haze-2);
  white-space: nowrap;
}
.chip--ok { border-color: color-mix(in srgb, var(--ok) 45%, transparent); color: var(--ok); }
.chip--warn { border-color: color-mix(in srgb, var(--warn) 45%, transparent); color: var(--warn); }
.chip--alarm { border-color: color-mix(in srgb, var(--alarm) 50%, transparent); color: var(--alarm); background: color-mix(in srgb, var(--alarm) 9%, transparent); }
.chip--live { border-color: color-mix(in srgb, var(--octane) 50%, transparent); color: var(--octane); }
.chip--grade { border-color: color-mix(in srgb, var(--c) 45%, transparent); color: var(--c); }

/* A level a purchase put there by hand. Deliberately not --warn: nothing is wrong with the
   tank, the reader is only being told which figure they are looking at. */
.chip--keyed {
  border-color: color-mix(in srgb, var(--petrol) 45%, transparent);
  color: var(--petrol);
  background: color-mix(in srgb, var(--petrol) 9%, transparent);
}

.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--c); flex: none; display: inline-block; }

/* ---------------------------------------------------------------- tables */

.table-wrap { overflow-x: auto; }

table.tbl { font-size: 12.5px; }
table.tbl th {
  font-family: var(--data);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--haze);
  text-align: left;
  padding: 9px 14px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  background: var(--ink-850);
  position: sticky;
  top: 0;
  z-index: 2;
}
table.tbl td {
  padding: 9px 14px;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent);
  white-space: nowrap;
}
table.tbl tbody tr:last-child td { border-bottom: none; }
table.tbl tbody tr:hover td { background: var(--ink-750); }
table.tbl .r { text-align: right; }
table.tbl .n { font-family: var(--data); font-variant-numeric: tabular-nums; letter-spacing: -0.03em; text-align: right; }
table.tbl .wide { white-space: normal; min-width: 180px; }

.rank {
  font-family: var(--display);
  font-variation-settings: 'wdth' 118;
  font-weight: 800;
  font-size: 12px;
  color: var(--haze);
  width: 18px;
  display: inline-block;
}
.rank--1 { color: var(--petrol); }

/* meter bar inside a table cell */
.meter { height: 4px; border-radius: 2px; background: var(--ink-600); overflow: hidden; min-width: 60px; }
.meter i { display: block; height: 100%; background: var(--c); border-radius: 2px; transition: width .8s var(--ease); }
.share-cell .meter { min-width: 0; width: 100%; margin-top: 5px; }
/* A short table in a stretched panel: its rows share the height instead of leaving a band. */
table.tbl--fill { height: 100%; }
table.tbl--fill thead tr { height: 1px; }

/* ---------------------------------------------------------------- forms */

.field { display: flex; flex-direction: column; gap: 5px; }
.field > span { font-family: var(--data); font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--haze); }

input[type=text], input[type=password], input[type=date], input[type=datetime-local], input[type=tel], input[type=search], input[type=email],
input[type=number], select, textarea {
  background: var(--ink-750);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 8px 10px;
  font-size: 13px;
  width: 100%;
  transition: border-color .15s, background .15s;
}
input:focus, select:focus, textarea:focus { border-color: var(--line-2); background: var(--ink-700); outline: none; }
input::placeholder { color: color-mix(in srgb, var(--haze) 70%, transparent); }

.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px;
  border-radius: var(--r);
  border: 1px solid var(--line-2);
  background: var(--ink-750);
  font-size: 12.5px;
  font-weight: 600;
  transition: background .15s, border-color .15s, transform .12s var(--ease);
}
.btn:hover { background: var(--ink-600); border-color: var(--haze); }
.btn:active { transform: translateY(1px); }
.btn--primary { background: var(--petrol); border-color: var(--petrol); color: var(--ink-900); }
.btn--primary:hover { background: color-mix(in srgb, var(--petrol) 85%, #fff); border-color: transparent; }
.btn--ghost { background: none; }
.btn--sm { padding: 5px 10px; font-size: 11.5px; }
.btn:disabled { opacity: .4; cursor: not-allowed; pointer-events: none; }

.filters { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }
.filters .field { min-width: 130px; }
.page__tools { display: flex; gap: 8px; flex-wrap: wrap; }
[data-live="rows"] { transition: opacity .15s; }
[data-live="rows"].is-loading { opacity: .45; }
.filters__clear:not(:has(a)) { display: none; }
.sales__act { width: 1%; white-space: nowrap; text-align: right; }
.sales__act form { display: inline; margin-left: 6px; }
.filters__search { flex: 1 1 320px; }
.filters__searchbox { display: flex; gap: 6px; }
.filters__searchbox input { flex: 1; min-width: 0; }

/* ---------------------------------------------------------------- charts */

.chart { width: 100%; }
.chart text { font-family: var(--data); font-size: 9px; fill: var(--haze); }
.chart .grid-line { stroke: var(--line); stroke-width: 1; }
.chart .axis-line { stroke: var(--line-2); stroke-width: 1; }

.legend { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.legend span { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--haze-2); }

/* hourly heat strip */
.heat { display: grid; grid-template-columns: repeat(24, 1fr); gap: 2px; }
.heat i {
  display: block;
  height: 34px;
  border-radius: 2px;
  background: color-mix(in srgb, var(--petrol) calc(var(--v) * 1%), var(--ink-700));
  position: relative;
  transition: transform .18s var(--ease);
}
.heat i:hover { transform: scaleY(1.12); }
.heat-axis { display: grid; grid-template-columns: repeat(24, 1fr); gap: 2px; margin-top: 5px; }
.heat-axis span { font-family: var(--data); font-size: 8.5px; color: var(--haze); text-align: center; }

/* ---------------------------------------------------------------- misc */

.empty {
  padding: 44px 20px;
  text-align: center;
  color: var(--haze);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
}
.empty b { font-family: var(--display); font-size: 14px; color: var(--paper); }

.alarm-banner {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 16px;
  border: 1px solid color-mix(in srgb, var(--alarm) 45%, transparent);
  background: color-mix(in srgb, var(--alarm) 10%, var(--ink-800));
  border-radius: var(--r-lg);
}
.alarm-banner .btn { margin-left: auto; }

.kv { display: grid; grid-template-columns: auto 1fr; gap: 7px 18px; font-size: 12.5px; align-items: baseline; }
.kv dt { color: var(--haze); font-family: var(--data); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; }
.kv dd { font-family: var(--data); font-size: 12.5px; word-break: break-all; }

.code {
  font-family: var(--data);
  font-size: 11.5px;
  background: var(--ink-900);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 11px 13px;
  overflow-x: auto;
  white-space: pre;
  color: var(--haze-2);
  line-height: 1.65;
}
.code b { color: var(--octane); font-weight: 500; }
.code i { color: var(--haze); font-style: normal; opacity: .7; }

/* page-load: panels settle in, quickly and once */
.settle { animation: settle .5s var(--ease) both; }
.settle:nth-child(2) { animation-delay: .05s; }
.settle:nth-child(3) { animation-delay: .1s; }
.settle:nth-child(4) { animation-delay: .15s; }
.settle:nth-child(5) { animation-delay: .2s; }
@keyframes settle {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------- sign in */

.signin {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
  background:
    radial-gradient(ellipse 60% 50% at 50% 0%, color-mix(in srgb, var(--petrol) 7%, transparent), transparent 65%),
    var(--ink-900);
}
.signin__card {
  width: min(390px, 100%);
  background: var(--ink-800);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 30px 28px;
  display: flex; flex-direction: column; gap: 16px;
}
.signin__err {
  font-size: 12.5px;
  color: var(--alarm);
  border: 1px solid color-mix(in srgb, var(--alarm) 40%, transparent);
  background: color-mix(in srgb, var(--alarm) 10%, transparent);
  border-radius: var(--r);
  padding: 8px 11px;
}

/* ---------------------------------------------------------------- responsive */

@media (max-width: 1180px) {
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--forecourt, .grid--split, .grid--3 { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 860px) {
  :root, :root[data-rail-mode="mini"] { --rail-w: 0px; }
  .shell { grid-template-columns: 1fr; }
  .rail-fold, .rail__resize { display: none; }
  /* The phone drawer always opens full, whatever the desktop menu was folded to. */
  :root[data-rail-mode="mini"] .rail .nav__text, :root[data-rail-mode="mini"] .rail__signed, :root[data-rail-mode="mini"] .rail__user { display: initial; }
  :root[data-rail-mode="mini"] .rail__brand > div:not(.rail__mark) { display: block; }
  :root[data-rail-mode="mini"] .rail a.nav { justify-content: flex-start; padding: 7px 18px; }
  :root[data-rail-mode="mini"] .rail__label { font-size: inherit; border: 0; margin: 0; padding: 0 18px 7px; }
  .rail {
    position: fixed; inset: 0 auto 0 0; width: 224px; z-index: 60;
    transform: translateX(-100%); transition: transform .24s var(--ease);
  }
  .rail.is-open { transform: none; }
  .rail-toggle { display: grid !important; }
  .grid--2 { grid-template-columns: minmax(0, 1fr); }
  .page { padding: 14px 14px 40px; }
  .bar { padding: 0 14px; gap: 12px; }
  .bar__cell--hide { display: none; }
  /* One button on a narrow bar: the mode you are not in. */
  :root:not([data-theme="light"]) .theme-switch__opt[data-theme-set="dark"],
  :root[data-theme="light"] .theme-switch__opt[data-theme-set="light"] { display: none; }
  .theme-switch { padding: 0; }
}

.rail-toggle {
  display: none;
  place-items: center;
  width: 32px; height: 32px;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
}

.rail-scrim {
  display: none;
  position: fixed; inset: 0;
  background: color-mix(in srgb, var(--ink-900) 70%, transparent);
  z-index: 50;
}
.rail-scrim.is-open { display: block; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ---------------------------------------------------------------- nozzle cards
   The forecourt plan as one card per nozzle, laid out to the client's reference:
   name and position in the head, the fill in progress above the lifetime meter
   readings, and a full-width state bar along the foot. Five across on a desk
   monitor, folding down to one on a phone. */

.ncards {
  display: grid;
  /* As many across as have room for the figures plus the scene's 44 px minimum (the totaliser
     is the widest line) — so the count follows the real width, folded menu included. */
  grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));   /* room for the figures + a 104 px photo panel */
  gap: 10px;
  padding: 0;   /* the .court wrapper carries the only inset */
}

.ncard {
  display: flex;
  flex-direction: column;
  background: var(--ink-800);
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
  transition: border-color .2s, background .2s;
}
.ncard.is-dispensing { border-color: color-mix(in srgb, var(--c) 55%, transparent); }
/* An offline nozzle keeps its figures at full strength — the last fill it took is exactly
   what someone is on the card to read. The state bar carries the fault, not the whole card. */
.ncard.is-offline { border-color: color-mix(in srgb, var(--alarm) 40%, transparent); }

.ncard__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 6px;
  padding: 8px 10px 0;
}
.ncard__name { font-size: 13px; letter-spacing: -0.01em; }
.ncard__no { font-family: var(--data); font-size: 10px; color: var(--haze); white-space: nowrap; }

.ncard__meta {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  padding: 6px 10px 8px;
  border-bottom: 1px solid var(--line);
}
.ncard__meta .dim { font-size: 10.5px; }

.ncard__body { position: relative; padding: 8px 10px; display: grid; grid-template-columns: minmax(0, max-content) minmax(104px, 1fr); gap: 0 10px; align-items: stretch; }
/* The figures keep their natural width and the scene takes what is left; when the card is too
   narrow for both, the figures give way first (ellipsis) down to the panel's 104 px minimum. */
.ncard__figures { min-width: 0; }


.ncard__section {
  display: block;
  font-size: 9.5px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--haze); margin: 0 0 4px;
}
.ncard__section + .ncard__section, .ncard__row + .ncard__section { margin-top: 9px; }

/* dt/dd on one line: the label shrinks, the figure keeps its digits. */
.ncard__row { display: flex; align-items: baseline; gap: 5px; margin: 0 0 3px; }
.ncard__row dt { font-size: 10.5px; color: var(--haze); flex: none; }
.ncard__row dd {
  margin: 0; font-family: var(--data); font-size: 11px; color: var(--paper);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ncard__row dd.strong { font-size: 13px; font-weight: 600; }
.ncard__row dd .taka { font-size: .85em; opacity: .75; }
.ncard__row--quiet dd { color: var(--haze-2); font-size: 10.5px; }

/* The scene is a column of its own beside the figures (at least 104 px, at most 200 px) and
   never sits over a figure. A rounded photo panel the height of the figures. */
.ncard__scene { position: relative; width: 100%; max-width: 200px; justify-self: end; align-self: stretch; pointer-events: none; }
/* The panel is exactly as tall as the figures beside it and 4:5 wide from that (narrower only
   when the card has no room), pinned to the right: a photo panel, not a skinny strip, and it
   never makes the card taller (client 10-13). The photo is cropped around the nozzle. */
.ncard__cam-box {
  position: absolute; top: 0; right: 0; height: 100%; aspect-ratio: 4 / 5; max-width: 100%;
  border-radius: 8px; overflow: hidden;
  border: 1px solid var(--line-2); background: var(--ink-700);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #fff 6%, transparent), 0 4px 14px color-mix(in srgb, var(--ink-900) 55%, transparent);
  transition: border-color .3s, box-shadow .3s;
}
/* The photo melts into the card along its lower edge and corners, so it reads as part of the
   card rather than a sticker on it. */
.ncard__cam-box::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background:
    linear-gradient(to top, color-mix(in srgb, var(--ink-800) 85%, transparent), transparent 42%),
    radial-gradient(120% 90% at 50% 40%, transparent 55%, color-mix(in srgb, var(--ink-800) 70%, transparent));
}
.ncard__still, .ncard__cam { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; object-position: 56% 50%; }
.ncard__still[hidden], .ncard__cam[hidden] { display: none; }
:root:not([data-theme="light"]) :is(.ncard__still, .ncard__cam) { filter: brightness(.9) saturate(.95); }
:root[data-theme="light"] .ncard__cam-box::after { background: linear-gradient(to top, color-mix(in srgb, var(--ink-800) 55%, transparent), transparent 40%); }
/* While the pump runs the tile is ringed and lit in the product's colour, so a fuelling nozzle
   is found from across the office before any figure is read. */
.ncard.is-dispensing .ncard__cam-box {
  border-color: var(--c);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--c) 24%, transparent), 0 6px 18px color-mix(in srgb, var(--c) 30%, transparent);
  animation: nz-glow 2s ease-in-out infinite;
}
@keyframes nz-glow { 50% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--c) 12%, transparent), 0 6px 22px color-mix(in srgb, var(--c) 45%, transparent); } }

/* One glow as a sale arrives, so the eye finds which nozzle just sold before reading any
   figure. Separate from is-dispensing: that stays on for ninety seconds, this fires once. */
.ncard.is-sold { animation: nz-sold 1.4s ease-out; }
@keyframes nz-sold {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--c) 75%, transparent); background: color-mix(in srgb, var(--c) 16%, var(--ink-800)); }
  100% { box-shadow: 0 0 0 14px transparent; background: var(--ink-800); }
}
@media (prefers-reduced-motion: reduce) { .ncard .ncard__cam-box, .ncard.is-sold { animation: none; } }

/* Solid bars, as on the client's reference: the state is read from across the room, and a
   tint on a dark ground was not carrying that far. Idle gets a steel blue of its own —
   the palette has no blue, and reusing --ok or --warn would have said something untrue. */
.ncard__state {
  --nz-idle: #3F638F;
  margin-top: auto;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 10px;
  font-size: 11px; font-weight: 600; letter-spacing: .01em;
  border-top: 1px solid var(--line);
  background: var(--nz-idle); color: var(--paper);
}
/* Shifts page: the day's shifts added up, set apart from the per-shift cards below it. */
.shift-total { border-color: var(--line-2); box-shadow: inset 3px 0 0 var(--amber, #F2A93B); }
.shift-total tfoot th { font-size: 13px; }

/* A manual (LPG) nozzle's Sell button, just above its state bar. */
.ncard__sell {
  margin: 0 12px 10px; padding: 8px 10px;
  font: 700 12.5px var(--body, inherit); letter-spacing: .02em;
  color: var(--ink-900); background: var(--c); border: 0; border-radius: var(--r, 6px); cursor: pointer;
}
.ncard__sell:hover { filter: brightness(1.08); }
.ncard__sell:focus-visible { outline: 2px solid var(--paper); outline-offset: 2px; }
.field.sale__check { flex-direction: row; align-items: center; gap: 8px; }
.sale__check input { width: 16px; height: 16px; }
.ncard__lamp { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
/* --ok and --alarm are both light enough that the label reads better knocked out in ink. */
.ncard.is-dispensing .ncard__state { background: var(--ok); color: var(--ink-900); }
.ncard.is-dispensing .ncard__lamp { animation: flow 1.15s ease-in-out infinite; }
.ncard.is-offline .ncard__state { background: var(--alarm); color: var(--ink-900); }

/* ================================================================ settings page
   Four sections behind a sticky index: what the station is called (with a paper proof of
   its letterhead), the piping board, the invoice paper, and what the controller owns. */
.set-layout { display: grid; grid-template-columns: 188px minmax(0, 1fr); gap: 28px; align-items: start; }
.set-nav {
  position: sticky; top: calc(var(--bar-h) + var(--gap));
  display: flex; flex-direction: column; gap: 2px;
}
.set-nav a {
  padding: 7px 12px; font-size: 13px; color: var(--haze);
  border-left: 2px solid var(--line); text-decoration: none;
}
.set-nav a:hover { color: var(--paper); }
.set-nav a[aria-current] { color: var(--paper); border-left-color: var(--petrol); }
.set-main { display: flex; flex-direction: column; gap: 40px; min-width: 0; }
.set-sec { scroll-margin-top: calc(var(--bar-h) + var(--gap)); }
.set-sec__head { margin-bottom: 14px; }
.set-sec__head h2 { font-size: 20px; }
.set-sec__head p { color: var(--haze); font-size: 13px; max-width: 68ch; margin-top: 4px; }

/* Station + letterhead proof */
.set-station { display: grid; grid-template-columns: minmax(0, 1fr) 330px; }
.set-station__form { display: flex; flex-direction: column; gap: 14px; padding: 20px; }
.set-station__form small { font-size: 11.5px; }
.set-station__form p.dim { max-width: 62ch; line-height: 1.5; }
.set-station__pair { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.set-station__print {
  display: flex; flex-direction: column; gap: 12px; padding: 20px;
  background: var(--ink-850); border-left: 1px solid var(--line);
}
.letterhead {
  background: #fff; color: #1d2629; border-radius: 2px; padding: 18px 18px 22px;
  box-shadow: 0 1px 0 rgba(0,0,0,.08), 0 10px 26px -12px rgba(0,0,0,.45);
  display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 4px 12px; align-items: center;
}
.letterhead__logo {
  width: 52px; height: 52px; display: grid; place-items: center;
  border: 1px dashed #c9d1d4; border-radius: 3px; overflow: hidden;
}
.letterhead__logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
.letterhead__logo:has(img) { border: 0; }
.letterhead__logo span { font-size: 9px; color: #8a979c; text-align: center; line-height: 1.2; }
.letterhead__text { display: flex; flex-direction: column; min-width: 0; }
.letterhead__text b { font-family: var(--display); font-size: 16px; line-height: 1.15; overflow-wrap: anywhere; }
.letterhead__text span { font-size: 11px; color: #56656b; }
.letterhead__text span:empty { display: none; }
.letterhead__rule { grid-column: 1 / -1; height: 2px; background: #1d2629; margin: 10px 0 8px; }
.letterhead__line { grid-column: 1 / -1; height: 5px; border-radius: 2px; background: #e3e8ea; margin-top: 5px; }
.letterhead__line--short { width: 60%; }
.set-station__logo { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.set-upload { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.set-upload__pick { position: relative; overflow: hidden; max-width: 220px; }
.set-upload__pick span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.set-upload__pick input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.set-upload__pick:focus-within { outline: 2px solid var(--paper); outline-offset: 2px; }
.set-station__print > p.dim { line-height: 1.5; }

/* The piping board: product → tanks → the nozzles each tank feeds */
.board { padding: 6px 20px; }
.board__product {
  display: grid; grid-template-columns: 170px minmax(0, 1fr); gap: 18px;
  padding: 18px 0; border-bottom: 1px solid var(--line);
}
.board__product:last-of-type { border-bottom: 0; }
.board__grade {
  align-self: start; display: grid; grid-template-columns: 14px auto; gap: 2px 10px; align-items: center;
  padding: 8px 10px; margin: 0; text-align: left; color: var(--paper);
  background: none; border: 1px solid transparent; border-radius: var(--r); font: inherit;
}
.board__grade b { font-family: var(--display); font-size: 16px; font-weight: 600; }
.board__swatch { width: 14px; height: 14px; border-radius: 3px; background: var(--c); }
.board__hint { grid-column: 2; font-size: 11.5px; color: var(--haze); }
button.board__grade { cursor: pointer; }
button.board__grade:hover { border-color: var(--line-2); background: var(--ink-750); }
.board__tanks { display: flex; flex-wrap: wrap; gap: 18px 26px; }
.board__tank { width: 230px; }
.board__empty { padding-top: 10px; }

/* A tank drawn as what it is: a horizontal cylinder with the product sitting in it. */
.tankshape {
  position: relative; overflow: hidden; width: 100%; height: 74px; margin: 0;
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-content: start; align-items: baseline; gap: 0 8px;
  padding: 13px 36px 0 24px; text-align: left; font: inherit; color: var(--paper);
  background: var(--ink-700); border: 1px solid color-mix(in srgb, var(--c) 55%, var(--line));
  border-radius: 37px / 50%;
}
.tankshape::before {           /* the liquid */
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 42%;
  background: linear-gradient(color-mix(in srgb, var(--c) 100%, #fff 18%), var(--c) 40%, color-mix(in srgb, var(--c) 78%, #000));
  transition: background .25s var(--ease);
}
.tankshape::after {            /* the far end cap */
  content: ''; position: absolute; top: 4px; bottom: 4px; right: 10px; width: 16px;
  border-radius: 50%; border-left: 1px solid color-mix(in srgb, var(--paper) 18%, transparent);
}
.tankshape > span { position: relative; z-index: 1; }
.tankshape__no { font-size: 11px; color: var(--haze-2); padding-top: 2px; }
.tankshape__name { font-family: var(--display); font-weight: 600; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tankshape__cap { font-size: 10.5px; color: var(--haze); }
button.tankshape { cursor: pointer; }
button.tankshape:hover { border-color: var(--c); }

/* The pipe: one line down from the tank, a branch out to each nozzle. */
.board__hoses { list-style: none; margin: 0 0 0 30px; padding: 6px 0 0; --pipe: color-mix(in srgb, var(--c) 70%, var(--line)); }
.board__hoses li { position: relative; padding: 4px 0 4px 20px; }
.board__hoses li::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; background: var(--pipe); }
.board__hoses li:last-child::before { bottom: 50%; }
.board__hoses li::after { content: ''; position: absolute; left: 0; top: 50%; width: 16px; height: 2px; margin-top: -1px; background: var(--pipe); }
.nozzle {
  display: inline-flex; align-items: center; gap: 8px; margin: 0;
  padding: 5px 10px 5px 6px; font: inherit; font-size: 12.5px; color: var(--paper);
  background: var(--ink-750); border: 1px solid var(--line-2); border-radius: var(--r);
}
.nozzle__tip { width: 10px; height: 16px; border-radius: 2px 2px 5px 5px; background: var(--n); flex: none; }
.nozzle em { font-style: normal; font-size: 11px; color: var(--warn); }
.nozzle.is-off { border-style: dashed; color: var(--haze); }
.nozzle.is-off .nozzle__tip { opacity: .45; }
button.nozzle { cursor: pointer; }
button.nozzle:hover { border-color: var(--n); }
.board :is(button.board__grade, button.tankshape, button.nozzle):focus-visible { outline: 2px solid var(--paper); outline-offset: 2px; }

/* The one editor every board item opens */
.set-edit {
  width: min(430px, calc(100vw - 32px)); padding: 0; margin: auto;
  background: var(--ink-800); color: var(--paper);
  border: 1px solid var(--line-2); border-radius: var(--r-lg);
  box-shadow: 0 24px 60px -20px rgba(0,0,0,.6);
}
.set-edit::backdrop { background: rgba(4, 10, 12, .55); }
.set-edit[open] { animation: set-edit-in .18s var(--ease); }
@keyframes set-edit-in { from { opacity: 0; transform: translateY(6px); } }
.set-edit__head { display: flex; align-items: center; gap: 10px; padding: 14px 14px 14px 18px; }
.set-edit__head h3 { flex: 1; font-size: 16px; min-width: 0; }
.set-edit__dot { width: 18px; height: 18px; border-radius: 4px; background: var(--c); flex: none; }
.set-edit__block { display: flex; flex-direction: column; gap: 10px; padding: 14px 18px 16px; border-top: 1px solid var(--line); }
.set-edit__block[hidden] { display: none; }
.set-edit__block > .btn { align-self: flex-start; }
.set-edit__label { font-size: 12px; color: var(--haze); }
.set-edit__row { display: flex; align-items: center; gap: 8px; }
.set-edit__row input { flex: 1; min-width: 0; }
.set-edit .cpick__sw { width: 30px; height: 30px; }

/* What the controller owns: quieter, packed into columns */
.ref-grid { columns: 2 470px; column-gap: var(--gap); }
.ref { break-inside: avoid; margin-bottom: var(--gap); background: var(--ink-850); }
.ref .panel__head { padding: 10px 16px; }
.ref .panel__head h3 { font-size: 14px; }
.ref tr.is-quiet td { color: var(--haze); }
/* The tanks table has the most columns: it gets the full width so nothing is cut off. */
.ref--wide { margin-bottom: var(--gap); }

@media (max-width: 1100px) {
  .set-layout { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .set-nav {
    position: static; flex-direction: row; overflow-x: auto; gap: 6px;
    padding-bottom: 2px; scrollbar-width: none;
  }
  .set-nav a { flex: none; border: 1px solid var(--line); border-radius: 16px; padding: 6px 12px; }
  .set-nav a[aria-current] { border-color: var(--petrol); }
  .set-station { grid-template-columns: minmax(0, 1fr); }
  .set-station__print { border-left: 0; border-top: 1px solid var(--line); }
}
@media (max-width: 640px) {
  .set-main { gap: 30px; }
  .set-station__form, .set-station__print { padding: 16px; }
  .set-station__pair { grid-template-columns: minmax(0, 1fr); }
  .board { padding: 2px 16px; }
  .board__product { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .board__tank { width: 100%; }
  .set-edit { width: 100%; max-width: none; margin: auto 0 0; border-radius: var(--r-lg) var(--r-lg) 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  .set-edit[open] { animation: none; }
  .tankshape::before { transition: none; }
}

/* ---------------------------------------------------------------- activity + delete log */
.actlog td { vertical-align: top; }
.actlog__row--deleted > td:first-child { box-shadow: inset 2px 0 0 var(--alarm); }
.actlog__fields { margin-top: 8px; border-collapse: collapse; font-size: 12px; min-width: 320px; }
.actlog__fields th, .actlog__fields td { padding: 4px 10px 4px 0; text-align: left; border-bottom: 1px solid var(--line-2); }
.actlog__fields th { font-family: var(--data); font-size: 9.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--haze); font-weight: 600; }
.actlog__fields td { word-break: break-word; max-width: 360px; }
.actlog__old { color: var(--alarm); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--alarm) 50%, transparent); }
.actlog__new { color: var(--ok); }
.modal__card--wide { width: min(760px, calc(100vw - 28px)); }
.actlog__h { font-size: 12px; font-family: var(--data); letter-spacing: .06em; text-transform: uppercase; color: var(--haze); margin: 16px 0 6px; }
.actlog__h:first-child { margin-top: 0; }
.actlog__dl { display: grid; grid-template-columns: minmax(110px, 160px) 1fr; gap: 6px 14px; margin: 0; font-size: 13px; }
.actlog__dl dt { color: var(--haze); }
.actlog__dl dd { margin: 0; word-break: break-word; }
.actlog__ua { font-size: 11px; color: var(--haze-2); }
@media (max-width: 520px) { .actlog__dl { grid-template-columns: 1fr; gap: 2px; } .actlog__dl dd { margin-bottom: 6px; } }

/* Settings ▸ Activity and delete log */
.set-logs { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--gap); }
.set-logs__card .panel__head { display: flex; align-items: center; gap: 10px; }
.set-logs__card .panel__head .btn { margin-left: auto; }
.set-logs__card--del { box-shadow: inset 3px 0 0 var(--alarm); }
.set-logs__nums { display: flex; gap: 28px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.set-logs__nums div { display: flex; flex-direction: column; gap: 2px; }
.set-logs__nums b { font-family: var(--data); font-size: 20px; }
.set-logs__bad { color: var(--alarm); }
.set-logs__empty { padding: 14px 16px; margin: 0; }
.set-logs__list { list-style: none; margin: 0; padding: 4px 0; }
.set-logs__list li { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 10px; align-items: baseline; padding: 8px 16px; border-bottom: 1px solid var(--line); font-size: 13px; }
.set-logs__list li:last-child { border-bottom: none; }
.set-logs__what { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.set-logs__at { font-size: 11px; white-space: nowrap; }
@media (max-width: 520px) { .set-logs__list li { grid-template-columns: auto minmax(0, 1fr); } .set-logs__at { grid-column: 2; } }

/* Users and access */
.users__roles { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 8px; }
.users__role { display: flex; gap: 9px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--line-2); border-radius: var(--r); cursor: pointer; }
.users__role:has(input:checked) { border-color: var(--petrol); background: color-mix(in srgb, var(--petrol) 8%, transparent); }
.users__role > span { display: flex; flex-direction: column; gap: 3px; font-size: 13px; }
.users__role .dim { font-size: 11.5px; line-height: 1.4; }
.actlog__h:has(.users__bulk) { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.users__bulk { margin-left: auto; display: inline-flex; gap: 6px; text-transform: none; letter-spacing: 0; }
.users__groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; }
.users__group { border: 1px solid var(--line-2); border-radius: var(--r); padding: 8px 12px 10px; margin: 0; }
.users__group legend { padding: 0 4px; }
.users__page { display: flex; gap: 8px; align-items: center; padding: 4px 0; font-size: 13px; cursor: pointer; }
.users__page input:disabled + span { color: var(--haze); }
.users__acts { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 8px; }
.users__act { display: flex; gap: 9px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--line-2); border-radius: var(--r); cursor: pointer; }
.users__act:has(input:checked) { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 8%, transparent); }
.users__act:has(input:disabled) { cursor: default; opacity: .75; }
.users__act > span { display: flex; flex-direction: column; gap: 3px; font-size: 13px; }
.users__act .dim { font-size: 11.5px; line-height: 1.4; }
.urow__acts { font-size: 11px; color: var(--ok); margin: -2px 0 4px; }
.users__ownernote { margin: 0 0 8px; }

/* Users and access — the list. Each login is a row read left to right: who, what they can
   open, when they were last here, what you can do about it. The access map is the one loud
   thing: a segment per page, grouped like the rail, lit in the role's colour. */
.ukey--owner { --rc: var(--petrol); }
.ukey--manager { --rc: var(--ok); }
.ukey--viewer { --rc: var(--water); }

.ukeys {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden;
  margin-bottom: var(--gap);
}
.ukeys__item { display: flex; gap: 12px; align-items: flex-start; padding: 12px 16px; background: var(--ink-850); }
.ukeys__n {
  flex: none; min-width: 30px; height: 30px; padding: 0 8px; border-radius: 15px;
  display: grid; place-items: center;
  font-family: var(--display); font-weight: 700; font-size: 15px;
  color: var(--rc); background: color-mix(in srgb, var(--rc) 13%, transparent);
}
.ukeys__txt { font-size: 12.5px; line-height: 1.45; color: var(--haze); }
.ukeys__txt b { color: var(--paper); font-weight: 600; margin-right: 2px; }

.ulist { background: var(--ink-800); border: 1px solid var(--line); border-radius: var(--r-lg); }
.ulist__head { display: flex; align-items: baseline; gap: 12px; padding: 14px 18px 10px; }
.ulist__head h2 { font-size: 17px; }
.ulist__cols, .urow {
  display: grid;
  /* A fixed actions column: rows with two buttons and rows with three must share one grid. */
  grid-template-columns: minmax(220px, 1.25fr) minmax(250px, 1.35fr) minmax(170px, 1fr) 212px;
  gap: 22px; align-items: center; padding: 0 18px;
}
.ulist__cols { padding-bottom: 8px; border-bottom: 1px solid var(--line); font-size: 12px; color: var(--haze); }
.urow { padding-top: 14px; padding-bottom: 14px; border-bottom: 1px solid var(--line); }
.urow:last-of-type { border-bottom: none; }

.urow__who { display: flex; gap: 12px; align-items: center; min-width: 0; }
.urow__mono {
  flex: none; width: 40px; height: 40px; border-radius: 10px;
  display: grid; place-items: center;
  font-family: var(--display); font-weight: 700; font-size: 14px; letter-spacing: .02em;
  color: var(--rc); background: color-mix(in srgb, var(--rc) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rc) 35%, transparent);
}
.urow__id { min-width: 0; }
.urow__name { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.urow__name b { font-family: var(--display); font-size: 15px; font-weight: 650; }
.urow__tag { font-size: 11px; color: var(--haze); border: 1px solid var(--line-2); border-radius: 9px; padding: 0 7px; line-height: 17px; }
.urow__meta { font-size: 12.5px; color: var(--haze); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.urow__meta .data { font-size: 11.5px; }
.urow__role { color: var(--rc); font-weight: 600; }

.urow__count { font-size: 12.5px; color: var(--haze-2); margin-bottom: 6px; }
.amap { display: flex; gap: 10px; flex-wrap: wrap; }
.amap__group { display: flex; flex-direction: column; gap: 4px; }
.amap__cells { display: flex; gap: 3px; }
.amap__cell {
  width: 11px; height: 20px; border-radius: 2px;
  background: var(--ink-600); box-shadow: inset 0 0 0 1px var(--line);
}
.amap__cell.is-on { background: var(--rc); box-shadow: none; }
.amap__label { font-size: 10.5px; color: var(--haze); line-height: 1; }

.urow__seen { display: flex; flex-direction: column; gap: 1px; font-size: 12.5px; min-width: 0; }
.urow__seen .data { font-size: 12px; }
.urow__seen .urow__ip { font-size: 11px; }

.urow__acts { display: flex; gap: 6px; align-items: center; justify-content: flex-end; }
.umenu { position: relative; }
.umenu > summary { list-style: none; min-width: 34px; justify-content: center; font-size: 16px; line-height: 1; }
.umenu > summary::-webkit-details-marker { display: none; }
.umenu__pop {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; min-width: 210px;
  display: flex; flex-direction: column; padding: 5px;
  background: var(--ink-750); border: 1px solid var(--line-2); border-radius: var(--r-lg);
  box-shadow: 0 14px 34px rgba(0, 0, 0, .35);
}
.umenu__pop button { width: 100%; text-align: left; padding: 8px 10px; border-radius: var(--r); font-size: 13px; }
.umenu__pop button:hover, .umenu__pop button:focus-visible { background: var(--ink-600); outline: none; }
.umenu__danger { color: var(--alarm); }

.urow--off { --rc: var(--haze); }
.urow--off .urow__who, .urow--off .urow__access, .urow--off .urow__seen { opacity: .5; }

.ulist__foot { padding: 12px 18px 14px; font-size: 12.5px; color: var(--haze); border-top: 1px solid var(--line); }

@media (max-width: 1100px) {
  .ulist__cols { display: none; }
  .urow { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "who acts" "access access" "seen seen"; row-gap: 12px; }
  .urow__who { grid-area: who; }
  .urow__acts { grid-area: acts; }
  .urow__access { grid-area: access; }
  .urow__seen { grid-area: seen; flex-direction: row; flex-wrap: wrap; gap: 4px 10px; }
}
@media (max-width: 640px) {
  .ukeys { grid-template-columns: 1fr; }
  .urow { grid-template-areas: "who" "access" "seen" "acts"; grid-template-columns: minmax(0, 1fr); }
  .urow__acts { justify-content: flex-start; }
  .umenu__pop { right: auto; left: 0; }
}

/* ---------------------------------------------------------------- products (lubricants & co.) */
/* Two-way switch on the stock dialog: Received / Count correction. */
.seg { display: inline-flex; border: 1px solid var(--line-2); border-radius: var(--r); overflow: hidden; }
.seg label { position: relative; cursor: pointer; }
.seg input { position: absolute; opacity: 0; pointer-events: none; }
.seg span { display: block; padding: 6px 14px; font-size: 12.5px; color: var(--haze); }
.seg label + label span { border-left: 1px solid var(--line-2); }
.seg input:checked + span { background: var(--ink-750); color: var(--paper); font-weight: 600; }
.seg input:focus-visible + span { outline: 2px solid var(--primary); outline-offset: -2px; }

/* A shift's products sit under its nozzle table, set off by a heavier rule. */
.tbl--items { border-top: 1px solid var(--line-2); }
.tbl--items thead th { padding-top: 12px; }
.tbl__grand th { color: var(--paper); font-weight: 700; font-size: 13px; }
.gsum--all { padding-left: 10px; border-left: 1px solid var(--line-2); }
.gsum--all .gsum__v { font-size: 13.5px; }
