use std::fmt::Write as _;
use rustyfi_backend::PageGeometry;
use super::Ctx;
pub(crate) fn stylesheet(geometry: &PageGeometry, ctx: &Ctx) -> String {
let max_width = geometry.text_width.0.max(1.0);
let body_size = ctx.body.size;
let body_family = ctx
.body
.font
.and_then(|f| ctx.font_family_for(f))
.unwrap_or_else(|| "Georgia, \"Noto Serif\", \"Noto Serif CJK JP\", serif".to_string());
format!(
"\
body {{\n\
margin: 0;\n\
padding: 2rem 1rem;\n\
font-family: {body_family};\n\
font-size: {body_size}pt;\n\
line-height: 1.7;\n\
background: #fff;\n\
color: #1a1a1a;\n\
}}\n\
.doc {{\n\
max-width: {max_width}pt;\n\
width: 100%;\n\
margin: 0 auto;\n\
box-sizing: border-box;\n\
}}\n\
.para {{\n\
margin: 0 0 0.9em 0;\n\
text-align: justify;\n\
hyphens: auto;\n\
overflow-wrap: break-word;\n\
}}\n\
.para[data-align=\"center\"] {{ text-align: center; }}\n\
.para[data-align=\"right\"] {{ text-align: right; }}\n\
.frame {{ margin: 0.6em 0; }}\n\
/* A frame that DREW something: the drawing is a sibling SVG stretched\n\
over the whole box, so the box has to be its containing block.\n\
No padding of its own: the frame's left padding is already folded into\n\
the contained lines' own offsets (`indent_left`) and its vertical ones\n\
arrive as `FramePad` skips, so adding CSS padding here would double all\n\
three. Only `padding-right`, which nothing else records, is written — per\n\
frame, from its real value. */\n\
.frame.framed {{ position: relative; }}\n\
/* Content sits ABOVE the drawing. `:not(.frame-deco)` is load-bearing:\n\
`.frame.framed > *` outranks `svg.frame-deco` on specificity, so without\n\
it the decoration is pulled into normal flow and every framed block\n\
renders as an empty box with its content underneath. */\n\
.frame.framed > *:not(.frame-deco) {{ position: relative; }}\n\
.frame.framed > svg.frame-deco {{\n\
position: absolute;\n\
left: 0;\n\
top: 0;\n\
width: 100%;\n\
height: 100%;\n\
overflow: visible;\n\
pointer-events: none;\n\
}}\n\
.embed {{ margin: 0.5em 0; }}\n\
.iframe {{ display: inline; }}\n\
.hskip {{ display: inline-block; }}\n\
.clearpage {{\n\
border: none;\n\
border-top: 1px dashed rgba(127,127,127,0.5);\n\
margin: 2em 0;\n\
}}\n\
.reflow-empty {{ font-style: italic; opacity: 0.7; }}\n\
.gfx-placeholder, .pdf-image {{\n\
display: inline-block;\n\
vertical-align: middle;\n\
border: 1px dashed rgba(127,127,127,0.5);\n\
border-radius: 3px;\n\
}}\n\
.img {{\n\
max-width: 100%;\n\
height: auto;\n\
vertical-align: middle;\n\
}}\n\
span.img {{\n\
display: inline-block;\n\
background-repeat: no-repeat;\n\
background-size: contain;\n\
background-position: center;\n\
}}\n\
a.link {{ color: #1a5fb4; text-decoration: underline; }}\n\
.heading {{\n\
margin: 1.4em 0 0.5em 0;\n\
font-weight: bold;\n\
line-height: 1.3;\n\
text-align: left;\n\
/* The heading's SIZE is the document's own, carried by the run inside\n\
it as an em ratio of the body. Without this the UA default for\n\
h1..h6 (2em, 1.5em, ...) multiplies that ratio and a 1.83em section\n\
title renders at 3.7em. */\n\
font-size: inherit;\n\
}}\n\
table.tabular {{\n\
border-collapse: collapse;\n\
margin: 1em auto;\n\
max-width: 100%;\n\
}}\n\
/* No border here: which grid lines a table draws is the DOCUMENT's, read\n\
off `TabularBox::rules` and written per cell (`structure.rs`'s `Borders`).\n\
A blanket rule turned every booktabs-style table into a full grid.\n\
No padding either — the cell's own margins arrive as real `hskip` struts\n\
inside it, so a CSS pad would be added on top of them. */\n\
table.tabular td {{\n\
padding: 0.15em 0;\n\
vertical-align: baseline;\n\
}}\n\
/* Fixed-pitch text: upstream's line breaks are the author's and survive as\n\
a hard break, so justification and hyphenation must not fight them. */\n\
.para.code {{\n\
text-align: left;\n\
hyphens: none;\n\
overflow-x: auto;\n\
}}\n\
ul.list, ol.list {{\n\
margin: 0 0 1em 0;\n\
padding: 0 0 0 1.5em;\n\
}}\n\
ul.list ul.list, ul.list ol.list, ol.list ul.list, ol.list ol.list {{\n\
margin: 0.2em 0;\n\
}}\n\
ul.list li, ol.list li {{ margin: 0.2em 0; }}\n\
/* The in-text footnote anchor is a zero-width link TARGET only — the\n\
document typesets its own reference marker. */\n\
.fnref {{ display: inline; }}\n\
aside.footnote {{\n\
margin: 0.6em 0 1.2em 0;\n\
padding: 0.2em 0 0.2em 1em;\n\
border-left: 3px solid rgba(127,127,127,0.35);\n\
font-size: 0.92em;\n\
}}\n\
aside.footnote .fnback {{\n\
margin-left: 0.4em;\n\
text-decoration: none;\n\
color: inherit;\n\
opacity: 0.55;\n\
}}\n\
aside.footnote .para {{ margin: 0; text-align: left; }}\n\
aside.footnote .para + .para {{ margin-top: 0.3em; }}\n\
"
)
}
pub(crate) fn shared_image_rules(ctx: &Ctx) -> String {
let mut out = String::new();
for id in ctx.shared_images.borrow().iter() {
if let Some(res) = ctx.images.get(*id) {
let _ = write!(
out,
".shared-img-{id} {{ background-image: url(\"{}\"); }}\n",
crate::image::data_uri(res),
);
}
}
out
}