UPG100 packet: Full detail page 1 rows follow the explanation
Page 1 of the Full detail list reserved a fixed block for its explanation and placed the rows below the reserve, so every language shorter than the tallest left a white gap above the head row (0.36 to 1.30 in). The explanation (at most the old reserve) and the rows now share one column: the head row sits right under the explanation and the spare room falls to the page's foot. The page still holds the same number of rows; the rows stay absolutely placed, only their origin moves.
This commit is contained in:
parent
0a4c9cc600
commit
446b0bfc8f
1 changed files with 20 additions and 7 deletions
|
|
@ -376,7 +376,11 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null, de
|
|||
.pray-head{position:absolute;inset-inline-end:${M}px;display:grid;grid-template-columns:repeat(${PRAY_COLS.length},${PRAY_CELL}px);
|
||||
height:${PRAY_HEAD_H - 6}px;align-items:end;font:700 15px/1.2 Georgia,serif;color:#6f6a5c;text-align:center}
|
||||
.pray-head span{text-wrap:balance;padding:0 0 5px;border-bottom:2px solid #3b463d}
|
||||
.fd-top{position:absolute;left:${M}px;top:${M + HEAD}px;width:${CW.toFixed(0)}px;height:${FD_TOP_H}px;overflow:hidden}
|
||||
/* Page 1 of the Full detail list: the explanation, then the head row and the rows right under it (listPages). */
|
||||
.fd-first{position:absolute;left:${M}px;top:${M + HEAD}px;width:${CW.toFixed(0)}px}
|
||||
.fd-top{max-height:${FD_TOP_H}px;overflow:hidden}
|
||||
.fd-rows{position:relative}
|
||||
.fd-rows .pray-head{inset-inline-end:0}
|
||||
.hd-r{position:absolute;right:${M}px;top:54px;font:400 19px Georgia,serif;color:#8c8170}
|
||||
/* ⚠ box-sizing:border-box IS LOAD-BEARING HERE, NOT HOUSEKEEPING. Without it the row's height
|
||||
is the CONTENT box and the padding + border are added OUTSIDE it, so the row renders taller
|
||||
|
|
@ -1191,7 +1195,14 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null, de
|
|||
PRAY_COLS.map((key) => `<span>${esc(t(key))}</span>`).join('')}</div>`;
|
||||
for (let start = 0, page = 0; start < groups.length; page += 1) {
|
||||
const per = page === 0 ? FD_FIRST : PER_PAGE;
|
||||
const rowsTop = page === 0 ? FD_ROWS_TOP : M + HEAD;
|
||||
// ★ PAGE 1'S ROWS FOLLOW THE EXPLANATION (2026-10-03). The explanation reserved a fixed FD_TOP_H and the
|
||||
// rows sat below the reserve, so every language shorter than the tallest left a gap above the head row
|
||||
// (0.36-1.30 in, measured in all 11). Now the explanation (at most FD_TOP_H) and the rows share one
|
||||
// column (.fd-first), and the rows are placed inside .fd-rows, right under it. The page still holds
|
||||
// FD_FIRST rows, sized for the full reserve, so a shorter explanation leaves the room at the page's foot.
|
||||
// The rows stay absolutely placed (see below), only their origin moves: no row can reflow to a page.
|
||||
const rowsTop = page === 0 ? PRAY_HEAD_H : M + HEAD;
|
||||
const left = page === 0 ? 0 : M;
|
||||
const slice = groups.slice(start, start + per);
|
||||
// ★ ONE FULL-WIDTH ROW PER GROUP. The column index is gone: `top` advances by the row, and the
|
||||
// three cells sit inside it. Absolute positioning is kept rather than switching to flow layout
|
||||
|
|
@ -1208,7 +1219,7 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null, de
|
|||
const img = src
|
||||
? `<img src="${esc(src)}" alt="">`
|
||||
: `<div class="nophoto">${esc(t('no_photo'))}</div>`;
|
||||
return `<div class="card" style="left:${M}px;top:${top.toFixed(0)}px;
|
||||
return `<div class="card" style="left:${left}px;top:${top.toFixed(0)}px;
|
||||
width:${CW.toFixed(0)}px;height:${CH.toFixed(0)}px">${img}
|
||||
<div class="d-cell">
|
||||
<div class="nm">${i + 1}. ${esc(g.name)}</div>
|
||||
|
|
@ -1217,15 +1228,17 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null, de
|
|||
<div class="pray-cols">${PRAY_COLS.map(() => '<span class="pray-col"><i class="pray-box"></i></span>').join('')}</div>
|
||||
</div>`;
|
||||
}).join('');
|
||||
const first = page === 0
|
||||
? `<div class="fd-top">${explainTop()}${explainBand(groups.length,
|
||||
const rowsH = PRAY_HEAD_H + slice.length * (CH + GUT) - GUT;
|
||||
const body = page === 0
|
||||
? `<div class="fd-first"><div class="fd-top">${explainTop()}${explainBand(groups.length,
|
||||
{ w: PRAY_COLS.length * PRAY_CELL, cols: `repeat(${PRAY_COLS.length},${PRAY_CELL}px)`, gap: 0, cell: 'xb-cell xb-cell-fd' })}</div>`
|
||||
: '';
|
||||
+ `<div class="fd-rows" style="height:${rowsH.toFixed(0)}px">${prayHead(0)}${cards}</div></div>`
|
||||
: `${prayHead(rowsTop - PRAY_HEAD_H)}${cards}`;
|
||||
pages.push(sheet(`
|
||||
<div class="hd">${esc(zone.label || zone.id)}</div>
|
||||
<div class="hd-r">${esc(fill(t('list_header'),
|
||||
{ from: num(start + 1), to: num(Math.min(start + per, groups.length)), count: num(groups.length) }))}</div>
|
||||
${first}${prayHead(rowsTop - PRAY_HEAD_H)}${cards}`));
|
||||
${body}`));
|
||||
start += per;
|
||||
}
|
||||
return pages;
|
||||
|
|
|
|||
Loading…
Reference in a new issue