- Add name_two_lines toggle (default: true) — uses CSS horizontal padding scaled by character count to coax short names (e.g. "Scott Idem") into a natural two-line wrap without a hard <br>; three tiers: ≤12 chars (18%), ≤20 (8%), ≤28 (2%), >28 no pad - Inner <div> (block element) used inside Element_fit_text for class: directives — Svelte scoped CSS requires static class names in the template; dynamic strings and class: on component elements both fail to match scoped CSS rules - Add leading-none to all four Element_fit_text fields (name, title, affiliations, location) — line-height must be set at the wrapper div level where fit_text measures scrollHeight, otherwise the binary-search scaler returns inflated sizes - name_two_lines state persisted to localStorage (ae_badge_print_tweaks key) alongside existing print_offset, hide_chrome, and banner_full_width tweaks - Rewrite badge_header_calibration.svg as a precise SVG ruler with labeled tick marks (major at 1in intervals, minor at 0.25in) for accurate physical print calibration - Gate debug outline CSS on html.debug_outlines class (set by controls panel) so outlines never appear in normal print mode Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
117 lines
4.6 KiB
CSS
117 lines
4.6 KiB
CSS
/*
|
|
* Badge Print Page — Print Media CSS
|
|
*
|
|
* Loaded via <link> in <svelte:head> on the badge print page only.
|
|
* Cannot be a component <style> block: Svelte 5 does not allow <style> inside
|
|
* <svelte:head>, and scoped component styles can't target html/body/global IDs.
|
|
*
|
|
* @page size is NOT here — it is injected dynamically via $effect in the page
|
|
* script because the size depends on the badge template layout field.
|
|
*/
|
|
|
|
@media print {
|
|
/* Full-page reset.
|
|
app.css sets overflow:hidden on html + body — override so they don't
|
|
create BFCs that shrink to content. */
|
|
html, body {
|
|
display: block !important;
|
|
width: 100% !important;
|
|
overflow: visible !important;
|
|
margin: 0 !important;
|
|
padding: 0 !important;
|
|
}
|
|
|
|
/* Hide all app chrome */
|
|
.submenu { display: none !important; }
|
|
|
|
/* #ae_main_content: make it a transparent, non-interfering passthrough block.
|
|
We cannot use display:contents here — it has overflow:auto, and per spec
|
|
display:contents cannot override overflow-clipping elements (Firefox
|
|
enforces this strictly). We just strip its visual/layout effects instead. */
|
|
#ae_main_content {
|
|
display: block !important;
|
|
position: static !important;
|
|
width: 100% !important;
|
|
max-width: none !important;
|
|
height: auto !important;
|
|
min-height: 0 !important;
|
|
overflow: visible !important;
|
|
background: transparent !important;
|
|
padding: 0 !important;
|
|
margin: 0 !important;
|
|
}
|
|
|
|
/* .main_content and #badge_render_area have no overflow constraints,
|
|
so display:contents safely dissolves their boxes in all browsers. */
|
|
.main_content,
|
|
#badge_render_area {
|
|
display: contents !important;
|
|
}
|
|
|
|
/* Center badge using position:fixed.
|
|
Why fixed instead of absolute/flex:
|
|
- position:fixed in print positions relative to the @page content area,
|
|
completely bypassing the ancestor hierarchy (no containing-block height
|
|
dependency, no overflow-clip interference, no flex-parent issues).
|
|
- top/left:50% + translate(-50%,-50%) centers within the page content area.
|
|
- Firefox applies physical printer hardware margins even with @page{margin:0};
|
|
this shrinks the content area slightly but top:50%/left:50% still centers
|
|
within whatever area the browser gives us — it's immune to asymmetric margins.
|
|
- Chrome: identical behavior to absolute+flex centering but more robust.
|
|
- min-height:0 overrides the Tailwind min-h-[6.0in] class on this wrapper;
|
|
badge_front/back provide their own dimensions. */
|
|
.event_badge_wrapper {
|
|
position: fixed !important;
|
|
top: 50% !important;
|
|
left: 50% !important;
|
|
transform: translate(-50%, -50%) !important;
|
|
min-height: 0 !important;
|
|
max-width: none !important;
|
|
margin: 0 !important;
|
|
padding: 0 !important;
|
|
gap: 0 !important;
|
|
}
|
|
|
|
/* Never split front/back across pages */
|
|
.badge_front,
|
|
.badge_back {
|
|
break-inside: avoid;
|
|
page-break-inside: avoid;
|
|
}
|
|
|
|
/* ============================================================
|
|
Debug outlines — toggled via "Show debug outlines" checkbox
|
|
in the Staff section of the print controls panel. Gated on
|
|
the html.debug_outlines class set by ae_comp__badge_print_controls.
|
|
These are intentionally permanent — not temporary.
|
|
============================================================ */
|
|
html.debug_outlines {
|
|
outline: 3px dashed lime !important;
|
|
outline-offset: -3px !important;
|
|
}
|
|
html.debug_outlines body {
|
|
outline: 4px solid blue !important;
|
|
outline-offset: -4px !important;
|
|
}
|
|
/* Red = #ae_main_content — block passthrough, should fill page width/height. */
|
|
html.debug_outlines #ae_main_content {
|
|
outline: 3px dashed red !important;
|
|
outline-offset: -6px !important;
|
|
}
|
|
/* Orange + purple = display:contents — should be INVISIBLE (no box). */
|
|
html.debug_outlines .main_content {
|
|
outline: 3px dashed orange !important;
|
|
outline-offset: -9px !important;
|
|
}
|
|
html.debug_outlines #badge_render_area {
|
|
outline: 3px dashed purple !important;
|
|
outline-offset: -12px !important;
|
|
}
|
|
/* Red = the actual badge — should be dead-center on page.
|
|
Thick + high-contrast so misalignment vs. physical card stock is obvious. */
|
|
html.debug_outlines .event_badge_wrapper {
|
|
outline: 6px solid red !important;
|
|
outline-offset: 3px !important;
|
|
}
|
|
}
|