/*
 * Béton template — a grey-block grid: a full-bleed concrete header (solid
 * #374151 identity cell beside a white portrait cell), a four-cell contact
 * band on light grey, then one body column whose every section label sits
 * under a thick concrete slab.
 * Shared by browser (edit) and mPDF (pdf). No flexbox, no CSS grid, no
 * transforms: floats / tables / block layout only, so the two renderers agree.
 *
 * WHICH BLOCKS ARE FILLS AND WHICH ARE BORDERS — the one rule in this file
 * that must not be "simplified" back into a background:
 *   - the header identity cell and the contact band are <td> BACKGROUNDS. They
 *     sit in plain page flow, inside no page-break-inside:avoid block, and a
 *     cell background paints one contiguous rect across the full cell in both
 *     renderers (a <div> background paints one small rect per rendered LINE,
 *     hugging that line's own text width);
 *   - every section label is inside a .cv-section-head-group, i.e. inside a
 *     page-break-inside:avoid block, and mPDF cannot paint a fill in one at
 *     all — confirmed by direct render twice in 2026-07: a <td> background is
 *     flushed onto the page the trial pass just left, leaving a ghost strip
 *     behind (soleil), and a <div> background is never painted at all, because
 *     PaintDivBB returns early while keep_block_together is set (terre,
 *     Mpdf.php:17162). Borders are drawn before that early return and go into
 *     the page's own content stream, so they paint on every page and are
 *     discarded with the page on a rewind. The label's slab is therefore
 *     .cv-sec-block's border-top and its tab .cv-sec-title's border-left.
 *
 * Palette: concrete #374151 (header block, labels, bullet squares, dots), the
 * light block #e5e7eb (contact band, slabs, tabs), ink #1f2937 (entry titles),
 * body #374151, secondary #4b5563, dates #6b7280, hairline #9ca3af. It is a
 * fixed design decision, not the user's settings.accentColor: the greys have
 * to stay legible when the page is photocopied in greyscale, which a
 * user-chosen accent could not guarantee. tpl_dots is therefore called with a
 * null accent and the dots inherit .cv-dot-on.
 *
 * multipage:true — no fixed heights anywhere, no bottom padding on the page
 * (real trailing space opens a blank final page), every entry block is
 * page-break-inside:avoid, and inter-block spacing is an unconditional
 * margin-TOP: a margin-bottom on a repeated avoid block double-counts in
 * mPDF's pagination estimate, and mPDF drops `+` sibling rules entirely, so
 * neither the sibling-combinator nor the first-child-override form works here.
 *
 * Font stacks lead with a DejaVu face: mPDF substitutes Arial/Helvetica with
 * DejaVu *Condensed* (no bold face), so bold weights would silently export as
 * regular otherwise. Every bold below is the KEYWORD `bold`, never a numeric
 * 600/700 (mPDF ignores numeric weights).
 */

/* ---- page margins (multi-page) ---------------------------------------- *
 * PdfService gives mPDF margin_* = 0, so a PDF's only vertical margin is
 * this wrapper's own padding — and a wrapper's padding-top lands on page 1
 * alone, leaving every later page hard against the sheet edge.
 *
 * @page restores an identical margin on every page; `@page :first` zeroes
 * the top one so page 1 keeps using the wrapper padding it always had and
 * its output is unchanged. Left/right stay 0 — the wrapper's horizontal
 * padding already applies to every page. Inert in the browser (@page is
 * print-only), and builder.js reads these same values back out of CSSOM
 * so its page-count model matches what mPDF actually does. */
@page {
    margin: 40px 0 40px 0;
}
@page :first {
    margin-top: 0;
}

.resume-page.resume-beton {
    width: 794px;                /* A4 @ 96dpi -> fills A4 width in mPDF */
    box-sizing: border-box;
    padding: 0;                  /* the header band is full-bleed; .cv-body carries the inset */
    background: #ffffff;
    color: #374151;
    font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif;
    font-size: 13.5px;
    line-height: 1.5;
}
/* mPDF does NOT inherit font-family/size into table cells — anything inside a
   <td> silently falls back to the serif document default. The header, the
   contact band, every entry row and the skills grid are tables here, so the
   font must be declared at td level too. No-op in the browser. Rules that
   override size/color inside a specific cell are ordered after this. */
.resume-beton td {
    font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif;
    font-size: 13.5px;
    line-height: 1.5;
    color: #374151;
}

/* ---- header: solid concrete identity cell | white portrait cell ----------
 * Full-bleed: the page has no side padding, so both cells run to the sheet
 * edge. The identity cell's padding-left matches .cv-body's inset, so the name
 * sits on the same left rule as every section below it. */
.resume-beton table.cv-head {
    width: 100%;
    border-collapse: collapse;
}
.resume-beton td.cv-head-id {
    background: #374151;
    padding: 22px 24px 22px 44px;
    vertical-align: middle;
}
/* UNPADDED: mPDF measures a td's CSS width from the padding box, the browser
   from the content box, so a padded fixed-width cell drifts between the
   renderers — the portrait's inset is the nested table's padding instead (and
   mPDF drops block margins inside a cell, so a nested table is the only
   reliable gap primitive there anyway). 140px, not the portrait's 95px plus
   its right margin: without the 22px on the left the portrait butts straight
   against the concrete block, which is invisible with a real photo but reads
   as one continuous slab when the initials fallback paints in a dark accent. */
.resume-beton td.cv-head-photo {
    width: 140px;
    padding: 0;
    background: #ffffff;
    vertical-align: middle;
}
.resume-beton table.cv-photo-box {
    border-collapse: collapse;
}
.resume-beton table.cv-photo-box td {
    padding: 20px 0 20px 22px;
}
/* No width/height here: tpl_photo emits both inline (and the pdf-mode initials
   fallback is a GD PNG, which keeps its geometry inside a cell). */
.resume-beton .cv-photo,
.resume-beton .cv-photo-initials {
    display: block;
}
/* Identity lines are ROWS of a nested table, not margin-stacked blocks: mPDF
   drops block margins inside a cell, so the vertical rhythm is td padding. */
.resume-beton table.cv-id {
    width: 100%;
    border-collapse: collapse;
}
.resume-beton table.cv-id td {
    padding: 0;
    background: #374151;
}
.resume-beton td.cv-id-title {
    padding-top: 7px;
}
.resume-beton .cv-name {
    font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif;
    font-size: 26px;
    font-weight: bold;
    color: #ffffff;
    letter-spacing: -0.2px;
    line-height: 1.15;
    margin: 0;
}
.resume-beton .cv-jobtitle {
    font-size: 12.5px;
    text-transform: uppercase;
    letter-spacing: 2.4px;
    color: #d1d5db;
}

/* ---- contact band: four fixed 25% cells on the light block ---------------
 * The fill is the cells' own background (see the note at the top of this
 * file). Filler cells carry a &nbsp; so the band's fill runs edge to edge even
 * when the last row is short. */
.resume-beton table.cv-cband {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
}
.resume-beton td.cv-cbox {
    width: 25%;
    background: #e5e7eb;
    padding: 9px 14px;
    vertical-align: top;
    font-size: 11.5px;
    line-height: 1.4;
    color: #374151;
}

/* ---- body ---------------------------------------------------------------
 * Side inset only: no bottom padding (real trailing space opens a blank final
 * page) and no top padding — the header band is meant to run into the sheet
 * edge, and the first slab's own margin-top opens the gap under it. */
.resume-beton .cv-body {
    padding: 0 44px 0;
}

/* ---- section labels: a concrete slab over a tabbed label ------------------
 * Borders, not fills — see the note at the top of this file. The slab is the
 * block's border-top (full body width, because the block is a block), the tab
 * is the label's own border-left. The inter-section gap is the slab's
 * unconditional margin-top; nothing here carries a margin-bottom. */
.resume-beton .cv-section {
    margin: 0;
}
.resume-beton .cv-sec-block {
    border-top: 13px solid #e5e7eb;
    margin-top: 24px;
    padding-top: 7px;
}
.resume-beton .cv-sec-title {
    font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif;
    font-size: 13px;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 1.6px;
    color: #374151;
    line-height: 1.3;
    border-left: 9px solid #e5e7eb;
    padding-left: 10px;
    margin: 0;
    page-break-after: avoid;
}
/* page-break-after:avoid on the label alone is not reliable in mPDF — this
   wrapper (label + first entry) is what actually holds the pair together. */
.resume-beton .cv-section-head-group {
    page-break-inside: avoid;
}
/* pdf mode: mPDF doesn't reliably honor :last-child, so the server marks
   whichever section/item renders last with this plain class instead. Unscoped
   on purpose — it applies to whichever element carries it. Belt-and-braces
   here, since spacing is margin-top only. */
.resume-beton .is-last {
    margin-bottom: 0;
}
/* Ragged-right, never justify (mPDF spacing artifacts). */
.resume-beton .cv-summary {
    margin-top: 10px;
    text-align: left;
    color: #374151;
}

/* ---- entries -------------------------------------------------------------
 * Two-column "title left / dates right" via table (mPDF-safe, no float — a
 * float inside a page-break-inside:avoid block makes mPDF miscalculate the
 * block height and duplicate content). Spacing is an UNCONDITIONAL margin-top
 * on every entry, with no first-item override of any kind. */
.resume-beton .cv-item {
    position: relative;
    page-break-inside: avoid;
    margin-top: 12px;
}
.resume-beton .cv-row {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
}
.resume-beton td.cv-row-main {
    padding: 0;
    vertical-align: top;
    text-align: left;
}
/* No white-space:nowrap: a spelled-out French range ("septembre 2021 – juin
   2024") is wider than this column, and one nowrap cell shrinks the WHOLE
   layout table in mPDF (graphite, 2026-07). It wraps to a second
   right-aligned line instead. */
.resume-beton td.cv-row-side {
    width: 150px;
    padding: 0 0 0 14px;
    vertical-align: top;
    text-align: right;
}
.resume-beton .cv-item-title {
    font-weight: bold;
    color: #1f2937;
}
.resume-beton .cv-item-org {
    color: #374151;
}
.resume-beton .cv-item-sep {
    color: #9ca3af;
}
/* edit mode only: a separator that must read as glued to the preceding
   editable text (the education comma) can't be nested inside it — anything
   inside an editable becomes stored user data — so it sits on its own source
   line and pulls back over that newline's rendered space. The pdf branch emits
   the same comma with no whitespace at all and never uses this class. */
.resume-beton .cv-sep-tight {
    margin-left: -4px;
}
.resume-beton .cv-item-field {
    color: #4b5563;
}
.resume-beton .cv-dates {
    font-size: 11.5px;
    letter-spacing: 0.3px;
    color: #6b7280;
}
.resume-beton .cv-item-loc {
    font-size: 11px;
    color: #9ca3af;
}
.resume-beton .cv-item-details {
    margin-top: 3px;
    font-size: 12.5px;
    color: #4b5563;
}

/* Bullets: native <ul>/<li> with a real ▪ marker span and a hanging indent
   (padding-left + negative text-indent). Native list items let mPDF estimate
   the enclosing avoid block's height accurately, and the marker is real HTML
   text — a CSS content: marker renders nothing at all in mPDF. */
.resume-beton .cv-bullets {
    margin: 7px 0 0;
    padding-left: 0;
    list-style: none;
}
.resume-beton .cv-bullets li {
    position: relative;
    padding-left: 16px;
    text-indent: -16px;
    margin-bottom: 3px;
    font-size: 13px;
    color: #374151;
}
.resume-beton .cv-bk {
    color: #374151;
    font-size: 11px;
    margin-right: 6px;
}

/* ---- skills grid: ONE two-column table ----------------------------------
 * Never a float grid (repeated same-direction floats stack instead of packing
 * into rows in mPDF) and never one small table per line (many small tables
 * inflate mPDF's pagination height enough to cost a page). The pdf branch
 * splits it in two — first row inside the avoid head group, the rest free to
 * break between rows — so the continuation must not repeat the top margin. */
.resume-beton .cv-grid {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
    margin-top: 9px;
}
.resume-beton .cv-grid.cv-grid--cont {
    margin-top: 0;
}
.resume-beton td.cv-grid-cell {
    width: 50%;
    padding: 2px 18px 2px 0;
    vertical-align: top;
    font-size: 13px;
}

/* ---- "name — level" lines (languages, and the skills list in edit mode) --- */
.resume-beton .cv-kv-list {
    margin-top: 9px;
}
.resume-beton .cv-kv-list.cv-kv-list--cont {
    margin-top: 0;
}
.resume-beton .cv-kv {
    position: relative;
    margin-bottom: 3px;
    font-size: 13px;
}
.resume-beton .cv-kv-key {
    font-weight: bold;
    color: #1f2937;
}
.resume-beton .cv-kv-sep {
    color: #9ca3af;
}
.resume-beton .cv-kv-val {
    color: #4b5563;
}
/* The level slot holds EITHER dot glyphs or free text (tpl_dots passes text
   through untouched), so the tracking that spaces the dots apart lives on the
   dots themselves — otherwise a written level like "C1 — professionnel"
   exports as letterspaced small type. */
.resume-beton .cv-level {
    font-size: 13px;
    color: #4b5563;
}
.resume-beton .cv-dot {
    font-size: 10px;
    letter-spacing: 1px;
}
.resume-beton .cv-dot-on {
    color: #374151;
}
.resume-beton .cv-dot-off {
    color: #d1d5db;
}

/* =====================================================================
 * Edit-mode affordances (browser only — these elements are never
 * emitted in pdf mode, so none of this reaches mPDF).
 * Every [contenteditable]/[data-ph] rule stays at ONE level below the page
 * class: mPDF can't parse those chunks and applies the declaration to a
 * two-or-more-level prefix instead, repainting whatever pdf-mode element that
 * prefix names (confirmed on graphite, 2026-07).
 * ===================================================================== */

.resume-beton [contenteditable][data-ph]:empty:before {
    content: attr(data-ph);
    color: #b8bfc9;
    font-style: italic;
    pointer-events: none;
}
.resume-beton [contenteditable] {
    outline: none;
    transition: box-shadow 0.12s ease, background 0.12s ease;
}
.resume-beton [contenteditable]:hover {
    box-shadow: 0 0 0 1px #cbd5e1;
}
.resume-beton [contenteditable]:focus {
    box-shadow: 0 0 0 2px #374151;
    background: #f3f4f6;
}
/* The name/title sit on the dark block, so their empty-state placeholder and
   focus tint have to read against #374151 rather than white. */
.resume-beton .cv-name[data-ph]:empty:before,
.resume-beton .cv-jobtitle[data-ph]:empty:before {
    color: #9ca3af;
}
.resume-beton .cv-name:focus,
.resume-beton .cv-jobtitle:focus {
    background: #4b5563;
}
/* Edit-mode contact fields carry their own class rather than being selected
   through [contenteditable] (see the note above); each occupies its own band
   cell, so an empty slot simply stays blank — the pdf branch drops empty
   fields before chunking the rest four to a row. */
.resume-beton .cv-contact-f {
    display: inline-block;
    min-width: 40px;
}

.resume-beton .edit-controls {
    position: absolute;
    top: -2px;
    right: -44px;
    opacity: 0;
    transition: opacity 0.12s ease;
    white-space: nowrap;
    z-index: 5;
}
.resume-beton .edit-controls--inline {
    position: absolute;
    left: -26px;
    right: auto;
    top: 0;
}
.resume-beton .cv-item:hover > .edit-controls,
.resume-beton .cv-kv:hover > .edit-controls,
.resume-beton .cv-bullets li:hover > .edit-controls,
.resume-beton .edit-controls:hover {
    opacity: 1;
}
.resume-beton .edit-controls button {
    font-family: inherit;
    font-size: 13px;
    line-height: 1;
    width: 20px;
    height: 20px;
    margin-left: 2px;
    padding: 0;
    border: 1px solid #d1d5db;
    background: #ffffff;
    color: #4b5563;
    cursor: pointer;
}
.resume-beton .edit-controls button:hover {
    background: #374151;
    border-color: #374151;
    color: #ffffff;
}

.resume-beton .cv-add {
    font-family: inherit;
    font-size: 12.5px;
    margin-top: 9px;
    padding: 4px 10px;
    border: 1px dashed #d1d5db;
    background: #ffffff;
    color: #374151;
    cursor: pointer;
}
.resume-beton .cv-add:hover {
    background: #f3f4f6;
    border-color: #374151;
}
.resume-beton .cv-add--sm {
    font-size: 11.5px;
    padding: 2px 8px;
}

.resume-beton .cv-current {
    display: block;
    font-family: inherit;
    font-size: 11px;
    font-weight: normal;
    color: #9ca3af;
    margin-top: 2px;
    cursor: pointer;
}
.resume-beton .cv-current input {
    vertical-align: middle;
}

.resume-beton .cv-dot-btn,
.resume-beton .cv-level-toggle {
    font-family: inherit;
    border: none;
    background: none;
    padding: 0 1px;
    cursor: pointer;
    font-size: 10px;
}
.resume-beton .cv-dot-btn.cv-dot-on {
    color: #374151;
}
.resume-beton .cv-dot-btn.cv-dot-off {
    color: #d1d5db;
}
.resume-beton .cv-level-toggle {
    font-size: 9px;
    color: #9ca3af;
    margin-left: 4px;
    opacity: 0;
    transition: opacity 0.12s ease;
}
.resume-beton .cv-kv:hover .cv-level-toggle {
    opacity: 1;
}
