/* ============================================================================
   AGC Quarry ERP — application chrome & component system
   Brand baseline: AGC Brand Portal v2.1 (portal.html). Primitives in
   design-tokens.css (loaded first). Local Inter variable font only — no CDN.
   This file is the full interaction system: shell, nav, page header,
   KPI/cockpit, unified table system (toolbar/sort/quick-actions/expand),
   stepper, cash gate, forms, toasts, skeletons, empty states.
   ============================================================================ */
/* `hidden` means hidden. The browser's own rule for it is only `display: none`
   at user-agent weight, so any author rule that gives an element a display —
   `.pay-form .fld { display: flex }`, for one — silently defeats it, and an
   element JavaScript believes it has hidden stays on screen. That is how the
   MoMo number field came to sit under "Bank Transfer", asking for a wallet for
   a payment that was not going to one. Anything toggled by this attribute
   depends on this rule, so it carries !important deliberately. */
[hidden] { display: none !important; }

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter-latin-wght-normal.8e433c0592f7.woff2") format("woff2-variations");
}
/* Archivo (Omnibus-Type, SIL Open Font License 1.1), latin subset, variable
   weight. Inter is a body face — even, wide-apertured, deliberately
   characterless, which is what makes it good at 13px and plain at 28. Page
   titles use Archivo instead: narrower, squarer, with real weight in its
   verticals, so a page name has presence on the dark ground without being set
   any larger. Self-hosted next to Inter — no CDN, and the CSP has never
   allowed one. */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("../fonts/archivo-latin-wght-normal.cd56e2ec63d7.woff2") format("woff2-variations");
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: var(--font-sans);
  color: var(--color-text);
  background: var(--agc-canvas);
  background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23d5d4ce' fill-opacity='0.25'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
  min-height: 100vh;
}

/* Every link that is not dressed as something else. Nothing set a link colour
   in any of the sheets, so a bare <a> — the payment reference in a list, the
   "daily export" cross-reference in an action panel — rendered in the
   browser's default blue, which is 1.79:1 on the command centre's canvas.
   Components that are links (buttons, nav items, table rows) set their own
   colour and are unaffected. */
a { color: var(--color-link); }
a:hover { color: var(--color-link-hover); }

.accent-bar { height: 5px; background: var(--gradient-accent); }
.shell { display: grid; grid-template-columns: 236px 1fr; min-height: calc(100vh - 5px); }

/* ── SIDEBAR ────────────────────────────────────────────────────────────── */
.sidebar {
  background: var(--gradient-chrome); color: var(--chrome-ink);
  padding: 20px 0 18px; position: relative; display: flex; flex-direction: column;
  border-right: 1px solid var(--chrome-edge);
}
.sidebar::after { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at 80% 0%, rgba(var(--accent-rgb), 0.06), transparent 55%); }
.sidebar > * { position: relative; z-index: 1; }

.brand-lockup { display: flex; align-items: center; gap: 10px; padding: 0 18px 2px; }
.brand-lockup svg { display: block; flex-shrink: 0; }
/* The subsidiary's own logo, on its own white plate. Both marks were drawn
   for paper, and a logo floating directly on the dark chrome reads as an
   afterthought — the plate is the square of white the artwork expects. Width
   follows the artwork (the two marks are not the same shape), so the plate is
   sized by height and never pushes the product name out of the lockup. */
.brand-mark {
  display: block; flex-shrink: 0; box-sizing: content-box;
  height: 26px; width: auto; max-width: 58px; object-fit: contain;
  padding: 4px 5px; border-radius: 7px; background: var(--logo-plate);
}
/* The AGC hexagon is still drawn on the login card, which is white — only the
   sidebar's copy takes the chrome's ink. */
.sidebar .brand-lockup svg polygon:first-child { fill: var(--chrome-ink); }
.sidebar .brand-lockup svg polygon:nth-child(2) { fill: var(--agc-green); }
.sidebar .brand-lockup svg polygon:nth-child(3) { fill: var(--agc-green-2); }
.brand-name { font-size: 17px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; color: var(--chrome-ink); }
.brand-name span { color: var(--agc-green); }

/* ── SUBSIDIARY SWITCH ──────────────────────────────────────────────────────
   Which company the session is in, and the way out of it. It sits between the
   product name and the New payment button, and it used to look like a third
   button — a saturated slab the same size and weight as the call to action
   directly beneath it, so the eye met two competing greens before it met the
   navigation.

   It reads as a control now rather than a pair of buttons: one bordered group
   under a small label, the company you are in raised and ticked, the other
   quiet until you point at it. Nothing here is filled with the accent, which
   leaves New payment the only solid thing in the sidebar — the one you press
   most, and the only one that should shout. */
.subs-switch {
  display: grid; gap: 2px; margin: 14px 16px 0; padding: 5px;
  border-radius: 12px; background: var(--chrome-sunk-bg);
  border: 1px solid var(--chrome-line-soft);
}
.subs-switch-label {
  padding: 3px 7px 5px; font-size: 8.5px; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--chrome-section);
}
/* Stacked rather than side by side: "Sun Electronics" does not fit half of a
   236px sidebar, and a switch whose options are elided to "SUN EL…" cannot be
   read at the speed it is meant to be read at. */
/* Each option is a one-button form now — switching company is a change, not a
   place. `display: contents` drops the form out of the box tree so the button
   stays a direct grid item of .subs-switch and the layout is unchanged. */
.subs-form { display: contents; }
/* Three columns: the mark, the name, the tick. The tick used to be pushed
   right with `margin-left: auto`, which let it land on top of the name at a
   narrow width; in a column of its own it cannot. */
.subs-opt {
  display: grid; grid-template-columns: 26px minmax(0, 1fr) 14px;
  align-items: center; gap: 10px; min-width: 0; min-height: 42px;
  width: 100%; text-align: left; background: none; cursor: pointer;
  font-family: inherit;
  padding: 6px 9px 6px 7px; border-radius: 11px; text-decoration: none;
  transition: background 0.14s, border-color 0.14s, color 0.14s;
  color: var(--chrome-ink-muted); font-size: 11.5px; font-weight: 500;
  letter-spacing: 0.005em;
  /* Both options carry a resting border, or the unselected one reads as a
     caption rather than as something you can press. */
  border: 1px solid var(--chrome-line-soft);
}
.subs-opt:hover {
  color: var(--chrome-ink-hover); background: var(--chrome-hover-bg);
  border-color: var(--chrome-line);
}
.subs-opt.on {
  background: var(--chrome-raised-bg); color: var(--chrome-ink);
  border-color: rgba(var(--accent-rgb), 0.5);
}
/* The logo sits on a white plate, selected or not. Tinting it with the accent
   is fine for a monogram and wrong for a logo: Egle's mark is dark artwork
   drawn for a white square, and on a green tint the company you are in becomes
   the one you cannot see. */
.subs-mark {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 26px; height: 26px; overflow: hidden; border-radius: 8px;
  background: var(--logo-plate);
}
.subs-opt.on .subs-mark { background: var(--logo-plate); }
.subs-mark img { display: block; width: 100%; height: 100%; padding: 3px; object-fit: contain; }
/* One line, and it fits — so an ellipsis here means a company name got longer,
   not that the control was always too small for it. */
.subs-name {
  display: block; min-width: 0; overflow: hidden; line-height: 1.25;
  text-overflow: ellipsis; white-space: nowrap;
}
/* The tick, not a colour, is what says "you are here" — it survives being
   looked at quickly, and it does not borrow the accent from New payment. */
.subs-opt .subs-here { flex-shrink: 0; width: 14px; height: 14px;
  color: var(--chrome-accent-ink); opacity: 0; transition: 0.15s; }
.subs-opt.on .subs-here { opacity: 1; }

.new-btn {
  margin: 14px 16px 6px; display: flex; align-items: center; justify-content: center; gap: 7px;
  padding: 10px; border-radius: 8px; background: rgba(var(--accent-rgb), 0.14); color: var(--chrome-accent-ink);
  border: 1px solid rgba(var(--accent-rgb), 0.3); font: inherit; font-size: 11px; font-weight: 700;
  letter-spacing: 0; cursor: pointer; transition: 0.15s; text-decoration: none;
}
.new-btn svg { width: 15px; height: 15px; }
.new-btn:hover { background: rgba(var(--accent-rgb), 0.22); color: var(--chrome-ink); }

.nav { display: flex; flex-direction: column; margin-top: 4px; }
.nav a {
  display: flex; align-items: center; gap: 11px; color: var(--chrome-ink-muted); text-decoration: none;
  padding: 9px 18px 9px 21px; font-size: 11.5px; font-weight: 600; letter-spacing: 0.08em;
  text-transform: uppercase; border-left: 3px solid transparent; transition: 0.2s;
}
.nav a svg { width: 16px; height: 16px; flex-shrink: 0; opacity: 0.8; }
.nav a:hover { color: var(--chrome-ink-hover); background: var(--chrome-hover-bg); }
.nav a.active, .nav a[aria-current="page"] { color: var(--chrome-ink); border-left-color: var(--agc-green); background: rgba(var(--accent-rgb), 0.07); }
.nav a.active svg, .nav a[aria-current="page"] svg { opacity: 1; color: var(--chrome-accent-ink); }
.nav a .count { margin-left: auto; background: var(--chrome-line); color: var(--chrome-ink-muted); font-size: 9px; padding: 1px 7px; border-radius: 12px; letter-spacing: 0; }
.nav a .count.alert { background: rgba(206,39,45,0.25); color: #ff9a9d; }
.nav .nav-section { margin: 12px 0 2px; padding: 0 18px; font-size: 9px; color: var(--chrome-section); letter-spacing: 0.25em; text-transform: uppercase; font-weight: 600; }

.sidebar-foot { margin: 14px 12px 0; padding: 14px 6px 0; border-top: 1px solid var(--chrome-line-soft); display: flex; align-items: center; gap: 9px; }
.avatar { width: 30px; height: 30px; border-radius: 8px; background: var(--accent-ink); color: var(--color-on-primary); display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 12px; text-transform: uppercase; }
.sidebar-foot .who { font-size: 11px; font-weight: 600; color: var(--chrome-ink); }
.sidebar-foot .who small { display: block; color: var(--chrome-ink-muted); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; font-weight: 500; }
.sidebar-foot form { margin-left: auto; }
.sidebar-foot .label { color: var(--chrome-ink-muted); }

/* ── MAIN + PAGE HEADER ─────────────────────────────────────────────────── */
.main { padding: 0; min-width: 0; }
/* Let tables scroll inside their wrapper instead of stretching the layout */
.card, .kpi { min-width: 0; }
.grid-2 > *, .flow > * { min-width: 0; }
.tbl-wrap { max-width: 100%; }
.pagehead { background: var(--color-surface); border-bottom: 1px solid var(--color-border); padding: 15px clamp(16px, 3vw, 44px) 17px; position: sticky; top: 0; z-index: 20; box-shadow: var(--shadow-sm); }
/* The trail lives in the app bar now (base.html, {% block crumbs %}) — it was
   printed twice, and only one of the two could be followed. */
.ph-row { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.ph-row h1 { font-size: 24px; font-weight: 800; letter-spacing: -0.02em; margin: 0; }
.ph-title { flex: 1 1 320px; min-width: 0; }
.ph-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.ph-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }
/* Fluid: fill the device viewport (no fixed cap) — the sidebar takes a fixed
   column, the content flexes to whatever width the device gives it. */
.body { padding: 28px clamp(16px, 3vw, 44px) 60px; max-width: none; }

/* ── HEADINGS ───────────────────────────────────────────────────────────── */
h1 { font-size: 24px; font-weight: 800; color: var(--color-text); letter-spacing: -0.02em; margin-bottom: 20px; }
h1 .muted { font-size: 13px; font-weight: 400; letter-spacing: 0; }
/* A card heading is a heading, not a banner. It was 12px uppercase at .1em
   tracking, so every card on the payment screen shouted its own name and
   there was no hierarchy left to spend on the one thing the person is
   actually there to do. */
h2 { font-size: 14px; font-weight: 600; color: var(--color-text); letter-spacing: -0.01em; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--color-border-row); display: flex; align-items: center; gap: 8px; }
h2 .r { margin-left: auto; }

/* ── CARDS ──────────────────────────────────────────────────────────────── */
.card { background: var(--color-surface); border: 1px solid rgba(0,0,0,0.04); border-radius: var(--radius-lg); padding: 22px 26px; box-shadow: var(--shadow); }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-bottom: 20px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }
.kpi { background: var(--color-surface); border: 1px solid rgba(0,0,0,0.04); border-radius: var(--radius-lg); padding: 18px 20px; box-shadow: var(--shadow-sm); position: relative; overflow: hidden; text-decoration: none; display: block; }
a.kpi:hover { box-shadow: var(--shadow); transform: translateY(-2px); transition: 0.2s; }
.kpi .dl { font-size: 11px; color: var(--color-text-muted); margin-top: 2px; }
.kpi .dl b { color: var(--agc-green-deep); }
.kpi.alert { border-color: rgba(217,138,0,0.3); background: linear-gradient(180deg, #fffdf8, #fff); }

.stat { min-height: 118px; }
.stat .label { font-size: 10px; letter-spacing: 0.25em; text-transform: uppercase; color: var(--agc-green-deep); font-weight: 600; margin-bottom: 6px; display: block; }
.stat-num { font-size: 30px; font-weight: 800; letter-spacing: -0.02em; color: var(--color-text); }
.stat-sub { color: var(--color-text-muted); font-size: 12px; margin-top: 4px; }

/* ── BAR CHART (inline, no lib) ─────────────────────────────────────────── */
.bars { display: flex; flex-direction: column; gap: 12px; }
.bar-track { height: 22px; background: var(--color-surface-alt); border-radius: 4px; overflow: hidden; }
.bar-fill { height: 100%; border-radius: 4px; background: linear-gradient(90deg, var(--agc-green), var(--agc-green-2)); min-width: 3px; transition: width 0.4s ease; }

.feed { list-style: none; display: flex; flex-direction: column; }
.feed li { padding: 10px 0 10px 16px; border-bottom: 1px solid var(--color-border-row); font-size: 12.5px; color: var(--agc-body); position: relative; }
.feed li:last-child { border-bottom: 0; }
.feed li::before { content: ''; position: absolute; left: 0; top: 15px; width: 6px; height: 6px; border-radius: 50%; background: var(--agc-grey); }
.feed li time { display: block; font-size: 10px; letter-spacing: 0.06em; color: var(--color-text-muted); text-transform: uppercase; margin-bottom: 2px; font-weight: 500; }/* BRD 6.1.2 — by-product/audit rows in red */
.feed li.red { color: var(--color-audit-flag); font-weight: 600; }
.feed li.red::before { background: var(--color-audit-flag); }

.activity { list-style: none; display: flex; flex-direction: column; }
.activity li { padding: 9px 0; border-bottom: 1px solid var(--color-border-row); font-size: 12.5px; color: var(--agc-body); }
.activity li:last-child { border-bottom: 0; }
.activity .label { display: block; text-transform: none; letter-spacing: 0.02em; font-size: 10px; color: var(--color-text-muted); font-weight: 500; margin-bottom: 2px; }

/* ── TABLE SYSTEM ───────────────────────────────────────────────────────── */
.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
/* A search or period picker that is a direct child of the page stands on a
   surface of its own. Left transparent, the box and its button sat on the
   canvas above a table that had one, which is the plainest sort of floating
   control. */
.body > .toolbar {
  padding: 12px 16px; background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.search { display: flex; align-items: center; gap: 8px; background: var(--color-surface); border: 1px solid var(--ui-line); border-radius: 8px; padding: 8px 12px; min-width: 240px; }
.search svg { width: 15px; height: 15px; color: var(--color-text-muted); flex-shrink: 0; }
.search input { border: none; outline: none; font: inherit; font-size: 13px; width: 100%; background: transparent; }
.chips { display: flex; gap: 6px; flex-wrap: wrap; }
.chip { padding: 6px 12px; border-radius: 20px; border: 1px solid var(--ui-line); background: var(--color-surface); font: inherit; font-size: 11px; color: var(--color-text-muted); cursor: pointer; letter-spacing: 0.03em; transition: 0.15s; text-decoration: none; }
.chip:hover { border-color: var(--agc-grey); }
.chip.on { background: var(--agc-dark); color: #fff; border-color: var(--agc-dark); font-weight: 600; }
.count { margin-left: auto; font-size: 11px; color: var(--color-text-muted); letter-spacing: 0.03em; }
.count b { color: var(--color-text); }

.tbl-wrap { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 8px; overflow-x: auto; box-shadow: var(--shadow-sm); }

table.data { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12.5px; background: var(--color-surface); }
.tbl-wrap table.data { border: 0; }
table.data thead th, table.data > tr:first-child th { background: var(--agc-dark); color: #fff; text-align: left; padding: 11px 14px; font-size: 10.5px; font-weight: 600; letter-spacing: 0.04em; text-transform: none; }
table.data td { padding: 11px 14px; border-bottom: 1px solid var(--color-border-row); color: var(--agc-body); vertical-align: middle; transition: background 0.15s; }
table.data tbody tr:nth-child(even) td, table.data tr:nth-child(even) td { background: var(--color-surface-alt); }
table.data tbody tr:hover td, table.data tr:hover td { background: #f0f7ee; color: var(--color-text); }
table.data tr:last-child td { border-bottom: 0; }
/* Uniform left alignment across every table — headers and cells, numbers
   included — so all columns line up on the same edge. tabular-nums keeps digit
   widths even; nowrap stops amounts breaking across lines. */
th.num, td.num { text-align: left; font-variant-numeric: tabular-nums; letter-spacing: normal; white-space: nowrap; }
table.data thead th.num, table.data > tr:first-child th.num { text-align: left; }
/* An amount still to leave a bank. Not coloured as a state — it is neither
   good nor bad, it is a commitment — but set in the body ink at the weight a
   figure needs to be read off a row of email addresses. */
.owed { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--color-text); white-space: nowrap; }
/* A link standing on its own in a cell is not an inline link in a sentence,
   so WCAG 2.2's 24px target minimum applies — these were 27x11 on the users
   list and 51x14 on the export queue. Only the hit area grows. */
table.data a.lead, table.data td .lead { display: inline-flex; align-items: center;
  min-height: 24px; font-weight: 600; color: var(--color-text); text-decoration: none; }
table.data a.lead:hover { color: var(--agc-green-deep); }
/* An account number, an IBAN or a SWIFT code broken across two lines is read
   wrong, which is the same failure a six-figure amount without separators is.
   The wrapper scrolls; the number does not break. (A payment reference is the
   exception — see table.data.plan below, where they are long and free-form.) */
table.data code { font-size: 11px; white-space: nowrap; }

/* The register is twenty columns of short values — a date, a payment number, a
   currency. Left to wrap, every one of them broke across two or three lines
   and the table squeezed itself into the card instead of scrolling, which is
   the one thing its wrapper is there to do. */
.register-page table.data th, .register-page table.data td { white-space: nowrap; }

.qa { display: flex; gap: 4px; justify-content: flex-end; }
/* flex: none — .qa is a flex row, so these shrank to 16x28 in a narrow cell. */
.qa a, .qa button { flex: none; width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--color-border); background: var(--color-surface); color: var(--color-text-muted); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: 0.15s; text-decoration: none; }
.qa a svg, .qa button svg { width: 14px; height: 14px; }
.qa a:hover, .qa button:hover { border-color: var(--agc-green-deep); color: var(--agc-green-deep); background: var(--agc-green-tint); }
.hidden { display: none !important; }
tr.detail td { border-bottom: 1px solid var(--color-border-row); }

.empty { text-align: center; padding: 46px 20px; color: var(--color-text-muted); }
/* An empty state that is the page, rather than the inside of a card, still
   stands on something. One sentence alone on the canvas is the plainest kind
   of floating text there is. */
.body > .empty {
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow);
}
.empty svg { width: 42px; height: 42px; opacity: 0.35; margin-bottom: 12px; }
.empty p { font-size: 13px; margin: 0 auto 16px; max-width: 52ch; }

/* ── STEPPER ────────────────────────────────────────────────────────────── */
/* The seven steps are wider than a phone, so this scrolls. A hard edge at the
   viewport reads as "that is the end"; the mask fades the last step out so it
   reads as "there is more", and lifts once you reach the end. */
.stepper {
  display: flex; align-items: center; margin: 4px 0 24px;
  overflow-x: auto; padding-bottom: 4px;
  mask-image: linear-gradient(90deg, #000 calc(100% - 34px), transparent);
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 34px), transparent);
}
@supports (animation-timeline: scroll(self inline)) {
  .stepper { animation: stepper-edge linear both; animation-timeline: scroll(self inline); }
  @keyframes stepper-edge {
    to { mask-image: linear-gradient(90deg, transparent, #000 34px);
         -webkit-mask-image: linear-gradient(90deg, transparent, #000 34px); }
  }
}
.step { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.step .ball { width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 800; background: var(--color-surface); border: 2px solid var(--agc-grey); color: var(--color-text-muted); }
.step .stx { font-size: 11px; letter-spacing: 0; font-weight: 500; color: var(--color-text-muted); }
.step.done .ball { background: var(--accent-ink); border-color: var(--accent-ink); color: var(--color-on-primary); }
/* A passed step you can go back into. It rests as the tick it always was and
   turns into an undo arrow under the pointer, so the affordance is discovered
   without printing a second row of controls under the stepper. */
.step-back { display: contents; }
.ball--back { padding: 0; cursor: pointer; font: inherit; position: relative; }
.ball--back .ball-undo {
  position: absolute; width: 15px; height: 15px; opacity: 0; transition: opacity .12s;
}
.ball--back:hover .ball-tick,
.ball--back:focus-visible .ball-tick { opacity: 0; }
.ball--back:hover .ball-undo,
.ball--back:focus-visible .ball-undo { opacity: 1; }
.ball--back:focus-visible { outline: 2px solid var(--color-link); outline-offset: 2px; }
.step.done .stx { color: var(--agc-green-deep); }
.step.cur .ball { background: var(--agc-dark); border-color: var(--agc-dark); color: #fff; box-shadow: 0 0 0 4px rgba(25,30,43,0.12); }
.step.cur .stx { color: var(--color-text); }
.step .line { width: 40px; height: 2px; background: var(--agc-grey); margin: 0 8px; }
.step.done .line { background: var(--agc-green); }

.flow { display: grid; grid-template-columns: 1.5fr 1fr; gap: 20px; align-items: start; }
.receipts { display: flex; flex-direction: column; gap: 8px; }
.receipt { display: flex; align-items: center; gap: 10px; padding: 11px 14px; background: var(--color-surface-alt); border: 1px solid var(--color-border); border-radius: 8px; font-size: 12px; color: var(--agc-body); }
.receipt .ck { width: 18px; height: 18px; border-radius: 50%; background: var(--accent-ink); color: var(--color-on-primary); display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 11px; }
/* The tick is green because most of them are a yes. The two that are not —
   something held back, something inactive — were carrying the colour as an
   inline style on the element, which is the one thing a component must not
   do: it pinned them to a literal that no theme and no contrast fix could
   reach. Both inks are the readable weight of their state. */
/* Both are filled with a state ink, so the glyph on top is white — the inks
   are chosen to carry it (--amber-ink is 5.1:1 with white, --ui-ink-muted
   5.6:1). The accent's near-black was 3.6:1 on the amber. */
.receipt .ck--warn { background: var(--amber-ink); color: #ffffff; }
.receipt .ck--mute { background: var(--ui-ink-muted); color: #ffffff; }
.receipt b { color: var(--color-text); }
.receipt .r { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--color-text-muted); }

.gate { background: linear-gradient(180deg, #0f1622, #191e2b); color: #fff; border-radius: 12px; padding: 24px; text-align: center; box-shadow: var(--shadow-lg); }
.gate .amt { font-size: 40px; font-weight: 800; letter-spacing: -0.02em; margin: 8px 0; }
.gate .amt small { font-size: 18px; color: var(--agc-green-2); }
.gate .sub { font-size: 11px; color: var(--agc-grey); margin-bottom: 16px; }
.gate input { width: 100%; padding: 12px; border-radius: 8px; border: 1px solid var(--ui-line-dark); background: #0d1018; color: #fff; font: inherit; font-size: 16px; text-align: center; font-variant-numeric: tabular-nums; margin-bottom: 12px; }
.gate .btn { width: 100%; justify-content: center; padding: 12px; font-size: 12px; }
.gate .hint { margin-top: 12px; font-size: 10px; color: var(--color-text-muted); letter-spacing: 0.05em; }

.totals-box { min-width: 280px; font-size: 13px; }
.totals-box .tr { display: flex; justify-content: space-between; padding: 6px 0; color: var(--agc-body); }
.totals-box .tr b, .totals-box .tr span { font-variant-numeric: tabular-nums; }
.totals-box .tr.mut { color: var(--color-text-muted); }
/* Label over value, for a pair whose value is an address list rather than a
   figure — two emails right-aligned against a label that wrapped left four
   ragged edges in a 300px card. */
.totals-box--stack { min-width: 0; }
.totals-box--stack .tr { display: block; padding: 7px 0; text-align: left; }
.totals-box--stack .tr > span:first-child { display: block; font-size: 11px; }
.totals-box--stack .tr > span + span,
.totals-box--stack .tr > span:last-child {
  display: block; margin-top: 2px; text-align: left;
  color: var(--color-text); overflow-wrap: anywhere;
}
.routing-edit { margin-top: 12px; }
/* What each role covers, for somebody who has not been given one. */
.role-list { list-style: none; margin: 4px 0 18px; padding: 0; }
.role-list li {
  padding: 7px 0; font-size: 12.5px; color: var(--color-text-muted);
  border-bottom: 1px solid var(--ui-line-soft);
}
.role-list li b { color: var(--color-text); }

/* ── BUTTONS ────────────────────────────────────────────────────────────── */
/* Sentence case: a button says what it does, and "PASS TO MANAGEMENT" in
   caps reads as a warning rather than the ordinary next step. */
.btn { display: inline-flex; align-items: center; gap: 7px; padding: 9px 16px; border-radius: 8px; border: none; cursor: pointer; font-family: var(--font-sans); font-size: 12.5px; font-weight: 600; letter-spacing: 0; text-transform: none; background: var(--accent-ink); color: var(--color-on-primary); box-shadow: 0 1px 3px rgba(0,0,0,0.1); transition: 0.2s; text-decoration: none; }
.btn svg { width: 14px; height: 14px; }
.btn:hover { filter: brightness(1.1); transform: translateY(-2px); box-shadow: 0 4px 12px rgba(var(--accent-rgb), 0.3); }
.btn:active { transform: translateY(0); box-shadow: 0 1px 3px rgba(var(--accent-rgb), 0.2); }
.btn--secondary { background: var(--agc-dark); filter: none; }
.btn--secondary:hover { background: var(--ui-line-dark); filter: none; box-shadow: 0 4px 12px rgba(25,30,43,0.3); }
.btn--danger { background: var(--agc-red); }
.btn--danger:hover { filter: brightness(1.08); box-shadow: 0 4px 12px rgba(206,39,45,0.3); }
.btn--ghost { background: transparent; color: var(--color-text-muted); box-shadow: inset 0 0 0 1px #d6d5d0; }
.btn--ghost:hover { background: var(--color-surface-alt); transform: none; color: var(--color-text); box-shadow: inset 0 0 0 1px var(--agc-grey); }
.btn.sm, .btn--sm { padding: 6px 11px; font-size: 10px; }
/* One glyph, one square. A remove control was a text button in a flex form
   with no alignment set, so it stretched to the height of a three-line row —
   a 50px pale box floating beside the thing it removes. */
.btn--icon { width: 30px; height: 30px; padding: 0; justify-content: center; font-size: 12px; flex: none; }
.rowacts { display: flex; align-items: flex-start; gap: 6px; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; transform: none !important; box-shadow: none !important; }

/* ── BADGES ─────────────────────────────────────────────────────────────── */
/* A badge is a single token — uppercase, tracked, with a leading dot. Letting
   it wrap splits words down the middle ("SCHEDUL / ED"), which it did in the
   narrow plan row. It shrinks by ellipsis or not at all. */
.badge { display: inline-flex; align-items: center; gap: 5px; font-size: 9px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; padding: 3px 10px; border-radius: 20px; white-space: nowrap; }
.badge::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge--success { background: var(--agc-green-tint); color: var(--agc-green-deep); }
.badge--warning { background: var(--agc-amber-tint); color: var(--amber-ink); }
.badge--danger { background: var(--agc-red-tint); color: var(--danger-ink); }
.badge--muted { background: #eceef0; color: var(--color-text-muted); }

/* ── FORMS ──────────────────────────────────────────────────────────────── */
form.stack { display: flex; flex-direction: column; gap: 4px; max-width: 680px; }
.errsum { background: var(--agc-red-tint); border: 1px solid rgba(206,39,45,0.3); border-left: 3px solid var(--agc-red); border-radius: 8px; padding: 12px 16px; margin-bottom: 20px; font-size: 12.5px; color: var(--agc-red); }
.errsum b { display: block; margin-bottom: 4px; letter-spacing: 0.04em; }
label, .label { font-size: 11px; font-weight: 600; letter-spacing: 0.04em; color: var(--color-text); text-transform: none; }
.label--wide { font-size: 11px; letter-spacing: 0; color: var(--color-text-muted); }
.req { color: var(--danger-ink); margin-left: 2px; }
input, select, textarea { font-family: var(--font-sans); font-size: 13px; color: var(--color-text); padding: 9px 12px; border: 1px solid var(--ui-line); border-radius: 8px; background: var(--color-surface); transition: box-shadow 0.12s, border-color 0.12s; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--agc-green); box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.18); }
/* A ticked box was the browser's blue — the one control in the app that did
   not follow the company's accent, on the screens that set up how money is
   sent. */
input[type=checkbox], input[type=radio] { accent-color: var(--accent-ink); }
input.bad, select.bad { border-color: var(--agc-red); box-shadow: 0 0 0 2px rgba(206,39,45,0.15); }
/* A label column that is 190px whatever the card is. In a 530px card that is
   a third of the width spent on "Last name" and a 200px gap before the box it
   belongs to, which is what reads as text floating away from its field. It
   takes what it needs and no more, and stacks where there is no room for two
   columns at all. */
.formline {
  /* One width for every label in the form, not `max-content` per row: sized
     per row, "New password confirmation" pushed its own box 50px right of the
     one above it and no two fields shared a left edge. Fixed at 190px it was
     a third of a narrow card spent on "Last name", with the box stranded from
     its label. This scales with the card and stays the same down the form. */
  display: grid; grid-template-columns: clamp(110px, 26%, 170px) minmax(0, 1fr);
  gap: 8px 16px; align-items: start; padding: 7px 0;
}
@media (max-width: 560px) { .formline { grid-template-columns: minmax(0, 1fr); } }
.formline > label { padding-top: 9px; }
/* Every box in a form is the same width. They were whatever the browser makes
   a text input — about 210px — while the help text under them ran the full
   width of the card, so each hint stuck out past the box it explains and no
   two fields shared a right edge. The cap keeps a name field from becoming a
   900px box on a wide card. */
.formline > input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]),
.formline > select,
.formline > textarea,
.formline > div > input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=button]),
.formline > div > select,
.formline > div > textarea { width: 100%; max-width: 440px; }
.formline > div { min-width: 0; }
.formline .help, .fe { font-size: 11px; color: var(--color-text-muted); margin-top: 5px; max-width: 440px; }
.fe { color: var(--agc-red); }
.actions { display: flex; gap: 10px; margin: 18px 0; flex-wrap: wrap; align-items: center; }
/* A published-sheet link is 90-odd characters, and the default input is about
   twenty. Truncated, there is no way to see whether the thing pasted in is the
   CSV link or the one from the address bar — which is the mistake this page
   exists to catch. */
.sheet-page .formline input[type=url] { width: 100%; }
/* What the last read of the sheet did: a heading per tab, and the changes
   under it. Flat, they read as one run of unrelated sentences. */
.sync-report { list-style: none; margin: 10px 0 0; padding: 0; }
.sync-report li { font-size: 13px; font-weight: 600; padding: 5px 0; }
.sync-report .is-detail {
  font-size: 12px; font-weight: 400; color: var(--color-text-muted);
  padding-left: 16px; border-left: 2px solid var(--ui-line-soft); margin-left: 3px;
}
.sync-report .is-problem { color: var(--amber-ink); font-weight: 600; }

/* The way in to Settlement. Deliberately the only thing on the page until
   the PIN is entered: a queue of amounts is itself worth something to
   whoever is standing at the screen the PIN is there for. */
/* The lock card. One alignment, not three: the mark was centred, the heading
   left with a full-width rule under it, and the paragraph centred again — so
   nothing in a 460px card shared an edge and the text read as floating. It is
   a focal card with one thing to do, so everything in it centres. */
.pinbox { max-width: 460px; margin: 40px auto; text-align: center; }
.pinbox-mark { width: 34px; height: 34px; color: var(--accent-ink); margin-bottom: 10px; }
.pinbox h2 {
  display: block; justify-content: center; margin-bottom: 8px;
  padding-bottom: 0; border-bottom: 0; text-align: center;
}
.pinbox p { margin: 0 auto 18px; max-width: 34ch; }
.pinbox .formline { text-align: left; }
.pinbox .pinform { justify-content: center; }
.pinbox .actions { justify-content: center; }
.pinform { display: flex; gap: 10px; justify-content: center; margin: 14px 0 10px; }
/* The transfers a payment is waiting on, in the action panel. Listed rather
   than counted: on a split invoice these are separate transfers on separate
   days, and which one is waiting is the thing you need. */
/* Which site you are on. Loud on purpose and never on the live one: the
   whole risk of a staging copy is that it is convincing. */
.deployment-band {
  background: var(--agc-amber-tint); color: var(--amber-ink);
  border-bottom: 2px solid var(--agc-amber);
  font-size: 12px; font-weight: 700; letter-spacing: .02em;
  padding: 6px clamp(16px, 3vw, 44px); text-align: center;
}
.deployment-band b { letter-spacing: .12em; }

.seen-invoice { margin-bottom: 14px; }
/* A toast about a payment is the way back to it. The whole line is the
   target, not just the number, because a toast is on screen for twelve
   seconds and a five-character link inside it is not something anybody
   catches in time. */
.toast-go {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  flex: 1 1 auto; min-width: 0; color: inherit; text-decoration: none;
}
.toast-go i {
  font-style: normal; font-weight: 600; white-space: nowrap;
  color: var(--accent-ink); text-decoration: underline;
}
.toast.err .toast-go i { color: var(--danger-ink); }
.totals-box .is-overdue { color: var(--danger-ink); }

.await-lines { list-style: none; margin: 0 0 14px; padding: 0; }
.await-lines li {
  font-size: 12px; color: var(--color-text-muted); padding: 6px 0;
  border-bottom: 1px solid var(--ui-line-soft);
}
.await-lines li:last-child { border-bottom: 0; }

/* The decision on a release row: the button, and the two other answers folded
   away under it.

   One column of one width, and every cell in the row starts at the top. With
   the fold open the row grows to 250px, and cells that centre their contents
   left the payment number floating in the middle of it while the button sat
   at the top — the two things a person reads together, a screen apart. */
.settlement-page table.data td,
.settlement-page table.data th { vertical-align: top; }
.line-decide {
  display: flex; flex-direction: column; align-items: stretch; gap: 6px;
  width: 210px; margin-left: auto; text-align: left;
}
.line-decide .btn { width: 100%; justify-content: center; }
.line-decide .muted { font-size: 11px; }
.line-more > summary {
  cursor: pointer; color: var(--color-text-muted); font-size: 11px;
  list-style: none; padding: 2px 0;
}
.line-more > summary::-webkit-details-marker { display: none; }
.line-more > summary::before { content: "▸ "; }
.line-more[open] > summary::before { content: "▾ "; }
.line-more .stack { margin-top: 8px; display: grid; gap: 8px; }
.line-more label { display: block; font-size: 11px; }
.line-more textarea { width: 100%; }

/* The approvals queue. A change carries names, so the names are the row's
   own line rather than a column that is empty on half of them. */
.approval-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 14px; flex-wrap: wrap;
}
.approval-head b { display: block; margin-top: 4px; }
.sig-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.sig {
  font-size: 11px; color: var(--accent-ink);
  border: 1px solid var(--color-border); border-radius: 999px;
  padding: 3px 10px;
}
.approval-actions {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin-top: 14px; padding-top: 14px;
  border-top: 1px solid var(--ui-line-soft);
}
.approval-actions input { flex: 1 1 220px; min-width: 0; }
.pinform input {
  width: 150px; text-align: center; letter-spacing: .5em; font-size: 18px;
  padding: 10px 12px 10px 17px;
}

/* ── MESSAGES / TOASTS ──────────────────────────────────────────────────── */
.messages { margin-bottom: 20px; }
.msg { padding: 12px 16px; border-radius: 8px; margin-bottom: 8px; font-size: 13px; background: var(--color-surface); border: 1px solid var(--color-border); border-left: 3px solid var(--agc-slate); box-shadow: var(--shadow-sm); }
.msg--warning { border-left-color: var(--agc-amber); color: var(--amber-ink);
  background: var(--color-warning-bg); }
.msg--error { border-left-color: var(--agc-red); color: var(--danger-ink);
  background: var(--color-danger-bg); }

.toast-wrap { position: fixed; bottom: 24px; right: 24px; display: flex; flex-direction: column; gap: 10px; z-index: 80; }
.toast { background: var(--color-surface); border: 1px solid var(--color-border); border-left: 3px solid var(--agc-green); border-radius: 8px; box-shadow: var(--shadow-lg); padding: 12px 16px 12px 14px; display: flex; align-items: center; gap: 10px; font-size: 12.5px; min-width: 280px; animation: slidein 0.25s ease; }
.toast.warn { border-left-color: var(--agc-amber); }
.toast.err { border-left-color: var(--agc-red); }
.toast .tk { width: 22px; height: 22px; border-radius: 50%; background: var(--agc-green-tint); color: var(--agc-green-deep); display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 12px; }
@keyframes slidein { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: none; } }
@keyframes sk { to { background-position: -200% 0; } }
.htmx-indicator { opacity: 0; transition: opacity 0.2s; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; }

/* ── LOGIN ──────────────────────────────────────────────────────────────── */
.login-wrap {
  display: flex; align-items: center; justify-content: center;
  min-height: calc(100vh - 5px); padding: 6vh 20px; position: relative; overflow: hidden;
  background:
    radial-gradient(ellipse at 15% 8%, rgba(35,170,8,0.16), transparent 45%),
    radial-gradient(ellipse at 85% 92%, rgba(70,184,46,0.10), transparent 50%),
    linear-gradient(160deg, #1c2233, var(--agc-dark) 55%, #12151e);
}
/* Subtle repeating hexagon motif, echoes the brand mark. Inline SVG data-uri, no asset. */
.login-wrap::before {
  content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0.5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='84' height='96' viewBox='0 0 84 96'%3E%3Cpolygon points='42,2 80,24 80,72 42,94 4,72 4,24' fill='none' stroke='%23ffffff' stroke-opacity='0.035' stroke-width='1.5'/%3E%3C/svg%3E");
  background-position: 0 0, 42px 48px;
}
.login-card {
  width: 380px; display: flex; flex-direction: column; gap: 14px; position: relative; overflow: hidden;
  z-index: 1; box-shadow: var(--shadow-lg); border: 1px solid rgba(255,255,255,0.06);
}
.login-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: var(--gradient-accent); }
.login-card form { display: flex; flex-direction: column; gap: 10px; }
.login-card h1 { margin-bottom: 0; font-size: 20px; }
.wordmark { font-weight: 900; letter-spacing: -0.02em; font-size: 22px; color: var(--agc-green-deep); }
.wordmark span { color: var(--color-text); font-weight: 300; letter-spacing: 0.12em; font-size: 13px; }
.wordmark--dark { color: var(--agc-green-deep); }
.wordmark--dark span { color: var(--color-text); }
code { background: var(--color-surface-alt); border: 1px solid var(--color-border); padding: 1px 7px; border-radius: 4px; font-size: 0.85em; }
.muted { color: var(--color-text-muted); }
p { line-height: 1.6; }
p.muted { font-size: 13px; margin-bottom: 14px; }

/* ── FOCUS / SCROLLBAR / MOTION ─────────────────────────────────────────── */
:focus-visible { outline: 2px solid var(--agc-green); outline-offset: 2px; border-radius: 4px; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: var(--agc-canvas); }
::-webkit-scrollbar-thumb { background: var(--agc-grey); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--agc-slate); }
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } }
@supports not (font-variation-settings: normal) { body { font-family: Arial, Helvetica, sans-serif; } }

/* ── RESPONSIVE ─────────────────────────────────────────────────────────── */
@media (max-width: 1000px) {
  .grid-2, .flow { grid-template-columns: 1fr; }
}
/* Collapsing the sidebar into a horizontal strip is a *mobile* layout, so it
   has to switch at the same width as the mobile chrome in preview-theme.css
   (760px). While this said 820px, widths of 761–820px got the desktop topbar
   and the mobile sidebar at once: the nav, the New payment button and the
   account footer were reordered into a wrapped row inside a column that was
   still styled as a dark desktop rail. */
@media (max-width: 760px) {
  .shell { grid-template-columns: 1fr; }
  .sidebar { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 4px 6px; padding: 10px 12px; }
  .sidebar::after { display: none; }
  .brand-lockup { padding: 0 8px 0 4px; }
  .new-btn { margin: 0; order: 3; padding: 8px 12px; }
  .nav { flex-direction: row; flex-wrap: wrap; width: 100%; order: 5; margin-top: 4px; }
  .nav a { border-left: none; border-bottom: 3px solid transparent; padding: 7px 10px; font-size: 10px; letter-spacing: 0.05em; }
  .nav a.active { border-bottom-color: var(--agc-green); }
  .nav a .count, .nav .nav-section { display: none; }
  .sidebar-foot { order: 4; margin: 0 0 0 auto; border-top: 0; padding: 0; }
  .pagehead { padding: 14px 16px; position: static; }
  .body { padding: 18px 14px 40px; }
  .formline { grid-template-columns: 1fr; gap: 4px; }
  h1, .ph-row h1 { font-size: 20px; }
}
@media (max-width: 480px) {
  .card { padding: 16px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   PAYMASTER — payment panel, split plan, spacing corrections
   ══════════════════════════════════════════════════════════════════════════ */

/* The detail layout. The action column needs about 340px for its inputs; past
   that, the width belongs to the left column, because that is where the plan
   table lives and the table is the thing that runs out of room first. At
   1.45fr the plan needed ~700px in a ~577px card and scrolled sideways on a
   full-width desktop. The action panel still lands around 360px here. */
.flow { grid-template-columns: minmax(0, 2fr) minmax(320px, 1fr); gap: 22px; }
@media (max-width: 1100px) { .flow { grid-template-columns: 1fr; } }

.card > h2:first-child { margin-top: 0; }
/* The line under a card heading that says what the card is for. It sat 14px
   below the heading's rule, far enough that it read as the first item in the
   card rather than as part of the heading, so nineteen templates pulled it
   back up with an inline `margin-top:-6px`. One rule instead, and it is
   measured for reading rather than for the card's width. */
.card > h2 + p.muted, .card > h2 + p.lede,
.card > .card-head + p.muted { margin: -6px 0 14px; max-width: 68ch; }
/* Prose is measured for reading, not stretched to the card. A paragraph run
   across a 1080px card is three times the line length anybody reads at. */
.card > p { max-width: 78ch; }
/* And a card holding nothing but a one-column form is measured the same way:
   `form.stack` is capped at 680px, so a full-width card left 400px of white
   to the right of every field on the page. */
.companies-page .card { max-width: 820px; }
/* The name is what the row is looked up by, and it was the one column the
   table would not give room to: "Guangzhou Appliance Mfg." broke over three
   lines beside a destination column with 200px to spare. */
.vendors-page table.data th:first-child,
.vendors-page table.data td:first-child { min-width: 190px; }

/* ── Outstanding strip ─────────────────────────────────────────────────── */
.outstanding {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  background: var(--color-surface-alt); border: 1px solid var(--color-border);
  border-radius: 8px; padding: 10px 14px; margin-bottom: 14px; font-size: 12.5px;
  color: var(--color-text-muted);
}
.outstanding b {
  font-size: 17px; font-weight: 800; color: var(--color-text);
  letter-spacing: -0.01em; font-variant-numeric: tabular-nums;
}
.outstanding .of { margin-left: auto; }

.btn--block { width: 100%; justify-content: center; }

/* ── Payment form: consistent vertical rhythm, full-width controls ──────── */
.pay-form { display: flex; flex-direction: column; gap: 14px; margin-top: 14px; }
.pay-form .fld { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pay-form .fld > label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em; color: var(--color-text);
}
.pay-form input, .pay-form select { width: 100%; max-width: 100%; }
.pay-form .help, .hint { font-size: 11px; color: var(--color-text-muted); line-height: 1.5; }
.hint { margin: 0; }
/* A hint that is reporting an error. It was written as an inline colour on
   each of the three fields that could raise one. */
/* "Reject / return" — the one destructive route out of a review. */
/* Sentence case, like every other control. Shouted in red it read as a
   warning about the payment rather than as a way to send it back. */
.reject-open {
  cursor: pointer; font-size: 12px; font-weight: 600;
  letter-spacing: 0; text-transform: none; color: var(--danger-ink);
}
.pay-form .btn { margin-top: 2px; }

/* ── Split builder ─────────────────────────────────────────────────────── */
.split-build { display: flex; flex-direction: column; gap: 14px; margin-top: 14px; }
.split-build .fld { display: flex; flex-direction: column; gap: 6px; }
.split-build .fld > label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em; color: var(--color-text);
}
.split-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.split-table th {
  text-align: left; font-size: 9px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--color-text-muted); font-weight: 700; padding: 0 6px 8px 0;
}
.split-table td { padding: 0 6px 8px 0; vertical-align: middle; }
.split-table td:last-child, .split-table th:last-child { padding-right: 0; }
.split-table .seq {
  width: 22px; color: var(--color-text-muted); font-weight: 700; font-size: 11px;
}
.split-table input { width: 100%; padding: 7px 9px; font-size: 12.5px; }

.split-total {
  font-size: 11.5px; font-weight: 600; border-radius: 8px; padding: 8px 11px;
  line-height: 1.45;
}
.split-total.is-ok { background: var(--agc-green-tint); color: var(--agc-green-deep); }
.split-total.is-off { background: var(--agc-amber-tint); color: var(--amber-ink); }

.btn-row { display: flex; flex-direction: column; gap: 8px; }

/* ── Inline "pay this instalment" row inside the plan table ─────────────── */
tr.line-pay > td { background: var(--color-surface-alt); padding: 0; }
.line-pay-inner { padding: 14px 16px 18px; max-width: 420px; }
.line-pay-head {
  font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  font-weight: 700; color: var(--agc-green-deep); 
}
.line-pay-inner .pay-form { margin-top: 10px; }

/* ── Secondary action block (bank instruction) ─────────────────────────── */
.sub-action {
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--color-border-row);
  display: flex; flex-direction: column; gap: 0;
}
.mt { margin-top: 12px; }
.mt-s { margin-top: 8px; }
.sub-action .hint { margin-top: 8px; }
/* It is a card of its own now, not a block bolted to the bottom of another. */
.card.sub-action { margin-top: 0; padding-top: 22px; border-top: 0; }

/* A field showing a value rather than asking for one — the beneficiary when
   the vendor has exactly one authorised destination. Not `disabled`: a
   disabled select submits nothing, and the payment needs the number. */
select.is-locked {
  background-color: var(--color-surface-alt); color: var(--ui-ink-muted);
  pointer-events: none; background-image: none;
}

/* ── Action panel ──────────────────────────────────────────────────────────
   The heading names the step — "Approve", "Record the payment" — so the lead
   line under it can be the one sentence saying what pressing the button does,
   in ink rather than the grey used for asides. A panel that carries no button
   says who it is waiting on instead of going blank.
   ------------------------------------------------------------------------ */
.act > h2 { margin-bottom: 6px; }
.act-lead {
  margin: 0 0 14px; font-size: 12.5px; line-height: 1.55; color: var(--color-text-body);
}
.act-lead b { font-weight: 700; color: var(--color-text); }
.act > form .btn { text-align: center; }
.act-wait, .act-done {
  display: flex; gap: 11px; align-items: flex-start;
  border-radius: 10px; padding: 12px 14px;
  background: var(--color-surface-alt); border: 1px solid var(--ui-line-soft);
}
.act-wait svg { width: 17px; height: 17px; flex: none; margin-top: 1px; color: var(--ui-ink-faint); }
.act-done { background: var(--agc-green-tint); border-color: transparent; }
.act-done .ck { color: var(--agc-green-deep); font-weight: 800; }
.act-wait b, .act-done b { display: block; font-size: 12.5px; color: var(--color-text); }
.act-wait span, .act-done span:not(.ck) {
  display: block; margin-top: 3px; font-size: 11.5px; line-height: 1.5; color: var(--ui-ink-muted);
}

/* ── Detail summary rows: stop long values colliding with their label ──── */
.totals-box .tr { gap: 18px; align-items: baseline; }
.totals-box .tr > span:last-child { text-align: right; word-break: break-word; }

/* Plan table: keep the action column tight against the right edge. */
table.data td.qa { width: 1%; white-space: nowrap; }

/* Plan table: dates and amounts on one line, with room before the Pay button
   so the button can never clip the figure next to it. */
table.data.plan td:nth-child(3) { white-space: nowrap; }
table.data.plan td.num, table.data.plan th.num { white-space: nowrap; padding-right: 8px; }
/* The shared .qa cell is display:flex, which stops the browser allocating a
   real column and lets the button overlap the amount. Restore a table cell and
   let it shrink-to-fit so the plan still fits the card without scrolling. */
table.data.plan th, table.data.plan td { padding-left: 7px; padding-right: 7px; }
table.data.plan td.qa, table.data.plan th:last-child {
  display: table-cell; width: 1%; white-space: nowrap;
  text-align: right; padding-left: 14px;
}
table.data.plan td.qa .btn { padding: 5px 10px; }
/* Seven columns of unbreakable content came to ~700px in a ~577px card, so the
   plan scrolled sideways on a full-width desktop. The reference is the only
   cell long enough to matter and the only one safe to break, so it wraps and
   the rest of the row keeps its single line. */
/* `anywhere` rather than `break-all`: the reference stays on one line whenever
   it fits and only splits when the column genuinely cannot hold it. Either way
   it stops contributing a minimum width, which is what let the table shrink. */
table.data.plan td.plan-reference code { white-space: normal; overflow-wrap: anywhere; }
/* Being the only breakable cell made it the only one the browser could take
   width from, so it was starved to ~98px and split "MP2407.9911.X" across two
   lines while every other column kept its full width. It gives way, but not
   below the width of a reference. */
table.data.plan th:nth-child(5),
table.data.plan td.plan-reference { min-width: 118px; }
table.data.plan td.plan-status .badge { padding-left: 6px; padding-right: 6px; }
/* The wallet a MoMo disbursement credited, under its reference — a second
   line, so it never widens the Reference column. */
table.data.plan td.plan-reference .plan-momo {
  font-size: 11px; color: var(--color-text-muted); margin-top: 3px; overflow-wrap: anywhere;
}

/* ── Stacked form field (login) ─────────────────────────────────────────────
   `.field` was used in the login template but never styled, so the label sat
   inline with the input and the two boxes ended up different widths. */
.field { display: flex; flex-direction: column; gap: 6px; }
.field > label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em; color: var(--color-text);
}
.field input, .field select, .field textarea { width: 100%; }

.login-card form { gap: 14px; }
.login-card h1 { margin-bottom: 2px; }

/* ── SIDEBAR COUNTS ─────────────────────────────────────────────────────── */
/* Pushed to the right of the nav row so the numbers line up in a column and
   read as a queue rather than as part of each label. */
.nav a { position: relative; }
.nav-count {
  margin-left: auto; min-width: 22px; padding: 1px 7px; border-radius: 999px;
  font-size: 11px; font-weight: 700; line-height: 1.55; text-align: center;
  letter-spacing: 0; flex-shrink: 0;
}
.nav-count--alert { background: var(--agc-red); color: #fff; }
.nav-count--muted { background: var(--chrome-line); color: var(--chrome-ink); }
.nav a.active .nav-count--muted { background: rgba(var(--accent-rgb), 0.22); color: var(--chrome-ink); }

/* ── NOTIFICATION POP-UPS ───────────────────────────────────────────────── */
/* Reuses .toast-wrap / .toast so alerts sit in the same bottom-right stack as
   action confirmations instead of competing with them. */
.toast--note { cursor: pointer; align-items: flex-start; }
.toast--note .tk { background: var(--agc-navy-tint, rgba(25, 30, 43, 0.08)); color: var(--agc-navy, #191e2b); }
.toast--note.err .tk { background: var(--agc-red-tint, rgba(206, 39, 45, 0.1)); color: var(--agc-red); }
.toast--note b { display: block; font-size: 12.5px; margin-bottom: 2px; }
.toast--note .sub { color: var(--color-text-muted, var(--ui-ink-muted)); font-size: 11px; line-height: 1.45; }
.toast--note .x {
  margin-left: 8px; opacity: 0.4; font-size: 14px; line-height: 1;
  background: none; border: 0; cursor: pointer; padding: 0 2px;
}
.toast--note .x:hover { opacity: 0.9; }

/* ── LOGS ───────────────────────────────────────────────────────────────── */
.logtabs { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 10px; margin-bottom: 16px; }
.logtab {
  display: block; padding: 12px 14px; border: 1px solid var(--color-border);
  border-radius: 12px; background: var(--color-surface); text-decoration: none; color: inherit;
  border-left: 3px solid transparent; transition: border-color .15s, box-shadow .15s;
}
.logtab:hover { box-shadow: var(--shadow-sm, 0 1px 3px rgba(0,0,0,.06)); }
.logtab.is-on { border-left-color: var(--agc-green); box-shadow: var(--shadow-sm, 0 1px 3px rgba(0,0,0,.06)); }
.logtab b { display: block; font-size: 13px; margin-bottom: 2px; }
.logtab span { display: block; font-size: 11px; color: var(--color-text-muted, var(--ui-ink-muted)); line-height: 1.4; }

/* The search sits on the list it searches. On the canvas above it, with the
   table carrying its own white surface underneath, the box and the count
   floated on the page background with nothing holding them. */
.logbar {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-bottom: 0; padding: 14px 16px;
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-bottom: 0; border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.logbar + .tbl-wrap { border-top-left-radius: 0; border-top-right-radius: 0; }
.logbar-q { flex: 1 1 240px; min-width: 200px; }
.logbar-count { margin-left: auto; font-size: 11.5px; color: var(--color-text-muted, var(--ui-ink-muted)); }

/* Date over time keeps the column narrow without losing either. */
.logtime { white-space: nowrap; font-size: 12px; }
.logtime span { display: block; font-size: 11px; color: var(--color-text-muted, var(--ui-ink-muted)); }
.logmsg { font-size: 12.5px; line-height: 1.5; }
.logdim { font-size: 11px; color: var(--color-text-muted, var(--ui-ink-muted)); font-family: var(--font-mono, monospace); }
.logempty { text-align: center; padding: 28px 0; color: var(--color-text-muted, var(--ui-ink-muted)); font-size: 12.5px; }
.logrow--flag { background: var(--agc-red-tint, rgba(206,39,45,.05)); }
.logflag {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border-radius: 50%; margin-right: 6px;
  background: var(--agc-red); color: #fff; font-size: 10px; font-weight: 700;
}
.logpage { display: flex; align-items: center; gap: 12px; justify-content: center; margin-top: 16px; }

/* Sortable column headers. */
/* 12px of text in a table head; the cell has room for a 24px target. */
.sortlink { color: inherit; text-decoration: none; display: inline-flex;
  align-items: center; gap: 4px; min-height: 24px; }
.sortlink span { opacity: 0.25; font-size: 10px; }
.sortlink:hover span { opacity: 0.6; }
.sortlink.is-on span { opacity: 1; color: var(--chrome-accent-ink); }
.recent-table { box-shadow: none; }
.mobile-dashboard-bar,
.mobile-nav-scrim,
.mobile-sidebar-close,
.mobile-bottom-nav { display: none; }
@media (max-width: 760px) {
  .dashboard-page .sidebar {
    flex-wrap: nowrap; min-width: 0; padding: 8px 12px; gap: 8px;
  }
  .dashboard-page .brand-lockup { flex-shrink: 0; }
  .dashboard-page .brand-lockup svg { width: 28px; height: 28px; }
  .dashboard-page .brand-name { font-size: 15px; }
  .dashboard-page .new-btn,
  .dashboard-page .sidebar-foot { display: none; }
  .dashboard-page .nav {
    order: 2; width: auto; min-width: 0; flex: 1; margin: 0;
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
  }
  .dashboard-page .nav::-webkit-scrollbar { display: none; }
  .dashboard-page .nav a { flex: 0 0 auto; white-space: nowrap; }
  .dashboard-page .pagehead { padding: 10px 14px 11px; }
}
@media (max-width: 560px) {
  body.dashboard-page {
    background: var(--agc-canvas); overflow-x: hidden; padding-bottom: 72px;
  }
  .dashboard-page .accent-bar { display: none; }
  .mobile-dashboard-bar {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto;
    align-items: center; gap: 10px; height: 58px; padding: 0 14px;
    position: sticky; top: 0; z-index: 60; background: var(--color-surface);
    border-bottom: 1px solid var(--color-border); box-shadow: var(--shadow-sm);
  }
  .mobile-menu-button,
  .mobile-new-request {
    width: 36px; height: 36px; border-radius: 8px; display: inline-flex;
    align-items: center; justify-content: center; border: 1px solid var(--color-border);
    background: var(--color-surface); color: var(--color-text); text-decoration: none;
  }
  .mobile-menu-button { cursor: pointer; }
  .mobile-menu-button svg,
  .mobile-new-request svg { width: 18px; height: 18px; }
  .mobile-new-request { color: var(--color-on-primary); background: var(--accent-ink); border-color: var(--accent-ink); }
  .mobile-brand {
    min-width: 0; display: flex; align-items: center; gap: 8px;
    color: var(--color-text); text-decoration: none; font-size: 16px; font-weight: 800;
  }
  .mobile-brand svg { width: 26px; height: 26px; color: var(--color-text); flex-shrink: 0; }
  .mobile-brand svg polygon:nth-child(2) { fill: var(--agc-green); }
  .mobile-brand .brand-mark { height: 22px; max-width: 46px; padding: 3px; border-radius: 5px; }
  .mobile-brand > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .mobile-brand > span span { color: var(--agc-green-deep); }
  .mobile-module {
    color: var(--color-text-muted); background: var(--color-surface-alt);
    border: 1px solid var(--color-border); border-radius: 20px;
    padding: 4px 8px; font-size: 9px; font-weight: 700; letter-spacing: 0.08em;
  }
  .dashboard-page .shell { display: block; min-height: 0; }
  .dashboard-page .sidebar {
    display: flex; position: fixed; inset: 0 auto 0 0; z-index: 80;
    width: min(84vw, 320px); height: 100dvh; padding: 22px 0 18px;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--gradient-chrome); transform: translateX(-105%);
    transition: transform 0.22s ease; overflow-y: auto;
    box-shadow: var(--shadow-lg);
  }
  .dashboard-page .mobile-sidebar-close {
    display: inline-flex; position: absolute; top: 16px; right: 16px; z-index: 2;
    width: 34px; height: 34px; align-items: center; justify-content: center;
    border: 1px solid var(--chrome-line); border-radius: 8px; background: var(--chrome-close-bg);
    color: var(--chrome-ink); cursor: pointer;
  }
  .dashboard-page .mobile-sidebar-close svg { width: 17px; height: 17px; }
  .dashboard-page.mobile-nav-open .sidebar { transform: translateX(0); }
  .dashboard-page .sidebar::after { display: block; }
  .dashboard-page .brand-lockup { padding: 0 18px 2px; }
  .dashboard-page .brand-lockup svg { width: 34px; height: 34px; }
  .dashboard-page .brand-name { font-size: 17px; }
  .dashboard-page .new-btn,
  .dashboard-page .sidebar-foot { display: flex; }
  .dashboard-page .new-btn { margin: 14px 16px 6px; order: initial; }
  .dashboard-page .nav {
    order: initial; width: auto; min-width: 0; flex: 1; margin-top: 4px;
    flex-direction: column; flex-wrap: nowrap; overflow: visible;
  }
  .dashboard-page .nav a {
    flex: 0 0 auto; border-left: 3px solid transparent; border-bottom: 0;
    padding: 10px 18px 10px 21px; font-size: 11px;
  }
  .dashboard-page .nav a.active { border-left-color: var(--agc-green); }
  .dashboard-page .nav .nav-section { display: block; }
  .dashboard-page .sidebar-foot {
    order: initial; margin: 14px 12px 0; padding: 14px 6px 0;
    border-top: 1px solid var(--chrome-line-soft);
  }
  .mobile-nav-scrim {
    position: fixed; inset: 0; z-index: 70; width: 100%; height: 100%;
    border: 0; background: rgba(15, 20, 30, 0.55); cursor: pointer;
  }
  .dashboard-page.mobile-nav-open .mobile-nav-scrim { display: block; }
  .dashboard-page.mobile-nav-open { overflow: hidden; }
  .dashboard-page .pagehead {
    position: static; padding: 14px; box-shadow: none; background: var(--color-surface);
  }
  /* The head's actions live in .ph-actions. They were addressed here as
     direct children of .ph-row, which is where they sat before the head was
     given one shape across every page — so none of this applied any more and
     the module chips rendered at full size inside a head clipped to 52px,
     showing as two slivers behind the card below it. */
  .dashboard-page .ph-row { display: grid; grid-template-columns: 1fr auto; gap: 10px; align-items: center; }
  .dashboard-page .ph-row > .ph-title { min-width: 0; }
  .dashboard-page .ph-row h1 { font-size: 22px; }
  .dashboard-page .ph-row > .ph-actions {
    display: contents;
  }
  .dashboard-page .ph-actions > .chips {
    grid-column: 1 / -1; grid-row: 2; display: grid; grid-template-columns: 1fr 1fr;
    width: 100%; gap: 7px;
  }
  .dashboard-page .ph-actions > .chips .chip { text-align: center; padding: 8px 7px; }
  .dashboard-page .ph-actions > .btn { grid-column: 2; grid-row: 1; }
  .recent-table { overflow: visible; border: 0; background: transparent; }
  .recent-table table.data,
  .recent-table tbody { display: block; background: transparent; }
  .recent-table thead { display: none; }
  .recent-table table.data tr {
    display: grid; grid-template-columns: 1fr auto; gap: 7px 12px;
    padding: 12px 0; border-bottom: 1px solid var(--color-border-row);
  }
  .recent-table table.data tr:first-child { padding-top: 2px; }
  .recent-table table.data tr:last-child { border-bottom: 0; padding-bottom: 0; }
  .recent-table table.data td {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 0; border: 0; background: transparent !important; white-space: normal;
  }
  .recent-table table.data td::before {
    content: attr(data-label); color: var(--color-text-muted); font-size: 9px;
    letter-spacing: 0.08em; text-transform: uppercase;
  }
  .recent-table table.data td:nth-child(1),
  .recent-table table.data td:nth-child(2) { grid-column: 1; }
  .recent-table table.data td:nth-child(3),
  .recent-table table.data td:nth-child(5) { grid-column: 2; }
  .recent-table table.data td:nth-child(3) { grid-row: 1; }
  .recent-table table.data td:nth-child(5) { grid-row: 2; }
  .recent-table table.data td:nth-child(4) { grid-column: 1 / -1; }
  .recent-table table.data td:nth-child(1)::before,
  .recent-table table.data td:nth-child(2)::before,
  .recent-table table.data td:nth-child(3)::before,
  .recent-table table.data td:nth-child(5)::before { display: none; }
  .recent-table table.data td.num { text-align: right; }
  .mobile-bottom-nav {
    display: grid; grid-template-columns: repeat(5, 1fr); align-items: end;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 55;
    height: 64px; padding: 7px 8px max(7px, env(safe-area-inset-bottom));
    background: rgba(255, 255, 255, 0.96); border-top: 1px solid var(--color-border);
    box-shadow: 0 -6px 18px rgba(25, 30, 43, 0.08);
    backdrop-filter: blur(12px);
  }
  .mobile-bottom-nav a {
    min-width: 0; color: var(--color-text-muted); text-decoration: none;
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    font-size: 9px; font-weight: 600;
  }
  .mobile-bottom-nav a.active { color: var(--agc-green-deep); }
  .mobile-bottom-nav svg { width: 19px; height: 19px; }
  .mobile-bottom-nav .mobile-bottom-create {
    width: 46px; height: 46px; justify-self: center; align-self: center;
    border-radius: 16px; background: var(--accent-ink); color: var(--color-on-primary);
    justify-content: center; transform: translateY(-10px);
    box-shadow: 0 8px 18px rgba(var(--accent-rgb), 0.26);
  }
  .mobile-bottom-create svg { width: 22px; height: 22px; }
  .mobile-bottom-create span { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE APP SHELL — shared across every authenticated Paymaster screen
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 560px) {
  body.app-shell {
    min-width: 0; overflow-x: hidden; padding-bottom: 72px;
    background: var(--agc-canvas);
  }
  .app-shell .accent-bar { display: none; }
  .app-shell .shell { display: block; min-height: 0; }

  /* One compact header, with the desktop navigation converted to a drawer. */
  .app-shell .mobile-dashboard-bar { display: grid; }
  .app-shell .sidebar {
    display: flex; position: fixed; inset: 0 auto 0 0; z-index: 80;
    width: min(84vw, 320px); height: 100dvh; padding: 22px 0 18px;
    flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 0;
    background: var(--gradient-chrome); transform: translateX(-105%);
    transition: transform 0.22s ease; overflow-y: auto; box-shadow: var(--shadow-lg);
  }
  .app-shell.mobile-nav-open .sidebar { transform: translateX(0); }
  .app-shell.mobile-nav-open .mobile-nav-scrim { display: block; }
  .app-shell.mobile-nav-open { overflow: hidden; }
  .app-shell .sidebar::after { display: block; }
  .app-shell .mobile-sidebar-close {
    display: inline-flex; position: absolute; top: 16px; right: 16px; z-index: 2;
    width: 34px; height: 34px; align-items: center; justify-content: center;
    border: 1px solid var(--chrome-line); border-radius: 8px; background: var(--chrome-close-bg);
    color: var(--chrome-ink); cursor: pointer;
  }
  .app-shell .mobile-sidebar-close svg { width: 17px; height: 17px; }
  .app-shell .brand-lockup { padding: 0 56px 2px 18px; }
  .app-shell .brand-lockup svg { width: 34px; height: 34px; }
  .app-shell .brand-name { font-size: 17px; }
  .app-shell .new-btn {
    display: flex; margin: 14px 16px 6px; order: initial; padding: 10px;
  }
  .app-shell .nav {
    order: initial; width: auto; min-width: 0; flex: 1; margin-top: 4px;
    flex-direction: column; flex-wrap: nowrap; overflow: visible;
  }
  .app-shell .nav a {
    flex: 0 0 auto; border-left: 3px solid transparent; border-bottom: 0;
    padding: 10px 18px 10px 21px; font-size: 11px;
  }
  .app-shell .nav a.active,
  .app-shell .nav a[aria-current="page"] { border-left-color: var(--agc-green); }
  .app-shell .nav .nav-section { display: block; }
  .app-shell .sidebar-foot {
    display: flex; order: initial; margin: 14px 12px 0; padding: 14px 6px 0;
    border-top: 1px solid var(--chrome-line-soft);
  }

  /* Page titles and contextual actions stay visible without a second toolbar. */
  .app-shell .pagehead {
    position: static; padding: 12px 12px 11px; box-shadow: none; background: var(--color-surface);
  }
  .app-shell .ph-row {
    display: flex; align-items: flex-start; gap: 8px; flex-wrap: wrap;
  }
  .app-shell .ph-row h1 { margin: 0; font-size: 20px; line-height: 1.12; }
  .app-shell .ph-title { flex: 1 1 100%; min-width: 0; }
  .app-shell .ph-actions { width: 100%; margin-left: 0; }
  .app-shell .ph-actions .chips {
    display: grid; grid-template-columns: 1fr 1fr; width: 100%; gap: 7px;
  }
  .app-shell .ph-actions .chips .chip { padding: 8px 7px; text-align: center; }
  .app-shell .ph-actions .btn { min-height: 36px; padding: 8px 11px; }
  .app-shell .ph-actions a[href*="/requests/new/"] { display: none; }
  .app-shell .body { padding: 10px 10px 18px; min-width: 0; }

  /* Dense vertical rhythm: preserve content, remove desktop whitespace. */
  .app-shell .card { padding: 14px; border-radius: 12px; }
  .app-shell .body > .card { margin-bottom: 10px !important; }
  .app-shell .grid-2,
  .app-shell .flow { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .app-shell .flow > div {
    gap: 10px !important; min-width: 0;
  }
  .app-shell.request-detail-page .flow > div:nth-child(2) { order: -1; }
  .app-shell h2 {
    margin-bottom: 10px; padding-bottom: 9px; font-size: 13px;
  }
  .app-shell p.muted { margin-bottom: 10px; font-size: 11.5px; line-height: 1.45; }
  .app-shell .msg { padding: 10px 12px; font-size: 11.5px; }
  .app-shell .empty { padding: 28px 14px; }

  /* Search and filters use the full width; filters swipe in one compact row. */
  .app-shell .toolbar {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px; margin-bottom: 10px;
  }
  .app-shell .toolbar .search { min-width: 0; width: 100%; padding: 8px 10px; }
  .app-shell .toolbar > .chips {
    grid-column: 1 / -1; flex-wrap: nowrap; overflow-x: auto;
    scrollbar-width: none; padding-bottom: 2px;
  }
  .app-shell .toolbar > .chips::-webkit-scrollbar { display: none; }
  .app-shell .toolbar > .chips .chip { flex: 0 0 auto; }
  .app-shell .toolbar .count {
    grid-column: 1 / -1; margin: -1px 0 0; font-size: 10px;
  }

  /* All desktop data tables become readable stacked records on phones. */
  .app-shell .tbl-wrap:not(.recent-table) {
    overflow: visible; border: 0; box-shadow: none; background: transparent;
  }
  .app-shell .tbl-wrap:not(.recent-table) table.data,
  .app-shell .tbl-wrap:not(.recent-table) table.data tbody {
    display: block; width: 100%; background: transparent;
  }
  .app-shell .tbl-wrap:not(.recent-table) table.data thead { display: none; }
  .app-shell .tbl-wrap:not(.recent-table) table.data tbody > tr:not(.line-pay) {
    display: block; width: 100%; margin-bottom: 9px; padding: 9px 11px;
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: 8px; box-shadow: var(--shadow-sm); cursor: pointer;
  }
  .app-shell .tbl-wrap:not(.recent-table) table.data tbody > tr:not(.line-pay):last-child {
    margin-bottom: 0;
  }
  .app-shell .tbl-wrap:not(.recent-table) table.data tbody > tr:not(.line-pay) > td {
    display: grid; grid-template-columns: minmax(76px, 32%) minmax(0, 1fr);
    gap: 9px; align-items: start; width: 100%; min-width: 0;
    padding: 5px 0; border: 0; background: transparent;
    text-align: right; white-space: normal; overflow-wrap: anywhere;
  }
  /* `table.data code` is nowrap so an account number never breaks mid-digit
     across a desktop column. On a phone the column is 220px and the number is
     one unbreakable 477px word, which slid the whole page sideways — so here
     it wraps, where there is no column for it to break out of. */
  .app-shell .tbl-wrap:not(.recent-table) table.data tbody > tr:not(.line-pay) > td code {
    white-space: normal; overflow-wrap: anywhere;
  }
  .app-shell .tbl-wrap:not(.recent-table) table.data tbody > tr:not(.line-pay) > td::before {
    content: attr(data-label); color: var(--color-text-muted); font-size: 9px;
    font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    text-align: left;
  }
  .app-shell .tbl-wrap:not(.recent-table) table.data td.num { text-align: right; }
  .app-shell .tbl-wrap:not(.recent-table) table.data td .bar-track {
    width: 100% !important; min-width: 90px;
  }
  .app-shell .tbl-wrap:not(.recent-table) table.data td.qa {
    display: flex; justify-content: flex-end; width: 100%; padding-top: 7px;
  }
  .app-shell .tbl-wrap:not(.recent-table) table.data td.qa::before { display: none; }
  .app-shell .tbl-wrap:not(.recent-table) tr.line-pay {
    display: block; margin: -5px 0 9px;
  }
  .app-shell .tbl-wrap:not(.recent-table) tr.line-pay > td {
    display: block; width: 100%; padding: 0; border: 0;
  }
  .app-shell .line-pay-inner { max-width: none; padding: 12px; }

  /* Forms stay single-column with touch-friendly, full-width controls. */
  .app-shell .stack.card { max-width: none !important; width: 100%; }
  .app-shell .formline,
  .app-shell .formline[style] {
    grid-template-columns: minmax(0, 1fr) !important; gap: 4px; padding: 5px 0;
  }
  .app-shell .formline > label { padding-top: 0; font-size: 10.5px; }
  .app-shell input:not([type="checkbox"]):not([type="radio"]),
  .app-shell select,
  .app-shell textarea { width: 100%; max-width: 100%; min-width: 0; }
  .app-shell textarea { min-height: 82px; }
  .app-shell .actions {
    display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
    margin: 12px 0;
  }
  .app-shell .actions .btn { width: 100%; justify-content: center; }
  .app-shell .pay-form,
  .app-shell .split-build { gap: 10px; margin-top: 10px; }

  /* Detail screens expose the current action first and compress metadata. */
  .app-shell .stepper {
    margin: 1px 0 10px; padding: 3px 1px 6px;
    scroll-snap-type: x proximity; scrollbar-width: none;
  }
  .app-shell .stepper::-webkit-scrollbar { display: none; }
  .app-shell .step { scroll-snap-align: start; gap: 6px; }
  .app-shell .step .ball { width: 26px; height: 26px; font-size: 10px; }
  .app-shell .step .stx { font-size: 9px; }
  .app-shell .stepper .line { width: 18px !important; margin: 0 3px !important; }
  .app-shell .stat-num { font-size: 24px; }
  .app-shell .totals-box { min-width: 0; font-size: 11.5px; }
  .app-shell .totals-box .tr { gap: 12px; padding: 5px 0; }
  .app-shell .totals-box .tr > span:first-child { flex: 0 0 38%; }
  .app-shell .totals-box .tr > span:last-child { min-width: 0; }
  .app-shell .outstanding { padding: 9px 11px; margin-bottom: 10px; }
  .app-shell .sub-action { margin-top: 12px; padding-top: 12px; }
  .app-shell .receipts { gap: 6px; }
  .app-shell .receipt { padding: 9px 10px; font-size: 11px; }
  .app-shell .feed li { padding: 8px 0 8px 14px; font-size: 11.5px; }
  .app-shell .feed li .muted {
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .app-shell .toast-wrap {
    left: 10px; right: 10px; bottom: 78px; width: auto;
  }
  .app-shell .toast { min-width: 0; width: 100%; }
}

@media (max-width: 560px) {
  .login-wrap { min-height: 100dvh; padding: 14px; }
  .login-card { width: 100%; max-width: 380px; padding: 20px; gap: 11px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   APPROVED RESPONSIVE POLISH — production implementation of the preview
   ══════════════════════════════════════════════════════════════════════════ */
.money-field { position: relative; }
.money-field-prefix {
  position: absolute; z-index: 1; left: 12px; top: 50%;
  transform: translateY(-50%); color: var(--agc-green-deep);
  font-weight: 800; pointer-events: none;
}
.money-field input { padding-left: 31px !important; }

@media (max-width: 560px) {
  .mobile-bottom-nav .mobile-bottom-create.active {
    color: #fff; background: var(--agc-green-deep);
  }
  .mobile-bottom-nav a {
    min-height: 44px; justify-content: center;
  }
  .mobile-bottom-nav a:focus-visible,
  .mobile-dashboard-bar a:focus-visible,
  .mobile-dashboard-bar button:focus-visible {
    outline: 2px solid var(--agc-green);
    outline-offset: 2px;
  }

  /* Dashboard: the live command view stays on one phone canvas. */
  body.dashboard-page {
    width: 100%; height: 100dvh; overflow: hidden; padding-bottom: 0;
  }
  .dashboard-page .shell {
    height: calc(100dvh - 58px); min-height: 0; overflow: hidden;
  }
  .dashboard-page .main { height: 100%; overflow: hidden; }
  .dashboard-page .pagehead {
    height: 52px; padding: 8px 10px; overflow: hidden;
  }
  .dashboard-page .pagehead .ph-row { display: flex; flex-wrap: nowrap; }
  .dashboard-page .pagehead .ph-row h1 { font-size: 20px; line-height: 1.05; }
  /* Short screens: the head keeps the title only. Both of these are reachable
     from the bottom bar, and the head is 52px here. */
  .dashboard-page .pagehead .ph-actions { display: none; }

  /* Requests: five filters and compact, scannable payment rows. */
  .requests-page .pagehead .chips { display: none; }
  .requests-page .body { padding-top: 8px; }
  .requests-page .msg { margin-bottom: 7px !important; padding: 8px 10px; }
  .requests-page .toolbar {
    grid-template-columns: minmax(0, 1fr) auto; gap: 5px; margin-bottom: 7px;
  }
  .requests-page .toolbar .search { min-height: 34px; padding: 6px 9px; }
  .requests-page .toolbar > .chips {
    display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 3px; overflow: visible; padding: 0;
  }
  .requests-page .toolbar > .chips .chip {
    min-width: 0; min-height: 28px; padding: 5px 2px;
    display: flex; align-items: center; justify-content: center;
    font-size: 9px; line-height: 1.05; text-align: center; white-space: normal;
  }
  .requests-page .toolbar .count { margin: 0; }
  .requests-page .tbl-wrap:not(.recent-table) table.data tbody > tr:not(.line-pay) {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: 3px 8px; margin-bottom: 5px; padding: 7px 9px;
  }
  .requests-page .tbl-wrap:not(.recent-table) table.data tbody > tr:not(.line-pay) > td {
    display: block; padding: 0; text-align: left;
  }
  .requests-page table.data td::before { display: none !important; }
  .requests-page table.data td:nth-child(3),
  .requests-page table.data td:nth-child(4),
  .requests-page table.data td:nth-child(5),
  .requests-page table.data td:nth-child(8) { display: none !important; }
  .requests-page table.data td:nth-child(1) { grid-column: 1; grid-row: 1; }
  .requests-page table.data td:nth-child(2) {
    grid-column: 1 / -1; grid-row: 2; font-weight: 700; font-size: 9px;
  }
  .requests-page table.data td:nth-child(6) {
    grid-column: 1; grid-row: 3; align-self: center;
  }
  .requests-page table.data td:nth-child(7) {
    grid-column: 2; grid-row: 1 / 4; align-self: center; justify-self: end;
  }
  .requests-page table.data td:nth-child(6) .bar-track {
    width: 100% !important; min-width: 120px; height: 5px !important;
  }
  .requests-page table.data a.lead { font-size: 9px; }
  .requests-page table.data .badge { font-size: 9px; }

  /* Forms mirror the approved compact payment-entry card. */
  .request-form-page .pagehead { padding-top: 8px; padding-bottom: 8px; }
  .request-form-page .body { padding-top: 7px; }
  .request-form-page .stack.card { padding: 9px 12px; }
  .request-form-page .formline { gap: 2px; padding: 3px 0; }
  .request-form-page .formline > label { font-size: 9px; }
  .request-form-page input:not([type="checkbox"]):not([type="radio"]),
  .request-form-page select { height: 34px; padding-top: 0; padding-bottom: 0; font-size: 9px; }
  .request-form-page .money-field input { padding-left: 28px !important; }
  .request-form-page .money-field-prefix { left: 10px; font-size: 10px; }
  .request-form-page .help { display: none; }
  .request-form-page .actions { margin: 7px 0 4px; }
  .request-form-page .actions .btn { min-height: 34px; font-size: 9px; }
  .request-form-page .stack.card > p.muted { display: none; }

  /* Vendor intake keeps the queue visible below a short form. */

  /* Logs use the three-source control and compact filter row from the preview. */
  .logs-page .body { padding-top: 8px; }
  .logs-page .logtabs {
    grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; margin-bottom: 7px;
  }
  .logs-page .logtab {
    min-width: 0; min-height: 44px; padding: 8px 7px;
    display: flex; align-items: center;
  }
  .logs-page .logtab b { margin: 0; font-size: 9px; }
  .logs-page .logtab span { display: none; }
  .logs-page .logbar {
    display: grid; grid-template-columns: minmax(0, 1fr) 72px 78px auto;
    gap: 5px; margin-bottom: 7px;
  }
  .logs-page .logbar-q {
    grid-column: 1 / -1; min-width: 0; width: 100%; height: 34px;
  }
  .logs-page .logbar select { min-width: 0; height: 32px; padding: 0 5px; font-size: 9px; }
  .logs-page .logbar .btn { min-height: 32px; padding: 5px 8px; }
  .logs-page .logbar-count {
    grid-column: 1 / -1; margin: 0; font-size: 9px;
  }
  .logs-page .tbl-wrap:not(.recent-table) table.data tbody > tr:not(.line-pay) {
    margin-bottom: 5px; padding: 7px 9px;
  }

  /* User management keeps identity, access and alert health in one row. */
  .users-page .body { padding-top: 8px; }
  .users-page .body > .receipt,
  .users-page .body > .msg { margin-bottom: 7px !important; padding: 8px 10px; }
  .users-page .logbar {
    display: grid; grid-template-columns: minmax(0, 1fr) auto;
    gap: 5px; margin-bottom: 7px;
  }
  .users-page .logbar-q { min-width: 0; width: 100%; height: 34px; }
  .users-page .logbar .btn { min-height: 34px; }
  .users-page .logbar-count {
    grid-column: 1 / -1; margin: 0; font-size: 9px;
  }
  .users-page .tbl-wrap:not(.recent-table) table.data tbody > tr:not(.line-pay) {
    display: grid; grid-template-columns: minmax(0, 1fr) auto auto;
    gap: 5px 7px; margin-bottom: 5px; padding: 7px 9px;
  }
  .users-page .tbl-wrap:not(.recent-table) table.data tbody > tr:not(.line-pay) > td {
    display: block; padding: 0; text-align: left;
  }
  .users-page table.data td::before { display: none !important; }
  .users-page table.data td:nth-child(2),
  .users-page table.data td:nth-child(3),
  .users-page table.data td:nth-child(5),
  .users-page table.data td:nth-child(7) { display: none !important; }
  .users-page table.data td:nth-child(1) { grid-column: 1; }
  .users-page table.data td:nth-child(4) { grid-column: 2; align-self: center; }
  .users-page table.data td:nth-child(6) { grid-column: 3; align-self: center; }
  .users-page table.data td:nth-child(1) .lead { font-size: 9px; }
  .users-page table.data td:nth-child(1) .muted { font-size: 9px !important; }
  .users-page table.data .badge { font-size: 9px; }
  .users-page .body > .card:last-child { display: none; }
}

/* ── MOBILE NAV COUNTS ──────────────────────────────────────────────────── */
/* The sidebar counts are the "what needs me" signal; without these the phone
   layout loses it entirely, since the sidebar is behind the hamburger. */
.mobile-bottom-nav a { position: relative; }
.mobile-nav-count {
  position: absolute; top: 2px; left: 50%; margin-left: 4px;
  min-width: 16px; padding: 0 4px; border-radius: 999px;
  background: var(--agc-red); color: #fff;
  font-size: 10px; font-weight: 700; font-style: normal; line-height: 16px;
  text-align: center;
}
.mobile-menu-button { position: relative; }
/* A dot, not a number: the hamburger hides several counts at once, so a
   figure there would be ambiguous. */
.mobile-menu-dot {
  position: absolute; top: 6px; right: 6px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--agc-red);
}

/* ── Your own settings ──────────────────────────────────────────────────────
   Two independent forms, so a rejected password does not discard an edited
   name. They read as two cards rather than one long column of fields. */
.account-body { display: grid; gap: 18px; max-width: 640px; }
.account-card > h2 { margin: 0 0 4px; }
.account-card .account-note { margin: 0 0 18px; font-size: 12px; line-height: 1.5; }
.account-card .account-actions {
  margin-top: 6px; padding-top: 16px; border-top: 1px solid var(--ui-line-soft);
  display: flex; justify-content: flex-end;
}

/* ── Notifications ──────────────────────────────────────────────────────────
   The feed is a list of lines, not a stack of documents. Printing every
   message in full meant ten notifications filled the screen and finding one
   was a scroll; a line carries what you search by — subject, recipient,
   payment, when — and pressing it opens the message on its own page.
   ------------------------------------------------------------------------ */
.note-feed { padding: 6px; }
.note-row {
  display: grid; align-items: center; gap: 14px;
  grid-template-columns: 30px minmax(0, 1fr) auto auto 16px;
  padding: 10px 10px; border-radius: 10px; color: inherit; text-decoration: none;
  border-bottom: 1px solid var(--ui-line-soft);
}
.note-row:last-child { border-bottom: 0; }
.note-row:hover { background: var(--color-surface-alt); }
.note-chan {
  display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 9px; background: var(--color-surface-alt); color: var(--ui-ink-muted);
}
.note-chan svg { width: 15px; height: 15px; }
.note-chan--sms { background: var(--agc-green-tint); color: var(--agc-green-deep); }
.note-chan--email { background: #eaf1f7; color: #2f5d80; }
/* The feedback list reuses this row, and its two kinds were reaching for
   note-chan--bug / --idea, which nothing defined — so a bug and an idea
   arrived in the same grey and the icon told you nothing. */
.note-chan--bug { background: var(--agc-red-tint); color: var(--danger-ink); }
.note-chan--idea { background: var(--agc-amber-tint); color: var(--amber-ink); }
.note-main { min-width: 0; }
.note-main b {
  display: block; font-size: 12.5px; font-weight: 700; color: var(--color-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.note-main small {
  display: block; margin-top: 2px; font-size: 11px; color: var(--ui-ink-faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.note-row .note-ref {
  font-size: 11px; font-weight: 700; color: var(--agc-green-deep); white-space: nowrap;
}
.note-row time {
  display: grid; justify-items: end; font-size: 11px; color: var(--ui-ink-faint);
  white-space: nowrap; line-height: 1.3;
}
.note-row time span { font-size: 10px; opacity: .8; }
.note-go { width: 16px; height: 16px; color: var(--ui-line); }
.note-row:hover .note-go { color: var(--ui-ink-faint); }

/* The message itself, on its own page: shown as it was sent, because a bank
   instruction is a document someone may have to produce later. */
.note-open .note-body {
  margin: 0; padding: 16px 18px; border-radius: 10px;
  background: var(--color-surface-alt); border: 1px solid var(--ui-line-soft);
  color: var(--color-text-body); font-family: inherit;
  font-size: 12.5px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere;
}
.note-empty { text-align: center; color: var(--ui-ink-muted); }

/* A path is not a word: the badge's uppercasing turned /requests/1/ into
   something that does not exist. */
.badge--path { text-transform: none; font-family: var(--font-mono, ui-monospace, monospace); }

/* ── Integrations ───────────────────────────────────────────────────────────
   One column. The page carried four cards of prose around a single text box,
   and the two standing explainers — how to set it up, what happens to the
   credentials — were read once and then in the way forever. They fold.
   ------------------------------------------------------------------------ */
.integrations-body {
  display: flex; flex-direction: column; gap: 16px; max-width: 780px;
}

/* A disclosure that reads as part of the page rather than a browser default:
   the marker is ours, so it turns with the fold and matches the ink. */
.fold > summary {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  padding: 2px 0; list-style: none;
  font-size: 12px; font-weight: 700; color: var(--ui-ink-muted);
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::before {
  content: ""; width: 0; height: 0; flex: none;
  border-left: 5px solid currentColor;
  border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform .15s ease;
}
.fold[open] > summary::before { transform: rotate(90deg); }
.fold > summary:hover { color: var(--color-text); }
.fold-body { padding-top: 12px; }
.fold-body ol, .fold-body ul { margin: 0 0 12px; padding-left: 18px; }
.fold-body li { margin-bottom: 6px; font-size: 12px; color: var(--ui-ink-muted); }
.fold-body p { margin: 0 0 12px; font-size: 12px; color: var(--ui-ink-muted); }
.fold-body > :last-child { margin-bottom: 0; }
.stack > .fold { border-top: 1px solid var(--ui-line-soft); padding-top: 12px; }

/* The test send sits under the form it proves, on one line — it is a check,
   not a second setup step. Both of them are a .formline like every other
   field on the page: the email one was a search box and a ghost button
   floating under the form with no label at all, and the SMS one had a label
   in a different weight starting 180px left of every box above it. */
.testrow { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.testrow input { flex: 1 1 180px; min-width: 0; max-width: 300px; }
.testrow .btn { flex: none; }
.prove { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--ui-line-soft); }
/* A tick answers the question beside it. */
.checkline { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; min-height: 34px; }
.checkline > span { font-size: 12px; color: var(--color-text-muted); }
.checkline .fe { flex-basis: 100%; margin-top: 0; }
/* A gateway URL is 90-odd characters and the whole point of the box is being
   able to read the one that was pasted in. */
.integrations-page .formline input[type=url] { max-width: none; }

.card-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
.card-head h2 { margin: 0; }
.card > .card-head:first-child { margin-bottom: 14px; }
.link-go {
  font-size: 11.5px; font-weight: 700; color: var(--agc-green-deep); text-decoration: none;
}
.link-go:hover { text-decoration: underline; }

/* The bank instruction is a numbered round-trip — print, upload, send — and the
   number is the part that says where you are in it. It was set in the same
   small uppercase as the rest of the label and disappeared into it. */
.sub-action .btn .step-n {
  display: inline-grid; place-items: center;
  min-width: 19px; height: 19px; margin-right: 7px; padding: 0 4px;
  border-radius: 6px; background: var(--ui-line-soft); color: var(--color-text);
  font-size: 12px; font-weight: 800; letter-spacing: 0; vertical-align: -3px;
}
.sub-action .btn--secondary .step-n { background: rgba(255, 255, 255, .22); color: #fff; }
.sub-action .btn[disabled] .step-n { opacity: .75; }

/* ── File inputs ────────────────────────────────────────────────────────────
   The outer control already picked up the shared input styling, but the button
   inside it is drawn by the browser and stayed the system default: a grey
   bevelled "Choose File" sitting between the numbered instruction steps and
   the upload button, the one native control left in the panel. ::file-selector
   -button lets it be styled without replacing the input, so it keeps the
   filename, the keyboard behaviour and the file picker for free.
   ------------------------------------------------------------------------ */
input[type="file"] {
  width: 100%; padding: 7px 9px; cursor: pointer;
  color: var(--ui-ink-muted); font-size: 11px;
}
input[type="file"]::file-selector-button {
  margin: 0 10px 0 0; padding: 6px 12px;
  border: 0; border-radius: 6px; cursor: pointer;
  background: var(--color-surface-alt); color: var(--color-text-muted);
  box-shadow: inset 0 0 0 1px var(--ui-line);
  font-family: var(--font-sans); font-size: 10px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  transition: background 0.15s, color 0.15s, box-shadow 0.15s;
}
input[type="file"]::file-selector-button:hover {
  background: var(--color-surface); color: var(--color-text);
  box-shadow: inset 0 0 0 1px var(--agc-grey);
}
input[type="file"]:focus-visible::file-selector-button {
  box-shadow: inset 0 0 0 1px var(--agc-green);
}

/* ── File picker ────────────────────────────────────────────────────────────
   The button is a <label> carrying the same classes as the buttons it sits
   between, so it inherits their shape rather than approximating it. The input
   lives inside that label, hidden by clip rather than by display: it keeps its
   focus stop, its keyboard behaviour and its place in the form, and a screen
   reader still meets a file input. See the enhancement in base.html; without
   it the input renders as itself, styled by the ::file-selector-button rules
   above.
   ------------------------------------------------------------------------ */
.filepick .filepick-input {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}
.filepick-btn { cursor: pointer; }
/* The ring belongs on the label, since that is what the eye reads as the
   control — the input it describes is one clipped pixel. */
.filepick-btn:focus-within {
  box-shadow: inset 0 0 0 1px var(--agc-green), 0 0 0 2px rgba(var(--accent-rgb), 0.18);
}
.filepick-file {
  display: flex; align-items: center; gap: 8px;
  margin-top: 7px; padding: 8px 9px 8px 11px;
  border: 1px solid var(--ui-line); border-radius: 8px;
  background: var(--color-surface-alt); font-size: 11px;
}
.filepick-name {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--color-text); font-weight: 600;
}
.filepick-size {
  flex: 0 0 auto; color: var(--ui-ink-faint);
  font-variant-numeric: tabular-nums;
}
.filepick-clear {
  flex: 0 0 auto; width: 20px; height: 20px;
  display: grid; place-items: center; padding: 0;
  border: 0; border-radius: 5px; background: transparent;
  color: var(--ui-ink-faint); font-size: 15px; line-height: 1; cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.filepick-clear:hover { background: var(--agc-red-tint); color: var(--agc-red); }

/* The dialling code and the number are one field, so they sit on one line —
   stacked, the code reads as a separate question and gets the whole number
   typed into it. The code box is sized to what it holds (+ and up to four
   digits) rather than sharing the width evenly: the number is the part being
   read back. */
.phone-pair { display: flex; gap: 8px; align-items: center; }
.phone-pair input[data-phone="dial"] { width: 84px; flex: none; text-align: center; }
.phone-pair input[data-phone="number"] { flex: 1; min-width: 0; }

/* The company's own mark beside its details, on the white plate the artwork
   was drawn for — the same lockup as the sidebar, because it is the same mark
   and a tinted square is where Egle's dark badge disappears. */
.company-head { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.company-plate {
  width: 42px; height: 42px; flex: none; border-radius: var(--radius-sm);
  background: var(--logo-plate); border: 1px solid var(--color-border);
  display: grid; place-items: center;
}
.company-plate img { width: 30px; height: 30px; object-fit: contain; }

/* Label above box: the action panel, and any card too narrow to hold two
   columns beside each other. One name for one shape — a second, near-identical
   `--stacked` is how two of them come to drift apart. The label carries the
   weight so it still reads as a question being asked. */
.formline--stack { display: block; grid-template-columns: minmax(0, 1fr); margin-bottom: 12px; }
.formline--stack > span,
.formline--stack > label { display: block; font-weight: 600; margin-bottom: 5px; padding-top: 0; }
.formline--stack input:not([type=checkbox]):not([type=radio]),
.formline--stack select,
.formline--stack textarea { width: 100%; max-width: none; }
.formline--stack .help, .formline--stack .fe { font-weight: 400; margin-top: 5px; max-width: none; }

/* The reports index. Tiles rather than a list because each one needs two
   lines to say what it is *for*, and a list of six titles says nothing about
   which to open. */
/* A group title on the canvas, not a card heading: the inherited rule under
   an h2 fell between this heading and its own lead line, so the sentence
   explaining the group read as the start of the next one. */
.reports-group { margin: 22px 0 6px; font-size: 15px; padding-bottom: 0; border-bottom: 0; }
.reports-group:first-of-type { margin-top: 4px; }
.reports-group-lead { margin: 0 0 12px; font-size: 12px; color: var(--color-text-muted); }
.report-tiles {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.report-tile {
  display: flex; flex-direction: column; gap: 7px;
  padding: 18px 18px 20px; text-decoration: none;
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  border-left: 3px solid var(--accent-ink);
  transition: box-shadow .15s ease, transform .15s ease;
}
.report-tile:hover, .report-tile:focus-visible {
  box-shadow: var(--shadow); transform: translateY(-1px);
}
.report-tile-title { font-weight: 600; font-size: 15px; color: var(--color-text); }
.report-tile-lead { font-size: 13px; line-height: 1.5; color: var(--color-text-body); }
.report-tile-why {
  font-size: 12px; line-height: 1.5; color: var(--color-text-muted);
  padding-top: 7px; border-top: 1px solid var(--color-border-row);
}
/* A figure that is the answer to the page, rather than one number among many. */
.report-figure { display: flex; flex-wrap: wrap; gap: 26px; margin-bottom: 18px; }
.report-figure b { display: block; font-size: 22px; font-weight: 600; letter-spacing: -.02em; }
.report-figure span { font-size: 11px; text-transform: uppercase;
                      letter-spacing: .08em; color: var(--color-text-muted); }
.report-figure .bad b { color: var(--danger-ink); }

/* The date range on a report. Label above the box so the pair reads as one
   control rather than as two unrelated fields in a toolbar. */
.period-field { display: flex; flex-direction: column; gap: 3px; }
.period-field > span {
  font-size: 10px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--color-text-muted);
}

/* The go-live list. One card per outstanding thing, with the blocking ones
   carrying a red edge — blocking and worth-doing are different, and a list
   that reads them the same is a list nobody prioritises from. */
.golive-item { margin-bottom: 12px; }
.golive-item--blocking { border-left: 3px solid var(--agc-red); }
.golive-head { display: flex; align-items: flex-start; gap: 12px; }
.golive-head .badge { margin-left: 8px; }
