/*!*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** css ../../node_modules/.pnpm/next@15.5.23_@types+node@22.20.1_react-dom@19.2.8_react@19.2.8__react@19.2.8/node_modules/next/dist/build/webpack/loaders/css-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[2]!../../node_modules/.pnpm/next@15.5.23_@types+node@22.20.1_react-dom@19.2.8_react@19.2.8__react@19.2.8/node_modules/next/dist/build/webpack/loaders/postcss-loader/src/index.js??ruleSet[1].rules[14].oneOf[10].use[3]!./src/app/globals.css ***!
  \*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
/* ieSmartSystems ops shell — token system
   Palette: paper/ink neutrals, ieSmart crimson accent (from the logotype),
   functional RAG colors. Signature: wide-tracked labels echoing the
   letterspaced "s y s t e m s" in the brand mark; job numbers in mono
   like job-ticket stamps. */

:root {
  --paper: #fbfaf8;
  --surface: #ffffff;
  --ink: #1a1a1a;
  --muted: #6b6b6b;
  --hairline: #e4e1dc;
  --brand: #c8102e;
  --brand-dark: #8f1d22;
  --rag-red: #c8102e;
  --rag-amber: #b98207;
  /* A busted budget line. Amber names the row, crimson names the figure, so the
     two carry different jobs: where to look, and what went wrong. */
  --bust: #b98207;
  --bust-tint: rgba(185, 130, 7, 0.09);
  --rag-green: #2f7d46;
  /* Plan/baseline series colour. Blue against the crimson actual is the pairing
     that survives colour-vision deficiency, which matters because the two lines
     converge — green would fail exactly where the chart has to be read. */
  --plan: #3b6ea5;
  --font-body: "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-mono: "Cascadia Mono", Consolas, ui-monospace, monospace;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
}

a { color: inherit; }
a:focus-visible, button:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

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

.shell-header {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding: 0.85rem 1.5rem;
  background: var(--surface);
  border-bottom: 1px solid var(--hairline);
}
.shell-header img { display: block; }
.shell-nav {
  display: flex;
  gap: 1.5rem;
  margin-left: 0.5rem;
}
.shell-nav a {
  text-decoration: none;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--muted);
  padding: 0.25rem 0;
  border-bottom: 2px solid transparent;
}
.shell-nav a:hover, .shell-nav a[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--brand);
}

.page {
  max-width: 1080px;
  margin: 0 auto;
  padding: 2rem 1.5rem 4rem;
}

/* ---- signature label style (echoes the logotype's letterspacing) ---- */

.label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--muted);
}

.page-title {
  font-size: 1.5rem;
  font-weight: 650;
  margin: 0.2rem 0 1.5rem;
}

/* ---- job number: mono ticket stamp ---- */

.jobnum {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  color: var(--brand-dark);
  white-space: nowrap;
}

/* ---- stage stamp badge ---- */

.stamp {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  padding: 0.18rem 0.55rem;
  border: 1.5px solid var(--ink);
  border-radius: 3px;
  white-space: nowrap;
}
.stamp--muted { border-color: var(--hairline); color: var(--muted); }

/* ---- RAG chip ---- */

.rag {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: capitalize;
}
.rag::before {
  content: "";
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  background: currentColor;
}
.rag--red { color: var(--rag-red); }
.rag--amber { color: var(--rag-amber); }
.rag--green { color: var(--rag-green); }

/* ---- table ---- */

.table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  overflow: hidden;
}
.table th {
  text-align: left;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-weight: 600;
  color: var(--muted);
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--hairline);
  background: var(--paper);
}
.table td {
  padding: 0.8rem 1rem;
  border-bottom: 1px solid var(--hairline);
  vertical-align: middle;
}
.table tr:last-child td { border-bottom: none; }
.table a.rowlink {
  text-decoration: none;
  font-weight: 600;
}
.table a.rowlink:hover { color: var(--brand); }

/* A whole row as the target. The hover tint is the only affordance a table row
   has — there is no underline to borrow — so it carries the whole signal that
   this row does something, and the focus ring inset keeps it from being clipped
   by the table's rounded overflow. */
.table tr.row-click { cursor: pointer; }
.table tr.row-click:hover { background: var(--paper); }
.table tr.row-click:hover .jobnum { color: var(--brand); }
.table tr.row-click:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: -2px;
}
/* Mid-pull: about a second of live JetBuilt round-trip, during which a second
   click would start a second pull. */
.table tr.row-click[aria-current="true"] { background: var(--paper); box-shadow: inset 3px 0 0 var(--brand); }
.table tr.row-click[aria-busy="true"] { opacity: 0.55; cursor: progress; }
.table tr.row-click[aria-disabled="true"] { cursor: not-allowed; }

/* ---- detail layout ---- */

.detail-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.75rem 1.25rem;
  margin-bottom: 1.5rem;
}
.detail-head h1 { font-size: 1.6rem; font-weight: 650; margin: 0; }

.detail-grid {
  display: grid;
  grid-template-columns: 1fr;
  grid-gap: 1.25rem;
  gap: 1.25rem;
}
@media (min-width: 860px) {
  .detail-grid { grid-template-columns: 3fr 2fr; align-items: start; }
}
.detail-col { display: grid; grid-gap: 1.25rem; gap: 1.25rem; }

.card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: 1.1rem 1.25rem;
}
.card > .label { display: block; margin-bottom: 0.75rem; }
.card table { width: 100%; border-collapse: collapse; }
.card td, .card th {
  text-align: left;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--hairline);
  font-size: 0.9rem;
}
.card tr:last-child td { border-bottom: none; }
.card th { font-weight: 600; color: var(--muted); font-size: 0.8rem; }

.figure { font-family: var(--font-mono); font-size: 0.9rem; }

.narrative { margin: 0.5rem 0 0; font-size: 0.95rem; }

.meta { color: var(--muted); font-size: 0.8rem; }

.empty {
  color: var(--muted);
  font-size: 0.9rem;
  padding: 0.5rem 0;
}

/* ---- financials ledger ----
   Full-width section above .detail-grid. Quiet hairline-ruled ledger; the
   margin stamp is the only bold element per the job-ledger design brief. */

.financials-section { margin-bottom: 1.25rem; }
.financials-section > .label { display: block; margin-bottom: 0.85rem; }

.ledger-group {
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--hairline);
}
.ledger-group:first-of-type { padding-top: 0; }
.ledger-group:last-child { border-bottom: none; padding-bottom: 0; }

.contract-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.85rem;
}
.contract-line .figure { font-size: 1rem; }

.ledger-line { margin: 0; }
.ledger-line .muted { color: var(--muted); }

/* ---- margin stamp: the one bold element ---- */

.stamp--margin {
  display: inline-flex;
  /* stretch, not baseline: only the current reading carries a delta line, and
     baseline alignment dropped the other readings to match its extra height. */
  align-items: stretch;
  gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: 1.05rem;
  font-weight: 700;
  padding: 0.3rem 0.8rem;
  border: 2px solid var(--ink);
  border-radius: 4px;
}
.stamp--margin .delta {
  font-family: var(--font-body);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.stamp--margin .delta--up { color: var(--rag-green); }
.stamp--margin .delta--down { color: var(--brand); }

/* Current and projected share the one stamp: each reading is a captioned
   column, split by a hairline. Keeps the page's single bold element intact. */
.stamp--margin .stamp__reading-group {
  display: inline-flex;
  align-items: stretch;
  gap: 0.6rem;
}
.stamp--margin .stamp__reading {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
}
.stamp--margin .stamp__cap {
  font-family: var(--font-body);
  font-size: 0.58rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
}
.stamp--margin .stamp__pct { line-height: 1.05; }
/* ---- projection trail chart ---- */

/* The projection row is itself the disclosure: the summary has to sit on the
   table's own rhythm so it reads as a row, not as a control bolted under one. */
.proj-drill-cell { padding: 0; border-bottom: none; }
.proj-summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.32rem 0;
  border-bottom: 1px solid var(--hairline);
  cursor: pointer;
  list-style: none;
}
.proj-summary::-webkit-details-marker { display: none; }
.proj-summary__label {
  font-weight: 600;
  color: var(--muted);
  font-size: 0.8rem;
}
/* A caret is the only hint that a row opens; it turns with the disclosure. One
   rule for every drill on the page — change orders, POs, phases and the
   projection row all read the same way. */
.co-drill > summary .co-row-label::before,
.proj-summary__label::before {
  content: "▸";
  display: inline-block;
  width: 0.85rem;
  color: var(--muted);
}
.co-drill[open] > summary .co-row-label::before,
.proj-drill[open] .proj-summary__label::before { content: "▾"; }
.co-drill > summary { list-style: none; cursor: pointer; }
.co-drill > summary::-webkit-details-marker { display: none; }
.proj-summary:hover .proj-summary__label { color: var(--brand); }
.proj-drill[open] .proj-summary { border-bottom: none; }

/* Drill content nests UNDER its row rather than replacing it: an indent plus a
   hairline spine. Without this the nested tables run flush to the margin at full
   width, and the position table's own rows — the skeleton — become the weakest
   thing on screen whenever a drill is open. */
.proj-drill > *:not(summary) {
  margin: 0.1rem 0 0.6rem 0.85rem;
  padding-left: 0.95rem;
  border-left: 1px solid var(--hairline);
}
/* The drill's own table already carries a top rule; doubled against the spine
   it reads as a box, which is not this page's idiom. */
.proj-drill > .co-drill-table { border-top: none; }
.trail { margin: 0.75rem 0 0; }
.trail__svg { width: 100%; height: auto; display: block; }
.trail__grid { stroke: var(--hairline); stroke-width: 1; }
.trail__ylab, .trail__xlab, .trail__cll {
  fill: var(--muted);
  font-family: var(--font-body);
  font-size: 11px;
}
.trail__budget { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 4 3; }
.trail__area { fill: var(--brand); opacity: 0.07; }
.trail__actual { fill: none; stroke: var(--brand); stroke-width: 2.2; }
.trail__pm { fill: none; stroke: var(--plan); stroke-width: 1.6; }
.trail__end { stroke: var(--ink); stroke-width: 1; stroke-dasharray: 3 3; opacity: 0.55; }
.trail__endlab { fill: var(--ink); font-family: var(--font-body); font-size: 11px; opacity: 0.75; }
.trail__dot { fill: var(--brand); }

/* Spend breakdown: one grid template shared by the header, the phase rows and
   the cost-type rows, so everything lines up while the phase row is itself a
   <summary> — which a table row cannot be. */
.spend { margin: 0.15rem 0 0.5rem; }
.spend__row {
  display: grid;
  grid-template-columns: 1fr 7rem 4.5rem 5.5rem;
}
/* The cost drill carries budget / used / projected / variance / hours, so it
   needs its own template rather than the four-column spend default. */
/* The cost drill's summary: label hard left like every other row in the position
   table, figures hard right where that table's figures live. It deliberately does
   NOT borrow the drill table's nine-column template — that parked the dollars
   mid-row, leaving them stranded against the empty hours columns. */
.proj-summary--cost {
  display: grid;
  grid-template-columns: 1fr 5.7rem 5.7rem 5.7rem 4.6rem;
  grid-gap: 0.6rem;
  gap: 0.6rem;
  align-items: end;
}
.proj-summary--cost > .proj-summary__label { text-align: left; }
.proj-summary--cost > .figure { text-align: right; }
/* Four figures on one collapsed row need naming, or they are just four numbers.
   The caption sits directly over its own figure rather than in a header row, so
   the row stays readable folded — which is how it is read most of the time. */
.proj-summary__cell {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.06rem;
}
.proj-summary__cap {
  font-size: 0.6rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
  line-height: 1.1;
}

.spend--cost .spend__row {
  grid-template-columns: 1fr 5.7rem 5.7rem 5.7rem 4.6rem 4.8rem 4.8rem 4.8rem 3.6rem;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.3rem 0;
}
/* The grid sits inside a .ledger-table cell, which right-aligns everything;
   the label column has to opt back out explicitly. */
.spend__row > span:first-child { text-align: left; }
.spend__row > span:not(:first-child) { text-align: right; }
.spend__row--head {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
  border-bottom: 1px solid var(--hairline);
}
.spend__row--phase {
  border-bottom: 1px solid var(--hairline);
  cursor: pointer;
  list-style: none;
}
.spend__row--phase::-webkit-details-marker { display: none; }
.spend__row--phase > span:first-child::before {
  content: "▸ ";
  color: var(--muted);
}
.spend__phase[open] > .spend__row--phase > span:first-child::before { content: "▾ "; }
.spend__row--phase:hover .jobnum { color: var(--brand); }
/* Cost types sit under their phase, indented, with no rule of their own. */
.spend__row--ct {
  padding: 0.16rem 0;
  font-size: 0.85rem;
}
.spend__row--ct > span:first-child { padding-left: 1.5rem; }
.spend__row--total {
  border-top: 1px solid var(--hairline);
  padding-top: 0.4rem;
}
.spend__phase[open] { border-bottom: 1px solid var(--hairline); }
.spend__phase[open] > .spend__row--phase { border-bottom: none; }

/* Second drill level: what a phase's budget is made of. Deliberately quieter
   than the phase row above it — a caret and muted text, no header row, so the
   phase table stays the thing being read. */
/* .ledger-table right-aligns td and is declared LATER in this file, so this
   needs the extra class to win on specificity rather than on order — the cell
   holds a control, not a figure. */
.ledger-table .ct-row > td {
  padding: 0;
  border-bottom: 1px solid var(--hairline);
  text-align: left;
}
.ct-drill > summary {
  list-style: none;
  cursor: pointer;
  font-size: 0.68rem;
  color: var(--muted);
  padding: 0.2rem 0 0.2rem 1.6rem;
}
.ct-drill > summary::-webkit-details-marker { display: none; }
.ct-drill > summary::before { content: "▸ "; }
.ct-drill[open] > summary::before { content: "▾ "; }
.ct-drill > summary:hover { color: var(--brand); }
.ct-table { margin: 0 0 0.4rem 1.6rem; width: calc(100% - 1.6rem); }
.ct-table td { border-bottom: none; padding: 0.18rem 0; font-size: 0.82rem; }

/* Access chips on the admin screen: state first, control second, so a row of
   them scans as a permissions matrix rather than a row of buttons. */
.chip {
  font-family: inherit;
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  background: none;
  border: 1px solid var(--hairline);
  border-radius: 3px;
  padding: 0.12rem 0.45rem;
  cursor: pointer;
}
.chip:hover { border-color: var(--ink); color: var(--ink); }
.chip--on { color: #fff; background: var(--brand); border-color: var(--brand); }
.chip--on:hover { background: var(--brand-dark); border-color: var(--brand-dark); color: #fff; }

/* Spend past the PM projection — the projection drill's only colour, reusing
   the RAG red rather than introducing a new critical token. */
.over-proj { color: var(--rag-red); font-weight: 600; }

/* Production at-completion tracking to finish meaningfully UNDER budget —
   the positive counterpart to .over-proj. Only fires past a tolerance band so
   phases landing on plan stay neutral and the green means something. */
.under-proj { color: var(--rag-green); font-weight: 600; }

/* How long a pending change order has been sitting. Amber past thirty days,
   red past ninety; a fresh one is left unmarked so the colour means something
   when it appears. The roll-up wears the oldest row's colour, or a year-old CO
   is only findable by opening every drill on every job. */
.age--aging { color: var(--rag-amber); font-weight: 600; }
.age--stale { color: var(--rag-red); font-weight: 600; }

/* ---- cost movement: gain / (fade) by category ---- */

/* A diverging bar from one zero line. Half the track is 20% of the job's
   budget — fixed, so a bar means the same thing on every job; scaling to the
   largest mover instead drew a 0.8% gain as long as a 21.6% one. */
.mv { padding: 0.35rem 0 0.1rem; }
.mv__row {
  display: grid;
  grid-template-columns: 6rem 1fr 6.2rem 3.8rem;
  align-items: center;
  grid-gap: 0.7rem;
  gap: 0.7rem;
  padding: 0.26rem 0;
}
.mv__row--net {
  border-top: 1px solid var(--hairline);
  margin-top: 0.3rem;
  padding-top: 0.45rem;
  font-weight: 600;
}
.mv__name { font-size: 0.8rem; }
.mv__row--head {
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--muted);
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 0.35rem;
}
.mv__row--head > span:nth-child(3),
.mv__row--head > span:nth-child(4) { text-align: right; }
/* Names the bar's own base, which is not the base of the figure beside it. */
.mv__axis { text-align: center; font-size: 0.56rem; }
.mv__track { position: relative; height: 0.7rem; }
/* The zero line is the only chrome; every bar is read from it. */
.mv__zero {
  position: absolute;
  left: 50%;
  top: -0.08rem;
  bottom: -0.08rem;
  width: 1px;
  background: var(--hairline);
}
.mv__bar { position: absolute; top: 0.1rem; height: 0.5rem; }
.mv__bar--gain { background: var(--plan); }
.mv__bar--fade { background: var(--brand); }
.mv__foot {
  margin: 0.45rem 0 0;
  font-size: 0.72rem;
  color: var(--muted);
  font-family: var(--font-mono);
  text-align: right;
}

/* Sits under the contract line, naming the whole contract the job's share came
   out of. Quiet: it is context for the figure above, not a second figure. */
.contract-note {
  margin: -0.35rem 0 0.9rem;
  font-size: 0.78rem;
}
/* A figure we cannot stand behind. Amber rather than crimson: the number is
   not necessarily wrong, but nobody should build on it until it is mapped. */
.contract-note--warn {
  color: var(--ink);
  background: var(--bust-tint);
  box-shadow: inset 2px 0 0 var(--bust);
  padding: 0.45rem 0.6rem;
  margin: -0.2rem 0 0.9rem;
}
.contract-note--warn strong { color: var(--rag-amber); }

/* A row where a real budget existed and something went past it. Deliberately a
   pale wash plus an edge rule rather than a filled band: 16% of phase rows bust,
   and three saturated bands in a ten-row table would out-shout the crimson stamp
   this page is built around. The negative margin cancels its own padding, so the
   tint bleeds past the columns without shifting them out of alignment. */
.spend__row.is-bust,
.proj-summary.is-bust {
  background: var(--bust-tint);
  box-shadow: inset 2px 0 0 var(--bust);
  margin-left: -0.5rem;
  padding-left: 0.5rem;
  margin-right: -0.5rem;
  padding-right: 0.5rem;
}
/* Cost types indent under their phase; keep that indent on a busted one. */
.spend__row--ct.is-bust > span:first-child { padding-left: 1rem; }

/* Cost booked against no budget line at all — 39% of live cost rows, because a
   phase's scope was estimated somewhere else or the cost type has no budget by
   construction (type 70 carries burden on 82 jobs). Arithmetically infinite
   overrun, in practice a coding difference, so it gets a word instead of a
   colour: "—" alone cannot tell "nothing to measure against" from "came in
   under". */
.figure--nobudget {
  font-size: 0.6rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

.stamp--margin .stamp__rule {
  align-self: stretch;
  width: 1px;
  background: var(--hairline);
  margin: 0 0.15rem;
}

/* ---- position ledger table: revenue group / hairline / cost group ---- */

.ledger-table { width: 100%; border-collapse: collapse; }
.ledger-table th {
  text-align: left;
  font-weight: 600;
  color: var(--muted);
  font-size: 0.8rem;
  padding: 0.32rem 0;
  border-bottom: 1px solid var(--hairline);
}
.ledger-table td {
  text-align: right;
  padding: 0.32rem 0;
  border-bottom: 1px solid var(--hairline);
}
.ledger-table tr:last-child th, .ledger-table tr:last-child td { border-bottom: none; }
.ledger-table tbody + tbody tr:first-child th,
.ledger-table tbody + tbody tr:first-child td {
  border-top: 1px solid var(--hairline);
  padding-top: 0.6rem;
}
.ledger-table .empty { text-align: left; padding: 0.32rem 0; }

/* ---- labor progress bar ---- */

.ledger-bar {
  position: relative;
  height: 6px;
  background: var(--hairline);
  border-radius: 3px;
  margin-bottom: 0.5rem;
}
.ledger-bar__fill {
  height: 100%;
  background: var(--brand);
  border-radius: 3px;
}
.ledger-bar__tick {
  position: absolute;
  top: -3px;
  width: 2px;
  height: 12px;
  background: var(--muted);
}

/* ---- home ---- */

.home {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
  padding: 5rem 1rem;
  text-align: center;
}
.home .cta {
  display: inline-block;
  text-decoration: none;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: #fff;
  background: var(--brand);
  padding: 0.65rem 1.4rem;
  border-radius: 4px;
}
.home .cta:hover { background: var(--brand-dark); }
/* the login screen's CTA is a submit button, not a link */
.home button.cta { border: 0; cursor: pointer; font-family: inherit; }

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

.form-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin-top: 0.75rem;
}
.form-row input[type="text"], .form-row input[type="date"], .form-row select, .form-row textarea {
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 4px;
  padding: 0.4rem 0.55rem;
}
.form-row textarea { width: 100%; resize: vertical; min-height: 3.2rem; }
.form-row input:focus-visible, .form-row select:focus-visible, .form-row textarea:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 1px;
}

.btn {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: #fff;
  background: var(--brand);
  border: none;
  border-radius: 4px;
  padding: 0.45rem 0.9rem;
  cursor: pointer;
}
.btn:hover { background: var(--brand-dark); }
.btn:disabled { opacity: 0.5; cursor: default; }
.btn--ghost {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--hairline);
}
.btn--ghost:hover { background: var(--paper); color: var(--ink); }
.btn--tiny { padding: 0.2rem 0.5rem; font-size: 0.65rem; }

.rag-picker { display: flex; gap: 0.4rem; }
.rag-picker button {
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: capitalize;
  border: 1.5px solid var(--hairline);
  border-radius: 999px;
  background: var(--surface);
  padding: 0.3rem 0.85rem;
  cursor: pointer;
}
.rag-picker button[aria-pressed="true"] { color: #fff; border-color: transparent; }
.rag-picker button[data-rag="red"][aria-pressed="true"] { background: var(--rag-red); }
.rag-picker button[data-rag="amber"][aria-pressed="true"] { background: var(--rag-amber); }
.rag-picker button[data-rag="green"][aria-pressed="true"] { background: var(--rag-green); }

.form-error { color: var(--brand); font-size: 0.8rem; margin-top: 0.5rem; }

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: center;
  margin-bottom: 1rem;
}
.filter-bar label { font-size: 0.8rem; color: var(--muted); display: inline-flex; align-items: center; gap: 0.35rem; }
.filter-search {
  font-size: 0.82rem;
  border: 1px solid var(--hairline);
  border-radius: 4px;
  padding: 0.35rem 0.55rem;
  background: var(--surface);
  min-width: 16rem;
  font-family: inherit;
  color: var(--ink);
}
.filter-search::placeholder { color: var(--muted); }
.filter-search:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.list-count { margin: 0 0 0.6rem; }

.filter-bar select {
  font-size: 0.82rem;
  border: 1px solid var(--hairline);
  border-radius: 4px;
  padding: 0.35rem 0.5rem;
  background: var(--surface);
}

.shell-user { margin-left: auto; display: flex; align-items: center; gap: 0.9rem; }
.shell-user span { font-size: 0.8rem; color: var(--muted); }
.shell-user a { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.14em; color: var(--muted); text-decoration: none; }
.shell-user a:hover { color: var(--brand); }

.label--sub {
  display: block;
  font-size: 0.62rem;
  margin-bottom: 0.35rem;
}

.ledger-bar__fill--over { background: var(--brand); }

.detail-subhead { margin: -0.5rem 0 1rem; }

.co-drill { margin: 0; }
.co-drill summary {
  cursor: pointer;
  list-style-position: inside;
}
.co-drill summary:hover .co-row-label { color: var(--brand); }
.co-drill[open] summary { margin-bottom: 0.35rem; }
.co-row {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.3rem 0;
  margin: 0;
  border-top: 1px solid var(--hairline);
}
.co-row-label {
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  min-width: 6.5rem;
}
p.co-row--empty { padding-left: 1.1rem; } /* aligns with summary disclosure marker */
.co-drill .co-drill-table { margin-bottom: 0.5rem; }
.co-drill-table {
  width: 100%;
  border-top: 1px solid var(--hairline);
}
.co-drill-table thead th {
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
  font-weight: 500;
  text-align: left;
  padding: 0.4rem 0.5rem 0.25rem 0;
}
.co-drill-table td { padding: 0.3rem 0.75rem 0.3rem 0; border-top: 1px solid var(--hairline); }
/* Compact columns hug content; the description column absorbs the slack. */
.co-drill-table th, .co-drill-table td { white-space: nowrap; }
/* The label column carries names, not figures — .ledger-table right-aligns td
   by default, which read as "$" columns with words in them. */
.ledger-table .col-flex { text-align: left; }
.co-drill-table .col-flex { width: 100%; white-space: normal; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* The phase picker carries 68 options in optgroups; without a floor it
   collapses to the width of the shortest name and the taxonomy is unreadable. */
.table select { min-width: 14rem; font: inherit; }

/* ---- Reports -------------------------------------------------------------- */
.report-card {
  display: block;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  background: var(--surface);
  text-decoration: none;
  color: var(--ink);
  margin-bottom: 0.6rem;
}
.report-card:hover { border-color: var(--brand); }
.report-card__title { display: block; font-weight: 600; margin-bottom: 0.15rem; }
.report-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
}
.report-actions { display: flex; gap: 0.5rem; }
.report-meta { margin: 0.2rem 0 1rem; }
/* The report as a per-job drill: each job is a <details>. */
.report-drill { border-top: 1px solid var(--hairline); }
.report-job { border-bottom: 1px solid var(--hairline); }
.report-job__summary {
  display: flex; align-items: baseline; gap: 1rem;
  padding: 0.55rem 0.4rem; cursor: pointer; list-style: none;
}
.report-job__summary::-webkit-details-marker { display: none; }
.report-job__summary::before { content: "\25B8"; color: var(--muted); font-size: 0.8em; }
.report-job[open] > .report-job__summary::before { content: "\25BE"; }
.report-job[open] > .report-job__summary { background: var(--paper); }
.report-leaf { display: flex; align-items: baseline; gap: 1rem; padding: 0.55rem 0.4rem; }
.report-job__id { flex: 1 1; min-width: 0; }
.report-job__fig { min-width: 7rem; text-align: right; }
.report-job .report-table { margin: 0 0 0.4rem; }
.report-total { margin-top: 0.75rem; font-weight: 600; text-align: right; }

@media print {
  .shell-header, .report-actions, .report-crumb { display: none !important; }
  body { background: #fff; color: #000; }
  .page { padding: 0; max-width: none; }
  /* Branded header on the printed page, then the report's own title below it. */
  .report-print::before {
    content: "ieSmartSystems";
    display: block; font-weight: 700; color: var(--brand); font-size: 13px;
    border-bottom: 2px solid var(--brand); padding-bottom: 0.25rem; margin-bottom: 0.5rem;
  }
  .report-print .page-title { margin: 0 0 0.15rem; }
  /* Force every job's drill open so the detail prints. */
  .report-job > *:not(summary) { display: block !important; }
  .report-job__summary { background: #f2efe9 !important; font-weight: 600; }
  .report-job__summary::before { display: none; }
  .report-table { font-size: 11px; }
  .report-table th, .report-table td { border: 0.5px solid #bbb; padding: 2px 5px; }
  /* Keep a job's rows together across page breaks. */
  .report-job { break-inside: avoid; page-break-inside: avoid; }
  a { color: #000 !important; text-decoration: none; }
}

/* ---- Dashboard ------------------------------------------------------------ */
.dashboard { max-width: 920px; }
.dash-title {
  font-size: 1.95rem; font-weight: 600; letter-spacing: -0.01em;
  margin: 0.2rem 0 0.1rem; color: var(--ink);
}
.dash-sub { margin: 0 0 1.7rem; }
.dash-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); grid-gap: 1.1rem; gap: 1.1rem;
}
.dash-card {
  position: relative; display: flex; flex-direction: column;
  padding: 1.5rem 1.4rem 1.25rem; border: 1px solid var(--hairline); border-radius: 12px;
  background: var(--surface); text-decoration: none; color: var(--ink); overflow: hidden;
  transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.dash-card::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--brand); opacity: 0; transition: opacity .15s ease;
}
.dash-card:hover {
  border-color: var(--brand); transform: translateY(-3px);
  box-shadow: 0 10px 28px rgba(26, 26, 26, 0.08);
}
.dash-card:hover::before { opacity: 1; }
.dash-card__icon {
  width: 2.7rem; height: 2.7rem; display: grid; place-items: center; border-radius: 10px;
  background: rgba(200, 16, 46, 0.08); color: var(--brand); margin-bottom: 0.7rem;
}
.dash-card__icon svg { width: 1.45rem; height: 1.45rem; }
.dash-card__name { font-weight: 600; font-size: 1.1rem; margin-bottom: 0.25rem; }
.dash-card__desc { color: var(--muted); font-size: 0.9rem; line-height: 1.45; flex: 1 1; }
.dash-card__go { color: var(--brand); font-weight: 600; font-size: 0.85rem; margin-top: 0.9rem; }

/* ---- Mobile --------------------------------------------------------------- */
@media (max-width: 720px) {
  .page { padding: 1.25rem 1rem 3rem; }

  /* Header wraps instead of overflowing: logo + user on top, nav below. */
  .shell-header { flex-wrap: wrap; gap: 0.5rem 1rem; padding: 0.7rem 1rem; }
  .shell-header img { width: 104px; height: auto; }
  .shell-nav { order: 3; width: 100%; margin-left: 0; gap: 1.15rem; flex-wrap: wrap; }
  .shell-user { margin-left: auto; }

  /* Tighten oversized headings for small screens. */
  .page-title { font-size: 1.3rem; }
  .detail-head h1 { font-size: 1.35rem; }
  .dash-title { font-size: 1.55rem; }

  /* Full-width dashboard cards. */
  .dash-grid { grid-template-columns: 1fr; }

  /* Wide tables scroll inside their own box rather than widening the page.
     display:block turns each table into a horizontal scroll container while its
     rows/cells keep table layout via anonymous table boxes. */
  .table, .ledger-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }
  .table th, .table td { padding: 0.6rem 0.7rem; }
  .ledger-table { font-size: 0.85rem; }

  /* Drill summary rows and figures wrap instead of overflowing. */
  .report-job__summary { flex-wrap: wrap; }
  .report-job__fig { min-width: 5.5rem; }
  .contract-line .figure { font-size: 0.95rem; }
}

@media (max-width: 720px) {
  /* The dense cost/commitment drills (multi-column grids) scroll sideways as a
     unit instead of forcing the page wide. */
  .spend { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .proj-drill-cell { max-width: 100%; }
  .filter-search { max-width: 100%; }
}

