/* ============================================================================
   tablet.css — shared 10" tablet / iPad layer for every MyPortalSense app
   ----------------------------------------------------------------------------
   Drop-in stylesheet. Add ONE line to the <head> of any app, last among the
   stylesheets so it can adjust what the page already defines:

       <link rel="stylesheet" href="/assets/tablet.css">

   Design rules this file follows
   ------------------------------
   1. It only ever takes effect inside a media query. On a desktop browser the
      file is inert — nothing here can change how the apps look today.
   2. It fixes LAYOUT problems that break on a tablet (fixed pixel widths,
      multi-column grids, wide tables, small tap targets). It does NOT restyle
      anything — no colour, font-family or branding changes.
   3. Print is explicitly untouched. Certificates and reports (PTC / CPC / PPC,
      IWO, MRF) must still come out at exact A4 millimetre sizes, so every rule
      below is scoped to `screen` and the whole file steps aside under @media
      print.
   4. Opt-out escape hatch: add class="no-tablet" to any element (or to <body>)
      and these rules skip it. Useful for a canvas, a signature pad, or a report
      preview that must keep its exact geometry.

   Target devices
   --------------
   10.2"–11" iPad and equivalent Android tablets:
       portrait   810 × 1080 css px   (also 768 × 1024 on older iPads)
       landscape 1080 ×  810 css px   (also 1024 ×  768)
   Range covered: 768px – 1180px. Phones (< 768px) get a tighter pass at the
   bottom so the apps stay usable there too, without being the focus.

   Written 2026-08-06.
   ========================================================================== */

/* ---------------------------------------------------------------------------
   0. Foundations — apply on any touch-capable screen up to 1180px wide.
   ------------------------------------------------------------------------ */
@media screen and (max-width: 1180px) {

  /* iOS bumps font size on rotate unless this is pinned. */
  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }

  /* A tablet has no hover, so a page that relies on :hover to reveal things
     needs its rows tappable. Momentum scrolling inside panes, too. */
  body:not(.no-tablet) {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
  }

  /* Nothing should be able to force a horizontal page scroll. Individual wide
     things (tables, report previews) get their own scroller further down. */
  body:not(.no-tablet) {
    overflow-x: hidden;
  }
}

/* ---------------------------------------------------------------------------
   1. TABLET RANGE — 768px to 1180px (covers both iPad orientations)
   ------------------------------------------------------------------------ */
@media screen and (min-width: 768px) and (max-width: 1180px) {

  /* --- 1.1 Containers -----------------------------------------------------
     Apps were laid out for a ~1280px+ desktop and many wrap their content in a
     fixed or min-width shell. Release those so the content reflows instead of
     spilling off the right edge. */
  body:not(.no-tablet) .container,
  body:not(.no-tablet) .wrap,
  body:not(.no-tablet) .wrapper,
  body:not(.no-tablet) .content,
  body:not(.no-tablet) .app,
  body:not(.no-tablet) .shell,
  body:not(.no-tablet) .main,
  body:not(.no-tablet) main,
  body:not(.no-tablet) .card,
  body:not(.no-tablet) .panel,
  body:not(.no-tablet) .section {
    max-width: 100% !important;
    min-width: 0 !important;
    box-sizing: border-box;
  }

  /* `.page` is NOT a container in this codebase — in ptc/cpc/ppc it is the
     A4 sheet itself (210mm × 297mm, fixed height, fixed padding in mm). It is
     handled with the other report surfaces in 1.7 and must never be reflowed. */

  /* Generic safety net: any element that declares a min-width wider than the
     viewport is the single most common cause of a sideways-scrolling tablet
     page. Tables and report pages are deliberately excluded — they are handled
     properly in 1.4 and 1.7. */
  body:not(.no-tablet) div[style*="min-width"]:not(.no-tablet):not([class*="report"]):not([class*="cert"]):not([class*="preview"]):not([class*="page"]) {
    min-width: 0 !important;
  }

  /* --- 1.2 Form grids -----------------------------------------------------
     Three- and four-column field grids are unreadable at 810px. Drop them to
     two columns; single-column grids are left alone. */
  body:not(.no-tablet) .grid-3,
  body:not(.no-tablet) .grid-4,
  body:not(.no-tablet) .g3,
  body:not(.no-tablet) .g4,
  body:not(.no-tablet) .cols-3,
  body:not(.no-tablet) .cols-4 {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }

  /* Inline-style grids. The calibration tools (ptc / cpc / ppc) build their
     field grids in JavaScript, so there is no class to hook — but they use a
     very specific signature:

         editor form grids : "1fr 1fr", "1fr 1fr 1fr", "1fr 1fr 1fr 1fr"
         report/cert grids : "80mm 6mm 1fr", "30px 1fr 20px 1fr", …

     Matching the exact `1fr`-only strings therefore reaches every form grid and
     cannot touch a certificate layout, which always carries a mm or px track.
     This is why these selectors are written out longhand instead of using a
     loose `[style*="grid"]` match. */
  body:not(.no-tablet) [style*="1fr 1fr 1fr 1fr"],
  body:not(.no-tablet) [style*="1fr 1fr 1fr"],
  body:not(.no-tablet) [style*="repeat(4,"],
  body:not(.no-tablet) [style*="repeat(4 ,"],
  body:not(.no-tablet) [style*="repeat(3,"],
  body:not(.no-tablet) [style*="repeat(3 ,"] {
    grid-template-columns: 1fr 1fr !important;
  }

  /* Any grid child that was told to span more columns than we now have. */
  body:not(.no-tablet) [style*="grid-column: span 3"],
  body:not(.no-tablet) [style*="grid-column:span 3"],
  body:not(.no-tablet) [style*="grid-column: span 4"],
  body:not(.no-tablet) [style*="grid-column:span 4"] {
    grid-column: span 2 !important;
  }

  /* Flex rows of form fields wrap instead of squashing. */
  body:not(.no-tablet) .form-row,
  body:not(.no-tablet) .field-row,
  body:not(.no-tablet) .row {
    flex-wrap: wrap !important;
  }

  /* --- 1.3 Touch targets --------------------------------------------------
     Apple's guidance is 44×44pt; Android's is 48dp. 44px is the compromise
     that doesn't visibly inflate a dense data form. */
  body:not(.no-tablet) button,
  body:not(.no-tablet) .btn,
  body:not(.no-tablet) [role="button"],
  body:not(.no-tablet) input[type="button"],
  body:not(.no-tablet) input[type="submit"],
  body:not(.no-tablet) select,
  body:not(.no-tablet) .tab,
  body:not(.no-tablet) .nav-item {
    min-height: 44px;
  }

  body:not(.no-tablet) input[type="text"],
  body:not(.no-tablet) input[type="number"],
  body:not(.no-tablet) input[type="date"],
  body:not(.no-tablet) input[type="time"],
  body:not(.no-tablet) input[type="email"],
  body:not(.no-tablet) input[type="tel"],
  body:not(.no-tablet) input[type="search"],
  body:not(.no-tablet) input[type="password"],
  body:not(.no-tablet) textarea,
  body:not(.no-tablet) select {
    min-height: 42px;
    /* iOS Safari zooms the whole page in when a focused field is under 16px.
       Pinning to 16px is the only reliable way to stop that. */
    font-size: 16px !important;
  }

  /* Checkboxes and radios are far too small to hit accurately with a finger. */
  body:not(.no-tablet) input[type="checkbox"],
  body:not(.no-tablet) input[type="radio"] {
    width: 20px;
    height: 20px;
  }

  /* Space out anything that was a tight row of icon buttons. */
  body:not(.no-tablet) .actions,
  body:not(.no-tablet) .toolbar,
  body:not(.no-tablet) .btn-group {
    gap: 8px;
    flex-wrap: wrap;
  }

  /* --- 1.4 Data tables ----------------------------------------------------
     Track Record, Equipment Inventory, UCUA and ECRS all render wide tables.
     Rather than shrink the text to nothing, put each table in its own
     horizontal scroller and keep the header row visible while scrolling. */
  body:not(.no-tablet) table:not(.no-tablet) {
    max-width: 100%;
  }

  body:not(.no-tablet) .table-wrap,
  body:not(.no-tablet) .table-container,
  body:not(.no-tablet) .table-scroll,
  body:not(.no-tablet) .tbl-wrap {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }

  /* Sticky header inside a scrolling table body. */
  body:not(.no-tablet) table:not(.no-tablet) thead th {
    position: sticky;
    top: 0;
    z-index: 2;
  }

  /* Slightly tighter cell padding buys back a column or two of width. */
  body:not(.no-tablet) table:not(.no-tablet) th,
  body:not(.no-tablet) table:not(.no-tablet) td {
    padding-left: 8px;
    padding-right: 8px;
  }

  /* --- 1.5 Sidebars and split layouts ------------------------------------
     A fixed 240–320px sidebar plus content does not fit in portrait. Stack
     them; in landscape there is room, so this only fires in portrait (1.8). */
  body:not(.no-tablet) .sidebar,
  body:not(.no-tablet) .side-panel,
  body:not(.no-tablet) aside {
    max-width: 100%;
  }

  /* --- 1.6 Modals ---------------------------------------------------------
     Desktop modals are often a fixed 560–720px and can end up taller than the
     tablet viewport with no way to scroll to the buttons. */
  body:not(.no-tablet) .modal,
  body:not(.no-tablet) .dialog,
  body:not(.no-tablet) .popup,
  body:not(.no-tablet) [role="dialog"] {
    max-width: 92vw !important;
    max-height: 88vh !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
  }

  /* --- 1.7 Report / certificate previews ---------------------------------
     A4 previews are 210mm (≈794px) or wider and MUST NOT be reflowed — the
     printed output has to stay dimensionally exact. Give the *wrapper* its own
     scroll box on screen; the sheet itself keeps its millimetre geometry. */
  body:not(.no-tablet) .report-preview,
  body:not(.no-tablet) .cert-preview,
  body:not(.no-tablet) .print-preview,
  body:not(.no-tablet) .cpc-report-overlay,
  body:not(.no-tablet) .ptc-report-overlay {
    overflow: auto !important;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }

  /* THE A4 SHEET ITSELF — hands off.
     `.page` in ptc/cpc/ppc is `width:210mm; height:297mm; padding:28mm …`.
     Nothing in this file may touch its width, padding or grid, or the on-screen
     preview stops matching the printed certificate. This block deliberately
     re-asserts "leave it alone" so that even the broad inline-style selectors
     in 1.2 cannot reach it. */
  body .page,
  body .a4,
  body .page-a4,
  body .cert-page,
  body .page *,
  body .a4 *,
  body .page-a4 *,
  body .cert-page * {
    max-width: none !important;
  }

  body .page,
  body .a4,
  body .page-a4,
  body .cert-page {
    min-height: 297mm;
    box-sizing: border-box;
    overflow: hidden;
  }

  /* Touch-target inflation must not reach a report either — a 44px minimum on
     a certificate table row would push content onto a second page. */
  body .page input,
  body .page select,
  body .page textarea,
  body .page button,
  body .a4 input,
  body .a4 select,
  body .a4 textarea,
  body .a4 button,
  body .cert-page input,
  body .cert-page select,
  body .cert-page textarea,
  body .cert-page button {
    min-height: 0 !important;
    font-size: inherit !important;
  }

  /* --- 1.8 Sticky bottom bars --------------------------------------------
     Keep primary Save/Next actions clear of the iPad home indicator. */
  body:not(.no-tablet) .sticky-bottom,
  body:not(.no-tablet) .action-bar,
  body:not(.no-tablet) .footer-actions {
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  }
}

/* ---------------------------------------------------------------------------
   2. TABLET PORTRAIT — the tighter of the two orientations (≈810px wide)
   ------------------------------------------------------------------------ */
@media screen and (min-width: 768px) and (max-width: 1024px) and (orientation: portrait) {

  /* Two-column grids become one column: at 810px minus padding, two columns of
     labelled fields leaves each around 380px, which truncates most labels. */
  body:not(.no-tablet) .grid-2,
  body:not(.no-tablet) .g2,
  body:not(.no-tablet) .cols-2,
  body:not(.no-tablet) [style*="1fr 1fr"],
  body:not(.no-tablet) [style*="repeat(2,"],
  body:not(.no-tablet) [style*="repeat(2 ,"] {
    grid-template-columns: minmax(0, 1fr) !important;
  }
  /* Certificate grids are safe from the above: they always carry a mm or px
     track ("80mm 6mm 1fr", "30px 1fr 20px 1fr"), so no report layout ever
     contains the literal "1fr 1fr" these selectors look for. */

  body:not(.no-tablet) [style*="grid-column: span 2"],
  body:not(.no-tablet) [style*="grid-column:span 2"] {
    grid-column: span 1 !important;
  }

  /* Sidebar above content rather than beside it. */
  body:not(.no-tablet) .layout,
  body:not(.no-tablet) .split,
  body:not(.no-tablet) .with-sidebar {
    display: block !important;
  }

  body:not(.no-tablet) .sidebar,
  body:not(.no-tablet) .side-panel,
  body:not(.no-tablet) aside {
    width: 100% !important;
    position: static !important;
    height: auto !important;
    margin-bottom: 12px;
  }

  /* Tab strips scroll sideways rather than wrapping into three ragged rows. */
  body:not(.no-tablet) .tabs,
  body:not(.no-tablet) .tab-bar,
  body:not(.no-tablet) .nav-tabs {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap !important;
    scrollbar-width: thin;
  }

  body:not(.no-tablet) .tabs > *,
  body:not(.no-tablet) .tab-bar > *,
  body:not(.no-tablet) .nav-tabs > * {
    flex: 0 0 auto;
  }

  /* Reclaim the outer gutter — every pixel counts in portrait.
     `.page` is excluded on purpose: it is the A4 sheet, whose 28mm/19.05mm
     margins are the printed page margins. */
  body:not(.no-tablet) .container,
  body:not(.no-tablet) .wrap {
    padding-left: 14px !important;
    padding-right: 14px !important;
  }
}

/* ---------------------------------------------------------------------------
   3. TABLET LANDSCAPE — ≈1080px wide, roughly a small laptop
   ------------------------------------------------------------------------ */
@media screen and (min-width: 1025px) and (max-width: 1180px) and (orientation: landscape) {

  /* Enough room for two columns, so 1.2's rule stands and nothing collapses
     further. Only the sidebar needs trimming so the content pane stays usable. */
  body:not(.no-tablet) .sidebar,
  body:not(.no-tablet) .side-panel {
    width: 220px !important;
    min-width: 0 !important;
  }

  /* On-screen keyboards eat roughly half the height in landscape; make sure a
     focused field can always be scrolled into view. */
  body:not(.no-tablet) form,
  body:not(.no-tablet) .form {
    scroll-padding-bottom: 320px;
  }
}

/* ---------------------------------------------------------------------------
   4. PHONE FALLBACK — under 768px. Not the target, but shouldn't be broken.
   ------------------------------------------------------------------------ */
@media screen and (max-width: 767px) {

  body:not(.no-tablet) .grid-2,
  body:not(.no-tablet) .grid-3,
  body:not(.no-tablet) .grid-4,
  body:not(.no-tablet) .g2,
  body:not(.no-tablet) .g3,
  body:not(.no-tablet) .g4,
  body:not(.no-tablet) [style*="1fr 1fr"],
  body:not(.no-tablet) [style*="repeat(2,"],
  body:not(.no-tablet) [style*="repeat(3,"],
  body:not(.no-tablet) [style*="repeat(4,"] {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  body:not(.no-tablet) [style*="grid-column: span 2"],
  body:not(.no-tablet) [style*="grid-column:span 2"],
  body:not(.no-tablet) [style*="grid-column: span 3"],
  body:not(.no-tablet) [style*="grid-column:span 3"],
  body:not(.no-tablet) [style*="grid-column: span 4"],
  body:not(.no-tablet) [style*="grid-column:span 4"] {
    grid-column: span 1 !important;
  }

  body:not(.no-tablet) input,
  body:not(.no-tablet) select,
  body:not(.no-tablet) textarea {
    font-size: 16px !important;
    min-height: 42px;
  }

  body:not(.no-tablet) button,
  body:not(.no-tablet) .btn {
    min-height: 44px;
  }

  body:not(.no-tablet) .sidebar,
  body:not(.no-tablet) aside {
    width: 100% !important;
    position: static !important;
  }

  body:not(.no-tablet) .modal,
  body:not(.no-tablet) [role="dialog"] {
    max-width: 96vw !important;
    max-height: 90vh !important;
    overflow-y: auto !important;
  }
}

/* ---------------------------------------------------------------------------
   5. Calibration client / Job No. pickers (client-db.js)
   The two injected search boxes span two grid columns by default; in portrait
   the grid is one column, so pull them back to a single span.
   ------------------------------------------------------------------------ */
@media screen and (max-width: 1024px) {
  .cdb-wrap,
  .cdb-job-wrap {
    grid-column: 1 / -1 !important;
  }

  .cdb-wrap input,
  .cdb-job-wrap input {
    font-size: 16px !important;
    min-height: 42px;
  }

  /* Result dropdowns need room for a fat fingertip. */
  .cdb-item,
  .cdb-job-item,
  .cdb-add {
    min-height: 44px;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}

/* ---------------------------------------------------------------------------
   6. PRINT — hands off entirely.
   Certificates, calibration reports, IWO and MRF forms must print at their
   exact designed size. Nothing above is allowed to survive into print.
   ------------------------------------------------------------------------ */
@media print {
  body .container,
  body .wrap,
  body .page,
  body .card,
  body .panel,
  body table,
  body .sidebar,
  body aside,
  body .modal,
  body [role="dialog"],
  body .report-preview,
  body .cert-preview,
  body .a4 {
    max-width: none !important;
    min-width: 0;
    overflow: visible !important;
  }

  body table thead th {
    position: static !important;
  }

  /* The injected search boxes are a screen tool; never print them. */
  .cdb-wrap,
  .cdb-job-wrap {
    display: none !important;
  }
}
