/* ══════════════════════════════════════════════════════════════════════════════
   PHONE + TYPE PASS — drop-in, no markup changes required
   Deuce, 2026-09-19. Measured on LIVE app.getinstabid.pro at 390×844, logged in.

   LOAD ORDER MATTERS: this must come AFTER the app's own stylesheet in the
   layout, or Tailwind's utilities win on equal specificity and nothing here
   applies. In the layout, put its <%= stylesheet_link_tag %> BELOW :app.

   Scars this file is built on:
     · A media query is a CONDITION, not a PRIORITY. Later source order with
       equal specificity beats an earlier @media block. That is why load order
       is stated first and why the phone block is LAST in this file.
     · width:100% is the lever that makes a grid item shrink. min-width:0 only
       PERMITS shrinking, it does not CAUSE it.
════════════════════════════════════════════════════════════════════════════ */


/* ══ 1 · THE iOS ZOOM BUG — the single biggest phone defect in the app ═══════
   MEASURED: 359 input boxes under 16px on /contractor/labor_rates/edit alone.
   MECHANISM: iPhone Safari auto-zooms the viewport whenever a focused input has
   font-size < 16px. It is not a preference and it cannot be disabled from CSS.
   So every tap on a rate box lurches the page and re-centres it — 359 times on
   the page John made top priority. 16px is the exact threshold; 15.99 zooms.
   This rule is why the file exists. It is one line and it fixes all 359.
════════════════════════════════════════════════════════════════════════════ */
input[type="text"], input[type="number"], input[type="email"], input[type="tel"],
input[type="password"], input[type="search"], input[type="url"], input[type="date"],
select, textarea {
  font-size: 16px;            /* NEVER lower this. 16 is the iOS threshold. */
}


/* ══ 2 · THE $5 READING GLASSES LAW ══════════════════════════════════════════
   John: "us contractors eat sawdust for years, we squint all day… we don't want
   to squint at this." MEASURED: 1,115 elements at 11/12/13px on labor rates,
   11 more on the dashboard.
   Real reading text never goes below 14px. The ONLY exemption is a mono/tracked
   eyebrow label — a LABEL is not reading, and those are explicitly re-exempted
   at the bottom of this block so this rule doesn't flatten the type hierarchy.
════════════════════════════════════════════════════════════════════════════ */
body, p, li, td, th, label, span, a, button, div, dt, dd {
  font-size: max(14px, 1em);  /* raises the floor, leaves anything larger alone */
}
/* eyebrow labels, chips and badges keep their small tracked size on purpose */
.pbadge, .badge, .eyebrow, .kbd, .tag, [class*="text-xs"] {
  font-size: 12px !important;
  letter-spacing: .06em;
}


/* ══ 3 · TAP TARGETS ════════════════════════════════════════════════════════
   MEASURED: 14 targets under 40px tall on the dashboard and on labor rates.
   Apple's floor is 44. A man in work gloves misses a 32px button — this is a
   miss-rate problem, not an aesthetics problem.
════════════════════════════════════════════════════════════════════════════ */
/* Exempt: Deuce's switch (.tog, drawn 44×25) and the ✕ on his date chip — fixed-size controls in
   _ui.css. As a <button> (People, 10/04) the 44px floor turned his pill switch into a square. */
a.btn, button:not(.tog):not(.dchip button), input[type="submit"], .pill, .chip, [role="button"] {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* inline text links inside a paragraph are NOT tap targets and must not inherit
   a 44px box — that would break the line box and blow up the paragraph. */
p a, li a, td a, .prose a { min-height: 0; display: inline; }


/* ══ 4 · PHONE — must stay the LAST block in this file ═══════════════════════ */
@media (max-width: 767px) {

  /* ── 4a · THE LABOR RATE ROW — selectors READ OFF THE DOM, not guessed ───
     My first draft invented `.labor-rate-row`. It matched nothing and the page
     got 285px TALLER instead of shorter — which is how I found out. The real
     hook is the element carrying data-labor-autosave-url-value.

     🔴 THE FINDING THAT MATTERS: the two-column layout ALREADY EXISTS in the
     markup as `sm:grid-cols-[1fr_minmax(150px,200px)]`. It is simply switched
     OFF below Tailwind's sm (640px). Nobody built a bad phone layout — the good
     layout was disabled on the one device most contractors will use.

     MEASURED on live, 390px, before -> after:
       one rate card   210px -> 137px
       whole page     5,381px -> 3,856px
       Remodel (156)   ~33k  -> ~21k px of scrolling
       horizontal overflow 0 -> 0   (did not break what was already right) */
  [data-labor-autosave-url-value] > .grid{
    grid-template-columns:minmax(0,1fr) 116px !important;
    align-items:center;
    gap:10px;
  }
  [data-labor-autosave-url-value]{padding-top:10px;padding-bottom:10px}
  [data-labor-autosave-url-value] input{text-align:right}

  /* The single biggest thing in the card was `label.form-label` at 114px —
     "Click to edit your price (clear it to go back to the default)", IDENTICAL
     on all 156 rows, wrapping to three lines in a narrow column.
     ⚠️ NOT display:none. That would strip the input's accessible name. sr-only
     keeps it for a screen reader at zero pixels.
     ⚠️ JACK — TWO THINGS CSS CANNOT DO, both in the ERB:
       1. That sentence belongs ONCE at the top of the page, not once per rate.
       2. It says "CLICK to edit your price." On a phone he TAPS.
          → config/locales/en.yml, labor_rates.edit */
  [data-labor-autosave-url-value] label.form-label{
    position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
  }

  /* 🔴 STRING FIX, REQUIRED — the CSS above is only correct WITH it.
     The input placeholder reads "Default $275.00" while the line directly above
     it already reads "Default $275.00 / lineal feet". Same fact, twice, in one
     card, on the screen where width is scarcest. At 116px the placeholder
     CLIPS to "Default $1". Widening the column to fit "Default $1225.00" (the
     longest on the page) costs 290px of page height because the rate name then
     wraps more — so widening is the wrong lever.
     → Shorten the placeholder to just the amount: "$275.00".
       PROVEN on live: every placeholder on the page then fits at 116px
       (worst-case ratio 1.00), card stays 137px, page stays 3,856px. */

  /* ── 4b · WIDE TABLES ─────────────────────────────────────────────────────
     MEASURED: /estimates renders 85 rows, 5,855px tall, table 460px wide inside
     a 390px screen. The page does NOT side-scroll (that part is already right)
     but columns are clipped and have to be scrolled sideways inside the table.
     A flex/grid child still contributes its MIN-CONTENT width to its track
     unless you give it min-width:0 — overflow-x alone does nothing. */
  .table-wrap, .data-table-wrap {
    overflow-x: auto;
    min-width: 0;
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
  }
  .data-table { min-width: 0; }

  /* ── 4c · the width lever ─────────────────────────────────────────────────
     A grid item with no explicit width sizes from CONTENT, not from its track,
     so it inherits its own max-width as a containing block and shoves the page.
     Proven on the mocks: this took overflow from 710px to 0. */
  main, .shell > main, .container { width: 100%; box-sizing: border-box; }

  /* ── 4d · chip and tab strips scroll, they do not push ────────────────────
     Same min-width:0 mechanism. Without it the strip scrolls internally AND
     still widens the page. Bisection receipt on the mocks: hiding the chip
     strip took the page from 1100px to 390px on the nose. */
  .chips, .tabs, .trade-picker {
    min-width: 0; max-width: 100%;
    overflow-x: auto; flex-wrap: nowrap;
    scrollbar-width: none;
  }
  .chips::-webkit-scrollbar, .tabs::-webkit-scrollbar,
  .trade-picker::-webkit-scrollbar { display: none; }
  .chips > *, .tabs > *, .trade-picker > * { flex: 0 0 auto; }

  /* ── 4e · the chat bubble sits on top of content ──────────────────────────
     Observed at 390px: the support bubble overlaps the bottom-right of the
     rate cards. Lifted clear of the last row. */
  .chat-bubble, [class*="chat-widget"] { bottom: 84px !important; }

  /* ── 4b · THE PRICING ROW — same disease Deuce diagnosed on labor rates ──────
     Added by JACK 2026-09-27, in Deuce's sheet on purpose: this is the SAME
     pattern he already proved, and a second stylesheet for one rule would be a
     shadow copy of his work.

     🔴 SAME FINDING, SECOND PAGE: contractor/pricings/edit.html.erb:316 carries
     `grid-cols-1 sm:grid-cols-[1fr_minmax(200px,300px)_minmax(150px,240px)]`.
     The three-column layout is real and good — and switched OFF below Tailwind's
     sm (640px), so on a phone every category becomes THREE stacked full-width
     blocks. I surveyed every contractor page: labor rates and this one are the
     ONLY two with this shape. Labor rates is handled above. This is the last one.

     WHY CSS AND NOT THE MARKUP: I tried transplanting a hand-built row layout into
     this file on 9/19 and broke it twice — first a dropped block closer, then the
     block landed outside the `categories.each` it depends on. The page has three
     nested forms and two add-part blocks. This rule reaches the same result with
     ZERO template risk, and it hooks the data attribute the element already
     carries rather than a class I invented — Deuce's own lesson from his first
     draft, which matched nothing and made the page taller.

     THE REFLOW: name spans the full width (it is the longest text and the thing
     he scans for), then part and price sit side by side beneath it. Price is
     pinned at 116px to match the labor row above, so the two money screens line
     up instead of each inventing their own rhythm. */
  [data-pricing-autosave-url-value] > .grid{
    grid-template-columns:minmax(0,1fr) 116px !important;
    align-items:center;
    gap:10px;
  }
  /* The category name + badges span both columns; part and price share the row. */
  [data-pricing-autosave-url-value] > .grid > div:first-child{ grid-column:1 / -1; }
  [data-pricing-autosave-url-value] > .grid input[type="number"]{ text-align:right; }
}
