/* 30-sheet.css — see 00-contract.css for the rules this file obeys.
   Every rule below is inside a max-width or pointer:coarse media query.

   Owns the shared page surface every one of the ~60 non-editor,
   non-sequence-viewer, non-annotator templates is built from:
   .shell__body, .sheet (+ --wide), .field/.form-stack/.filter-bar,
   .btn/.icon-btn, .data-table, .panel, and the handful of typography
   classes (.mono, code/kbd/samp) that carry hashes and accession numbers.

   Jeremy's ask, verbatim: "borders have to go to use the already narrow
   full width." At 375px, the desktop rules spend it like this:
     .shell__body   padding: 2rem 1rem 4rem     -> 1rem   (16px) each side
     .sheet         padding: 2.2rem 2.4rem 2.6rem -> 2.4rem (38.4px) each side
   That's 54.4px of gutter on EACH side before any content — ~109px of a
   375px screen, or 29% of the width, spent on two nested margins that
   both exist for the same reason (keep text off the edge). Section A
   below collapses both to the one --gutter-compact token, so the same
   job is done once instead of twice: 900px tier leaves ~27px a side
   (0.85rem × 2 layers), 600px tier ~22px a side (0.7rem × 2 layers) —
   the content column gains roughly a quarter of the screen back. */

/* ============================================================
   A. Full-bleed the sheet — shell__body and sheet gutters collapse to
      the same token so they read as one edge margin, not two.
   ============================================================ */

@media (max-width: 900px) {
  /* Only the horizontal padding is ours to touch — top/bottom rhythm
     (and any safe-area inset) belongs to 10-shell.css/the theme, which
     this rule leaves alone by naming the two sides explicitly instead
     of restating the `padding` shorthand. */
  .shell__body {
    padding-left: var(--gutter-compact);
    padding-right: var(--gutter-compact);
  }

  /* .sheet--wide is the SAME element as .sheet (templates write
     class="sheet sheet--wide"), so this one selector already reaches
     both — no separate .sheet--wide rule needed for padding.

     .sheet--seq and .sheet--annotate are excluded on purpose: they are
     already `max-width: none` full-bleed viewers set up by
     40-sequences.css/50-annotate.css (which load AFTER this file), and
     they carry the base .sheet class too. A plain `.sheet { padding }`
     rule here would win the cascade against the theme's unconditional
     `.sheet--seq, .sheet--annotate` rule (equal specificity, later
     source), so it would silently reach into pages this file does not
     own. :not() keeps this section scoped to the ~55 prose/table/form
     sheets it's actually meant for. */
  .sheet:not(.sheet--seq):not(.sheet--annotate) {
    padding-left: var(--gutter-compact);
    padding-right: var(--gutter-compact);
  }
}

@media (max-width: 600px) {
  /* Below 600px there is no room left to spend on a "floating card" —
     drop the chrome that makes .sheet read as a card on --ground
     (rounded corners, the drop shadow, and any max-width the theme set)
     so it reads as the page itself. Vertical padding is untouched: the
     ask was to recover horizontal space, not to flatten the page's
     top/bottom rhythm. Same :not() scoping as above, same reason. */
  .sheet:not(.sheet--seq):not(.sheet--annotate) {
    max-width: none;
    border-radius: 0;
    box-shadow: none;
  }
}

/* ============================================================
   B. Tables — 21 templates' .data-table, 0.6rem cell padding, width:
      100%. A four-or-five-column table at that padding does not fit a
      375px viewport; the invariant is that the PAGE must never scroll
      sideways, only the table may.

   Approach: make the table element itself the scroll container
   (display: block; overflow-x: auto) instead of wrapping it — there is
   no markup lever available to this file, and the repo has no
   <colgroup> usage anywhere (grepped), so the one layout feature this
   trick is known to interact badly with does not exist here to break.

   What actually happens: setting `display: block` on <table> turns
   *that* box into a plain block box — the width: 100% already on
   .data-table now sizes the SCROLL CONTAINER to the sheet's width. Its
   <thead>/<tbody>/<tr>/<td> children keep their table-part display
   values, so the browser still lays them out as a table, but that
   table box is now free-floating inside the block box rather than
   being it — its width is no longer pinned to 100%, so cells with
   unbreakable content (mono hashes, numbers, `white-space: nowrap`
   spans) push it past the container's width instead of being crushed,
   and overflow-x: auto scrolls exactly that excess.

   Trade-off, honestly: `border-collapse: collapse` is specified on
   .data-table itself, and it is not settled across engines whether a
   collapse mode set on an element applies once that element stops
   being display:table and an anonymous table box is generated for its
   table-part children instead. Where it doesn't carry through, adjacent
   1px cell borders stop merging and instead sit border-spacing apart —
   a busier grid than the desktop rendering, not a broken one.
   `border-spacing: 0` below closes that gap regardless of which way a
   given engine resolves it, so the worst case is "borders look a touch
   heavier," never a visible seam. This has not been checked in a real
   phone browser (no browser tool in this pass) — worth a five-minute
   look on a device before calling it done.

   Tables with only wrapping prose in their cells will simply reflow
   inside the available width and never trigger the scrollbar at all;
   only the ones with genuinely wide/unbreakable columns (evidence's
   hex digests, backups' run hashes) do. .data-table--scroll's own
   `overflow-x: auto` (no display:block) becomes redundant here rather
   than conflicting — every .data-table gets the same treatment below
   900px regardless of whether a page opted into the modifier. */
@media (max-width: 900px) {
  .data-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-spacing: 0;
    /* A visible-by-default scrollbar is the "discoverable" half of the
       ask — coarse pointers don't hover to discover a hidden one, and
       a table that merely LOOKS complete at the right edge gives no
       hint there is more of it to the right. Firefox/Chromium only;
       Safari keeps its own overlay scrollbar regardless. */
    scrollbar-width: thin;
    scrollbar-color: var(--rule) transparent;
  }
  /* A long unbroken token (accession number, hex digest) sitting alone
     in an otherwise ordinary 2-3 column table would force the WHOLE
     table into scroll-mode for the sake of one cell. Letting it wrap
     keeps the common case (a few short columns, one wide text field)
     reflowing instead of scrolling, and only genuinely wide tables
     fall through to the scroll container above. */
  .data-table td {
    overflow-wrap: anywhere;
  }
}

/* ============================================================
   C. Forms — the iOS zoom trap, multi-column layouts, and overflow.

   --text-ui is 14px. iOS Safari zooms in on focus of any <input>,
   <select> or <textarea> whose computed font-size is under 16px, and
   it does not zoom back out on blur — every text field in the app
   currently trips this. All of it lives at the PHONE tier per
   00-contract.css's own assignment of "16px form text" to 600px.
   ============================================================ */
@media (max-width: 600px) {
  .field input[type="text"],
  .field input[type="email"],
  .field input[type="password"],
  .field input[type="number"],
  .field input[type="tel"],
  .field input[type="search"],
  .field input[type="date"],
  .field input[type="datetime-local"],
  .field input[type="time"],
  .field select,
  .field textarea {
    font-size: 16px;
  }

  /* .field's own input/select/textarea rule (app.css ~line 213) lists
     text/email/password/number/tel/select/textarea but not date,
     datetime-local or time — those three currently fall through to the
     bare UA control on EVERY viewport, desktop included (app.css is not
     this file's to fix). At phone width they matter enough to give them
     the same box: full-width, bordered, legible, and not undersized for
     a thumb. */
  .field input[type="date"],
  .field input[type="datetime-local"],
  .field input[type="time"] {
    width: 100%;
    font: inherit;
    font-size: 16px;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 0.5rem 0.6rem;
  }

  /* Two- and three-across form rows. Grepped: exactly three templates
     write bare class="row" around sibling .field elements (planner's
     dependency picker, sequences' primer-design start/end pair) — the
     fourth `.row` in the templates (samples/storage.html's
     `row storage-box-row`) is a name+meta content row, not a field
     pair, so this is scoped with :has() to the actual form case rather
     than reflowing every `.row` in the app sight-unseen. Once it's a
     column, the flexbox `min-width: auto` quirk that let a squeezed
     .field push its input past the sheet's edge stops applying on the
     axis that mattered. */
  .row:has(> .field) {
    flex-direction: column;
    align-items: stretch;
  }

  /* Defensive belt-and-suspenders for any .field sitting in a flex row
     this file didn't anticipate: min-width: auto (the flex default) is
     exactly what stops a squeezed flex item from shrinking below its
     content's width, which is how an input ends up wider than the
     sheet. Costs nothing when .field isn't a flex item. */
  .field {
    min-width: 0;
  }

  /* .form-stack is already `flex-direction: column` on every viewport —
     nothing to collapse there, it was single-column from the start. */

  /* The filter bar above library tables (tasks/samples/references/
     reagents/sequences): several .field siblings with individual
     min-widths, wrapping via flex-wrap when they don't fit. On a phone
     that wrap can still leave two unevenly-sized fields sharing a
     cramped line; forcing one-per-row reads far better than a wrap
     point that lands wherever the labels happen to fit. */
  .filter-bar .field,
  .filter-bar .field--grow {
    flex: 1 1 100%;
    min-width: 0;
  }
  .filter-bar--default .field {
    flex: 1 1 100%;
  }

  /* A .btn whose label is long enough to matter (a handful of
     confirm/cancel actions carry a full sentence) currently can't wrap
     its own text (`white-space: nowrap`, app.css ~line 322), so instead
     of wrapping the row (already flex-wrap: wrap) it can force a single
     button — and the row around it — wider than the viewport. Letting
     the label wrap keeps the overflow inside the button. */
  .btn {
    white-space: normal;
    text-align: center;
  }
}

/* ============================================================
   D. Buttons and touch targets — hit-area only, never layout, so this
      lives under pointer:coarse and nowhere else. An iPad in landscape
      matches this and should NOT get phone-width layout, but SHOULD
      get a 44px button — that split is exactly what this query buys.

      Scoped to .sheet/.panel so it reaches the generic buttons inside
      page content without touching the topbar's or sidebar's own
      icon-btn (10-shell.css's job) or the editor docbar's (20-editor
      .css's job) — neither lives inside a .sheet or .panel.
   ============================================================ */
@media (pointer: coarse) {
  .btn {
    min-height: var(--tap);
    min-width: var(--tap);
  }

  .sheet .icon-btn,
  .panel .icon-btn {
    width: var(--tap);
    height: var(--tap);
  }
}

/* ============================================================
   E. Typography — long unbroken content must wrap, not force a
      horizontal scroll on the page (only .data-table above is allowed
      to scroll sideways).

      .secret and .hashbox already carry `word-break: break-all`
      unconditionally in app.css, so the 2FA secret and the sign-dialog
      hash box are already safe on every viewport — nothing to add here.
      .page pre already has `overflow-x: auto` unconditionally too, and
      .page belongs to notes/shell.html alone (the editor's surface, not
      this file's), so code blocks there are both already handled and
      not this file's to touch.

      What's left uncovered: `.mono` (and the bare code/kbd/samp it's
      grouped with, app.css ~line 113) is used for exactly this kind of
      content — chain-hash prefixes, backup run hashes, evidence tx
      hashes — across evidence/, backups/, mattermostbot/, samples/ and
      accounts/profile.html, and today it sets nothing but a font. Table
      cells are covered above (section B); this catches the same
      content wherever it appears outside a table (.meta lines, plain
      paragraphs). Scoped to 900px, not 600, since a squeezed iPad
      portrait sheet can overflow on a long hash just as easily as a
      phone can. */
@media (max-width: 900px) {
  code,
  kbd,
  samp,
  .mono {
    overflow-wrap: anywhere;
  }
}
