/* Responsive card mode for every table the CRM shell renders (2026-08-17,
   made universal 2026-09-13 under d-2026-09-13-040).
   Desktop keeps the table; under 768px each row becomes a labelled card.
   Labels come from data-label attributes stamped by erpal-resptable.js and, for
   anything rendered through a render array, by the theme's own preprocess. */

/* ── THE SCROLL FRAME ───────────────────────────────────────────────────────
   The other half of card mode, and the reason "opt out" is safe. A table that
   must stay a table on a phone (an email body's layout tables, a knowledge
   record's third-party report, a calendar grid) keeps its natural column widths
   and SCROLLS; it is never allowed to crush instead. The mobile gate encodes
   the same contract from the other side — it exempts cells inside this class
   from its 120px minimum and fails every narrow cell outside one. */
.erpal-scrollframe {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  max-width: 100%;
}
.erpal-scrollframe > table {
  /* Inside a scroll frame the table sizes to its CONTENT, which is the whole
     point — `table-layout: fixed` from the shell's shrink rules would defeat
     the frame by squeezing the table back into the viewport.
     `width: auto` was not enough and measuring proved it: a table inside a
     narrow block still shrink-to-fits its container, so fleet_watch's payload
     dump sat at 145px inside the frame and wrapped exactly as before. Ask for
     max-content and floor it at the frame's width. */
  table-layout: auto !important;
  width: max-content;
  max-width: none;
  min-width: 100%;
}
/* Machine output inside a frame is read by SCROLLING, not by wrapping: a
   collector payload is one 358-character JSON token and there is no line break
   that helps. */
.erpal-scrollframe > table.fw-kv td { white-space: pre; }
.erpal-scrollframe:focus-visible {
  outline: 2px solid var(--erpal-accent, #2563eb);
  outline-offset: 2px;
}

/* The sort strip only exists where the header does not — see sortBar() for why
   it exists at all. Above the breakpoint the real header is right there. */
.erpal-sortbar { display: none; }

@media (max-width: 767px) {
  table.erpal-resptable thead { display: none; }

  .erpal-sortbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem;
    margin: 0 0 .55rem;
    font-size: .78rem;
  }
  .erpal-sortbar__lead {
    color: var(--erpal-muted, #6b7280);
    text-transform: uppercase;
    letter-spacing: .03em;
    font-weight: 600;
  }
  .erpal-sortbar__link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;          /* a thumb target, like every other control here */
    padding: 0 .6rem;
    border: 1px solid var(--erpal-border, #e5e7eb);
    border-radius: 999px;
    background: var(--erpal-surface, #fff);
    /* A CHIP IS A BUTTON, AND IT HAS TO PASS AA LIKE ONE. These are real <a>
       elements cloned out of the header, so the shell's link colour applied and
       the contrast gate measured 3.09:1 on /deals at 390 — a miss this file
       introduced, caught on the promote it shipped in. `:link` and `:visited`
       are named explicitly because the bare class loses to `a:link` on
       specificity ties and the chip would silently go blue again. */
    color: var(--erpal-text, #111827);
    text-decoration: none;
    white-space: nowrap;
  }
  .erpal-sortbar__link:link,
  .erpal-sortbar__link:visited,
  .erpal-sortbar__link:hover,
  .erpal-sortbar__link:focus { color: var(--erpal-text, #111827); }
  .erpal-sortbar__link.is-active {
    border-color: var(--erpal-accent, #2563eb);
    font-weight: 600;
  }
  /* A HEADER ROW IS NOT ALWAYS IN A <thead>. Hand-written tables put the <th>
     row straight in the implicit tbody; erpal-resptable.js marks it. */
  table.erpal-resptable tr.erpal-headrow { display: none; }
  table.erpal-resptable, table.erpal-resptable tbody { display: block; width: 100%; }

  /* CARD MODE OUTRANKS THE SHELL'S SHRINK RULES. app.css narrows every table on
     a phone with `table-layout: fixed` + `overflow-wrap: anywhere`, which is a
     reasonable last resort for a table that stays a table and is catastrophic
     for one that does not: measured on Troy's screenshot, six columns of a
     390px screen is 53px each, and `anywhere` then breaks a decision id into
     one character per line. A card has no columns to shrink, so both rules are
     switched off here rather than left to specificity. */
  table.erpal-resptable {
    table-layout: auto;
    border-collapse: collapse;
  }

  table.erpal-resptable tbody tr,
  table.erpal-resptable > tr {
    display: block;
    margin: 0 0 .65rem;
    padding: .55rem .8rem;
    border: 1px solid var(--erpal-border, #e5e7eb);
    border-radius: 10px;
    background: var(--erpal-surface, #fff);
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
  }

  table.erpal-resptable td {
    display: flex;
    align-items: baseline;
    gap: .6rem;
    padding: .18rem 0;
    border: 0;
    font-size: .85rem;
    /* `break-word`, NOT `anywhere`: a card gives a value the room it needs, so
       a word should only ever break when it genuinely cannot fit. `anywhere`
       is what turns "Oregon Institute of Technology" into "Orego/n Institut/e"
       and a decision id into a vertical column of characters. */
    overflow-wrap: break-word;
    word-break: normal;
    min-width: 0;
    width: auto;
  }

  table.erpal-resptable td::before {
    content: attr(data-label) ": ";
    flex: 0 0 34%;
    max-width: 34%;
    font-size: .68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .02em;
    color: var(--erpal-muted, #6b7280);
  }

  /* A LONG VALUE GETS THE WHOLE CARD, LABEL ABOVE IT.
     With the label beside it, a value column is 66% of a 390px card minus
     padding — 159px measured — and the mobile gate calls anything over 25
     characters at that width crushed prose, correctly: /leads failed on a
     single 27-character email address rendered exactly there, on a page that
     had had card mode for four weeks. The stamper marks any cell over the
     gate's own prose threshold, so "long enough to need room" means the same
     thing in the layout and in the gate that checks it. */
  table.erpal-resptable td.erpal-td-long { display: block; }
  table.erpal-resptable td.erpal-td-long::before {
    display: block;
    flex: none;
    max-width: none;
    margin-bottom: .1rem;
  }

  /* Empty cells add nothing on a card. */
  table.erpal-resptable td:empty { display: none; }

  /* NO LABEL, NO COLON — FAIL-SAFE, NOT BEST-EFFORT.
     `content: attr(data-label) ": "` prints ": " for any cell the stamper never
     labelled, and there are three ways to be that cell: a column whose <th> is
     blank (the truck board's origin state, which leaves its header empty so the
     DESKTOP table reads the lane across two columns), the checkbox column that
     precedes every header, and a cell some OTHER behaviour appends to the row
     after this one has run — erpal_tidy's row-action cell does exactly that, and
     it is why the LD hub's own /leads cards have carried a bare ": " above the
     edit icons. Draw the label from the ATTRIBUTE'S PRESENCE rather than from
     its value, so a cell nobody labelled is silently unlabelled however it got
     there, and no JS ordering has to be right for the card to read correctly. */
  table.erpal-resptable td:not([data-label])::before,
  table.erpal-resptable td.erpal-td-cont::before { content: none; }
  /* A continuation aligns under the VALUE it continues, not under the labels. */
  table.erpal-resptable td.erpal-td-cont {
    padding-top: 0;
    padding-inline-start: calc(34% + .6rem);
  }
  table.erpal-resptable td.erpal-td-cont.erpal-td-long { padding-inline-start: 0; }

  /* Bulk-select checkbox column: no label, inline compact. */
  table.erpal-resptable td.views-field-operations::before,
  table.erpal-resptable td:has(> input[type="checkbox"]:only-child)::before { content: none; }
  table.erpal-resptable td:has(> input[type="checkbox"]:only-child) { padding: 0 0 .25rem; }

  /* A CELL THAT IS A CONTROL IS A CONTROL, NOT A FIELD.
     The desk's per-row "Mark executed" lives in a header-less last column. In a
     53px table cell it rendered as a vertical stack of fourteen letters — 44px
     tall and 20px wide, which is exactly why a tap-target check measuring HEIGHT
     passed it. On a card the button is the row's action: full width, one line,
     and a thumb-sized target. */
  table.erpal-resptable td.erpal-td-action { display: block; padding-top: .4rem; }
  table.erpal-resptable td.erpal-td-action::before { content: none; }
  table.erpal-resptable td.erpal-td-action > button,
  table.erpal-resptable td.erpal-td-action > input[type="submit"],
  table.erpal-resptable td > button,
  table.erpal-resptable td > input[type="submit"] {
    display: block;
    width: 100%;
    min-height: 44px;
    white-space: nowrap;
  }

  /* Phone cells: keep call + text side by side, numbers unbroken. */
  table.erpal-resptable .erpal-celllink { white-space: nowrap; }

  /* A KEY/VALUE TABLE HAS NO HEADER TO LABEL WITH — it IS label and value.
     fleet_watch's .fw-kv is the fleet's example: two columns, the left one a
     field name. Measured at 390 before this rule: the key column rendered at
     106px and "klamathliving-press-release-poller.service,mail-…" wrapped one
     word per line in the other. Stack the pair instead. */
  table.erpal-resptable-kv,
  table.erpal-resptable-kv tbody { display: block; width: 100%; }
  table.erpal-resptable-kv tbody tr,
  table.erpal-resptable-kv > tr {
    display: block;
    padding: .35rem 0;
    border-bottom: 1px solid var(--erpal-border, #e5e7eb);
  }
  table.erpal-resptable-kv td {
    display: block;
    border: 0;
    padding: 0;
    width: auto;
    overflow-wrap: break-word;
    word-break: normal;
  }
  table.erpal-resptable-kv td:first-child {
    font-size: .68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .02em;
    color: var(--erpal-muted, #6b7280);
  }
}

@media (max-width: 767px) {
  table.erpal-resptable td.erpal-td-empty { display: none; }
}


/* ── WHERE ANOTHER CARD DESIGN ALREADY WON ─────────────────────────────────
   The CRM listing tables (/leads and its siblings) have had erpal_tidy's own
   phone card since before this file existed: `.erpal-app .erpal-listing table
   tbody tr` is a flex-wrap row whose cells are ordered chips. That design is
   more specific than the generic card rules above and it wins, correctly — it
   is the design Troy pointed at when he asked for this.

   What it cannot know is which of its chips is a SENTENCE. Measured at 390:
   "Watt Construction Services" sat in a 157px chip beside two others, which is
   the same too-narrow-for-prose the gate condemns everywhere else. The stamper
   already marks any cell over the gate's prose threshold; give those chips the
   whole row and leave every short one exactly where the tidy design put it. */
@media (max-width: 767px) {
  .erpal-app .erpal-listing table tbody td.erpal-td-long {
    flex: 1 1 100%;
    width: 100%;
    min-width: 0;
  }
}
