/* =================================================================================================
   REPORT-01 — the Step 8 workspace.

   THIS SHEET IS A PORT OF `PRESTEC_BaoCao_v2.html`, NOT AN INTERPRETATION OF IT.

   The Owner's source is the visual and interaction authority for the Report workspace. Its class
   names, its tokens, its proportions and its densities are reproduced here as closely as the app
   shell allows. The first attempt treated the source as inspiration and rebuilt Report in the
   generic white PRESTEC CRUD style; that was rejected, correctly — the Report workspace is a
   specialised dark document editor and it is supposed to look like one.

   EVERYTHING IS NAMESPACED UNDER `.rpt-root`.

   The source uses short generic class names — `.btn`, `.panel`, `.rail`, `.ed`, `.tb`, `.modal` —
   which collide head-on with this application's globals. Scoping under one root solves both
   directions at once: inside Report the source's rules win on specificity (0,2,0 beats 0,1,0), and
   outside it nothing changes, because no other page carries `.rpt-root`. Accepted global pages are
   not touched by this file.

   NO @page RULE IS DECLARED HERE. @page cannot be scoped — the last one parsed wins for the whole
   application — so a margin set for the report would silently change every other printed document
   in the product (AGENTS §5.54.6). Sheet geometry lives on the page element itself.
   ================================================================================================= */

.rpt-root {
  /* The source's palette, verbatim. */
  --pc-orange: #F35B27;
  --pc-orange-deep: #C63A15;
  --pc-black: #1A1A1A;
  --pc-gray: #4A4A4A;
  --pc-gray-light: #E8E8E8;
  --pc-ivory: #F7F5F2;
  --pc-gold: #C89B3C;
  --ok: #1F8A54;
  --warn: #B8791A;
  --bad: #C0392B;

  --cjk: 'Microsoft YaHei', 'Yu Gothic UI', 'Malgun Gothic', 'Noto Sans CJK SC',
         'Noto Sans JP', 'Noto Sans KR', 'MS PGothic', sans-serif;
  --font-head: 'Montserrat', 'Be Vietnam Pro', 'Segoe UI', Arial, var(--cjk);
  --font-body: Calibri, 'Be Vietnam Pro', 'Segoe UI', Arial, var(--cjk);
  --font-num: Consolas, 'SF Mono', 'Courier New', monospace;

  --pg-w: 210mm;
  --pg-h: 297mm;
  --pg-x: 14mm;
  --pg-t: 10mm;
  --pg-b: 8mm;
  --foot-h: 8mm;

  font-family: var(--font-body);
  font-size: 10.5pt;
  color: var(--pc-black);
}
.rpt-root *, .rpt-root *::before, .rpt-root *::after { box-sizing: border-box; }

/* ── the workspace shell ──────────────────────────────────────────────────────────────────────── */

body.rpt-modal-open {
  /* The project underneath is LOCKED rather than merely covered: without this a wheel over the
     workspace scrolls the page behind it, and closing lands the reader somewhere they never went. */
  overflow: hidden;
}

/*
  Every property is stated rather than inherited from `.modal`.

  `.modal` is declared twice in this application — styles.css makes it a full-screen overlay,
  prestec.css then redeclares it as a 520px white card, and being loaded later prestec.css wins
  those properties. A workspace that inherited the hybrid rendered as a narrow white column down
  the left of the screen.
*/
#reportWorkspace,
#reportPicker.rpt-screen-host {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: none;
  width: auto;
  max-height: none;
  overflow: auto;
  /* The source's own workspace ground. Not white. */
  background: #55585c;
  padding: 0;
  border-radius: 0;
  box-shadow: none;
}
#reportWorkspace.open,
#reportPicker.rpt-screen-host.open { display: block; }

/* ACCEPTANCE-01 — Step 9's workspace is the same kind of surface and needs the same rules.
   Without them the host rendered INLINE at the foot of the project page: visible, never hidden when
   closed, and sitting below a screenful of process cards rather than over them. */
#acceptanceWorkspace {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: none;
  width: auto;
  max-height: none;
  overflow: auto;
  background: #55585c;
  padding: 0;
  border-radius: 0;
  box-shadow: none;
}
#acceptanceWorkspace[data-acceptance-workspace="open"] { display: block; }
/* Screen 1 sits ABOVE the workspace: it is opened from the project page, never from inside a
   report, so nothing of the workspace should show through behind it. */
#reportPicker.rpt-screen-host { z-index: 1250; }

/* ══════════════ TOOLBAR ══════════════ */

.rpt-root .toolbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--pc-black);
  border-bottom: 3px solid var(--pc-orange);
  padding: 9px 16px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  font-family: var(--font-head);
}
.rpt-root .toolbar .brand {
  color: #fff; font-weight: 700; font-size: 12px; letter-spacing: .08em;
  margin-right: 6px; text-transform: uppercase;
}
.rpt-root .toolbar .brand i { color: var(--pc-orange); font-style: normal; }
.rpt-root .toolbar .sep { width: 1px; height: 22px; background: #4a4a4a; margin: 0 3px; }
.rpt-root .toolbar .crumb { color: #9aa0a5; font-size: 11.5px; font-weight: 600; letter-spacing: .04em; }
.rpt-root .toolbar .crumb b { color: var(--pc-gold); }
.rpt-root .toolbar .rt { margin-left: auto; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* Screen chips in the toolbar — the four-step flow, always visible. */
.rpt-root .steps { display: flex; gap: 4px; align-items: center; }
.rpt-root .step {
  font-family: var(--font-head); font-size: 11px; font-weight: 600; letter-spacing: .04em;
  border: 1px solid #3f464c; background: #23272b; color: #9aa0a5;
  padding: 5px 11px; border-radius: 4px; cursor: pointer; white-space: nowrap;
}
.rpt-root .step:hover { border-color: #6d757c; color: #cdd3d8; }
.rpt-root .step.on { background: var(--pc-orange); border-color: var(--pc-orange); color: #fff; }
.rpt-root .step.done { color: #cdd3d8; border-color: #4a5158; }
.rpt-root .step i { font-style: normal; font-family: var(--font-num); opacity: .7; margin-right: 5px; }
/* On the ACTIVE step the chip sits on orange, where a quietened grey reads at 1.25:1 — invisible.
   The number is the one thing that says which of the four screens you are on. */
.rpt-root .step.on i { opacity: 1; color: #fff; }

/* ══════════════ BUTTONS ══════════════ */

.rpt-root .btn {
  font-family: var(--font-head); font-size: 12px; font-weight: 600;
  border: 1px solid #5a5a5a; background: #2b2b2b; color: #eaeaea;
  padding: 7px 13px; border-radius: 4px; cursor: pointer; transition: .15s;
  white-space: nowrap; line-height: 1.2;
}
.rpt-root .btn:hover { background: #3a3a3a; border-color: #7a7a7a; }
.rpt-root .btn.primary { background: var(--pc-orange); border-color: var(--pc-orange); color: #fff; }
.rpt-root .btn.primary:hover { background: var(--pc-orange-deep); border-color: var(--pc-orange-deep); }
.rpt-root .btn.gold { background: var(--pc-gold); border-color: var(--pc-gold); color: #1a1a1a; }
.rpt-root .btn.ghost { background: transparent; }
.rpt-root .btn.sm { padding: 4px 9px; font-size: 11px; }
.rpt-root .btn[disabled], .rpt-root .btn.off { opacity: .4; cursor: not-allowed; pointer-events: none; }
.rpt-root .btn.on { background: var(--pc-orange); border-color: var(--pc-orange); color: #fff; }
.rpt-root .btn.danger:hover { background: var(--bad); border-color: var(--bad); color: #fff; }

/* ══════════════ SCREENS ══════════════ */

.rpt-root .screen { display: none; }
.rpt-root .screen.on { display: block; }
.rpt-root .wrapc { max-width: 1180px; margin: 0 auto; padding: 26px 18px 60px; }
.rpt-root .wrapw { max-width: 1560px; margin: 0 auto; padding: 14px 16px 50px; }

.rpt-root .hd1 {
  font-family: var(--font-head); color: #fff; font-size: 22px; font-weight: 800;
  letter-spacing: -.01em; margin: 0;
}
.rpt-root .hd1 .sub {
  display: block; font-size: 11px; font-weight: 600; letter-spacing: .18em;
  color: #dde1e4; text-transform: uppercase; margin-top: 4px;
}
.rpt-root .hd2 {
  font-family: var(--font-head); color: #e4e8eb; font-size: 13px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase; margin: 26px 0 10px;
  padding-bottom: 5px; border-bottom: 1px solid #6a6e72;
}
.rpt-root .lead { color: #d3d7da; font-size: 13px; line-height: 1.65; max-width: 760px; margin: 9px 0 0; }
.rpt-root .lead b { color: #fff; }

/* ── report type cards ── */
.rpt-root .kgrid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
  gap: 13px; margin-top: 18px;
}
.rpt-root .kcard {
  background: #2b3036; border: 1px solid #3f464c; border-left: 4px solid #4a5158;
  border-radius: 5px; padding: 16px 17px; cursor: pointer; transition: .14s; text-align: left;
  display: flex; flex-direction: column; min-height: 186px; font: inherit;
}
.rpt-root .kcard:hover { border-left-color: var(--pc-gold); background: #33393f; transform: translateY(-2px); }
.rpt-root .kcard.on {
  border-left-color: var(--pc-orange); background: #3a3230;
  box-shadow: 0 0 0 1px var(--pc-orange), 0 10px 26px rgba(0, 0, 0, .4);
}
.rpt-root .kcard .kc { font-family: var(--font-num); font-size: 11px; font-weight: 700; color: #8c9399; letter-spacing: .06em; }
.rpt-root .kcard.on .kc { color: var(--pc-orange); }
.rpt-root .kcard .kt { font-family: var(--font-head); font-size: 15px; font-weight: 700; color: #fff; margin: 4px 0 2px; line-height: 1.3; }
.rpt-root .kcard .kt2 { font-size: 11px; color: #93a7b4; font-style: italic; margin-bottom: 8px; }
.rpt-root .kcard .kd { font-size: 12px; color: #b9bfc4; line-height: 1.55; flex: 1; }
.rpt-root .kcard .kf { margin-top: 11px; padding-top: 9px; border-top: 1px solid #3f464c; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.rpt-root .kcard .kn { font-family: var(--font-num); font-size: 10.5px; color: #a5acb2; }
.rpt-root .kcard .badge { font-family: var(--font-head); font-size: 9.5px; font-weight: 700; letter-spacing: .06em; background: var(--pc-gold); color: #1a1a1a; padding: 2px 7px; border-radius: 3px; }
.rpt-root .kcard .go { margin-left: auto; font-family: var(--font-head); font-size: 10px; font-weight: 700; letter-spacing: .08em; color: #9aa0a5; }
.rpt-root .kcard.on .go { color: var(--pc-orange); }

/* ── section preview inside a card ── */
.rpt-root .secpv { background: #22262a; border: 1px solid #3a4046; border-radius: 5px; padding: 14px 16px; margin-top: 16px; }
.rpt-root .secpv h4 { font-family: var(--font-head); font-size: 10.5px; font-weight: 700; letter-spacing: .08em; color: var(--pc-gold); text-transform: uppercase; margin: 0 0 9px; }
.rpt-root .secpv ol { margin: 0; padding-left: 20px; columns: 2; column-gap: 26px; }
@media (max-width: 700px) { .rpt-root .secpv ol { columns: 1; } }
.rpt-root .secpv li { color: #d3d7da; font-size: 12.5px; line-height: 1.85; break-inside: avoid; }
.rpt-root .secpv li .sr { font-family: var(--font-head); font-size: 9px; font-weight: 700; letter-spacing: .05em; padding: 1px 5px; border-radius: 3px; margin-left: 6px; vertical-align: 1px; }
.rpt-root .sr-auto, .rpt-root .sr-pick { background: #1e3a52; color: #8ec5f0; }
.rpt-root .sr-edit { background: #4a3a15; color: #e8c476; }
.rpt-root .sr-user { background: #33383d; color: #a9b0b6; }
.rpt-root .sr-na { background: #2a2e32; color: #9aa2a9; border: 1px dashed #5a6167; }
/* Struck through and quietened, but still legible: a reader checking which sections this form
   will NOT ask for has to be able to read their names. */
.rpt-root .secpv li.off { color: #99a1a8; text-decoration: line-through; text-decoration-color: #5a6167; }
.rpt-root .secpv li.off .sr { text-decoration: none; }
.rpt-root .secpv .nanote { margin: 11px 0 0; font-size: 11.5px; color: #8c9399; font-style: italic; }

/* ══════════════ FORMS ══════════════ */

.rpt-root .fgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(232px, 1fr)); gap: 0 20px; }
.rpt-root .fld { margin-bottom: 15px; }
.rpt-root .fld > label {
  display: block; font-family: var(--font-head); font-size: 11px; font-weight: 700;
  letter-spacing: .05em; color: #b9bfc4; text-transform: uppercase; margin-bottom: 5px;
}
.rpt-root .fld > label .rq { color: var(--pc-orange); }
.rpt-root .inp, .rpt-root .sel, .rpt-root .ta {
  width: 100%; font-family: var(--font-body); font-size: 13px; background: #2b3036;
  color: #e8ecef; border: 1px solid #3f464c; border-radius: 4px; padding: 8px 10px; transition: .12s;
}
.rpt-root .inp:focus, .rpt-root .sel:focus, .rpt-root .ta:focus {
  outline: 0; border-color: var(--pc-orange); box-shadow: 0 0 0 3px rgba(243, 91, 39, .2);
}
.rpt-root .inp[disabled], .rpt-root .sel[disabled], .rpt-root .ta[disabled] { opacity: .55; cursor: not-allowed; }
.rpt-root .ta { resize: vertical; min-height: 74px; line-height: 1.6; }
/* A styled control, never the browser's own. The source replaces the native arrow. */
.rpt-root .sel {
  appearance: none; padding-right: 28px; cursor: pointer;
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%238c9399' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 9px center; background-size: 9px;
}
.rpt-root .hint { font-size: 11.5px; color: #c9ced3; margin-top: 4px; line-height: 1.5; }
/* On a panel the ground is dark and #9aa0a5 is comfortable; on the workspace ground (#55585c) the
   same grey falls to 2.7:1. Panels get the quieter tone back. */
.rpt-root .panel .hint, .rpt-root .ro .hint, .rpt-root .ed .hint,
.rpt-root .fcard .hint, .rpt-mask .hint { color: #9aa0a5; }
.rpt-root .panel { background: #22262a; border: 1px solid #3a4046; border-radius: 5px; padding: 17px 19px; }
.rpt-root .panel + .panel { margin-top: 13px; }
.rpt-root .ro { background: #1e2226; border: 1px solid #343a40; border-radius: 4px; padding: 13px 15px; }
.rpt-root .rogrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(178px, 1fr)); gap: 12px 20px; }
.rpt-root .rok { font-family: var(--font-head); font-size: 10px; font-weight: 700; letter-spacing: .05em; color: #8c9399; text-transform: uppercase; margin-bottom: 2px; }
.rpt-root .rov { font-size: 12.5px; color: #e4e8eb; font-weight: 600; line-height: 1.45; }
.rpt-root .rov em { color: #8c9399; font-weight: 400; }

/* ── language buttons ── */
.rpt-root .langs { display: flex; gap: 7px; flex-wrap: wrap; }
.rpt-root .lbtn {
  font-family: var(--font-head); font-size: 12px; font-weight: 600; border: 1px solid #4a5158;
  background: #2b3036; color: #cdd3d8; padding: 8px 14px; border-radius: 4px; cursor: pointer;
  transition: .12s; display: flex; align-items: center; gap: 7px;
}
.rpt-root .lbtn:hover { border-color: #6d757c; }
.rpt-root .lbtn.on { background: var(--pc-orange); border-color: var(--pc-orange); color: #fff; }
.rpt-root .lbtn .lc { font-family: var(--font-num); font-size: 10px; opacity: .75; }
.rpt-root .lbtn[disabled] { opacity: .45; cursor: not-allowed; }

/* ── alerts ── */
.rpt-root .al { border-radius: 4px; padding: 11px 14px; margin-bottom: 13px; font-size: 12.5px; line-height: 1.6; }
.rpt-root .al .alt { font-family: var(--font-head); font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; margin-bottom: 4px; }
.rpt-root .al.info { background: #1c2530; border: 1px solid #2f5a7d; color: #b8d4ea; }
.rpt-root .al.info .alt { color: #8ec5f0; }
.rpt-root .al.warn { background: #2b2314; border: 1px solid #6a5122; color: #e8d5a8; }
.rpt-root .al.warn .alt { color: #e8c476; }
.rpt-root .al.bad { background: #2c1618; border: 1px solid #7a3228; color: #f0b8ae; }
.rpt-root .al.bad .alt { color: #ff8b78; }
.rpt-root .al.ok { background: #132a1d; border: 1px solid #2f6b47; color: #a8dcc2; }
.rpt-root .al.ok .alt { color: #5fd39a; }
.rpt-root .al ul { margin: 6px 0 0; padding-left: 18px; }
.rpt-root .al li { margin-bottom: 3px; }
.rpt-root .al .lnk {
  color: #8ec5f0; background: none; border: 0; padding: 0; font: inherit;
  text-decoration: underline; cursor: pointer;
}

/* ══════════════ EDITOR SCREEN ══════════════ */

.rpt-root .edwrap { display: grid; grid-template-columns: 272px 1fr; gap: 13px; align-items: start; }
@media (max-width: 1000px) { .rpt-root .edwrap { grid-template-columns: 1fr; } }

.rpt-root .rail {
  background: #22262a; border: 1px solid #3a4046; border-radius: 5px; overflow: hidden;
  position: sticky; top: 62px;
}
.rpt-root .rail .rh {
  background: #1c2024; border-bottom: 1px solid #3a4046; padding: 9px 13px;
  font-family: var(--font-head); font-size: 10px; font-weight: 700; letter-spacing: .07em;
  color: #8c9399; text-transform: uppercase;
}
.rpt-root .si {
  display: flex; align-items: center; gap: 9px; padding: 9px 12px;
  border-bottom: 1px solid #2c3136; cursor: pointer; transition: .1s;
  width: 100%; background: none; border-left: 0; border-right: 0; border-top: 0;
  /* An explicit colour, because a <button> inherits the browser's default otherwise — black, on a
     dark rail. Every visible word here sits in a child span that sets its own, so this changes
     nothing on screen; it means text added to the button later is legible rather than invisible. */
  font: inherit; text-align: left; color: #d3d7da;
}
.rpt-root .si:last-of-type { border-bottom: 0; }
.rpt-root .si:hover { background: #2b3036; }
.rpt-root .si.on { background: #3a3230; box-shadow: inset 3px 0 0 var(--pc-orange); }
.rpt-root .si .n { font-family: var(--font-num); font-size: 10.5px; color: #9aa0a5; width: 17px; flex: none; }
.rpt-root .si.on .n { color: var(--pc-orange); font-weight: 700; }
/* A long bilingual title TRUNCATES. It never wraps into one character per line, and it never
   pushes the dot out of the row — the rail has a fixed width and the title is the flexible part. */
.rpt-root .si .t {
  flex: 1 1 auto; min-width: 0; font-size: 12.5px; font-weight: 600; color: #d3d7da;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rpt-root .si.on .t { color: #fff; }
.rpt-root .si .d { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.rpt-root .d-empty { background: #4a5158; }
.rpt-root .d-auto { background: #3b82f6; }
.rpt-root .d-need { background: var(--pc-gold); }
.rpt-root .d-ok { background: #2fa36a; }
/* NOT APPLICABLE — a hollow ring, deliberately unlike "no content yet", which is a solid grey dot.
   If those two look the same, somebody goes hunting for an input that does not exist. */
.rpt-root .d-na { background: transparent; box-shadow: inset 0 0 0 2px #5a6167; }
/* A section that does not apply is struck through and dimmed — but it still has to be READ. A
   reader checking what was skipped needs to see which section it was, and at 2.6:1 they could not. */
.rpt-root .si.is-na .t { color: #99a1a8; text-decoration: line-through; text-decoration-color: #5a6167; }
.rpt-root .rail .rl {
  padding: 9px 13px; background: #1c2024; border-top: 1px solid #3a4046;
  font-size: 10.5px; color: #8c9399; line-height: 1.95;
}
.rpt-root .rail .rl i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; vertical-align: middle; }

.rpt-root .ed {
  background: #22262a; border: 1px solid #3a4046; border-radius: 5px; min-height: 540px;
  display: flex; flex-direction: column; min-width: 0;
}
.rpt-root .ed .eh {
  background: #1c2024; border-bottom: 1px solid #3a4046; padding: 13px 18px;
  display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap;
}
.rpt-root .ed .en {
  width: 27px; height: 27px; border-radius: 4px; flex: none; display: grid; place-items: center;
  background: var(--pc-orange); color: #fff; font-family: var(--font-num); font-size: 12px; font-weight: 700;
}
.rpt-root .ed .eti { min-width: 0; flex: 1 1 300px; }
.rpt-root .ed .et { font-family: var(--font-head); font-size: 15px; font-weight: 700; color: #fff; line-height: 1.25; }
/* The secondary-language title sits UNDER the Vietnamese, never beside it. Inline, a long pair
   overflows and shoves the section actions off the row. */
.rpt-root .ed .et small { display: block; font-size: 11px; color: #93a7b4; font-style: italic; font-weight: 400; margin-top: 1px; }
.rpt-root .ed .edsc { font-size: 11.5px; color: #9aa0a5; margin-top: 4px; max-width: 660px; line-height: 1.5; }
.rpt-root .ed .ea { margin-left: auto; display: flex; gap: 7px; align-items: center; flex-wrap: wrap; }
.rpt-root .ed .eb { padding: 17px 18px 20px; flex: 1 1 auto; min-width: 0; }
.rpt-root .ed .ef {
  padding: 11px 18px; border-top: 1px solid #3a4046; background: #1c2024;
  display: flex; gap: 9px; align-items: center; flex-wrap: wrap;
  position: sticky; bottom: 0; z-index: 2;
}
.rpt-root .ed .ef .pos { font-size: 11.5px; color: #8c9399; }
.rpt-root .srt { font-family: var(--font-head); font-size: 9.5px; font-weight: 700; letter-spacing: .05em; padding: 2px 7px; border-radius: 3px; }

/* ── source / print pair ── */
.rpt-root .pair { display: grid; grid-template-columns: 1fr 1fr; gap: 13px; }
@media (max-width: 900px) { .rpt-root .pair { grid-template-columns: 1fr; } }
.rpt-root .pane { border: 1px solid #3a4046; border-radius: 4px; overflow: hidden; background: #1e2226; min-width: 0; }
.rpt-root .pane .ph {
  padding: 7px 11px; background: #272c31; border-bottom: 1px solid #3a4046; display: flex;
  align-items: center; gap: 7px; font-family: var(--font-head); font-size: 10px; font-weight: 700;
  letter-spacing: .05em; color: #8c9399; text-transform: uppercase;
}
.rpt-root .pane .ph .btn { margin-left: auto; }
.rpt-root .pane .pbd { padding: 11px 13px; font-size: 12.5px; line-height: 1.65; color: #c3c9ce; max-height: 270px; overflow-y: auto; }
.rpt-root .pane .pbd .lb { font-family: var(--font-head); font-size: 9.5px; font-weight: 700; color: #8f969c; letter-spacing: .05em; text-transform: uppercase; margin: 10px 0 2px; }
.rpt-root .pane .pbd .lb:first-child { margin-top: 0; }
.rpt-root .pane .pbd p { margin: 0 0 6px; white-space: pre-wrap; }
.rpt-root .pane.edit { border-color: #5a4a20; }
.rpt-root .pane.edit .ph { background: #3a3118; color: var(--pc-gold); border-color: #5a4a20; }
.rpt-root .pane.edit .ta { border: 0; border-radius: 0; min-height: 228px; background: #1e2226; }
.rpt-root .pane.edit .ta:focus { box-shadow: none; }

/* ── tables ── */
.rpt-root .tbw { border: 1px solid #3a4046; border-radius: 4px; overflow-x: auto; background: #1e2226; }
.rpt-root .tb { width: 100%; border-collapse: collapse; font-size: 12px; color: #d3d7da; }
.rpt-root .tb th {
  background: #272c31; text-align: left; padding: 7px 9px; font-family: var(--font-head);
  font-size: 9.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: #8c9399; border-bottom: 1px solid #3a4046; white-space: nowrap;
}
.rpt-root .tb td { padding: 6px 9px; border-bottom: 1px solid #2c3136; vertical-align: middle; }
.rpt-root .tb tbody tr:last-child td { border-bottom: 0; }
.rpt-root .tb tbody tr:hover { background: #252a2f; }
.rpt-root .tb tr.off { opacity: .4; }
.rpt-root .tb tr.off .ci { text-decoration: line-through; }
.rpt-root .tb .n { text-align: right; font-family: var(--font-num); }
.rpt-root .tb .c { text-align: center; }
/* The item column is the one that may grow; every other column keeps its natural width so a long
   label can never squeeze a header into one character per line. */
.rpt-root .tb .grow { width: 99%; min-width: 220px; }
.rpt-root .tb .fit { width: 1%; white-space: nowrap; }
.rpt-root .ci {
  width: 100%; border: 1px solid transparent; background: transparent; border-radius: 3px;
  padding: 5px 7px; font-size: 12px; color: #e4e8eb; font-family: var(--font-body);
}
.rpt-root .ci:hover { background: #272c31; }
.rpt-root .ci:focus { outline: 0; background: #1a1e22; border-color: var(--pc-orange); }
.rpt-root .ci::placeholder { color: #8f969c; font-style: italic; }
/* The TRANSLATION input always sits directly under the Vietnamese one, in the same cell. A red
   border while it is empty: a half-translated report is a defect, not an option. */
.rpt-root .ci.tr, .rpt-root .ta.tr {
  display: block; width: 100%; margin-top: 3px; color: #93a7b4; font-style: italic;
  font-size: 11px; border: 1px solid #3a4046; background: #1a1e22;
}
.rpt-root .ci.tr { padding: 2px 6px; }
.rpt-root .ci.tr.miss, .rpt-root .ta.tr.miss { border-color: #7a4038; background: #241b1a; }
.rpt-root .ci.miss, .rpt-root select.sel.miss { border-color: #7a4038; background: #241b1a; }

/* ── assessment colours ── */
.rpt-root .a-ok { color: #4bbd8a; }
.rpt-root .a-mon { color: #e8c476; }
.rpt-root .a-rep { color: #e8796a; }
.rpt-root .a-cri { color: #ff5f45; }
.rpt-root .a-na { color: #99a1a8; }
.rpt-root .a-todo { color: #99a1a8; }
.rpt-root select.asel { font-family: var(--font-num); font-weight: 700; font-size: 11.5px; }
.rpt-root select.asel.a-cri { border-color: #7a3228; background: #2a1714; }
.rpt-root select.asel.a-rep { border-color: #6a3a33; }
.rpt-root select.asel.a-mon { border-color: #5c4d24; }
.rpt-root select.bsel { font-size: 11px; padding: 3px 5px; }

/* ── group headers inside a checklist ── */
.rpt-root .ghd { display: flex; gap: 9px; align-items: center; margin: 18px 0 8px; padding-bottom: 6px; border-bottom: 1px solid #3a4046; }
.rpt-root .ghd:first-child { margin-top: 0; }
.rpt-root .ghd .gk { background: var(--pc-orange); color: #fff; font-family: var(--font-head); font-weight: 700; font-size: 11px; width: 20px; height: 20px; display: grid; place-items: center; border-radius: 2px; }
.rpt-root .ghd .gt { font-family: var(--font-head); font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #e4e8eb; }
.rpt-root .ghd .gn { font-family: var(--font-num); font-size: 10.5px; color: #9aa0a5; }
.rpt-root .ghd .gs { margin-left: auto; display: flex; gap: 9px; font-family: var(--font-num); font-size: 11px; font-weight: 700; }
.rpt-root .ghd .gs i { font-style: normal; }
.rpt-root .legend { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 9px; font-size: 11.5px; }
.rpt-root .legend span { display: flex; gap: 5px; align-items: center; }
.rpt-root .sfb { font-family: var(--font-head); font-size: 8.5px; font-weight: 700; letter-spacing: .08em; background: #4a2a24; color: #f0a596; border-radius: 2px; padding: 1px 5px; vertical-align: 1px; }

/* ── measurement blocks ── */
.rpt-root .mesw {
  display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap; border-radius: 5px;
  padding: 11px 15px; margin-bottom: 14px; background: #26201c; border: 1px solid #5a4436;
}
.rpt-root .mesw.on { background: #1c2530; border-color: #2f5a7d; }
.rpt-root .mesw label { display: flex; gap: 8px; align-items: center; cursor: pointer; flex: 0 0 auto; }
.rpt-root .mesw b { font-size: 12.5px; color: #e4e8eb; font-weight: 600; }
.rpt-root .mesw span { font-size: 11.5px; color: #8c9399; line-height: 1.55; flex: 1 1 260px; }
.rpt-root .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 10px; margin: 12px 0; }
.rpt-root .st { background: #1e2226; border: 1px solid #3a4046; border-radius: 5px; padding: 11px 14px; text-align: center; }
.rpt-root .st .l1 { font-size: 11px; color: #c8ced3; line-height: 1.3; }
.rpt-root .st .l2b { font-size: 9.5px; color: #8f969c; font-style: italic; margin-bottom: 6px; }
.rpt-root .st .v { font-family: var(--font-num); font-size: 23px; font-weight: 700; color: #e8ecef; line-height: 1.05; }
.rpt-root .st .u { font-size: 9.5px; color: #8f969c; letter-spacing: .08em; }
.rpt-root .st.hi { background: #1c2530; border-color: #2f5a7d; }
.rpt-root .st.hi .v { color: #8ec5f0; }
.rpt-root .st.ng .v { color: #ff8b78; }
.rpt-root .vbox {
  display: flex; gap: 12px; align-items: baseline; border-radius: 4px; padding: 11px 16px;
  margin: 11px 0; font-family: var(--font-head); font-weight: 700; letter-spacing: .06em;
}
.rpt-root .vbox b { font-size: 17px; }
.rpt-root .vbox span { font-size: 11.5px; font-weight: 600; letter-spacing: 0; }
.rpt-root .vbox.pass { background: #16301f; border: 1px solid #2f6b47; color: #5fd39a; }
.rpt-root .vbox.fail { background: #33191a; border: 1px solid #7a3228; color: #ff8b78; }
.rpt-root .vbox.wait { background: #1e2226; border: 1px solid #3a4046; color: #8c9399; }
.rpt-root .calc {
  display: flex; gap: 18px; flex-wrap: wrap; background: #1e2226; border: 1px solid #3a4046;
  border-radius: 4px; padding: 9px 13px; margin: 10px 0; font-family: var(--font-num);
  font-size: 11.5px; color: #a9b0b6;
}
.rpt-root .calc b { color: #e8ecef; font-size: 12.5px; }
.rpt-root .calc .fml { margin-left: auto; color: var(--pc-gold); }

/* ── conclusion cards ── */
.rpt-root .ocards { display: grid; grid-template-columns: repeat(auto-fit, minmax(196px, 1fr)); gap: 9px; }
.rpt-root .cc {
  background: #2b3036; border: 1px solid #3f464c; border-radius: 5px; padding: 12px 14px;
  cursor: pointer; transition: .12s; text-align: left; font: inherit; position: relative;
}
.rpt-root .cc:hover { border-color: #6d757c; }
.rpt-root .cc .t { font-family: var(--font-head); font-size: 13px; font-weight: 700; color: #e4e8eb; }
.rpt-root .cc .t2 { font-size: 11px; color: #93a7b4; font-style: italic; margin-top: 2px; }
.rpt-root .cc.on { border-color: var(--pc-orange); background: #3a3230; box-shadow: 0 0 0 1px var(--pc-orange); }
.rpt-root .cc.on .t { color: var(--pc-orange); }
.rpt-root .ocards .cc .sg {
  position: absolute; top: 7px; right: 9px; font-family: var(--font-head); font-size: 8.5px;
  font-weight: 700; letter-spacing: .07em; background: #1e3a52; color: #8ec5f0;
  border-radius: 2px; padding: 1px 6px;
}
/* THE DESCRIPTION UNDER A RESULT CARD HAD NO COLOUR OF ITS OWN.
   A `<button>` child inherits the button's colour, and a DISABLED button's is the browser's
   greyed-out default — black at 30% alpha, which on this panel is unreadable. It went unseen while
   the extractor was dropping the acceptance results' descriptions on the way to the browser: the
   element existed and was empty. Carrying the description for the printed verdict box (D3) filled
   it in, and the same defect the rail's `.si` had in D1 surfaced in a second place. The text under
   a BLOCKED card is exactly what a technician reads to understand why it is blocked. */
.rpt-root .cc .d { margin-top: 4px; font-size: 11.5px; line-height: 1.5; color: #9aa1a7; }
.rpt-root .cc.on .d { color: #c8ced3; }
.rpt-root .ocards .cc.dis { opacity: .72; cursor: not-allowed; }
.rpt-root .ocards .cc .bl { margin-top: 6px; font-size: 10.5px; color: #f0a596; font-style: italic; }

/* ── findings ── */
.rpt-root .fcard { border: 1px solid #3a4046; border-radius: 5px; margin-bottom: 9px; background: #1e2226; overflow: hidden; }
.rpt-root .fcard.cri { border-color: #7a3228; }
.rpt-root .fh { display: flex; gap: 9px; align-items: center; flex-wrap: wrap; padding: 9px 13px; background: #22262a; border-bottom: 1px solid #343a40; }
.rpt-root .fcard.cri .fh { background: #2a1714; }
.rpt-root .fno { font-family: var(--font-num); font-weight: 700; font-size: 11px; color: #8f969c; }
.rpt-root .fh b { font-size: 12.5px; color: #e8ecef; }
.rpt-root .fsrc { margin-left: auto; font-family: var(--font-num); font-size: 10.5px; color: #8f969c; }
.rpt-root .fb { padding: 11px 13px; }

/* ── selected photo rows ── */
.rpt-root .selrow {
  display: flex; gap: 10px; align-items: center; border: 1px solid #3a4046; border-radius: 4px;
  padding: 8px; background: #1e2226; margin-bottom: 7px;
}
.rpt-root .selrow .th { width: 88px; height: 66px; flex: none; position: relative; background: #15181b; border-radius: 3px; overflow: hidden; cursor: pointer; }
.rpt-root .selrow .th img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rpt-root .selrow .th svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.rpt-root .selrow .th .ed2 { position: absolute; inset: 0; background: rgba(0, 0, 0, .55); display: none; place-items: center; font-family: var(--font-head); font-size: 10px; font-weight: 700; color: #fff; }
.rpt-root .selrow .th:hover .ed2 { display: grid; }
.rpt-root .selrow .ff { flex: 1 1 auto; min-width: 0; }
.rpt-root .selrow .cap { font-size: 12px; color: #d3d7da; line-height: 1.5; min-height: 18px; }
.rpt-root .selrow .cap b { color: var(--pc-orange); font-family: var(--font-num); }
.rpt-root .selrow .cap .l2 { display: block; color: #93a7b4; font-size: 11px; margin-top: 2px; border-left: 2px solid #3f464c; padding-left: 6px; }
.rpt-root .selrow .none { color: #8f969c; font-style: italic; font-size: 11.5px; }
.rpt-root .selrow .idx2 { font-family: var(--font-num); font-size: 11px; color: #8f969c; width: 18px; flex: none; text-align: center; }

/* ══════════════ MODALS ══════════════ */

.rpt-mask {
  position: fixed; inset: 0; background: rgba(15, 17, 19, .82); z-index: 1300;
  display: none; align-items: center; justify-content: center; padding: 18px;
}
.rpt-mask.on { display: flex; }
.rpt-mask .modal {
  background: #22262a; border: 1px solid #3a4046; border-radius: 6px; width: min(1180px, 100%);
  max-height: 100%; display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 24px 70px rgba(0, 0, 0, .6);
}
.rpt-mask .mh {
  background: var(--pc-black); border-bottom: 2px solid var(--pc-orange); padding: 9px 14px;
  display: flex; gap: 9px; align-items: center; flex-wrap: wrap; font-family: var(--font-head);
}
.rpt-mask .mh .t { color: #fff; font-weight: 700; font-size: 12.5px; letter-spacing: .05em; margin-right: auto; }
.rpt-mask .mh .t small { display: block; color: #9aa0a5; font-weight: 400; letter-spacing: 0; font-size: 10.5px; }
.rpt-mask .mb { display: flex; gap: 0; min-height: 0; flex: 1; }
.rpt-mask .mstage { flex: 1 1 auto; min-width: 0; background: #15181b; display: flex; align-items: center; justify-content: center; padding: 12px; overflow: auto; }
.rpt-mask .mside { width: 298px; flex: none; background: #272c31; border-left: 1px solid #3a4046; display: flex; flex-direction: column; min-height: 0; }
.rpt-mask .mside .sh { padding: 7px 11px; font-family: var(--font-head); font-size: 10.5px; font-weight: 700; letter-spacing: .06em; color: #9aa0a5; text-transform: uppercase; border-bottom: 1px solid #3a4046; }
.rpt-mask .mside .sl { flex: 1; overflow: auto; padding: 7px; }
.rpt-mask .mfoot { background: #1c2024; border-top: 1px solid #3a4046; padding: 9px 14px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.rpt-mask .mfoot .sp { margin-left: auto; }
.rpt-mask .mempty { color: #8f969c; font-size: 12px; text-align: center; padding: 26px 14px; line-height: 1.6; }
.rpt-mask .sepv { width: 1px; height: 22px; background: #3f464c; }

/* ── annotation canvas ── */
/* A site photograph is usually smaller than the frame. It is scaled UP to fill it: drawing an
   arrow on a 360px image cannot be aimed accurately. */
.rpt-mask .canvasWrap {
  /* SIZED IN PIXELS BY THE ANNOTATOR, not by CSS. The overlay's coordinates are fractions of THIS
     box, so the box has to be exactly the picture — letterboxing inside it, which is what
     object-fit: contain plus a max-height produced, silently moves every mark by the size of the
     bars. It was drawing arrows two centimetres from where the technician put them. */
  position: relative; display: block; line-height: 0; cursor: crosshair;
  touch-action: none; margin: 0 auto;
}
.rpt-mask .canvasWrap img { display: block; width: 100%; height: 100%; object-fit: fill; }
.rpt-mask .canvasWrap svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.rpt-mask .tool { display: flex; gap: 5px; align-items: center; }
.rpt-mask .tool button {
  font-family: var(--font-head); font-size: 11px; font-weight: 600; border: 1px solid #4a5158;
  background: #31373d; color: #cdd3d8; padding: 6px 10px; border-radius: 4px; cursor: pointer;
}
.rpt-mask .tool button.on { background: var(--pc-orange); border-color: var(--pc-orange); color: #fff; }
.rpt-mask .tool button:hover { border-color: #6d757c; }
.rpt-mask .swatch { width: 22px; height: 22px; border-radius: 4px; border: 2px solid #4a5158; cursor: pointer; padding: 0; }
.rpt-mask .swatch.on { border-color: #fff; box-shadow: 0 0 0 2px var(--pc-orange); }
.rpt-mask .mark { background: #31373d; border: 1px solid #3f464c; border-radius: 4px; padding: 6px 7px; margin-bottom: 6px; cursor: pointer; }
.rpt-mask .mark.sel { border-color: var(--pc-orange); background: #3a3230; }
.rpt-mask .mark .mt { display: flex; gap: 6px; align-items: center; margin-bottom: 4px; }
.rpt-mask .mark .idx { width: 18px; height: 18px; border-radius: 50%; color: #fff; font-family: var(--font-num); font-size: 10px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex: none; }
.rpt-mask .mark .ty { font-size: 10px; color: #9aa0a5; font-family: var(--font-head); letter-spacing: .03em; flex: 1; }
.rpt-mask .mark .rm { width: 18px; height: 18px; border: 1px solid #4a5158; background: #272c31; color: #9aa0a5; border-radius: 3px; cursor: pointer; font-size: 11px; line-height: 1; padding: 0; }
.rpt-mask .mark .rm:hover { background: var(--bad); border-color: var(--bad); color: #fff; }
.rpt-mask .mark input { width: 100%; font-family: var(--font-body); font-size: 11.5px; background: #1e2226; color: #e4e8eb; border: 1px solid #3f464c; border-radius: 3px; padding: 4px 6px; margin-bottom: 3px; }
.rpt-mask .mark input:focus { outline: 0; border-color: var(--pc-orange); }
.rpt-mask .mark input.i2 { color: #93a7b4; font-size: 11px; }

/* ── photo library ── */
.rpt-mask .libbar { display: flex; gap: 7px; padding: 9px 12px; background: #272c31; border-bottom: 1px solid #3a4046; flex-wrap: wrap; align-items: center; }
.rpt-mask .libbar input, .rpt-mask .libbar select {
  font-family: var(--font-body); font-size: 12.5px; background: #1e2226; color: #e4e8eb;
  border: 1px solid #3f464c; border-radius: 4px; padding: 6px 9px;
  /* styles.css gives every bare `select` and `input` `width: 100%`, which turned the library
     toolbar into four stacked full-width bars instead of one row of controls. */
  width: auto; max-width: 100%;
}
.rpt-mask .libbar input { flex: 1; min-width: 170px; }
.rpt-mask .libbar .hint { margin: 0; }
.rpt-mask .liblist { flex: 1; overflow: auto; padding: 11px 12px; background: #22262a; }
.rpt-mask .lgrp { font-family: var(--font-head); font-size: 10px; font-weight: 700; letter-spacing: .08em; color: var(--pc-gold); text-transform: uppercase; margin: 13px 0 7px; padding-bottom: 3px; border-bottom: 1px solid #3a4046; }
.rpt-mask .lgrp:first-child { margin-top: 0; }
.rpt-mask .pgal { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 9px; }
.rpt-mask .pit { background: #2b3036; border: 2px solid #383e44; border-radius: 4px; overflow: hidden; cursor: pointer; transition: .12s; position: relative; padding: 0; text-align: left; font: inherit; }
.rpt-mask .pit:hover { border-color: #6d757c; }
.rpt-mask .pit.on { border-color: var(--pc-orange); box-shadow: 0 0 0 2px rgba(243, 91, 39, .35); }
.rpt-mask .pit img { width: 100%; display: block; aspect-ratio: 4/3; object-fit: cover; }
.rpt-mask .pit .pc { padding: 5px 7px; font-size: 11px; color: #c3c9ce; line-height: 1.4; }
.rpt-mask .pit .pk { font-family: var(--font-num); font-size: 9px; color: #9aa0a5; }
.rpt-mask .pit .pb { position: absolute; top: 5px; right: 5px; width: 21px; height: 21px; border-radius: 50%; background: rgba(28, 32, 36, .9); border: 1px solid #4a5158; display: grid; place-items: center; font-family: var(--font-num); font-size: 10px; font-weight: 700; color: #9aa0a5; }
.rpt-mask .pit.on .pb { background: var(--pc-orange); border-color: var(--pc-orange); color: #fff; }
.rpt-mask .pit .pm { position: absolute; bottom: 29px; left: 5px; font-family: var(--font-head); font-size: 9px; font-weight: 700; letter-spacing: .05em; background: rgba(243, 91, 39, .92); color: #fff; padding: 1px 5px; border-radius: 2px; }

/* ══════════════ EDITOR COMPONENTS — the rest of the source's vocabulary ══════════════ */

/* Checkboxes and the drag grip. The native control is kept and TINTED rather than replaced: a
   custom checkbox loses keyboard behaviour, loses the platform's own focus ring, and gains
   nothing a technician can see from two feet away. */
.rpt-root .cbx { width: 14px; height: 14px; accent-color: var(--pc-orange); cursor: pointer; }
.rpt-root .grip { cursor: grab; color: #5a6167; user-select: none; font-size: 12px; }
.rpt-root tr.dover td { box-shadow: inset 0 2px 0 var(--pc-orange); }
.rpt-root .ctb td { vertical-align: top; }
.rpt-root .tb tr.bad td:first-child { box-shadow: inset 3px 0 0 #e8796a; }

/* The damage signals on a checklist row: chips that toggle, not a multi-select. Sixteen possible
   signs on one row have to be readable at a glance and tappable with a glove on. */
.rpt-root .dfx { display: flex; flex-wrap: wrap; gap: 3px 5px; padding-top: 8px !important; }
.rpt-root .dfx i {
  font-style: normal; font-size: 10.5px; background: #2b3036; border: 1px solid #3a4046;
  border-radius: 2px; padding: 2px 7px; color: #98a0a7; white-space: nowrap;
}
.rpt-root .dfx i.sg { cursor: pointer; user-select: none; transition: none; }
.rpt-root .dfx i.sg:hover { border-color: #5a6167; color: #c8ced3; }
.rpt-root .dfx i.sg.on { background: #4a2a24; border-color: #8a4a40; color: #f0a596; font-weight: 600; }
.rpt-root .dfx i.sg.on::before { content: '✓ '; font-weight: 700; }

.rpt-root .mrow { display: flex; gap: 5px; align-items: center; margin-top: 5px; }
.rpt-root .mrow label { font-size: 10px; color: #8c9399; flex: 0 0 auto; max-width: 88px; line-height: 1.25; }
.rpt-root .mrow .mu { font-family: var(--font-num); font-size: 10px; color: #8f969c; flex: none; }
.rpt-root .chk2 {
  display: inline-flex; gap: 7px; align-items: center; font-size: 12.5px; color: #c8ced3;
  margin: 2px 0 12px; cursor: pointer;
}
.rpt-root .addrow { margin: 8px 0 4px; }
.rpt-root .addbar { display: flex; gap: 6px; align-items: center; margin-top: 5px; }
.rpt-root .sfb.ad { background: #3a3220; color: #d9bd76; }

/* The working figures behind a verdict, shown rather than hidden. A technician arguing with a
   PASS needs to see the numbers it came from. */
.rpt-root .calc {
  display: flex; gap: 18px; flex-wrap: wrap; background: #1e2226; border: 1px solid #3a4046;
  border-radius: 4px; padding: 9px 13px; margin: 10px 0; font-family: var(--font-num);
  font-size: 11.5px; color: #a9b0b6;
}
.rpt-root .calc b { color: #e8ecef; font-size: 12.5px; }
.rpt-root .calc .fml { margin-left: auto; color: var(--pc-gold); }

/*
  The four-corner diagram: the input for each corner sits where that corner actually is on the
  machine. A technician crouched at the rear-left of a press reads "RR" on a form and has to
  translate; a box in the top-right of a rectangle needs no translating.
*/
.rpt-root .pgwrap {
  background: #1e2226; border: 1px solid #3a4046; border-radius: 5px;
  padding: 14px 16px 10px; margin: 12px 0;
}
.rpt-root .pgside {
  text-align: center; font-family: var(--font-head); font-size: 10px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: #8c9399; margin: 0 0 7px;
}
.rpt-root .pgside.b { margin: 7px 0 0; }
.rpt-root .pgbox {
  border: 2px solid #5a6167; border-radius: 5px; display: grid;
  grid-template-columns: 1fr 1fr; position: relative; max-width: 620px; margin: 0 auto;
  background: #1a1e22;
}
.rpt-root .pgbox::before {
  content: ''; position: absolute; left: 50%; top: 8px; bottom: 8px; width: 0;
  border-left: 1px dashed #3f464c;
}
.rpt-root .pgbox::after {
  content: ''; position: absolute; top: 50%; left: 8px; right: 8px; height: 0;
  border-top: 1px dashed #3f464c;
}
.rpt-root .pgc { padding: 13px 16px; text-align: center; position: relative; z-index: 1; }
.rpt-root .pgc .n1 { font-size: 11.5px; color: #c8ced3; line-height: 1.35; text-transform: capitalize; }
.rpt-root .pgc .n2 { font-size: 10px; color: #8f969c; font-style: italic; margin-bottom: 6px; }
.rpt-root .pgc input {
  width: 100%; max-width: 180px; text-align: center; font-family: var(--font-num);
  font-size: 14px; font-weight: 700; color: #e8ecef; background: #252a2f;
  border: 1px solid #3f464c; border-radius: 3px; padding: 6px 8px;
}
.rpt-root .pgc input:focus { outline: 0; border-color: var(--pc-orange); background: #1a1e22; }
.rpt-root .pgc.ref input { background: #1c2a36; border-color: #2f5a7d; color: #8ec5f0; }
.rpt-root .pgc.ref .n2 { color: #6f9dc4; }
.rpt-root .pgnote { font-size: 11.5px; color: #8c9399; line-height: 1.6; margin-top: 9px; }

/*
  The verdict. Thirty pixels of type, because it is the one thing on a measurement screen that
  someone will look for from across a workshop — and because a PASS that reads at the same weight
  as the field labels around it invites nobody to check it.
*/
.rpt-root .vd { border-radius: 5px; padding: 18px 20px; text-align: center; margin: 12px 0; }
.rpt-root .vd .vk {
  font-family: var(--font-head); font-size: 10px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: #8c9399; margin-bottom: 8px;
}
.rpt-root .vd .vv {
  font-family: var(--font-head); font-size: 30px; font-weight: 800; letter-spacing: .03em;
  line-height: 1.1;
}
.rpt-root .vd .ve { font-size: 12px; font-style: italic; margin-top: 3px; letter-spacing: .1em; }
.rpt-root .vd.pass .ve { color: #4aa87c; }
.rpt-root .vd.fail .ve { color: #d1705f; }
.rpt-root .vd.wait .ve { color: #8f969c; }
.rpt-root .vd .vx { font-size: 12px; margin-top: 8px; font-weight: 600; }
.rpt-root .vd.pass .vx { color: #8fd9b5; }
.rpt-root .vd.fail .vx { color: #f5b4a8; }
.rpt-root .vd.wait .vx { color: #a9b0b6; }
.rpt-root .vd.pass { background: #132a1d; border: 1px solid #2f6b47; }
.rpt-root .vd.pass .vv { color: #5fd39a; }
.rpt-root .vd.fail { background: #2c1618; border: 1px solid #7a3228; }
.rpt-root .vd.fail .vv { color: #ff8b78; }
.rpt-root .vd.wait { background: #1e2226; border: 1px solid #3a4046; }
.rpt-root .vd.wait .vv { color: #8c9399; font-size: 20px; }

/* Which standard produced that verdict, stated on the same screen as the verdict. */
.rpt-root .fnote {
  background: #1a2028; border-left: 3px solid #2f5a7d; border-radius: 0 4px 4px 0;
  padding: 11px 15px; margin: 12px 0; font-size: 11.5px; line-height: 1.7; color: #a9b0b6;
}
.rpt-root .fnote b { color: #cdd3d8; }
.rpt-root .fnote .tmp {
  display: block; margin-top: 7px; padding-top: 7px; border-top: 1px solid #2a323b;
  color: #8c9399; font-style: italic;
}

.rpt-root .bstat {
  margin-top: 12px; padding: 11px 15px; border-radius: 4px; display: flex; gap: 12px;
  align-items: baseline; flex-wrap: wrap;
}
.rpt-root .bstat span {
  font-family: var(--font-head); font-size: 10px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; opacity: .8;
}

/* A number field in a form grid reads right-aligned and tabular — a column of readings is
   compared down the column, not read as prose. */
.rpt-root .inp.n { font-family: var(--font-num); text-align: right; }

/* ══════════════ A4 PREVIEW ══════════════ */

.rpt-root .pv { background: #3c3f43; padding: 22px; border-radius: 5px; overflow: auto; }
/* The sheet is centred the way the source centres it: the wrapper is widened by exactly the
   inverse of the scale and then auto-margined, so the scaled result lands back in the middle.
   Scaling a full-width wrapper instead pushed the page off to one side of its own surround. */
.rpt-root .pvzoom { transform-origin: top center; margin: 0 auto; }

/* The A4 sheet itself. Geometry in millimetres, as the source declares it. */
.rpt-root .page {
  width: var(--pg-w); min-height: var(--pg-h); margin: 0 auto 20px;
  padding: var(--pg-t) var(--pg-x) var(--pg-b); background: #fff;
  box-shadow: 0 10px 40px rgba(0, 0, 0, .45); position: relative;
  /* NOT `overflow: hidden`. The packer estimates how much fits; when it estimates low the
     surplus has to be VISIBLE — on screen and on paper alike — because screen 4 exists to show
     what prints. Clipping would make the preview agree with itself and disagree with the
     printer, and silently drop content off a document a customer signs. */
  overflow: visible;
  font-family: var(--font-body); font-size: 10pt; line-height: 1.5; color: #111;
}
.rpt-root .pbody { min-height: calc(var(--pg-h) - var(--pg-t) - var(--pg-b) - var(--foot-h)); position: relative; }
.rpt-root .pfoot {
  position: absolute; left: var(--pg-x); right: var(--pg-x); bottom: var(--pg-b);
  height: var(--foot-h); border-top: 1px solid var(--pc-gray-light); display: flex;
  align-items: center; justify-content: space-between; font-size: 7.5pt; color: #6e6e6e; padding-top: 3px;
}
.rpt-root .pfoot b { color: var(--pc-orange); font-weight: 700; }
.rpt-root .pfoot .mid { color: #6e6e6e; }
.rpt-root .letter { display: flex; gap: 12px; align-items: flex-start; }
.rpt-root .letter .logo { width: 40mm; flex: none; padding-top: 1px; }
.rpt-root .letter .logo img { width: 100%; display: block; }
.rpt-root .letter .co { flex: 1; text-align: right; line-height: 1.42; font-size: 8.5pt; color: var(--pc-gray); }
.rpt-root .letter .co .c1 { font-family: var(--font-head); font-weight: 700; font-size: 10pt; color: var(--pc-black); letter-spacing: .02em; }
.rpt-root .letter .co .c2 { color: var(--pc-orange-deep); font-weight: 600; }
.rpt-root .rule { height: 3px; background: var(--pc-orange); margin: 6px 0 0; }
.rpt-root .ttl { text-align: center; margin: 9px 0 3px; }
.rpt-root .ttl .t1 { font-family: var(--font-head); font-size: 16pt; font-weight: 800; letter-spacing: -.01em; line-height: 1.15; color: var(--pc-black); }
.rpt-root .ttl .t2 { font-family: var(--font-head); font-size: 9.5pt; font-weight: 600; letter-spacing: .06em; color: #8a8a8a; margin-top: 2px; }
.rpt-root .ttl .t3 { font-family: var(--font-num); font-size: 9pt; color: var(--pc-gray); margin-top: 4px; }
.rpt-root .sech {
  font-family: var(--font-head); font-size: 10pt; font-weight: 700; margin: 9px 0 4px;
  color: #fff; background: var(--pc-black); padding: 3.5px 9px; letter-spacing: .02em;
  line-height: 1.3; display: flex; gap: 8px; align-items: baseline;
  break-after: avoid; page-break-after: avoid;
}
.rpt-root .pbody > .sech:first-child { margin-top: 0; }
.rpt-root .sech .no { background: var(--pc-orange); min-width: 5.2mm; height: 5.2mm; display: inline-grid; place-items: center; font-size: 8pt; flex: none; border-radius: 1px; padding: 0 1mm; white-space: nowrap; }
.rpt-root .page .sech i, .rpt-root .sech i { color: #c9c9c9; font-weight: 500; }
.rpt-root .sech .sec2 { font-family: var(--font-head); font-weight: 500; font-size: 8pt; color: #c9c9c9; letter-spacing: .02em; }
.rpt-root .kv { display: grid; grid-template-columns: 34mm 1fr 30mm 1fr; gap: 2.5px 6px; font-size: 9pt; margin: 5px 0 2px; }
.rpt-root .kv .k { color: var(--pc-gray); }
.rpt-root .kv .k .sec { display: block; font-size: 7pt; color: #a5a5a5; font-style: italic; }
.rpt-root .kv .v { font-weight: 600; }
.rpt-root .para { font-size: 9.5pt; line-height: 1.55; margin: 4px 0; text-align: justify; white-space: pre-wrap; }
.rpt-root .page .sec { font-style: italic; font-weight: 500; color: #6e6e6e; }
.rpt-root .page .l2 { display: block; }
.rpt-root .para .l2 { color: #3c4c5c; font-size: 9pt; line-height: 1.42; margin-top: 2px; border-left: 2px solid #dfe6ec; padding-left: 5px; }
.rpt-root .kv .v .l2 { color: #5c6c7c; font-size: 7.5pt; font-weight: 400; font-style: italic; margin-top: 1px; }
.rpt-root .ptb { width: 100%; border-collapse: collapse; font-size: 8.5pt; margin: 4px 0; }
.rpt-root .ptb th { background: var(--pc-ivory); text-align: left; padding: 3.5px 5px; border: 1px solid #DDD; font-family: var(--font-head); font-size: 7.5pt; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--pc-gray); }
.rpt-root .ptb th .sec { display: block; font-size: 6.5pt; font-weight: 500; color: #a5a5a5; text-transform: none; letter-spacing: 0; font-style: italic; }
.rpt-root .ptb td { padding: 3.5px 5px; border: 1px solid #E6E6E6; vertical-align: top; }
.rpt-root .ptb .n { text-align: right; font-family: var(--font-num); }
.rpt-root .ptb .c { text-align: center; }
.rpt-root .ptb .ok { color: #16663d; font-weight: 700; }
.rpt-root .ptb .ng { color: var(--bad); font-weight: 700; }
.rpt-root .ptb .l2 { display: block; color: #3c4c5c; font-size: 7.5pt; margin-top: 1px; }
.rpt-root .pgrid { display: grid; gap: 3mm; margin: 4px 0; }
.rpt-root .pgrid.n1 { grid-template-columns: 1fr; }
.rpt-root .pgrid.n2 { grid-template-columns: repeat(2, 1fr); }
.rpt-root .pgrid.n3 { grid-template-columns: repeat(3, 1fr); }
.rpt-root .pcell { display: flex; flex-direction: column; break-inside: avoid; page-break-inside: avoid; }
.rpt-root .phb { position: relative; width: 100%; overflow: hidden; background: #eceff1; border: 1px solid #DDD; }
.rpt-root .phb img { width: 100%; height: 100%; display: block; object-fit: cover; }
.rpt-root .phb svg.ov { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.rpt-root .pcap { font-size: 7.5pt; color: var(--pc-gray); padding: 2px 1px 0; line-height: 1.38; }
.rpt-root .pcap b { color: var(--pc-orange-deep); font-family: var(--font-num); }
.rpt-root .pcap .l2 { display: block; color: #5c6c7c; font-size: 7pt; margin-top: 1px; }
/* The conclusion callout on the printed page. Bordered and weighted because it is the one
   line a customer reads first, and a sentence that important should not look like a paragraph. */
.rpt-root .ovbox { border: 1.5px solid var(--pc-black); border-radius: 1mm; padding: 3mm 4mm; margin: 2mm 0; }
.rpt-root .ovbox .ovk { font-family: var(--font-head); font-size: 13pt; font-weight: 800; letter-spacing: .04em; }
.rpt-root .ovbox .ovk2 { font-size: 9.5pt; font-style: italic; color: #555; margin-top: .3mm; }
.rpt-root .ovbox .ovd { font-size: 9pt; color: #444; margin-top: 1mm; white-space: pre-wrap; }
.rpt-root .ovbox.c-bad { border-color: #c0392b; background: #fdf1ef; }
.rpt-root .ovbox.c-warn { border-color: #d35400; background: #fdf6ef; }
.rpt-root .ovbox.c-ok { border-color: #1e7d4e; background: #f0f9f4; }

.rpt-root .bul { font-size: 9.5pt; margin: 3px 0; padding-left: 5mm; line-height: 1.55; }
.rpt-root .bul li { margin-bottom: 1.5px; }
.rpt-root .sign { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6mm; margin-top: 6mm; break-inside: avoid; }
.rpt-root .sign .box { text-align: center; }
.rpt-root .sign .box .t1 { font-family: var(--font-head); font-size: 8.5pt; font-weight: 700; letter-spacing: .03em; }
.rpt-root .sign .box .t2 { font-size: 7.5pt; color: var(--pc-gray); font-style: italic; }
.rpt-root .sign .box .sp { height: 22mm; }
.rpt-root .sign .box .nm { font-size: 9pt; border-top: 1px solid var(--pc-black); padding-top: 1.5mm; }

/* ══════════════ THE STEP 8 CARD (on the project page, not inside the workspace) ══════════════ */

.rpt-card { border: 1px solid var(--line, #e4e7ec); border-radius: 8px; padding: 14px 16px; background: #fff; }
.rpt-card-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.rpt-card-title { margin: 0; font-size: 14px; }
.rpt-card-sum { margin: 0; font-size: 12px; color: var(--text-muted, #55585c); }
.rpt-card-head .btn { margin-left: auto; }
.rpt-rows { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 1px; background: var(--line, #e4e7ec); border: 1px solid var(--line, #e4e7ec); border-radius: 6px; overflow: hidden; }
.rpt-row-open { display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 12px; background: #fff; border: 0; font: inherit; font-size: 12.5px; text-align: left; cursor: pointer; }
.rpt-row-code { font-weight: 700; color: #f35b27; }
.rpt-row-number { font-variant-numeric: tabular-nums; }
.rpt-row-date, .rpt-row-rev, .rpt-row-lang { font-size: 11.5px; color: var(--text-muted, #55585c); }
.rpt-row-open .rpt-chip { margin-left: auto; }
.rpt-chip { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 10px; background: #eef0f3; color: #55585c; white-space: nowrap; }
.rpt-chip--ok { background: #eefaf4; color: #147a4e; }
.rpt-chip--warn { background: #fff4ef; color: #a34a00; }
.rpt-chip--void { background: #fdecec; color: #e01b24; text-decoration: line-through; }
.rpt-chip--review { background: #eaf2fd; color: #1a5fb4; }
.rpt-empty { font-size: 13px; color: var(--text-muted, #55585c); margin: 8px 0; }
.rpt-error { font-size: 13px; color: #e01b24; background: #fdecec; padding: 10px 14px; border-radius: 6px; margin: 10px 0 0; }

/* ══════════════ MEASUREMENT DIAGRAMS ══════════════ */

/*
  ONE SET OF TOKENS, TWO CONTEXTS.

  The same drawing functions serve the dark editor and the white printed sheet, so the colours they
  use are named rather than literal and each context supplies its own values. Without these the
  `var(--dg-*)` references resolve to nothing, `fill` falls back to black, and the slide in the
  clearance diagram renders as a solid black slab with an invisible label on it — which is exactly
  what happened.

  The alternative — two copies of every diagram, one per context — drifts apart within a wave.
*/
.rpt-root {
  --dg-line: #5a6167;
  --dg-grid: #3a4046;
  --dg-axis: #8f969c;
  --dg-lbl: #9aa1a7;
  --dg-lbl2: #8f969c;
  --dg-val: #e8ecef;
  --dg-ref-bg: #1c2a36;
  --dg-ref-bd: #2f5a7d;
  --dg-ref-fg: #8ec5f0;
}

/* The printed sheet is paper: dark ink, light grounds, the same variable names. */
.rpt-root .page {
  --dg-line: #1a1a1a;
  --dg-grid: #dfe3e6;
  --dg-axis: #9aa1a7;
  --dg-lbl: #5c6368;
  --dg-lbl2: #8a9198;
  --dg-val: #1a1a1a;
  --dg-ref-bg: #e8f0f8;
  --dg-ref-bd: #8fb4d4;
  --dg-ref-fg: #1f5c8c;
}

/*
  A diagram is a diagram, not a poster. Left to fill the editor it renders half a metre tall and
  pushes the readings it is supposed to explain off the bottom of the screen.
*/
.rpt-root .dgbox {
  max-width: 620px; margin: 0 auto; background: #1a1e22; border: 1px solid #343a40;
  border-radius: 4px; padding: 10px 14px;
}
.rpt-root .page .dgbox { background: none; border: 0; padding: 0; max-width: none; }

/*
  A measured value must never wrap.

  "0.2800" broken into six lines is the defect the Owner photographed on the checklist, and it
  appears anywhere a numeric column is narrower than its content. Numbers are atomic: the column
  scrolls or the table gets wider, but the value stays on one line.
*/
.rpt-root .tb td.n, .rpt-root .tb th.n,
.rpt-root .tb td.c, .rpt-root .tb th.c,
.rpt-root .ptb td.n, .rpt-root .ptb td.c { white-space: nowrap; }
.rpt-root .st .v, .rpt-root .vd .vv, .rpt-root .calc { white-space: nowrap; }

/*
  ══════════════ COLLISION RESETS ══════════════

  `.rpt-root` stops the source's short class names from leaking OUT. It does not stop the
  application's own global rules from leaking IN — `.rpt-root .brand` (0,2,0) wins over `.brand`
  (0,1,0) only for the properties it actually declares, and inherits the rest.

  Every rule below was found by walking the live DOM and asking, element by element, which global
  rules match it. That is the only reliable way: `.brand` lives in `frontend/public/styles.css`,
  a file this workspace has nothing to do with, and it painted the PRESTEC wordmark white-on-white
  in the toolbar — invisible, and invisible in a way no unit test can see.

  Each reset states the property the global rule set, back to what the source has.
*/

/* styles.css `.brand` — a white card with padding and a bottom border. The source's brand is text
   on the black toolbar and nothing else. */
.rpt-root .toolbar .brand {
  display: inline; background: none; padding: 0; border: 0; border-radius: 0; gap: 0;
}

/* styles.css `.toolbar` — `justify-content: space-between` (which fights `.rt { margin-left:auto }`)
   and an 8px bottom margin that opened a stripe of page ground under a sticky bar. */
.rpt-root .toolbar { justify-content: flex-start; margin-bottom: 0; }

/* prestec.css `.btn` — `height: var(--control-h)`, the application's 36px control height. The
   source's buttons are sized by their own padding; forcing a height makes `.btn.sm` the same size
   as `.btn` and a row of them twice as tall as the toolbar that holds them. */
.rpt-root .btn { height: auto; min-height: 0; }

/* styles.css `table { table-layout: fixed }`. A fixed layout divides the width equally over the
   columns and ignores the per-column widths the checklists set, so a 65-row inspection table came
   out with a 30mm "TT" column and the item names wrapped to four lines each. */
.rpt-root table, .rpt-mask table { table-layout: auto; }

/*
  prestec.css `.modal` — a 520px white card; styles.css declares `.modal` as a full-screen overlay.
  Loaded later, prestec.css wins, and the hybrid gave the modal `position: fixed`, `top/left: 0`,
  `padding: 18px` and — the visible one — `align-items: center`, which in a column flexbox shrinks
  every child to its own content width. The photo library rendered as four differently sized bars
  floating over the mask instead of one panel.
*/
.rpt-mask .modal {
  position: relative; inset: auto; margin: 0; padding: 0; transform: none;
  align-items: stretch; justify-content: flex-start; min-width: 0;
}

/*
  ══════════════ READABILITY ══════════════

  Owner defect: dark text on a dark ground in places inside the Report workspace.

  The cause is always the same shape. This application's global stylesheet styles BARE elements —
  `select, textarea { background: #fff }`, `input { font: inherit }` — and those rules reach any
  control here that does not happen to carry `.inp`, `.sel`, `.ta` or `.ci`. The control then keeps
  the workspace's light foreground on a white ground it inherited from three files away, or the
  reverse. Neither is visible.

  So this block styles BY ELEMENT rather than by class: inside `.rpt-root` and `.rpt-mask`, every
  control gets the dark palette whether or not anybody remembered a class name. The class rules
  above still do the finer work; this is the floor beneath them, and a new control added next year
  is readable before anyone styles it.

  Every state is stated, because a state nobody wrote is a state the browser fills in from
  somewhere else: normal, hover, focus, disabled, readonly, placeholder, selection, the option list
  a native dropdown paints itself, and the calendar button Chromium draws in near-black.
*/

.rpt-root input, .rpt-root select, .rpt-root textarea,
.rpt-mask input, .rpt-mask select, .rpt-mask textarea {
  color: #e8ecef;
  background-color: #2b3036;
  border-color: #3f464c;
  font-family: var(--font-body);
}

/* Transparent-by-design controls keep their ground; only the INK is forced. */
.rpt-root .ci, .rpt-root .ci:hover { color: #e4e8eb; }
.rpt-root .ci { background-color: transparent; }
.rpt-root .ci:hover { background-color: #272c31; }
.rpt-root .ci:focus { background-color: #1a1e22; }

/*
  The native dropdown list. Chromium paints it from the OPTION's own colours, not the select's, so
  a select styled dark still opens a white list with white text on some platforms.
*/
.rpt-root option, .rpt-mask option { background-color: #22262a; color: #e8ecef; }
.rpt-root optgroup, .rpt-mask optgroup { background-color: #1c2024; color: #9aa0a5; }

.rpt-root ::placeholder, .rpt-mask ::placeholder { color: #8f969c; opacity: 1; }
.rpt-root ::selection, .rpt-mask ::selection { background: rgba(243, 91, 39, .38); color: #fff; }

/*
  DISABLED MUST NOT LOOK LIKE READONLY, and neither may become unreadable.

  Opacity alone was doing both jobs and doing neither: at .55 a disabled select's text falls below
  any sensible contrast, and a reader cannot tell "you may not change this" from "this is a fact,
  not a field". So disabled dims the GROUND and keeps the ink legible, readonly keeps the ground and
  softens the border, and the two look different on purpose.
*/
.rpt-root input:disabled, .rpt-root select:disabled, .rpt-root textarea:disabled,
.rpt-mask input:disabled, .rpt-mask select:disabled, .rpt-mask textarea:disabled {
  color: #a9b0b6; background-color: #23272b; border-color: #343a40;
  opacity: 1; cursor: not-allowed;
}
.rpt-root .inp[disabled], .rpt-root .sel[disabled], .rpt-root .ta[disabled] { opacity: 1; }
.rpt-root input[readonly], .rpt-root textarea[readonly] {
  color: #c3c9ce; background-color: #262b30; border-style: dashed; cursor: default;
}

/* An invalid value is named by colour AND by border, so it survives a monochrome screenshot. */
.rpt-root input:invalid, .rpt-root select:invalid {
  border-color: #7a4038; background-color: #241b1a;
}

/*
  Chromium draws the date input's calendar button as a near-black glyph, which on a #2b3036 ground
  is a smudge. Inverting it is the only hook the browser gives.
*/
.rpt-root input[type="date"]::-webkit-calendar-picker-indicator,
.rpt-mask input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(0.75);
  cursor: pointer;
}

/* The workspace ground for anything that inherits rather than declares. */
.rpt-root { color: #d3d7da; }
.rpt-root label, .rpt-root .rok { color: #8c9399; }
.rpt-root .rov, .rpt-root b, .rpt-root strong { color: #e4e8eb; }
.rpt-root em, .rpt-root i { color: #9aa0a5; }
.rpt-root a { color: var(--pc-gold); }

/*
  The printed sheet is the ONE place inside `.rpt-root` that is light, and everything above would
  otherwise reach into it and paint white text onto white paper. Re-stated here for the sheet and
  everything in it, including the controls a preview never has but a future one might.
*/
.rpt-root .page { color: #111; }
.rpt-root .page input, .rpt-root .page select, .rpt-root .page textarea {
  color: #111; background-color: #fff; border-color: #ddd;
}
.rpt-root .page option { background-color: #fff; color: #111; }
.rpt-root .page label { color: var(--pc-gray); }
.rpt-root .page b, .rpt-root .page strong { color: inherit; }
.rpt-root .page em, .rpt-root .page i { color: #6e6e6e; }
.rpt-root .page a { color: var(--pc-orange-deep); }

/* ══════════════ PRINTING ══════════════ */

@media print {
  /* The sheet is moved to <body> for the duration of the print and everything else is hidden.
     `body.prj-doc-printing > *` is the canonical isolation this application already uses for the
     quotation and the contract — reused rather than reinvented, so one rule governs every printed
     document in the product. */
  body.prj-doc-printing > * { display: none !important; }
  body.prj-doc-printing > [data-report-print-host] { display: block !important; }
  /* ACCEPTANCE-01 D3 — the BBNT travels in its own host, and it needs the same two rules. Without
     them the acceptance record printed as correctly laid out, correctly sized, completely blank A4
     sheets: the host was hidden by the line above and nothing opted it back in. Found by taking the
     PDF of a real preview and reading its size. */
  body.prj-doc-printing > [data-acceptance-print-host] { display: block !important; }
  /* styles.css sets a global @media print { body * { visibility: hidden } } and expects
     printable content to opt back IN — .print-area is its own escape hatch. Without this the
     report printed as correctly laid out, correctly sized, completely invisible white A4
     sheets: right page count, right geometry, nothing on them. The other printed documents in
     this application carry the same opt-in for the same reason. */
  body.prj-doc-printing [data-report-print-host],
  body.prj-doc-printing [data-report-print-host] *,
  body.prj-doc-printing [data-acceptance-print-host],
  body.prj-doc-printing [data-acceptance-print-host] * { visibility: visible !important; }
  .rpt-root .pv { background: none; padding: 0; }
  .rpt-root .pvzoom { transform: none !important; }
  .rpt-root .page { box-shadow: none; margin: 0; break-after: page; page-break-after: always; }
  .rpt-root .page:last-child { break-after: auto; page-break-after: auto; }
  .rpt-root .toolbar, .rpt-root .ef, .rpt-root .rail { display: none !important; }
}

/* ── reading-column floors ──
   A reading column holds a control, and `.ci` is `width:100%` — which an auto table layout measures
   as zero-wide intrinsic content. The column then collapses to its padding, clipping the reading
   out of sight, while the declared `width` sits there being treated as the suggestion it is. The
   flatness table failed exactly this way: three stored readings, three empty-looking boxes, and a
   |Δ| column computing correctly from numbers nobody could see. `min-width` is a floor, and a
   column of measurements needs a floor rather than a preference. */
.rpt-root .tb .wRead { width: 130px; min-width: 130px; }
.rpt-root .tb .wCalc { width: 96px; min-width: 96px; }

/* Root cause of the same defect: a `width:100%` control has no intrinsic width at all, so a column
   holding one is free to collapse to nothing no matter what its header asks for. A floor on the
   control itself means no reading column can vanish even where nobody remembered to size it. */
.rpt-root .tb .ci, .rpt-root .tb .sel { min-width: 64px; }

/* ── §5-M measurement blocks on paper ──
   The diagram sits BESIDE the readings it explains, not above them: a figure on one page and its
   table on the next is the same defect as a photograph separated from its caption, and the packer
   is told so with `data-rp-keep`. On a narrow sheet the pair stacks rather than shrinking the
   drawing into illegibility. */
.rpt-root .page .mrow {
  display: grid; grid-template-columns: 62mm 1fr; gap: 4mm; align-items: start; margin: 4px 0;
}
.rpt-root .page .mfig {
  border: 1px solid #E0E4E8; background: #FCFDFE; border-radius: 2px; padding: 2mm;
}
.rpt-root .page .mfig svg { display: block; width: 100%; height: auto; }
.rpt-root .page .mnum > .ptb { margin-top: 0; }
.rpt-root .page .mcap {
  font-size: 7.5pt; color: var(--pc-gray); text-align: center; margin-top: 1mm;
  font-family: var(--font-head); text-transform: uppercase; letter-spacing: .03em;
}
/* The verdict a reader looks for first, given the weight it has on screen. Ink, not a colour
   wash — a fax or a mono office printer must still resolve ĐẠT from KHÔNG ĐẠT, so the word
   carries the meaning and the tint only reinforces it. */
.rpt-root .page .mvd {
  display: flex; align-items: baseline; gap: 4mm; margin: 5px 0 3px; padding: 2.5mm 3mm;
  border: 1px solid #DDD; border-left: 3px solid var(--pc-gray); background: var(--pc-ivory);
  break-inside: avoid; page-break-inside: avoid;
}
.rpt-root .page .mvd .mvl {
  font-family: var(--font-head); font-size: 7.5pt; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--pc-gray);
}
.rpt-root .page .mvd .mvv { font-size: 11pt; font-weight: 700; color: #1a1a1a; }
.rpt-root .page .mvd.ok { border-left-color: #16663d; background: #F3F9F5; }
.rpt-root .page .mvd.ok .mvv { color: #16663d; }
.rpt-root .page .mvd.ng { border-left-color: var(--bad); background: #FDF5F4; }
.rpt-root .page .mvd.ng .mvv { color: var(--bad); }
.rpt-root .page .mvd .l2 { display: block; font-size: 7.5pt; font-weight: 400; font-style: italic; }
@media (max-width: 900px) {
  .rpt-root .page .mrow { grid-template-columns: 1fr; }
}

/* ── §3 · the two greys the dark editor could not carry ──
   `#7d848a` and `#6b7278` are the source's own greys and they are right on white paper, where the
   source uses them. On the workshop-dark editor ground they land at 3.1–4.2:1 — under the 4.5:1
   floor for body text, and they were carrying the stat cards' English sub-labels, the units beside
   every measurement, the corner codes on the four-point grids and every placeholder in the form.
   Lifted to #8f969c (≥4.8:1 on all four panel grounds) for the EDITOR only; `.rpt-root .page`
   keeps the source's paper palette, because that is the document PRESTEC has always issued and
   §3 asks about the dark theme. */

/* A required-but-empty textarea wears the same red the required inputs do — `.ci.miss` and
   `select.sel.miss` already existed; the multi-line case did not, so the one field §14 makes
   mandatory was the one field that could not show it was missing. */
.rpt-root .ta.miss { border-color: #7a4038; background: #241b1a; }
/* And the line under it that says why, in the colour the report uses for a problem. */
.rpt-root .hint.bad { color: #e8796a; }

/* ── §4 · a row with no factors ──
   Said with a dash rather than left blank, so an empty cell reads as "this item has no signal
   list" instead of as a column that failed to render. `.none` already existed but only inside
   `.selrow`, so in the checklist it had no colour at all. */
.rpt-root .dfx .none { color: #8f969c; font-style: italic; }
/* The legend's symbol carries the level's colour and a little more weight than its wording: it is
   the token being defined. */
.rpt-root .legend span b { font-family: var(--font-num); font-size: 13px; line-height: 1; }
.rpt-root .al .hint { margin-top: 7px; font-size: 11px; color: #98a0a7; }
.rpt-root .al .hint b { font-family: var(--font-num); font-size: 13px; }

/* ── §8 · the checklist evidence, quoted on the finding ──
   Chips in their selected state and not clickable: this is a quotation of what was recorded on the
   row, and the row is where it can be changed. */
.rpt-root .fev { display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: center; margin: 2px 0 8px; }
.rpt-root .fev i {
  font-style: normal; font-size: 10.5px; background: #4a2a24; border: 1px solid #8a4a40;
  border-radius: 2px; padding: 2px 7px; color: #f0a596; font-weight: 600; white-space: nowrap;
}
.rpt-root .fev i::before { content: '✓ '; }
.rpt-root .fev .fmv { font-size: 11px; color: #b8c0c6; }
.rpt-root .fev .fmv b { font-family: var(--font-num); color: #e4e8eb; }

/* ── §6, §23 · the assessment ON PAPER is the symbol ──
   A 10mm column carrying O Δ × ! / –, in the source's own inks (v2 line 372). The customer reads
   a column of glyphs down the page and sees the shape of the inspection before reading a word;
   printing "Cần sửa" in full there would need four times the width and say the same thing. These
   inks survive a mono printer as differing weights, which is why the glyph carries the meaning
   and the colour only reinforces it. */
.rpt-root .ptb td.sym {
  font-family: var(--font-num); font-weight: 700; font-size: 11pt; text-align: center;
}
.rpt-root .sym-cri { color: #c0392b; }
.rpt-root .sym-rep { color: #d35400; }
.rpt-root .sym-mon { color: #8a6d1f; }
.rpt-root .sym-ok  { color: #1e7d4e; }
.rpt-root .sym-na, .rpt-root .sym-todo { color: #999; }
/* A ticked factor is the evidence; an unticked one is the checklist it was found on. The customer
   should see what the technician FOUND without reading everything they looked at.

   THE DIFFERENCE IS A SHAPE, NOT A COLOUR. These reports are printed, and they are printed on
   whatever is in the office — which is very often a mono laser. Bold red against grey separates
   cleanly on screen and collapses to two nearly equal greys on paper, at which point the customer
   cannot tell what was found from what was merely looked for. So a ticked factor is a BOXED chip:
   a dark rule around a light ground, which survives any printer, and the red ink stays for the
   colour copies. An unticked one is plain text with no border — the two are different objects at
   arm's length, before anybody reads a word. */
.rpt-root .ptb .sig-on {
  display: inline-block; border: 1px solid #1a1a1a; border-radius: 0.8mm;
  padding: 0.1mm 1.3mm; background: #ededed; font-weight: 700; color: #a5281b;
  line-height: 1.45;
}
.rpt-root .ptb .sig-off { color: #8a8a8a; }
.rpt-root .ptb .sig-sep { color: #c4c4c4; }

/* ── §10 · the squareness panels ──
   Ported verbatim from the source (v2 lines 312-321), and their absence is the whole reason the
   squareness screen looked nothing like the approved one: the markup already asked for `.vgrid`,
   `.vpan`, `.vpt`, `.vpg` and `.vchart`, and with no rules behind them the two axis panels
   collapsed into one stacked column with an unbounded diagram underneath.

   THE TWO AXES SIT SIDE BY SIDE because that is the comparison being made. X and Y are two
   readings of the same stroke, and a technician deciding whether the slide is square reads them
   against each other — stacked, one is a screen-scroll away from the other. */
.rpt-root .vgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 12px 0; }
.rpt-root .vpan {
  background: #1e2226; border: 1px solid #3a4046; border-radius: 5px; padding: 12px 14px;
}
.rpt-root .vpt {
  font-family: var(--font-head); font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: #e4e8eb; margin-bottom: 10px; padding-bottom: 6px;
  border-bottom: 1px solid #343a40;
}
.rpt-root .vpg { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.rpt-root .vpg .fld { margin-bottom: 0; }
.rpt-root .vchart {
  margin-top: 11px; background: #1a1e22; border: 1px solid #343a40; border-radius: 4px;
  padding: 6px;
}
/* The source's own breakpoint: below 900px the two panels stack rather than shrink, because half
   of a 900px workspace is not enough to read a trajectory in. */
@media (max-width: 900px) {
  .rpt-root .vgrid { grid-template-columns: 1fr; }
}

/* ── §20 · the executive summary ──
   Ported from the source (v2 lines 205-220). The markup already emitted `.exec`, `.eh2`,
   `.etiles`, `.xtile`, `.etop` and `.etl`; with no rules behind them the six tallies rendered as a
   bare stack of text and the top findings as an unstyled list, which is why Tổng quan read as a
   dump rather than as the summary page one of the report is supposed to be.

   THE COUNT IS THE HEADLINE, in the numeric face at 21px, with its level's wording underneath —
   somebody opening a 65-row inspection wants "1 nguy hiểm" before they want anything else. The
   critical tile takes a border and a ground of its own, because a 1 in that column is not the same
   kind of fact as a 52 in the normal one. */
.rpt-root .exec {
  background: #22262a; border: 1px solid #3a4046; border-left: 3px solid var(--pc-orange);
  border-radius: 5px; padding: 14px 16px; margin: 14px 0;
}
.rpt-root .eh2 {
  font-family: var(--font-head); font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--pc-orange); margin-bottom: 11px;
}
.rpt-root .etiles { display: flex; gap: 9px; flex-wrap: wrap; }
.rpt-root .xtile {
  background: #1a1e22; border: 1px solid #3a4046; border-radius: 4px; padding: 8px 13px;
  min-width: 92px;
}
.rpt-root .xtile b { display: block; font-family: var(--font-num); font-size: 21px; line-height: 1.1; }
.rpt-root .xtile span { font-size: 10.5px; color: #8c9399; }
.rpt-root .xtile.a-cri { border-color: #7a3228; background: #241614; }
.rpt-root .xtile.a-rep { border-color: #5e332c; }
.rpt-root .etop { margin-top: 12px; padding-top: 11px; border-top: 1px solid #343a40; }
.rpt-root .etl {
  font-family: var(--font-head); font-size: 10px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: #8c9399; margin-bottom: 6px;
}
.rpt-root .etop ol { margin: 0; padding-left: 19px; font-size: 12.5px; line-height: 1.75; color: #d3d7da; }
.rpt-root .etop ol i { font-style: normal; font-family: var(--font-num); font-weight: 700; }

/* ── §16 · a step of the measuring guide ──
   The last class the source styles and this stylesheet had not ported (v2 lines 239-243). It is
   the box around one step of the measuring guide — internal help for the technician, which is why
   it appears in the modal and never on the customer's sheet. */
.rpt-root .gbx, .rpt-mask .gbx {
  background: #1e2226; border: 1px solid #3a4046; border-radius: 4px; padding: 11px 14px;
  margin-bottom: 9px;
}
.rpt-root .gbx h4, .rpt-mask .gbx h4 {
  margin: 0 0 4px; font-family: var(--font-head); font-size: 11.5px; font-weight: 700;
  color: var(--pc-gold); letter-spacing: .02em;
}
.rpt-root .gbx p, .rpt-mask .gbx p { margin: 0; font-size: 12.5px; line-height: 1.65; color: #c1c7cc; }

/* The muted "nothing here" line, wherever it appears. It used to be written as an inline colour on
   each site, which put it out of reach of the stylesheet — including out of reach of the §3 pass
   that lifted the two source greys the dark ground could not carry, so one of them survived as a
   4.2:1 sentence nobody could see to fix. A class can be audited; an inline style cannot. */
.rpt-root .none { color: #8f969c; font-style: italic; }

/* ── §20 · the executive summary ON PAPER ──
   Ported from the source (v2 lines 375-382). `overviewBody` emits `.xsum`, `.xt` and `.xtop`, and
   without these rules the summary printed as a run-on line of numbers. The critical and repair
   tiles take a border and a tint of their own, because a 1 in that column is not the same kind of
   fact as a 52 in the normal one — and the BORDER is what survives a mono printer. */
.rpt-root .page .xsum { display: flex; gap: 4mm; margin: 3mm 0 2mm; flex-wrap: wrap; }
.rpt-root .page .xsum .xt {
  border: 1px solid #ccc; border-radius: 1mm; padding: 1.6mm 3mm; min-width: 20mm;
}
.rpt-root .page .xsum .xt b {
  display: block; font-family: var(--font-num); font-size: 15pt; line-height: 1.05;
}
.rpt-root .page .xsum .xt span { font-size: 7pt; color: #666; }
.rpt-root .page .xsum .xt.c-cri { border-color: #c0392b; background: #fdf1ef; }
.rpt-root .page .xsum .xt.c-rep { border-color: #d35400; background: #fdf6ef; }
.rpt-root .page .xtop {
  border-left: 2px solid var(--pc-orange); padding-left: 3mm; margin-top: 2mm;
}
.rpt-root .page .xtop ol { margin: 1mm 0 0; padding-left: 5mm; font-size: 9pt; line-height: 1.55; }

/* ═════════════════════════════════════════════════════════════════════════════════════════════
   ACCEPTANCE-01 · BBNT — Step 9, the acceptance and handover record.

   Ported from the approved source, not re-designed: the lifecycle chain (v2:607-623), the Step 8
   quotation box (v2:625-638), the two-column signature block on paper (v2:783-790). Namespaced
   under .rpt-root like everything else here, so Step 9 is the next stage of the same workspace
   rather than a second application living in the same page.
   ═════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── the document lifecycle chain ──
   Shown at the head of Tổng quan and again above the signatures, because whoever is writing needs
   to know WHERE IN THE LIFECYCLE they are, not only which box they are typing in. */
.rpt-root .ntflow {
  background: #1e2226; border: 1px solid #3a4046; border-radius: 5px; padding: 11px 13px;
  margin-bottom: 13px;
}
.rpt-root .ntfl {
  font-family: var(--font-head); font-size: 10px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: #8c9399; margin-bottom: 8px;
}
.rpt-root .ntchain { display: flex; gap: 5px; flex-wrap: wrap; }
.rpt-root .ntstep {
  background: #2b3036; border: 1px solid #3f464c; border-radius: 4px; padding: 6px 10px;
  text-align: left; cursor: pointer; transition: .12s; min-width: 104px;
}
.rpt-root .ntstep:hover:not(.dis) { border-color: #6d757c; }
.rpt-root .ntstep .k {
  display: block; font-family: var(--font-num); font-size: 8.5px; letter-spacing: .05em;
  color: #7d848a;
}
.rpt-root .ntstep .t {
  display: block; font-family: var(--font-head); font-size: 11.5px; font-weight: 700;
  color: #c8ced3; margin-top: 1px;
}
.rpt-root .ntstep.past { border-color: #2f6b47; }
.rpt-root .ntstep.past .t { color: #5fd39a; }
.rpt-root .ntstep.on { border-color: var(--pc-orange); background: #3a3230; }
.rpt-root .ntstep.on .t { color: var(--pc-orange); }
.rpt-root .ntstep.dis { opacity: .35; cursor: not-allowed; }

/* ── what Step 8 said, quoted ──
   Gold rather than the workspace grey, because this block is the one thing on the screen the
   technician may NOT change: it is the technical report speaking. */
.rpt-root .ntrep {
  border: 1px solid #4a4028; background: #241f16; border-radius: 5px; padding: 11px 13px;
  margin-bottom: 12px;
}
.rpt-root .ntrh { font-size: 11.5px; color: #d9bd76; margin-bottom: 9px; }
.rpt-root .ntrh b { font-family: var(--font-num); color: #f0d79a; }
.rpt-root .ntrg {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 9px;
}
.rpt-root .ntrc {
  background: #1e2226; border: 1px solid #3a4046; border-left-width: 3px; border-radius: 4px;
  padding: 8px 11px;
}
.rpt-root .ntrc span {
  display: block; font-family: var(--font-head); font-size: 9.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: #8c9399;
}
.rpt-root .ntrc b {
  display: block; font-family: var(--font-head); font-size: 14px; font-weight: 800; margin-top: 3px;
}
.rpt-root .ntrc.a-ok { border-left-color: #2fa36a; } .rpt-root .ntrc.a-ok b { color: #5fd39a; }
.rpt-root .ntrc.a-mon { border-left-color: #b8912f; } .rpt-root .ntrc.a-mon b { color: #e8c476; }
.rpt-root .ntrc.a-rep { border-left-color: #a4453a; } .rpt-root .ntrc.a-rep b { color: #ff8b78; }
.rpt-root .ntrc.a-na { border-left-color: #5a6066; } .rpt-root .ntrc.a-na b { color: #9aa0a5; }

/* ── the fixed legal sentences ──
   A list, never an input. §22: the wording is issued by PRESTEC and an engineer does not restate
   it per project, so it must not even LOOK editable. */
.rpt-root .ntstmt {
  font-size: 12.5px; color: #c8ced3; line-height: 1.6; margin: 0 0 13px; padding-left: 18px;
}
.rpt-root .ntstmt li { margin-bottom: 5px; }
.rpt-root .ntstmt .l2 { display: block; color: #8c9399; font-size: 11.5px; font-style: italic; }
.rpt-root .ntwrap { display: flex; gap: 14px; flex-wrap: wrap; }

/* ── the warranty verdict ──
   NOT a subtle badge. A deferred warranty has contractual significance, and the difference between
   "running" and "not yet running" must survive a glance (§18). */
.rpt-root .ntwar {
  border: 1px solid #3a4046; border-left-width: 4px; border-radius: 5px; padding: 12px 14px;
  background: #1e2226; margin-bottom: 13px;
}
.rpt-root .ntwar .wl {
  font-family: var(--font-head); font-size: 9.5px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: #8c9399;
}
.rpt-root .ntwar .wv {
  font-family: var(--font-head); font-size: 17px; font-weight: 800; margin: 3px 0 0;
}
.rpt-root .ntwar .wd { font-size: 12px; color: #a8aeb4; margin-top: 5px; line-height: 1.55; }
.rpt-root .ntwar.w-on { border-left-color: #2fa36a; } .rpt-root .ntwar.w-on .wv { color: #5fd39a; }
.rpt-root .ntwar.w-off { border-left-color: #b8912f; background: #24211a; }
.rpt-root .ntwar.w-off .wv { color: #e8c476; }
.rpt-root .ntwar.w-no { border-left-color: #a4453a; } .rpt-root .ntwar.w-no .wv { color: #ff8b78; }
.rpt-root .ntwar ul { margin: 6px 0 0; padding-left: 17px; font-size: 12px; color: #c8ced3; }
.rpt-root .ntwar ul li { margin-bottom: 3px; }

/* ── the truth ceiling, explained where it bites ──
   §9: a disabled option with no explanation is how a technician concludes the system is broken. */
.rpt-root .ntlock {
  display: block; margin-top: 4px; font-size: 11px; color: #d9bd76; line-height: 1.45;
}
.rpt-root .ntlock b { color: #f0d79a; font-family: var(--font-num); }

/* ── the completion gate, grouped by section ── */
.rpt-root .ntgate { margin-top: 10px; }
.rpt-root .ntgate .gsec {
  font-family: var(--font-head); font-size: 10px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: #8c9399; margin: 9px 0 4px;
}
.rpt-root .ntgate ul { margin: 0; padding-left: 17px; }
.rpt-root .ntgate li { margin-bottom: 4px; font-size: 12.5px; line-height: 1.5; }
.rpt-root .ntgate button.gjump {
  background: none; border: 0; padding: 0; font: inherit; color: #e8c476; cursor: pointer;
  border-bottom: 1px dotted #7a6a3a; text-align: left;
}
.rpt-root .ntgate button.gjump:hover { color: #f0d79a; border-bottom-style: solid; }

/* ═══ ON PAPER ═══════════════════════════════════════════════════════════════════════════════ */

/* Two parties, two columns, from the first glance (v2:783-790). A record that two sides sign must
   not read as one long list of people. */
.rpt-root .page .ntsides {
  display: grid; grid-template-columns: 1fr 1fr; gap: 5mm; margin-top: 5mm; margin-bottom: 3mm;
}
.rpt-root .page .ntsl {
  font-family: var(--font-head); font-size: 8.5pt; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--pc-gray); border-bottom: 1px solid var(--pc-gray-light);
  padding-bottom: 1mm;
}
.rpt-root .page .ntsl .sec { font-style: italic; font-weight: 500; color: #9a9a9a; }
.rpt-root .page .sign.nt2 { margin-top: 0; grid-template-columns: repeat(2, 1fr); }
.rpt-root .page .sign.nt2 .box .sp { height: 20mm; }
.rpt-root .page .twobox { display: grid; grid-template-columns: 1fr 1fr; gap: 4mm; }
.rpt-root .page .ovbox {
  border: 1px solid var(--pc-gray-light); border-radius: 1mm; padding: 2mm 3mm;
}
.rpt-root .page .ovl {
  font-family: var(--font-head); font-size: 7.5pt; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--pc-gray);
}
.rpt-root .page .ovk {
  font-family: var(--font-head); font-size: 13pt; font-weight: 800; margin-top: 1mm;
}
.rpt-root .page .ovk2 { font-size: 9pt; font-style: italic; color: #666; }
.rpt-root .page .ovd { font-size: 8.5pt; color: #444; margin-top: 1mm; line-height: 1.5; }

/* MONOCHROME SAFETY (§38). REPORT-01 established that a customer prints these in black and white:
   the acceptance verdict, a deferred warranty and an outstanding item must each be legible with no
   colour at all, so every one carries a BORDER and a weight as well as a tint. */
.rpt-root .page .ovbox.c-ok { border-color: #1e7d4e; border-left-width: 2mm; }
.rpt-root .page .ovbox.c-warn { border-color: #9a7b1f; border-left-width: 2mm; background: #fdfaf0; }
.rpt-root .page .ovbox.c-bad { border-color: #a4302a; border-left-width: 2mm; background: #fdf1ef; }
.rpt-root .page .callout {
  border: 1px solid var(--pc-gray-light); border-left: 2mm solid #888; border-radius: 1mm;
  padding: 2mm 3mm; margin: 2mm 0; background: #fafafa;
}
.rpt-root .page .ntw {
  border: 1px solid #333; border-left-width: 2mm; border-radius: 1mm; padding: 2mm 3mm;
  margin: 2mm 0;
}
.rpt-root .page .ntw .wl {
  font-family: var(--font-head); font-size: 7.5pt; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--pc-gray);
}
.rpt-root .page .ntw .wv {
  font-family: var(--font-head); font-size: 12pt; font-weight: 800; margin-top: .5mm;
}
.rpt-root .page .ntw.w-off { border-color: #9a7b1f; background: #fdfaf0; }
.rpt-root .page .ntw.w-no { border-color: #a4302a; background: #fdf1ef; }
.rpt-root .page .ntw ul { margin: 1mm 0 0; padding-left: 4mm; font-size: 8.5pt; }

/* ═════════════════════════════════════════════════════════════════════════════════════════════
   ACCEPTANCE-01 · PHASE D2 — the lifecycle surface.

   Actions, signature capture, the issue confirmation, the two drawers. Same namespace, same
   palette, same components as everything above: Step 9's lifecycle is the next part of the same
   workspace and must not arrive looking like a different product.

   MONOCHROME FIRST (§42). PARTIALLY_SIGNED, SIGNED and ISSUED are the three states a reader is
   most likely to confuse and the three whose difference matters most, so none of them is told
   apart by colour: each carries its own mark, its own words, and its own BORDER WEIGHT AND STYLE.
   Print it in black and white, or read it with no colour vision at all, and the three are still
   three different things.
   ═════════════════════════════════════════════════════════════════════════════════════════════ */

.rpt-root .ntlife {
  background: #1e2226; border: 1px solid #3a4046; border-radius: 5px;
  padding: 12px 14px; margin-bottom: 13px;
}
.rpt-root .ntlife-state { display: flex; gap: 10px; flex-wrap: wrap; align-items: stretch; }
.rpt-root .ntlife-acts {
  display: flex; gap: 7px; flex-wrap: wrap; margin-top: 11px;
  padding-top: 11px; border-top: 1px solid #31373d;
}

/* ── the lifecycle state ── */
.rpt-root .ntstate {
  display: inline-flex; align-items: center; gap: 9px;
  background: #262b31; border: 1px solid #454c53; border-radius: 4px; padding: 8px 13px;
  color: #d3d7da;
}
.rpt-root .ntstate-m { font-family: var(--font-num); font-size: 15px; line-height: 1; color: #c8ced3; }
.rpt-root .ntstate-t {
  font-family: var(--font-head); font-size: 12.5px; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: #e8ecef;
}
.rpt-root .ntstate-n { font-style: normal; font-size: 11px; color: #9aa1a7; }

.rpt-root .ntstate-DRAFT { border-style: dotted; }
.rpt-root .ntstate-READY_FOR_REVIEW { border-color: #4b6480; }
.rpt-root .ntstate-IN_REVIEW { border-color: #4b6480; border-width: 2px; }
.rpt-root .ntstate-APPROVED { border-color: #2f6b47; border-width: 2px; }
.rpt-root .ntstate-READY_FOR_SIGNATURE { border-color: #6a5122; border-width: 2px; }
/* The three that must never be mistaken for one another. */
.rpt-root .ntstate-PARTIALLY_SIGNED {
  border-color: #b8791a; border-width: 2px; border-style: dashed; background: #2b2314;
}
.rpt-root .ntstate-PARTIALLY_SIGNED .ntstate-t { color: #f0c476; }
.rpt-root .ntstate-SIGNED {
  border-color: #2f6b47; border-width: 2px; border-style: solid; background: #17261e;
}
.rpt-root .ntstate-SIGNED .ntstate-t { color: #7fe0ac; }
.rpt-root .ntstate-ISSUED {
  border-color: #c8ced3; border-width: 4px; border-style: double; background: #2a2f34;
}
.rpt-root .ntstate-ISSUED .ntstate-t { color: #ffffff; }
.rpt-root .ntstate-CANCELLED { border-color: #8a3b33; border-width: 2px; background: #2a1a18; }
.rpt-root .ntstate-CANCELLED .ntstate-t { color: #f0a79c; }

/* ── the acceptance outcome, at every stage (§34) ── */
.rpt-root .ntout {
  display: inline-flex; align-items: center; gap: 8px;
  background: #262b31; border: 1px solid #454c53; border-left-width: 4px; border-radius: 4px;
  padding: 8px 13px; color: #d3d7da;
}
.rpt-root .ntout b { font-family: var(--font-num); font-size: 14px; line-height: 1; }
.rpt-root .ntout > span {
  font-family: var(--font-head); font-size: 12px; font-weight: 800; letter-spacing: .05em;
}
.rpt-root .ntout i { font-style: normal; font-size: 11px; color: #9aa1a7; }
.rpt-root .ntout-acc { border-left-color: #2f6b47; }
.rpt-root .ntout-acc > span { color: #7fe0ac; }
.rpt-root .ntout-cond { border-left-color: #b8791a; border-left-style: dashed; }
.rpt-root .ntout-cond > span { color: #f0c476; }
.rpt-root .ntout-no { border-left-color: #a4302a; border-left-width: 6px; }
.rpt-root .ntout-no > span { color: #f0a79c; }
.rpt-root .ntout-none { border-left-style: dotted; }
.rpt-root .ntout-none > span { color: #9aa1a7; }

/* ── the signature meter (§13, §29) ── */
.rpt-root .ntmeter {
  display: inline-flex; align-items: center; gap: 9px;
  background: #262b31; border: 1px solid #454c53; border-radius: 4px; padding: 8px 13px;
  color: #d3d7da;
}
.rpt-root .ntmeter-t {
  font-family: var(--font-head); font-size: 10px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: #8c9399;
}
.rpt-root .ntmeter b { font-family: var(--font-num); font-size: 14px; color: #e8ecef; }
.rpt-root .ntmeter-bar { display: inline-flex; gap: 3px; }
.rpt-root .ntmeter-bar i {
  width: 16px; height: 7px; border-radius: 2px; border: 1px solid #6d757c; display: inline-block;
}
.rpt-root .ntmeter-bar i.on { background: #7fe0ac; border-color: #2f6b47; }
.rpt-root .ntmeter-bar i.off { background: transparent; }
.rpt-root .ntmeter-opt { font-size: 10.5px; color: #8c9399; }

.rpt-root .ntactor { margin-top: 9px; font-size: 11.5px; color: #9aa1a7; }
.rpt-root .ntactor b { color: #d3d7da; }

/* ── the return notice (§8, §25) ──
   Loud on purpose: it is the first thing an author needs and the last thing that should be one
   click inside a history drawer. */
.rpt-root .ntreturn { border-left: 5px solid #a4302a; }
.rpt-root .ntreturn-r { display: flex; gap: 9px; align-items: baseline; margin: 4px 0 7px; }
.rpt-root .ntreturn-r > span {
  font-family: var(--font-head); font-size: 10px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; opacity: .8; flex: 0 0 auto;
}
.rpt-root .ntreturn-r b { font-size: 13.5px; line-height: 1.55; }
.rpt-root .ntreturn-m { display: flex; gap: 16px; flex-wrap: wrap; font-size: 11.5px; opacity: .9; }
.rpt-root .ntreturn button { margin-top: 9px; }

/* ── the signature panel (§11, §12, §13, §30) ── */
.rpt-root .ntsigpanel { margin-top: 16px; }
.rpt-root .ntsgs { display: flex; gap: 11px; flex-wrap: wrap; }
.rpt-root .ntsg {
  flex: 1 1 300px; min-width: 0;
  background: #1e2226; border: 1px solid #3a4046; border-radius: 5px; overflow: hidden;
}
.rpt-root .ntsg > header {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  background: #262b31; border-bottom: 1px solid #3a4046; padding: 7px 11px;
}
.rpt-root .ntsg-side {
  font-family: var(--font-head); font-size: 10.5px; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; color: #d9bd76;
}
.rpt-root .ntsg-req { font-size: 10px; color: #8c9399; }
.rpt-root .ntsg-st {
  margin-left: auto; display: inline-flex; gap: 5px; align-items: center;
  font-family: var(--font-head); font-size: 10.5px; font-weight: 800; letter-spacing: .06em;
  color: #9aa1a7;
}
.rpt-root .ntsg-st b { font-family: var(--font-num); font-size: 12px; }
.rpt-root .ntsg-b { padding: 10px 11px; font-size: 12px; color: #b9bfc4; }
.rpt-root .ntsg-n { font-size: 14px; font-weight: 700; color: #e8ecef; }
.rpt-root .ntsg-n.miss { color: #f0a79c; font-style: italic; font-weight: 400; }
.rpt-root .ntsg-r, .rpt-root .ntsg-o, .rpt-root .ntsg-m { margin-top: 2px; color: #9aa1a7; }
.rpt-root .ntsg-at, .rpt-root .ntsg-ev { margin-top: 6px; font-size: 11px; color: #8c9399; }
.rpt-root .ntsg-dec { margin-top: 6px; font-size: 11.5px; color: #f0a79c; }
.rpt-root .ntsg > footer {
  display: flex; gap: 7px; padding: 9px 11px; border-top: 1px solid #31373d; flex-wrap: wrap;
}
.rpt-root .ntsg > footer .hint { margin: 0; }
/* Signed / pending / declined told apart by border as well as by the word in the header. */
.rpt-root .ntsg-signed { border-color: #2f6b47; border-left: 4px solid #2f6b47; }
.rpt-root .ntsg-signed .ntsg-st { color: #7fe0ac; }
.rpt-root .ntsg-pending { border-left: 4px dashed #6d757c; }
.rpt-root .ntsg-declined { border-color: #8a3b33; border-left: 4px solid #a4302a; }
.rpt-root .ntsg-declined .ntsg-st { color: #f0a79c; }

/* ── dialogs (§8, §16, §19, §20, §31) ──
   In the document rather than in window.confirm, because the issue confirmation has to SHOW the
   outcome, the warranty verdict and the conditions travelling forward, and a native dialog can
   show one line of text. */
.rpt-root .ntdlg-back {
  position: fixed; inset: 0; background: rgba(12, 14, 16, .72); z-index: 40;
}
.rpt-root .ntdlg {
  position: fixed; z-index: 41; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: min(620px, calc(100vw - 32px)); max-height: calc(100vh - 48px); overflow: auto;
  background: #1e2226; border: 1px solid #4a525a; border-radius: 6px;
  box-shadow: 0 18px 60px rgba(0, 0, 0, .55);
}
.rpt-root .ntdlg.danger { border-color: #8a3b33; }
.rpt-root .ntdlg-h {
  font-family: var(--font-head); font-size: 13px; font-weight: 800; letter-spacing: .05em;
  text-transform: uppercase; color: #e8ecef;
  padding: 13px 16px; border-bottom: 1px solid #3a4046; background: #262b31;
}
.rpt-root .ntdlg-b { padding: 14px 16px; }
.rpt-root .ntdlg-lead { margin: 0 0 13px; font-size: 12.5px; line-height: 1.65; color: #b9bfc4; }
.rpt-root .ntdlg-f {
  display: flex; gap: 8px; justify-content: flex-end;
  padding: 11px 16px; border-top: 1px solid #3a4046; background: #1a1e22;
}

/* ── the issue confirmation (§16, §33) ── */
.rpt-root .ntconf-dl { margin: 0 0 12px; }
.rpt-root .ntconf-dl > div {
  display: flex; gap: 12px; align-items: baseline;
  padding: 6px 0; border-bottom: 1px solid #2b3036;
}
.rpt-root .ntconf-dl dt {
  flex: 0 0 210px; font-family: var(--font-head); font-size: 10.5px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: #8c9399;
}
.rpt-root .ntconf-dl dd { margin: 0; font-size: 13px; color: #e8ecef; font-weight: 600; }
.rpt-root .ntconf-warn {
  margin: 12px 0 0; padding: 10px 12px; font-size: 12px; line-height: 1.65;
  background: #2b2314; border: 1px solid #6a5122; border-left-width: 4px; border-radius: 4px;
  color: #e8d5a8;
}

.rpt-root .ntsign-asset { margin-bottom: 13px; }
.rpt-root .ntsign-asset .al { margin-bottom: 0; }

/* ── the two drawers (§21, §22) ── */
.rpt-root .ntdrawer {
  background: #1e2226; border: 1px solid #3a4046; border-radius: 5px;
  padding: 12px 14px; margin-bottom: 13px;
}
.rpt-root .ntdrawer > header {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-bottom: 10px;
}
.rpt-root .ntdrawer > header b {
  font-family: var(--font-head); font-size: 11.5px; font-weight: 800; letter-spacing: .06em;
  text-transform: uppercase; color: #d3d7da;
}
.rpt-root .ntrev-now > td { background: #2a2f34; }
.rpt-root .ntlog { list-style: none; margin: 0; padding: 0; }
.rpt-root .ntlog > li {
  display: flex; gap: 11px; flex-wrap: wrap; align-items: baseline;
  padding: 7px 0; border-bottom: 1px solid #2b3036; font-size: 12px; color: #b9bfc4;
}
.rpt-root .ntlog-t { font-family: var(--font-num); font-size: 11px; color: #8c9399; flex: 0 0 120px; }
.rpt-root .ntlog-a {
  font-family: var(--font-head); font-size: 11.5px; font-weight: 700; color: #e8ecef;
  flex: 0 0 170px;
}
.rpt-root .ntlog-w { color: #d9bd76; flex: 0 0 auto; }
.rpt-root .ntlog-d { color: #9aa1a7; }
.rpt-root .ntlog-n { flex: 1 1 100%; color: #9aa1a7; font-style: italic; }

/* ── narrow screens (§42) ──
   Nothing here is allowed to need sideways scrolling. The action bar wraps, the signer cards drop
   to one column, and the confirmation list stacks its labels above its values. */
@media (max-width: 900px) {
  .rpt-root .ntlife-state { flex-direction: column; }
  .rpt-root .ntsg { flex: 1 1 100%; }
  .rpt-root .ntconf-dl > div { flex-direction: column; gap: 2px; }
  .rpt-root .ntconf-dl dt { flex: 1 1 auto; }
  .rpt-root .ntlog > li { flex-direction: column; gap: 2px; }
  .rpt-root .ntlog-t, .rpt-root .ntlog-a { flex: 1 1 auto; }
}

/* ═════════════════════════════════════════════════════════════════════════════════════════════
   ACCEPTANCE-01 · PHASE D3 — the BBNT on paper.

   Everything here is scoped under `.rpt-root .page` or under the BBNT preview shell, so no rule
   below can reach a REPORT-01 sheet (§31). The A4 frame itself — `.page`, `.pbody`, `.pfoot`, the
   letterhead, `.sech`, `.kv`, `.ptb`, `.bul`, `.sign`, `.ovbox`, `.callout`, `.twobox`,
   `.ntsides`, `.ntw` — is the one REPORT-01 and the D-phase visual port already established, and
   this block adds only what the printed BBNT needs on top of it.

   MONOCHROME IS THE DEFAULT ASSUMPTION (§30). The source carries a severity in `.sym-*`, which is
   colour and nothing else; printed in black and white, "đạt" and "chưa đạt" then look identical.
   Every status that matters here therefore also carries a GLYPH and a WEIGHT, and the `@media
   print` block at the end strips the colour entirely to prove it still reads.
   ═════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── the severity colours the source declares (v2:373) ── */
.rpt-root .page .sym-cri { color: #c0392b; }
.rpt-root .page .sym-rep { color: #c0392b; }
.rpt-root .page .sym-mon { color: #8a6d1f; }
.rpt-root .page .sym-ok { color: #1e7d4e; }
.rpt-root .page .sym-na, .rpt-root .page .sym-todo { color: #8a8a8a; }

/* The glyph that carries the same meaning with no colour at all. Kept in the numeric face so the
   three marks line up down a column and read as a shape before they read as a word. */
.rpt-root .page .apmark {
  font-family: var(--font-num); font-size: 9pt; font-weight: 700; margin-right: .8mm;
}

/* The method line in a BBNT signature box (v2:778) — missing from the visual port. */
.rpt-root .page .sign .box .s3 { color: var(--pc-gray); font-size: 7.5pt; margin-bottom: 1mm; }

/* ── a scope line's condition, under the item it belongs to ── */
.rpt-root .page .apcond {
  font-size: 8pt; color: #555; margin-top: .8mm; padding-left: 2mm;
  border-left: 1.5px solid var(--pc-gray-light);
}

/* §12 — the customer-facing meaning of a condition that defers the warranty. On the row it is true
   of, and nowhere else: stamping "không ảnh hưởng" on every other row buries the one that matters. */
.rpt-root .page .apwarn {
  font-size: 8pt; font-weight: 600; color: #8a6d1f; margin-top: .8mm;
  padding-left: 2mm; border-left: 2px solid #9a7b1f;
}

/* §17 — a date that would have started the clock, under its own caveat and never styled as one. */
.rpt-root .page .apcand {
  font-size: 8.5pt; color: #6e6e6e; margin-top: 1mm;
}

/* §4 — an unissued acceptance that reaches a printer says so on its face. */
.rpt-root .page .apdraft {
  margin-top: 2mm; padding: 1.5mm 3mm; text-align: center;
  font-family: var(--font-head); font-size: 9pt; font-weight: 800; letter-spacing: .12em;
  color: #a4302a; border: 1.5px dashed #a4302a; border-radius: 1mm; background: #fdf1ef;
}

/* ── the signature space ── */
.rpt-root .page .apsig {
  font-family: var(--font-head); font-size: 8pt; font-weight: 700; color: #1e7d4e;
}
.rpt-root .page .apsigt { font-weight: 400; color: #666; font-size: 7.5pt; }
.rpt-root .page .apsige {
  font-weight: 400; color: #8a8a8a; font-size: 7pt; font-style: italic;
}
.rpt-root .page .apdec {
  font-family: var(--font-head); font-size: 8pt; font-weight: 700; color: #a4302a;
}

/* §14 — the three handover-document statuses, each with a border weight as well as its glyph, so
   the column survives a grayscale print and a reader who does not see colour. */
.rpt-root .page .ap-st { border-left-width: 2px; border-left-style: solid; }
.rpt-root .page .ap-st-given { border-left-color: #1e7d4e; color: #1e7d4e; }
.rpt-root .page .ap-st-later { border-left-color: #9a7b1f; border-left-style: dashed; color: #8a6d1f; }
.rpt-root .page .ap-st-na { border-left-color: #b8b8b8; border-left-style: dotted; color: #6e6e6e; }
.rpt-root .page .ap-st-none { border-left-color: #e0e0e0; color: #8a8a8a; }

/* The warranty verdict block is a bordered box rather than a line of body text — the deliberate,
   recorded deviation from the source (§18). Contractual significance plus monochrome safety. */
.rpt-root .page .ntw .wv { letter-spacing: .04em; }
.rpt-root .page .ntw[data-ap-warranty="ELIGIBLE_AND_STARTED"] { border-color: #1e7d4e; }
.rpt-root .page .ntw[data-ap-warranty="ELIGIBLE_AND_STARTED"] .wv { color: #1e7d4e; }
.rpt-root .page .ntw[data-ap-warranty="DEFERRED_BY_ACCEPTANCE_CONDITION"] .wv { color: #8a6d1f; }
.rpt-root .page .ntw[data-ap-warranty="NOT_ELIGIBLE_NOT_ACCEPTED"] .wv { color: #a4302a; }
.rpt-root .page .ntw[data-ap-warranty="NOT_APPLICABLE"] .wv { color: #6e6e6e; }

/* ── the preview bar above the A4 pages (§48) ── */
.rpt-root .appv-bar {
  display: flex; gap: 9px; align-items: center; flex-wrap: wrap;
  background: #1e2226; border: 1px solid #3a4046; border-radius: 5px;
  padding: 11px 15px; margin-bottom: 11px;
}
.rpt-root .appv-bar .appv-t {
  font-family: var(--font-head); font-size: 11px; font-weight: 700; letter-spacing: .05em;
  color: #8c9399; text-transform: uppercase;
}

/* ═══════════════ WHAT COMES OUT OF THE PRINTER ═══════════════
   The proof that none of the above needs colour: on paper the severity tints are dropped to black
   and every distinction is carried by the glyph, the weight and the border. If a status is
   indistinguishable here, it is indistinguishable on a customer's monochrome printer — and that is
   the printer most of these documents meet. */
@media print {
  .rpt-root .page .sym-cri, .rpt-root .page .sym-rep,
  .rpt-root .page .sym-mon, .rpt-root .page .sym-ok { color: #111; }
  .rpt-root .page .sym-rep .apmark, .rpt-root .page .sym-cri .apmark { font-weight: 800; }
  .rpt-root .page .ap-st-given, .rpt-root .page .ap-st-later,
  .rpt-root .page .ap-st-na, .rpt-root .page .ap-st-none { color: #111; }
  .rpt-root .page .apdraft { color: #111; border-color: #111; background: none; }
  .rpt-root .appv-bar { display: none; }
}
