/* Self-hosted, not Google Fonts — those are blocked in mainland China, which is
   where the inspectors filling these in actually are. Latin subsets only, 128KB total.

   IBM Plex was drawn for technical documentation, which is what this is. Plex Mono
   carries the identifiers and measurements — SKUs, PO numbers, dimensions, defect
   counts — because those are data, and setting them as data makes a column scannable.
   Chinese is not in these files; it falls through to the CJK chain below, unchanged. */
@font-face{font-family:'IBM Plex Sans';src:url('fonts/ibm-plex-sans-latin-400-normal.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'IBM Plex Sans';src:url('fonts/ibm-plex-sans-latin-500-normal.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'IBM Plex Sans';src:url('fonts/ibm-plex-sans-latin-600-normal.woff2') format('woff2');font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:'IBM Plex Sans';src:url('fonts/ibm-plex-sans-latin-700-normal.woff2') format('woff2');font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url('fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url('fonts/ibm-plex-mono-latin-600-normal.woff2') format('woff2');font-weight:600;font-style:normal;font-display:swap}

/* Fesco Reports — screen UI + the print stylesheet that produces the PDF. */

/* Every CJK family that might carry 简体中文 has to be named explicitly: browsers do
   NOT fall back to an installed CJK font from a Latin-only stack, so Chinese remark
   text renders as blank space if the list stops at sans-serif.

   ORDER MATTERS. "PingFang SC" must come AFTER the Hiragino/Heiti/Songti entries.
   On macOS builds where PingFang is not a real font file the name still resolves to
   a glyph-less face, and Chrome then drops the entire Chinese run instead of
   continuing down the list — verified by rendering print-to-PDF output. Listing it
   later keeps iOS working (where Hiragino is absent and PingFang is the real font)
   without breaking macOS. */
:root{
  --font-mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,monospace;
  --font-ui:'IBM Plex Sans',-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,
    "Hiragino Sans GB","Heiti SC","Songti SC","PingFang SC","Microsoft YaHei",
    "Noto Sans CJK SC","Source Han Sans SC","WenQuanYi Micro Hei","Droid Sans Fallback",sans-serif;
  --bg:#f1f5f9; --card:#fff; --ink:#0f172a; --muted:#64748b; --line:#e2e8f0;
  --navy:#0f172a; --accent:#b45309; --accent-soft:#fef3c7;
  --pass:#047857; --fail:#b91c1c; --hold:#b45309; --na:#64748b;
  --radius:10px;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  background:var(--bg); color:var(--ink);
  font:15px/1.5 var(--font-ui);
  -webkit-text-size-adjust:100%;
}
h1,h2,h3,h4{margin:0 0 .4em; line-height:1.25}
button{font:inherit; cursor:pointer}
input,select,textarea{font:inherit; color:inherit}

/* ---------------- gate ---------------- */
#gate{position:fixed; inset:0; display:grid; place-items:center; background:var(--navy); padding:24px; z-index:50}
/* An id selector outranks the UA's [hidden]{display:none}, so the gate needs its
   own hidden rule or it stays on screen after unlocking. */
#gate[hidden],#app[hidden]{display:none}
.gatebox{width:min(360px,100%); background:#fff; border-radius:14px; padding:28px 24px; text-align:center}
.gatemark{font-size:11px; letter-spacing:.22em; font-weight:800; color:var(--accent)}
.gatebox h1{font-size:20px; margin-top:10px}
.gatebox p{color:var(--muted); font-size:14px; margin:0 0 18px}
.gatebox input{width:100%; padding:12px 14px; border:1px solid var(--line); border-radius:8px; margin-bottom:10px}
.gatebox button{width:100%; padding:12px; border:0; border-radius:8px; background:var(--navy); color:#fff; font-weight:600}
.gateerr{color:var(--fail); font-size:13px; min-height:18px; margin-top:8px}
.gateerr.gatenote{color:var(--muted)}

/* ---------------- chrome ---------------- */
.topbar{
  position:sticky; top:0; z-index:20; background:var(--navy); color:#fff;
  display:flex; flex-wrap:wrap; gap:8px; align-items:center; justify-content:space-between;
  padding:10px 16px; padding-top:max(10px,env(safe-area-inset-top));
}
.brand{display:flex; align-items:baseline; gap:10px; color:#fff; text-decoration:none; min-width:0}
.mark{font-size:12px; letter-spacing:.18em; font-weight:600; color:#fbbf24}
.crumb{font-size:14px; color:#cbd5e1; white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.toolbar{display:flex; gap:8px; align-items:center; flex-wrap:wrap}
/* A class selector beats the UA's [hidden]{display:none}, so without this the editor
   buttons stayed on screen after going back to the report list. */
.toolbar[hidden]{display:none !important}
.toolbar button{
  background:#1e293b; color:#fff; border:1px solid #334155; border-radius:8px;
  padding:8px 12px; font-size:13px; font-weight:600;
}
.toolbar button:hover{background:#334155}
.toolbar button.primary{background:#b45309; border-color:#b45309}
.toolbar button.primary:hover{background:#d97706}
.savestate{font-size:12px; color:#94a3b8; min-width:96px}
.toolbar button.back{background:transparent; border-color:#475569}
.toolbar button.ghostbtn{background:transparent}
.syncbadge{font-size:11.5px; font-weight:600; padding:3px 9px; border-radius:20px; white-space:nowrap}
.syncbadge.s-idle{background:#064e3b; color:#6ee7b7}
.syncbadge.s-syncing{background:#1e3a8a; color:#93c5fd}
.syncbadge.s-offline{background:#7c2d12; color:#fdba74}
.syncbadge.s-off{background:#334155; color:#cbd5e1}
.syncbadge.s-unsaved{background:#78350f; color:#fcd34d}
.cloudtag{font-style:normal; color:#2563eb; font-weight:700}

main{max-width:1080px; margin:0 auto; padding:18px 16px 80px}

/* ---------------- report list ----------------
   Hierarchy, loudest to quietest:
     1. New report — the only filled button on the page
     2. Search and filters — the actual job of this page is finding a report
     3. Import — a plain menu item
     4. Delete all / Delete report — destructive, so they live inside a menu and
        are the only things allowed to be red
   The list itself reads as a register: grouped by the month the work was done, with
   a coloured spine down the left carrying the verdict, using the same red / blue
   language as the remarks inside the report. */

.listhead{display:flex; align-items:center; gap:10px; margin-bottom:14px}
.newwrap{position:relative}

.btn{
  border:1px solid transparent; border-radius:9px; padding:9px 14px;
  font-size:14px; font-weight:600; white-space:nowrap; background:none; color:var(--ink);
}
.btn.primary{background:var(--navy); color:#fff}
.btn.primary:hover{background:#1e293b}
.btn.quiet{border-color:var(--line); background:#fff; color:var(--muted)}
.btn.quiet:hover{border-color:#94a3b8; color:var(--ink)}
.btn.quiet.on{border-color:var(--navy); color:var(--ink)}
.btn.icon{padding:9px 12px; font-size:17px; line-height:1}
.btn.icon.sm{padding:4px 8px; font-size:15px; color:#94a3b8; border-color:transparent; background:none}
.btn.icon.sm:hover{background:#f1f5f9; color:var(--ink)}
.btn .count{
  display:inline-block; min-width:17px; margin-left:5px; padding:1px 5px; border-radius:9px;
  background:var(--navy); color:#fff; font-size:11px; font-weight:700; text-align:center;
}

.search{
  flex:1 1 auto; min-width:0; padding:10px 14px; font-size:14px;
  border:1px solid var(--line); border-radius:9px; background:#fff;
}
.search:focus{outline:none; border-color:var(--navy); box-shadow:0 0 0 3px #e2e8f0}

.menu{
  position:absolute; top:calc(100% + 6px); left:0; z-index:40; width:290px;
  background:#fff; border:1px solid var(--line); border-radius:10px; padding:5px;
  box-shadow:0 12px 34px rgba(15,23,42,.16);
}
.menu.right{left:auto; right:0}
.menu[hidden]{display:none}
.menu button,.menu .menurow{
  display:block; width:100%; text-align:left; background:none; border:0;
  border-radius:7px; padding:9px 11px; cursor:pointer;
}
.menu button:hover,.menu .menurow:hover{background:#f1f5f9}
.menu b{display:block; font-size:13.5px; font-weight:600}
.menu i{display:block; font-style:normal; font-size:12px; color:var(--muted); margin-top:2px}
.menu .danger b{color:var(--fail)}
.menu .danger:hover{background:#fef2f2}

/* filters */
.chips{display:flex; gap:6px; flex-wrap:wrap; align-items:center; margin-bottom:10px}
.chips.stages{margin-top:-4px}
.chipsep{width:1px; height:18px; background:var(--line); margin:0 4px}
.fchip{
  font-size:13px; font-weight:500; color:var(--muted); background:none;
  border:1px solid var(--line); border-radius:20px; padding:5px 11px;
  display:inline-flex; align-items:center; gap:6px;
}
.fchip span{font-family:var(--font-mono); font-size:11px; font-weight:400; color:#94a3b8}
.fchip:hover{border-color:#94a3b8; color:var(--ink)}
.fchip.on{background:var(--navy); border-color:var(--navy); color:#fff; font-weight:600}
.fchip.on span{color:#94a3b8}

.advfilters{display:flex; gap:8px; flex-wrap:wrap; align-items:center;
  padding:12px; background:#fff; border:1px solid var(--line); border-radius:10px; margin-bottom:14px}
.advfilters[hidden]{display:none}
.pick{display:flex; align-items:center; gap:6px; font-size:12px; color:var(--muted);
  border:1px solid var(--line); border-radius:8px; padding:3px 5px 3px 11px; background:#fff}
.pick>span{font-weight:600; white-space:nowrap}
.pick select,.pick input{border:0; background:none; font-size:13px; padding:5px 4px;
  max-width:170px; color:var(--ink)}
.pick select:focus,.pick input:focus{outline:none}

/* the register */
.month{margin-bottom:18px}
.month>h2{
  display:flex; align-items:center; gap:8px; font-size:11.5px; font-weight:700;
  text-transform:uppercase; letter-spacing:.1em; color:var(--muted);
  margin:0 0 8px; padding-bottom:6px; border-bottom:1px solid var(--line);
}
.month>h2 span{font-family:var(--font-mono); font-size:11px; color:#94a3b8}

.rlist{list-style:none; margin:0; padding:0; display:grid; gap:6px}
.rlist li{
  position:relative; background:var(--card); border:1px solid var(--line); border-radius:10px;
  display:flex; align-items:center; gap:12px; padding:12px 14px 12px 17px; flex-wrap:wrap;
  overflow:visible;
}
/* verdict spine — scan the left edge to read the state of the whole list */
.rlist li::before{
  content:''; position:absolute; left:0; top:10px; bottom:10px; width:3px; border-radius:0 3px 3px 0;
  background:#cbd5e1;
}
.rlist li.r-pass::before{background:var(--pass)}
.rlist li.r-fail::before{background:var(--fail)}
.rlist li.r-hold::before{background:#0070c0}
.rlist li:hover{border-color:#cbd5e1}
.rlist a{flex:1 1 260px; min-width:0; text-decoration:none; color:inherit; display:grid; gap:2px}
.rkind{font-size:11px; font-weight:600; color:var(--muted); letter-spacing:.02em}
.rtitle{font-weight:600; font-size:15.5px; letter-spacing:-.01em}
.rmeta{font-family:var(--font-mono); font-size:12px; color:var(--muted); overflow:hidden;
  text-overflow:ellipsis; white-space:nowrap}
.rright{display:flex; align-items:center; gap:8px}
.rdate{font-family:var(--font-mono); font-size:12px; color:#94a3b8; white-space:nowrap}
.tag{font-size:11px; font-weight:600; color:var(--muted); background:#f1f5f9;
  border-radius:20px; padding:3px 8px; white-space:nowrap}
.tag.warn{background:var(--accent-soft); color:#92400e}
.verdict{font-size:11.5px; font-weight:700; padding:3px 9px; border-radius:20px; letter-spacing:.02em}
.verdict.r-pass{background:#d1fae5; color:var(--pass)}
.verdict.r-fail{background:#fee2e2; color:var(--fail)}
.verdict.r-hold{background:#e0efff; color:#0070c0}

.blank{text-align:center; padding:56px 20px; color:var(--muted)}
.blank p{margin:0 0 14px; font-size:15px}
.empty{color:var(--muted); font-size:14px; padding:14px 0}
.notice{
  background:#fffbeb; border:1px solid #fcd34d; color:#78350f; border-radius:9px;
  padding:10px 12px; font-size:13px; margin:0 0 14px; line-height:1.5;
}
.linkish{background:none; border:0; padding:0; color:#b45309; font-weight:700;
  text-decoration:underline; font-size:13px}
.storage{font-size:12.5px; color:var(--muted); margin-top:22px; line-height:1.6}

/* ---------------- section nav ---------------- */
.secnav{
  display:flex; gap:6px; overflow-x:auto; padding-bottom:12px; margin-bottom:6px;
  scrollbar-width:thin; -webkit-overflow-scrolling:touch;
}
.chip{
  flex:0 0 auto; font-size:12.5px; text-decoration:none; color:var(--muted);
  background:#fff; border:1px solid var(--line); border-radius:20px; padding:6px 12px; white-space:nowrap;
}
.chip:hover{border-color:var(--accent); color:var(--accent)}

/* ---------------- cards ---------------- */
.card{
  background:var(--card); border:1px solid var(--line); border-radius:12px;
  padding:20px 22px 22px; margin-bottom:12px; scroll-margin-top:72px;
}
.card>h2{
  font-size:16px; font-weight:600; letter-spacing:-.01em; color:var(--ink);
  border-bottom:1px solid var(--line); padding-bottom:12px; margin-bottom:18px;
  display:flex; align-items:center; gap:8px; flex-wrap:wrap;
}
.badge{font-size:11px; font-weight:700; background:#e0e7ff; color:#3730a3; border-radius:20px; padding:2px 8px; letter-spacing:0}
.badge-fail{background:#fee2e2; color:var(--fail)}
.help,.note{font-size:12.5px; color:var(--muted); margin:0 0 12px; line-height:1.55}
.note{background:#f8fafc; border-left:3px solid var(--line); padding:8px 10px; border-radius:0 6px 6px 0}

/* ---------------- fields ---------------- */
.fgrid{display:grid; grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); gap:10px 12px}
.fgrid.tight{gap:8px 10px}
.field{display:flex; flex-direction:column; gap:4px; min-width:0}
.field>span{font-size:12.5px; font-weight:500; color:var(--muted); letter-spacing:0}
.field input,.field select,.field textarea{
  width:100%; padding:10px 12px; border:1px solid #dfe5ec; border-radius:8px; background:#fff;
  font-size:14.5px; transition:border-color .12s, box-shadow .12s;
}
/* identifiers and measurements read as data */
.field.xs input,.field.sm input,.field input[type="number"],.field input[type="date"]{
  font-family:var(--font-mono); font-size:13.5px; letter-spacing:-.01em;
}
.field textarea{resize:vertical; min-height:44px}
.field input:hover,.field select:hover,.field textarea:hover{border-color:#c7d2de}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none; border-color:var(--navy); box-shadow:0 0 0 3px rgba(15,23,42,.08);
}
.field input[readonly]{background:#f8fafc; color:var(--muted)}
.field.wide{grid-column:1/-1}
.field.haslookup{position:relative}
.suggest{
  position:absolute; top:100%; left:0; right:0; z-index:25; background:#fff;
  border:1px solid var(--line); border-radius:8px; margin-top:4px; overflow:hidden;
  box-shadow:0 10px 26px rgba(15,23,42,.14); max-height:230px; overflow-y:auto;
}
.suggest[hidden]{display:none}
.suggest button{
  display:block; width:100%; text-align:left; background:none; border:0;
  padding:9px 11px; font-size:13px; line-height:1.4; border-bottom:1px solid #f1f5f9;
}
.suggest button:last-child{border-bottom:0}
.suggest button:hover{background:#f8fafc}
.suggestnote{margin:0; padding:10px 12px; font-size:12.5px; color:var(--muted)}
.search{
  flex:1 1 220px; min-width:0; padding:9px 12px; font-size:14px;
  border:1px solid var(--line); border-radius:20px; background:#fff;
}
.search:focus{outline:none; border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-soft)}
.fsep{width:1px; align-self:stretch; background:var(--line); margin:0 2px}
.pick{display:flex; align-items:center; gap:6px; font-size:12px; color:var(--muted);
  background:#fff; border:1px solid var(--line); border-radius:20px; padding:3px 5px 3px 11px}
.pick>span{font-weight:600; white-space:nowrap}
.pick select,.pick input{border:0; background:none; font-size:12.5px; padding:4px 6px;
  max-width:170px; color:var(--ink)}
.pick select:focus,.pick input:focus{outline:none}
.field.strong input,.field.strong select{font-weight:700}
.field.sm{max-width:170px} .field.xs{max-width:120px}
@media screen and (min-width:700px){ .fgrid .field.sm{grid-column:span 1} }

/* ---------------- tables / rows ---------------- */
.trow,.dcard{border:0; border-top:1px solid var(--line); border-radius:0;
  padding:18px 0 4px; margin:0; background:none}
.trow:first-of-type,.dcard:first-of-type{border-top:0; padding-top:0}
.finding{border:1px solid var(--line); border-radius:10px; padding:16px; margin-bottom:12px; background:#fff}
.trowhead,.fhead{display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:10px}
.tnum,.fnum{font-family:var(--font-mono); font-size:12px; font-weight:600; color:var(--muted)}
.fnum{font-size:12.5px; background:var(--accent-soft); color:var(--accent); padding:4px 11px; border-radius:20px}
/* Severity colouring mirrors the source reports: red = Failed, blue = On Hold. */
.finding.sev-fail{border-left:4px solid var(--fail); background:#fffafa}
.finding.sev-hold{border-left:4px solid #0070c0; background:#f8fbff}
.fnum.sev-fail{background:#fee2e2; color:var(--fail)}
.fnum.sev-hold{background:#e0efff; color:#0070c0}
.sumline{font-size:12.5px; color:var(--muted); margin:10px 0 0; padding-top:10px; border-top:1px dashed var(--line)}
.sumline b{color:var(--ink)}
.fhactions{display:flex; gap:6px}
.tcells{display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:10px 12px}
.mini{background:#fff; border:1px solid var(--line); border-radius:6px; padding:4px 9px; font-size:12px; color:var(--muted)}
.mini:hover{border-color:var(--navy); color:var(--navy)}
.mini.danger:hover{border-color:var(--fail); color:var(--fail)}
.add{
  width:100%; background:#fff; border:1px dashed #94a3b8; border-radius:8px;
  padding:10px; font-size:13.5px; font-weight:600; color:var(--muted); margin-top:4px;
}
.add:hover{border-color:var(--accent); color:var(--accent); background:#fffbeb}
.dgroup{margin-bottom:10px}
.dgroup h4{font-size:11px; font-weight:800; text-transform:uppercase; letter-spacing:.08em;
  color:var(--accent); margin-bottom:6px}
.dtitle{margin-bottom:12px; max-width:280px}
.dtitle input{font-weight:700}
.totals{display:flex; gap:16px; margin-bottom:12px; flex-wrap:wrap}
.totals span{font-size:13px; font-weight:700}
.totals i{display:block; font-style:normal; font-size:11px; font-weight:600; color:var(--muted); text-transform:uppercase}

/* ---------------- checklist ---------------- */
.clgroup{border:1px solid var(--line); border-radius:8px; margin-bottom:8px; background:#fff}
.clgroup>summary{
  cursor:pointer; padding:11px 14px; display:flex; justify-content:space-between;
  align-items:center; gap:10px; font-size:14px; list-style:none;
}
.clgroup>summary::-webkit-details-marker{display:none}
.clgroup>summary::before{content:'▸'; color:var(--muted); margin-right:6px}
.clgroup[open]>summary::before{content:'▾'}
.clgroup[open]>summary{border-bottom:1px solid var(--line); background:#f8fafc}
.cltally{font-size:12px; color:var(--muted); font-weight:600; white-space:nowrap}
.cltally em{color:var(--fail); font-style:normal}
.clrow{padding:12px 14px; border-bottom:1px solid #f1f5f9}
.clrow:last-child{border-bottom:0}
.clrow.fail{background:#fef2f2; border-left:3px solid var(--fail)}
.clsub{font-weight:600; font-size:14.5px; margin-bottom:3px; letter-spacing:-.005em}
.clreq{font-size:12px; color:var(--muted); margin-bottom:8px; line-height:1.5}

/* ---------------- photos ---------------- */
.photos{margin-top:12px; padding-top:10px; border-top:1px dashed var(--line)}
.pgrid{display:grid; grid-template-columns:repeat(auto-fill,minmax(92px,1fr)); gap:8px; margin-bottom:8px}
.pthumb{position:relative; margin:0; border-radius:7px; overflow:hidden; border:1px solid var(--line); background:#fff}
.pthumb img{width:100%; aspect-ratio:1; object-fit:cover; display:block; cursor:zoom-in}
.pmiss{aspect-ratio:1; display:grid; place-items:center; color:var(--muted); background:#f1f5f9}
.pthumb figcaption{position:absolute; left:0; bottom:0; background:rgba(15,23,42,.78); color:#fff;
  font-size:10px; font-weight:700; padding:2px 6px; border-radius:0 6px 0 0}
.pdel{position:absolute; top:3px; right:3px; width:22px; height:22px; border:0; border-radius:50%;
  background:rgba(15,23,42,.72); color:#fff; font-size:15px; line-height:1; display:grid; place-items:center}
.pdel:hover{background:var(--fail)}
.addphoto span{
  display:inline-block; font-size:13px; font-weight:600; padding:9px 14px; border-radius:8px;
  border:1px dashed var(--accent); color:var(--accent); background:#fffbeb; cursor:pointer;
}
.addphoto span:hover{background:var(--accent-soft)}
.lightbox{position:fixed; inset:0; background:rgba(15,23,42,.94); display:grid; place-items:center; z-index:60; padding:20px}
.lightbox img{max-width:100%; max-height:100%; border-radius:6px}
.lbclose{position:absolute; top:16px; right:20px; background:none; border:0; color:#fff; font-size:34px; line-height:1}

/* ---------------- busy ---------------- */
.busy{position:fixed; inset:0; background:rgba(15,23,42,.6); display:grid; place-items:center; z-index:70}
.busybox{background:#fff; border-radius:12px; padding:26px 32px; text-align:center; min-width:260px}
.busybox p{margin:14px 0 4px; font-weight:600}
.busybox small{color:var(--muted); font-size:12px; word-break:break-all}
.spinner{width:30px; height:30px; margin:0 auto; border:3px solid var(--line); border-top-color:var(--accent);
  border-radius:50%; animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---------------- phone ----------------
   `screen and` matters: without it these rules also apply when printing from a
   phone, and the PDF came out laid out at phone width instead of paper width. */
@media screen and (max-width:720px){
  main{padding:14px 14px 90px}
  .card{padding:14px 14px 16px; border-radius:12px}
  .card>h2{font-size:13.5px; margin-bottom:10px}

  /* the toolbar wrapped into a tall stack that pushed the form off screen —
     scroll it sideways instead and keep the report title on its own line */
  .topbar{flex-wrap:nowrap; gap:10px; padding:8px 12px; padding-top:max(8px,env(safe-area-inset-top))}
  .brand{flex:0 0 auto}
  .crumb{display:none}
  /* flex-end clips the start of an overflowing flex row, which hid Back / Save /
     Generate PDF behind the scroll. Start-aligned keeps the important ones first. */
  .toolbar{
    flex:1 1 auto; flex-wrap:nowrap; overflow-x:auto; justify-content:flex-start;
    -webkit-overflow-scrolling:touch; scrollbar-width:none;
  }
  .toolbar::-webkit-scrollbar{display:none}
  .toolbar button{padding:8px 11px; font-size:12.5px; flex:0 0 auto}
  .savestate{display:none}
  .syncbadge{flex:0 0 auto}

  /* one clean column, with the same margin either side of every field */
  .fgrid,.tcells{grid-template-columns:1fr; gap:12px}
  .field.sm,.field.xs{max-width:none}
  .field input,.field select,.field textarea{padding:11px 12px; font-size:16px}  /* 16px stops iOS zooming on focus */
  .field>span{font-size:11px}
  .trow,.dcard,.finding{padding:12px; border-radius:10px}
  .clrow{padding:12px}
  .secnav{margin:0 -14px 6px; padding:0 14px 12px}
  .pgrid{grid-template-columns:repeat(auto-fill,minmax(76px,1fr))}

  .listhead{flex-wrap:wrap; gap:8px}
  .listhead .search{order:3; flex:1 1 100%}
  .listhead .btn.primary{flex:1 1 auto}
  .chips{flex-wrap:nowrap; overflow-x:auto; margin:0 -14px 10px; padding:0 14px 4px;
    scrollbar-width:none}
  .chips::-webkit-scrollbar{display:none}
  .fchip{flex:0 0 auto}
  .advfilters{gap:6px}
  .pick{flex:1 1 46%}
  .rlist li{padding:12px 12px 12px 16px; gap:8px}
  .rright{width:100%; justify-content:flex-end}
  .menu{width:min(300px,calc(100vw - 28px))}
}

/* ================================================================== *
 * PREVIEW — the same document, shown on screen before printing
 * ================================================================== */
#printroot{display:none}

/* fixed, not sticky: the bar is appended after #printroot, so a sticky bar would
   sit below the whole document and be unreachable. */
.pvbar{
  position:fixed; top:0; left:0; right:0; z-index:80; display:flex; align-items:center;
  gap:12px; justify-content:space-between; background:var(--navy); color:#fff;
  padding:10px 14px; padding-top:max(10px,env(safe-area-inset-top));
  box-shadow:0 2px 12px rgba(15,23,42,.3);
}
.pvbar button{
  background:#1e293b; color:#fff; border:1px solid #334155; border-radius:8px;
  padding:9px 13px; font-size:13.5px; font-weight:600; white-space:nowrap;
}
.pvactions{display:flex; gap:8px}
.pvbar .pvpdf{background:#1e293b; border-color:#334155}
.pvbar button[disabled]{opacity:.75}
/* the offscreen page used to build the PDF must never be visible or printed */
#pdfroot{background:#fff}
@media print{ #pdfroot{display:none !important} }
.pvbar .pvprint{background:var(--accent); border-color:var(--accent)}
.pvname{font-size:12.5px; color:#94a3b8; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
body.previewing{background:#64748b}
body.previewing>*:not(#printroot):not(.pvbar){display:none !important}
body.previewing #printroot{
  display:block; background:#fff; max-width:210mm; margin:76px auto 40px;
  padding:16mm 14mm; border-radius:4px; box-shadow:0 8px 40px rgba(15,23,42,.35);
}
/* page breaks are invisible on screen, so mark them */
body.previewing .p-photopage,
body.previewing .p-sec.p-break,
body.previewing .p-cover{border-top:2px dashed #cbd5e1; padding-top:10mm; margin-top:10mm}
body.previewing .p-cover{border-top:0; padding-top:0; margin-top:0}
body.previewing .p-phframe{height:auto; max-height:none}
body.previewing .p-phframe img{max-height:150mm}
@media screen and (max-width:820px){
  /* Show the real page, scaled to fit — not a reflowed phone version. Reflowing made
     the preview a different document from the one that prints, which is exactly the
     thing a preview must not do. `zoom` (rather than `transform`) keeps the page in
     flow, so it scrolls normally and the height is right. */
  body.previewing #printroot{
    width:210mm; max-width:none; margin:60px auto 40px; padding:14mm;
    border-radius:0; zoom:var(--pv-zoom, .46);
  }
  .pvname{display:none}
  .pvbar button{flex:0 0 auto; font-size:13px; padding:9px 11px}
}

@media print{
  body>*:not(#printroot){display:none !important}
  .pvbar{display:none !important}
  body.previewing{background:#fff}
  body.previewing #printroot{max-width:none; margin:0; padding:0; box-shadow:none; border-radius:0}
  body.previewing .p-photopage,body.previewing .p-sec.p-break{border-top:0; padding-top:0; margin-top:0}
  #printroot{display:block}
  @page{size:Letter; margin:14mm 12mm 16mm}
  body{background:#fff; font-size:9.5pt; color:#000}
  a{color:#1d4ed8; text-decoration:none}
}

#printroot{font-size:9.5pt; color:#111827; font-family:var(--font-ui)}

/* cover */
.p-cover{page-break-after:always; padding-top:14mm}
.p-brand{font-size:9pt; letter-spacing:.28em; font-weight:800; color:#b45309}
.p-title{font-size:26pt; margin:6mm 0 1mm; letter-spacing:-.01em}
.p-sub{font-size:11pt; color:#6b7280; margin-bottom:8mm}
.p-verdict{
  display:inline-block; font-size:15pt; font-weight:800; letter-spacing:.06em;
  padding:2.5mm 8mm; border-radius:2mm; margin-bottom:9mm;
}
.p-verdict.r-pass{background:#d1fae5; color:#047857}
.p-verdict.r-fail{background:#fee2e2; color:#b91c1c}
.p-verdict.r-hold{background:#fef3c7; color:#b45309}
.p-facts{
  width:100%; margin-bottom:8mm; border-collapse:separate; border-spacing:0;
  border:.5pt solid #cbd5e1; border-radius:2mm;
}
.p-facts th{
  text-align:left; width:44mm; padding:2mm 3mm; vertical-align:middle; background:#f8fafc;
  font-size:8pt; text-transform:uppercase; letter-spacing:.05em; color:#4b5563; font-weight:600;
  border-top:.4pt solid #e5e7eb; border-right:.4pt solid #e5e7eb;
}
.p-facts td{padding:2mm 3mm; vertical-align:middle; border-top:.4pt solid #e5e7eb}
.p-facts tr:first-child th,.p-facts tr:first-child td{border-top:0}
.p-facts tr:first-child th{border-top-left-radius:1.6mm}
.p-facts tr:last-child th{border-bottom-left-radius:1.6mm}
.p-covernote{font-size:8.5pt; color:#4b5563; background:#f8fafc; border-left:2pt solid #b45309;
  border-radius:0 1.5mm 1.5mm 0; padding:2.5mm 3mm; line-height:1.6}

/* sections */
.p-sec{margin-bottom:7mm}
.p-sec.p-break{page-break-before:always}
.p-sec>h2{
  font-size:10.5pt; text-transform:uppercase; letter-spacing:.07em; color:#0f172a;
  background:#e8edf3; border-left:2.5pt solid #0f172a; border-radius:0 1.5mm 1.5mm 0;
  padding:1.8mm 3mm; margin-bottom:3.5mm;
  page-break-after:avoid;
}
.p-grp{font-size:9.5pt; margin:4mm 0 2mm; color:#0f172a; background:#f3f4f6;
  border-left:2pt solid #b45309; border-radius:0 1.2mm 1.2mm 0; padding:1.4mm 2.5mm;
  page-break-after:avoid}
.p-hint{font-size:8.5pt; color:#6b7280; margin:0 0 3mm}

.p-kv{
  width:100%; margin-bottom:3mm; border-collapse:separate; border-spacing:0;
  border:.5pt solid #cbd5e1; border-radius:2mm;
}
.p-kv th{text-align:left; width:46mm; padding:1.8mm 3mm; vertical-align:middle;
  font-size:8pt; color:#4b5563; font-weight:600; background:#f8fafc;
  border-top:.4pt solid #e5e7eb; border-right:.4pt solid #e5e7eb}
.p-kv td{padding:1.8mm 3mm; vertical-align:middle; border-top:.4pt solid #e5e7eb}
.p-kv tr:first-child th,.p-kv tr:first-child td{border-top:0}
.p-kv tr:first-child th{border-top-left-radius:1.6mm}
.p-kv tr:last-child th{border-bottom-left-radius:1.6mm}
.p-kvsm{border:0}
.p-kvsm th{width:34mm; font-size:7.5pt; background:none; border-right:0}
.p-kvsm td{font-size:8.5pt}
/* Two label/value pairs per line — short header fields wasted a whole row each.
   Laid out as a grid, so the shared table border rules do not apply here. */
.p-kv2{display:grid; grid-template-columns:36mm 1fr 36mm 1fr; gap:0;
  border:.5pt solid #cbd5e1; border-radius:2mm; overflow:hidden}
.p-kv2 tbody{display:contents}
.p-kv2 tr{display:contents}
.p-kv2 th{width:auto; padding:1.8mm 3mm; align-self:stretch; display:flex;
  align-items:center; background:#f8fafc; border-top:.4pt solid #e5e7eb;
  border-right:.4pt solid #e5e7eb; border-radius:0}
.p-kv2 td{padding:1.8mm 3mm; display:flex; align-items:center;
  border-top:.4pt solid #e5e7eb; border-right:.4pt solid #e5e7eb}
.p-kv2 td:last-child{border-right:0}
.p-kv2 tr:first-child th,.p-kv2 tr:first-child td{border-top:0}

/* auto, not fixed: fixed layout gave 11 equal columns and the headers collided.
   Letting the browser size to content keeps wide data tables readable.

   border-collapse must be SEPARATE for rounded corners to render at all. With
   collapse the outer radius is ignored and the right/bottom edge can go missing,
   so each cell paints its own right + bottom rule and the table paints the outer
   box. No overflow:hidden — that clips rows when a table breaks across pages. */
.p-tbl{
  width:100%; margin-bottom:3mm; table-layout:auto;
  border-collapse:separate; border-spacing:0;
  border:.5pt solid #94a3b8; border-radius:2mm;
}
.p-tbl thead{display:table-header-group}
.p-tbl th{
  background:#0f172a; color:#fff; text-align:left; font-size:7.5pt; font-weight:600;
  padding:1.8mm 2mm; text-transform:uppercase; letter-spacing:.03em;
  vertical-align:middle; border-right:.4pt solid #334155;
}
.p-tbl th:last-child{border-right:0}
.p-tbl thead tr:first-child th:first-child{border-top-left-radius:1.6mm}
.p-tbl thead tr:first-child th:last-child{border-top-right-radius:1.6mm}
.p-tbl tbody tr:last-child td:first-child{border-bottom-left-radius:1.6mm}
.p-tbl tbody tr:last-child td:last-child{border-bottom-right-radius:1.6mm}
/* Not every table deserves the full page width. These are short by definition, so
   keep them whole rather than orphaning a single row onto the next page. */
.p-tbl.p-narrow{width:auto; min-width:60%; max-width:100%; table-layout:auto;
  page-break-inside:avoid}
/* A heading should never be the last thing on a page. */
.p-sec>h2+*{page-break-before:avoid}
.p-kv,.p-kv2{page-break-inside:avoid}
.p-tbl td{
  padding:1.8mm 2mm; font-size:8.5pt;
  vertical-align:middle;                 /* text centred in the row, not hugging the top */
  border-top:.4pt solid #d1d5db; border-right:.4pt solid #d1d5db;
  word-wrap:break-word; overflow-wrap:break-word;
}
.p-tbl td:last-child{border-right:0}
.p-tbl tbody tr:nth-child(even) td{background:#f6f8fa}
.p-tbl td.p-nw{white-space:nowrap; font-family:var(--font-mono); font-size:7.8pt}
/* Headers must be allowed to wrap. Nine nowrap headers set a min-content width
   wider than the page, and the table then ran off the right edge. */
.p-tbl th{white-space:normal; hyphens:none}
.p-tbl.p-wide th{font-size:7pt; padding:1.4mm 1.5mm}
.p-tbl.p-wide td{font-size:8pt; padding:1.4mm 1.5mm}
.p-tbl tr{page-break-inside:avoid}
.p-req{color:#6b7280; font-size:7.5pt}
.p-tag{font-size:7pt; font-weight:800; background:#fee2e2; color:#b91c1c; padding:.4mm 1.6mm; border-radius:1mm}

/* Scoped to the printed document: these are result-cell colours. Unscoped they also
   hit the report list, which uses the same class names on its rows for the spine. */
#printroot .r-pass{color:#047857; font-weight:700}
#printroot .r-fail{color:#b91c1c; font-weight:700}
#printroot .r-hold{color:#b45309; font-weight:700}
#printroot .r-na{color:#6b7280}

.p-card{border:.4pt solid #d1d5db; border-radius:1.5mm; padding:3mm 3.5mm; margin-bottom:2.5mm; page-break-inside:avoid}
.p-cardtitle{font-size:10.5pt; font-weight:800; letter-spacing:-.01em; color:#0f172a;
  background:#e8edf3; margin:-3mm -3.5mm 3mm; padding:2mm 3.5mm;
  border-radius:1.2mm 1.2mm 0 0; border-bottom:.5pt solid #cbd5e1}
.p-cardgrp{margin-bottom:2.5mm}
.p-cardgrp h4{font-size:8.5pt; font-weight:800; text-transform:uppercase; letter-spacing:.06em;
  color:#b45309; margin:0 0 1.5mm; border-left:1.5pt solid #d9a441; padding-left:2mm}
.p-cardvals{display:flex; flex-wrap:wrap; gap:1.5mm 7mm}
.p-cardvals span{font-size:9pt; font-weight:600}
.p-cardvals i{display:block; font-style:normal; font-size:6.5pt; font-weight:600; color:#6b7280;
  text-transform:uppercase; letter-spacing:.04em}

/* issues */
.p-issue{border:.5pt solid #d1d5db; border-left:2.5pt solid #b45309; border-radius:1.5mm;
  padding:3mm 3.5mm; margin-bottom:3mm; page-break-inside:avoid}
.p-issuehead{margin:-3mm -3.5mm 2mm; padding:1.6mm 3.5mm; display:flex; align-items:center;
  gap:2mm; background:#f3f4f6; border-bottom:.4pt solid #e5e7eb; border-radius:1.2mm 1.2mm 0 0}
.p-issuenum{font-size:8pt; font-weight:800; letter-spacing:.06em; background:#fef3c7; color:#b45309;
  padding:.8mm 2.5mm; border-radius:6mm}
.p-issuesev{font-size:7pt; font-weight:700; text-transform:uppercase; letter-spacing:.08em; color:#6b7280}
.p-issuetext{margin:0 0 1.5mm; font-size:9.5pt; line-height:1.5; white-space:pre-wrap}

/* The source reports print the whole remark in its severity colour — red for Failed,
   blue (0070C0) for On Hold — so the reader can triage the list at a glance. */
.p-issue.sev-fail{border-left-color:#FF0000}
.p-issue.sev-fail .p-issuehead{background:#fdeaea; border-bottom-color:#f6c9c9}
.p-issue.sev-fail .p-issuenum{background:#fee2e2; color:#FF0000}
.p-issue.sev-fail .p-issuetext{color:#FF0000}
.p-issue.sev-fail .p-issuesev{color:#FF0000}
.p-issue.sev-hold{border-left-color:#0070C0}
.p-issue.sev-hold .p-issuehead{background:#e8f2fb; border-bottom-color:#c7ddf1}
.p-issue.sev-hold .p-issuenum{background:#e0efff; color:#0070C0}
.p-issue.sev-hold .p-issuetext{color:#0070C0}
.p-issue.sev-hold .p-issuesev{color:#0070C0}
.p-tag.sev-fail{background:#fee2e2; color:#FF0000}
.p-tag.sev-hold{background:#e0efff; color:#0070C0}
.p-meta{display:flex; flex-wrap:wrap; gap:1mm 6mm; margin:1.5mm 0}
.p-meta span{font-size:8.5pt; font-weight:600}
.p-meta i{display:block; font-style:normal; font-size:6.5pt; font-weight:600;
  color:#6b7280; text-transform:uppercase; letter-spacing:.05em}

/* clickable thumbnails */
.p-thumbs{display:flex; flex-wrap:wrap; gap:2mm; margin-top:2mm}
.p-thumb{display:block; width:26mm; text-decoration:none; page-break-inside:avoid}
.p-thumb img{width:26mm; height:26mm; object-fit:cover; border:.5pt solid #9ca3af; border-radius:1mm; display:block}
.p-thumb span{display:block; font-size:6.5pt; font-weight:700; color:#1d4ed8; text-align:center; padding-top:.6mm}

/* one photo per page */
.p-photopage{page-break-before:always; page-break-inside:avoid; height:100%}
.p-phhead{display:flex; justify-content:space-between; align-items:baseline;
  border-bottom:.8pt solid #0f172a; padding-bottom:1.5mm; margin-bottom:3mm}
.p-phlabel{font-size:10pt; font-weight:800; letter-spacing:.04em}
.p-phback{font-size:8pt; font-weight:600}
.p-phframe{height:196mm; display:flex; align-items:center; justify-content:center;
  background:#f8fafc; border:.4pt solid #e5e7eb; border-radius:1.5mm; overflow:hidden}
.p-phframe img{max-width:100%; max-height:196mm; object-fit:contain}
.p-phcap{font-size:8.5pt; line-height:1.5; margin-top:2.5mm; color:#374151}

/* general photo grid */
.p-grid{display:grid; grid-template-columns:1fr 1fr; gap:4mm}
.p-grid figure{margin:0; page-break-inside:avoid}
.p-grid img{width:100%; height:62mm; object-fit:contain; background:#f8fafc; border:.4pt solid #e5e7eb; border-radius:1mm}
.p-grid figcaption{font-size:7pt; color:#6b7280; text-align:center; padding-top:.8mm; word-break:break-all}

.p-coverlink{font-size:8pt; color:#6b7280; margin-top:4mm}
.p-coverlink a{color:#1d4ed8; word-break:break-all}
.p-end{text-align:center; font-size:9pt; color:#6b7280; margin-top:8mm; padding-top:4mm; border-top:.4pt solid #d1d5db}
