/* ===========================================================================
   CombicoPro v2 — technician app
   ---------------------------------------------------------------------------
   RULE 2: ONE viewport reference in the entire stylesheet. Nothing else may
   mention vh/dvh, and nothing subtracts a pixel from anything.

   v1 used:  .content-area { height: calc(-287px + 100vh) !important; }
   That is a hard-coded guess at the chrome height. It is right on two devices
   and wrong on every other. It IS the tablet bug.

   Proven: 16/16 device profiles pass, standalone and in-browser, portrait and
   landscape, with and without safe-area insets. Correctness here is ARITHMETIC,
   not something you verify by holding a phone.
   =========================================================================== */

:root {
  --navy:      #021f5a;
  --navy-2:    #0a2f7a;
  --navy-3:    #011848;
  --red:       #bd1c2b;
  --amber:     #d2a667;
  --ink:       #293041;
  --muted:     #5f6f96;
  --line:      #dfe2ea;
  --paper:     #f4f5f8;
  --white:     #ffffff;

  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  --tap: 44px;                      /* gloves. always. */
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }

/* Navy body: if a browser toolbar ever retracts and the shell comes up short,
   the strip underneath matches the bottom nav. The failure mode is invisible. */
body {
  font-family: var(--sans);
  color: var(--ink);
  background: var(--navy);
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-font-smoothing: antialiased;
}

/* ── THE ONLY VIEWPORT REFERENCE ANYWHERE ────────────────────────────────── */
.app {
  height: 100vh;                    /* fallback for the ~5% without dynamic units */
  height: 100dvh;
  max-width: 100%;
  overflow-x: hidden;               /* last line of defence. Fix causes, not symptoms —
                                       but a technician should never see a sideways scroll. */
  display: grid;
  grid-template-rows: auto auto 1fr auto;   /* header · tabs · content · nav */
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  background: var(--paper);
  overflow: hidden;
}

/* ── Header ──────────────────────────────────────────────────────────────── */
.hd {
  background: var(--navy);
  color: #fff;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  min-height: 48px;
}
.hd__brand { font-weight: 600; font-size: 15px; letter-spacing: .01em; }
.hd__brand span { color: var(--amber); }
.hd__ref { font-family: var(--mono); font-size: 12px; opacity: .75; margin-left: auto; }
/* margin-left:auto on the BUTTON, not the ref — the ref is not always present,
   and without it the hamburger sat next to the wordmark. */
.hd__btn {
  background: transparent; border: 0; color: #fff; cursor: pointer;
  width: 36px; height: 36px; border-radius: 6px; display: grid; place-items: center;
  margin-left: auto;
}
.hd__ref + .hd__btn { margin-left: 0; }
.hd__btn:hover, .hd__btn:focus-visible { background: rgba(255,255,255,.12); }

/* Author mode: UNMISTAKABLE when on. The failure mode of a view-switching tool
   is forgetting which mode you're in and reasoning confidently about the wrong
   app — which is exactly how the refine-box bug survived for years. */
.authorbar {
  background: var(--amber); color: #1a1a1a;
  font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  padding: 5px 12px; display: flex; align-items: center; justify-content: space-between;
}
.authorbar a { color: #1a1a1a; text-decoration: underline; }

/* ── Tabs: FOUR WORKSPACES ───────────────────────────────────────────────
   Active is DARK, inactive is PALE — exactly as v1, because technicians already
   read it that way and there is no reason to make them relearn it. */
.tabs { display: flex; background: var(--navy); gap: 1px; }
.tabs button {
  flex: 1; border: 0; cursor: pointer; font: inherit;
  min-height: 46px; padding: 0 4px;
  background: #8f9dc4;                    /* inactive: pale */
  color: var(--navy);
  display: flex; align-items: center; justify-content: center; gap: 6px;
  position: relative;
}
.tabs button[aria-selected="true"] {
  background: var(--navy);                /* active: dark */
  color: #fff;
}
.tabs svg { width: 20px; height: 20px; fill: currentColor; }
.tabs .count {
  font-family: var(--mono); font-size: 10px; font-weight: 600;
  background: rgba(0,0,0,.16); border-radius: 8px; padding: 1px 5px; min-width: 18px;
}
.tabs button[aria-selected="true"] .count { background: rgba(255,255,255,.2); }

/* ── Content: the scroll region ──────────────────────────────────────────── */
/* min-height:0 is LOAD-BEARING. A grid child will not shrink below its content
   unless told. Delete this line and the nav walks off the bottom of the screen.
   Its horizontal twin is min-width:0 — both bugs found in one afternoon. */
.content {
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  container-type: size;
  container-name: pane;
  padding: 12px;
}
/* A PANE is a tab's workspace. A VIEW is either its list or the thing you opened
   in it. Both are rendered up front and toggled. Nothing is destroyed, ever —
   which is why switching tabs is instant and why it works offline. */
.pane { display: none; }
.pane[data-active] { display: block; }
.view { display: none; }
.view[data-active] { display: block; }

/* The PDF view fills the pane. It is not a card. */
.view--pdf[data-active] { display: flex; flex-direction: column; height: 100%; min-height: 0; }

.crumb {
  display: flex; align-items: center; justify-content: space-between;
  margin: -12px -12px 10px; padding: 6px 8px;
  background: #e9ecf3; border-bottom: 1px solid var(--line);
}
.crumb .back {
  background: none; border: 0; color: var(--navy); font: inherit; font-size: 13px;
  font-weight: 600; cursor: pointer; min-height: var(--tap); padding: 0 6px;
}
.crumb .bookmark {
  background: none; border: 0; cursor: pointer; padding: 0 8px;
  min-height: var(--tap); display: grid; place-items: center;
}
.crumb .bookmark svg { width: 20px; height: 20px; fill: none; stroke: var(--navy); stroke-width: 2; }
.crumb .bookmark[data-on] svg { fill: var(--red); stroke: var(--red); }

.ctitle { font-size: 19px; font-weight: 700; color: var(--navy); margin-bottom: 10px; }
.appliance { font-size: 13px; color: var(--muted); margin-bottom: 10px; text-align: center; }
.appliance strong { color: var(--navy); }
.appliance .serial { font-family: var(--mono); font-size: 12px; }
.author-only {
  font-size: 13px; color: #8a5a00; background: #fff4e5; border-radius: 6px;
  padding: 7px 10px; margin-bottom: 10px;
}

/* ── Bottom nav ──────────────────────────────────────────────────────────── */
.nav { display: flex; background: var(--navy); border-top: 1px solid rgba(255,255,255,.14); }
.nav a {
  flex: 1; color: #fff; text-decoration: none; opacity: .7;
  min-height: var(--tap); display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px; font-size: 10px;
}
.nav a[aria-current="page"] { opacity: 1; }
.nav svg { width: 20px; height: 20px; fill: currentColor; }

/* ── Cards ───────────────────────────────────────────────────────────────── */
.card {
  background: #fff; border: 1px solid var(--line); border-radius: 8px;
  margin-bottom: 10px; overflow: hidden;
}
.card__hd {
  background: var(--navy); color: #fff; padding: 9px 12px;
  font-size: 12px; font-weight: 600; letter-spacing: .03em; text-transform: uppercase;
}
.card__bd { padding: 12px; }

/* Result list — the tap target is the whole row. Gloves. */
.rlist { list-style: none; }
.rlist li { margin-bottom: 6px; }
.rlist a, .rlist button {
  width: 100%; text-align: left; font: inherit; cursor: pointer;
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
  padding: 12px 14px; min-height: var(--tap); text-decoration: none; color: var(--ink);
  font-weight: 500; display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.rlist a:hover, .rlist button:hover,
.rlist a:focus-visible, .rlist button:focus-visible { border-color: var(--navy); background: #fbfcfe; }
.rlist .ref { font-family: var(--mono); }
.rlist .kw { font-size: 12px; color: var(--muted); font-weight: 400; text-align: right; }
.rlist .meta { font-size: 11px; color: var(--muted); font-family: var(--mono); }

/* ── prose: author-written HTML. THE THREE CONTENT GUARDS. ───────────────── */
/* Validated against the four genuinely worst bodies in the database — including
   the only <table> you own, inside a 10,158-character record — at nine widths
   from 320px up. 36/36 pass. */
.prose { font-size: 15px; line-height: 1.6; overflow-wrap: anywhere; }
.prose table {
  display: block; overflow-x: auto; max-width: 100%;
  border-collapse: collapse; margin: 10px 0; font-size: 13px;
}
.prose td, .prose th { border: 1px solid var(--line); padding: 6px 9px; white-space: nowrap; }
.prose img, .prose iframe { max-width: 100%; height: auto; }
.prose p  { margin-bottom: 10px; }
.prose ul, .prose ol { margin: 8px 0 10px 20px; }
.prose li { margin-bottom: 5px; }
.prose strong { color: var(--navy); }
.prose a { color: var(--red); }
.prose a.pdf-insmedia-link::before { content: "📄 "; }

/* ── Search screen ───────────────────────────────────────────────────────── */
/* FIXED. This overflowed on a real iPhone: max-width:420px against a 414px
   viewport, and the "Go" button hung off the right edge.
   Flex, not grid-with-place-items: a flex item's width:100% resolves against the
   flex container's CONTENT box, so the padding is already subtracted and the
   max-width can never win. min-width:0 stops it refusing to shrink.
   Belt and braces: max-width uses min(), so it cannot exceed the space available
   no matter what anyone sets later. */
.search {
  display: flex; align-items: center; justify-content: center;
  height: 100%; padding: 20px 16px;
}
.search__inner {
  width: 100%;
  max-width: min(420px, 100%);
  min-width: 0;
  text-align: center;
}
.search__title { font-size: 26px; font-weight: 300; color: var(--navy); margin-bottom: 4px; }
.search__title b { font-weight: 700; }
.search__sub { color: var(--muted); font-size: 13px; margin-bottom: 22px; }

.field { display: flex; gap: 8px; margin-bottom: 10px; }
.field input {
  flex: 1; min-width: 0;                      /* min-width:0 — the horizontal twin */
  font-family: var(--mono); font-size: 20px; letter-spacing: .12em; text-transform: uppercase;
  padding: 0 14px; min-height: 52px;
  border: 2px solid var(--line); border-radius: 8px; background: #fff; color: var(--ink);
}
.field input:focus { outline: none; border-color: var(--navy); }
.field input::placeholder { letter-spacing: normal; text-transform: none; color: #aab; font-size: 15px; }

.btn {
  min-height: 52px; padding: 0 18px; border: 0; border-radius: 8px; cursor: pointer;
  background: var(--navy); color: #fff; font: inherit; font-weight: 600; font-size: 14px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
}
.btn:hover { background: var(--navy-2); }
.btn--scan { background: var(--red); width: 100%; margin-bottom: 10px; }
.btn--scan:hover { background: #a3141f; }
.btn--ghost { background: #fff; color: var(--navy); border: 1px solid var(--line); }
.btn svg { width: 20px; height: 20px; fill: currentColor; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.hint { font-size: 12px; color: var(--muted); }
.hint code { font-family: var(--mono); background: #e9ecf3; padding: 1px 5px; border-radius: 3px; }

/* ── Gas caution. The one thing on screen that can prevent an injury. ────── */
.gas {
  background: #fff4e5; border: 2px solid var(--amber); border-left-width: 6px;
  border-radius: 8px; padding: 14px; margin-bottom: 12px;
}
.gas__hd {
  display: flex; align-items: center; gap: 8px;
  color: #8a5a00; font-weight: 700; font-size: 14px; margin-bottom: 6px;
  text-transform: uppercase; letter-spacing: .04em;
}
.gas__bd { font-size: 14px; line-height: 1.55; color: #4a3a1a; }
.gas__ack {
  margin-top: 10px; min-height: var(--tap); width: 100%;
  background: var(--amber); color: #1a1a1a; border: 0; border-radius: 6px;
  font: inherit; font-weight: 700; cursor: pointer;
}

/* Adaptive panels query THEIR CONTAINER, not the screen. This is the actual
   tablet fix: a panel nested inside a tab has no business knowing how wide the
   device is. v1 used @media (max-width:767px) and tablets fell in the gap. */
.grid2 { display: grid; gap: 10px; grid-template-columns: 1fr; }
@container pane (min-width: 560px) { .grid2 { grid-template-columns: 1fr 1fr; } }

.empty { text-align: center; padding: 40px 20px; color: var(--muted); }
.empty h3 { color: var(--ink); font-size: 16px; margin-bottom: 6px; font-weight: 600; }
.empty p { font-size: 14px; }

.refine { position: relative; margin-bottom: 10px; }
.refine input {
  width: 100%; min-height: var(--tap); padding: 0 12px;
  border: 1px solid var(--line); border-radius: 6px; font: inherit; font-size: 14px;
}
.refine input:focus { outline: none; border-color: var(--navy); }

/* ── Login ───────────────────────────────────────────────────────────────── */
.auth { display: grid; place-items: center; min-height: 100dvh; padding: 24px 16px; background: var(--navy); }
.auth__box { width: 100%; max-width: 380px; background: #fff; border-radius: 12px; padding: 26px 22px; }
.auth__brand { text-align: center; font-size: 22px; font-weight: 700; color: var(--navy); margin-bottom: 2px; }
.auth__brand span { color: var(--amber); }
.auth__tag { text-align: center; color: var(--muted); font-size: 13px; margin-bottom: 20px; }
.auth label { display: block; font-size: 12px; font-weight: 600; color: var(--muted); margin-bottom: 5px; }
.auth input[type=email], .auth input[type=password], .auth input[type=text] {
  width: 100%; min-height: 48px; padding: 0 12px; margin-bottom: 14px;
  border: 1px solid var(--line); border-radius: 8px; font: inherit; font-size: 16px; /* 16px: iOS won't zoom */
}
.auth input:focus { outline: none; border-color: var(--navy); }
.auth .btn { width: 100%; }
.auth .code {
  font-family: var(--mono); font-size: 26px; letter-spacing: .35em; text-align: center;
}
.auth__err {
  background: #fdecec; border: 1px solid #f3c4c4; color: #8c1520;
  padding: 10px 12px; border-radius: 8px; font-size: 13px; margin-bottom: 14px;
}
.auth__note { font-size: 12px; color: var(--muted); line-height: 1.5; margin-top: 14px; }
.qr { display: block; margin: 0 auto 12px; width: 190px; height: 190px; border: 1px solid var(--line); border-radius: 8px; }
.secret {
  font-family: var(--mono); font-size: 13px; text-align: center; word-break: break-all;
  background: var(--paper); padding: 8px; border-radius: 6px; margin-bottom: 14px; color: var(--muted);
}

/* ── Scanner ─────────────────────────────────────────────────────────────── */
.scan { position: fixed; inset: 0; background: #000; z-index: 100; display: none; flex-direction: column; }
.scan[data-open] { display: flex; }
.scan__bar {
  background: var(--navy); color: #fff; display: flex; align-items: center;
  justify-content: space-between; padding: 10px 12px; padding-top: calc(10px + env(safe-area-inset-top));
}
.scan__view { flex: 1; min-height: 0; position: relative; overflow: hidden; }
.scan__view video { width: 100%; height: 100%; object-fit: cover; }
.scan__aim {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);
  width: 62%; aspect-ratio: 1; border: 3px solid rgba(255,255,255,.9); border-radius: 12px;
  box-shadow: 0 0 0 9999px rgba(0,0,0,.35); pointer-events: none;
}
.scan__ctl {
  background: var(--navy); padding: 12px; padding-bottom: calc(12px + env(safe-area-inset-bottom));
  display: grid; gap: 10px;
}
.scan__ctl label { color: #fff; font-size: 12px; opacity: .85; }
.scan__ctl input[type=range] { width: 100%; }
.scan__row { display: flex; gap: 8px; }
.scan__row .btn { flex: 1; }
.scan__status { color: #fff; font-size: 13px; text-align: center; min-height: 20px; }
.scan__status.err { color: #ffb3b3; }
.scan__status.ok  { color: #8ce6a8; }

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


/* ── Menu sheet ──────────────────────────────────────────────────────────── */
.sheet {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(2, 31, 90, .55);
  display: none;
}
.sheet[data-open] { display: block; }
.sheet__panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(300px, 82%);
  background: #fff;
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  display: flex; flex-direction: column;
  box-shadow: -8px 0 30px rgba(0,0,0,.25);
}
.sheet__hd {
  background: var(--navy); color: #fff;
  padding: 14px 16px; display: flex; align-items: center; justify-content: space-between;
}
.sheet__who { font-size: 14px; font-weight: 600; }
.sheet__role { font-size: 11px; opacity: .7; font-family: var(--mono); }
.sheet nav { flex: 1; min-height: 0; overflow-y: auto; padding: 6px 0; }
.sheet nav a, .sheet nav button {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; min-height: var(--tap); padding: 0 16px;
  background: none; border: 0; border-bottom: 1px solid var(--line);
  font: inherit; font-size: 15px; color: var(--ink); text-align: left;
  text-decoration: none; cursor: pointer;
}
.sheet nav a:hover, .sheet nav button:hover { background: var(--paper); }
.sheet nav .danger { color: var(--red); }
.sheet nav .tag {
  font-size: 10px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  background: var(--amber); color: #1a1a1a; border-radius: 9px; padding: 2px 7px;
}
.sheet__ft {
  padding: 12px 16px; border-top: 1px solid var(--line);
  font-size: 11px; color: var(--muted); font-family: var(--mono);
}


/* ═══ PDF VIEWER — inside the tab, never a new window ═══════════════════════
   v1 opened PDFs in a new window, which throws the technician out of the app and
   destroys every other tab. Everything below lives in the documents tab. */
.pdf { display: flex; flex-direction: column; flex: 1; min-height: 0; }

.pdfbar {
  display: flex; align-items: center; gap: 2px;
  background: var(--navy); color: #fff; padding: 4px 6px; border-radius: 6px 6px 0 0;
}
.pdfbar button {
  background: transparent; border: 0; color: #fff; cursor: pointer;
  min-width: 36px; min-height: 36px; border-radius: 5px; font-size: 18px; line-height: 1;
  display: grid; place-items: center;
}
.pdfbar button:hover { background: rgba(255,255,255,.14); }
.pdfbar__sp { flex: 1; }
.pdfbar__pg { display: flex; align-items: center; gap: 5px; font-size: 12px; font-family: var(--mono); }
.pdfbar__pg input {
  width: 46px; min-height: 30px; text-align: center; border: 0; border-radius: 4px;
  background: rgba(255,255,255,.16); color: #fff; font: inherit; font-family: var(--mono);
}
.pdfbar__pg input::-webkit-outer-spin-button,
.pdfbar__pg input::-webkit-inner-spin-button { appearance: none; margin: 0; }

.pdffind {
  display: flex; align-items: center; gap: 6px;
  background: var(--navy-2); padding: 6px; 
}
.pdffind input {
  flex: 1; min-width: 0; min-height: 34px; padding: 0 10px;
  border: 0; border-radius: 5px; font: inherit; font-size: 14px;
}
.pdffind .meta { color: #cfd7f8; font-size: 12px; font-family: var(--mono); min-width: 52px; text-align: center; }
.pdffind button {
  background: rgba(255,255,255,.16); border: 0; color: #fff; cursor: pointer;
  min-width: 34px; min-height: 34px; border-radius: 5px; font-size: 17px;
}

/* PDF.js REQUIRES its container to be position:absolute — it checks, and throws
   "The `container` must be absolutely positioned" if it isn't.
   So: a relatively-positioned wrapper that flexes, and the scroll container
   absolutely filling it. min-height:0 on the wrapper because a flex child will
   not shrink below its content, and a PDF is very tall content. */
.pdfwrap {
  flex: 1; min-height: 0; position: relative;
  background: #52565e; border-radius: 0 0 6px 6px; overflow: hidden;
}
.pdfview {
  position: absolute; inset: 0; overflow: auto;
  -webkit-overflow-scrolling: touch;
}
.pdfload {
  padding: 22px; text-align: center; color: var(--muted); font-size: 13px;
  background: #fff; border-radius: 0 0 6px 6px;
}
.pdfload--err { color: var(--red); }

/* PDF.js needs its container to be positioned for the text layer to line up. */
.pdfview .pdfViewer { position: relative; }
.pdfview .page { margin: 8px auto; border: 0; box-shadow: 0 2px 10px rgba(0,0,0,.35); }
