/*
Reservation invoice / confirmation document.

Scoped entirely under `.invoice-doc` so it can load beside the public stylesheet on the wizard
review step without either fighting the other. The markup deliberately uses none of
Bootstrap/CoreUI's class names (`table.light`, not `.table`), so their rules have nothing to
grab even where both are present.

Ported from the approved CCSUP-131 mockup. The print values are empirically tuned: 8.5pt body
on 0.3in/0.25in letter margins is what makes a minimal reservation fit one page while the
logo box still reserves its height. See ai/plans/invoice/cap-1124-rendering-rules.md.

WeasyPrint constraints that shape this file, verified the hard way:
  - flexbox is fine, CSS grid is not
  - flex `gap` is silently ignored — margins between flex children instead
  - tables must not be direct children of inset sections; wrap them in a plain div
  - print-media overrides use longhand properties only, never shorthands
*/

/* Noto Sans, served from our own static files.

   The standalone invoice page and the emailed PDF are the same document, and an employee who
   opens one to check it before it goes out should be reading what the recipient will read.
   Without a webfont they were not: a Windows browser resolved Segoe UI while the render
   container had neither Segoe UI nor Noto and fell through to DejaVu Sans.

   Deliberately NOT applied to the wizard review step, which keeps the app's own stack — it is
   a booking screen that happens to show this document, not the document itself. The
   `.invoice-page` body class is what separates the two; only the standalone shell carries it.

   Paths are relative to this stylesheet, so they resolve the same whether the browser fetches
   it over HTTP or WeasyPrint loads it from disk. Bold-italic is not shipped because nothing in
   the document sets both; a browser would synthesise it if that ever changed. */
@font-face {
  font-family: "Noto Sans";
  src: url("../fonts/noto-sans/NotoSans-Regular.3752fe705980.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Noto Sans";
  src: url("../fonts/noto-sans/NotoSans-Bold.2f56f12fd943.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Noto Sans";
  src: url("../fonts/noto-sans/NotoSans-Italic.e694730ef8d3.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

  /* One palette for screen and paper. The document people actually receive is the PDF that
     gets emailed to them; the on-screen version is an employee view of the same thing. So the
     values are pitched for print — a printer loses the pale end of a screen palette to toner
     thresholds and greyscale conversion — and the screen carries them rather than keeping a
     lighter set of its own that nobody outside the office sees. */
  :root {
    --ink: #000; --label: #333; --muted: #5f5f5f; --rule: #888; --rule-light: #ccc;
    --chapter-bar: #ebecef;
  }
  /* the root is included deliberately: its max-width is the page measure, so the
     padding has to sit inside it rather than widen it */
  .invoice-doc,
  .invoice-doc * { box-sizing: border-box; }
  /* ---------- header ---------- */
  /* NO flex gap anywhere — WeasyPrint 64 ignores it; use margins between flex children */
  /* logo box reserves height for a stacked (tall) mark; image scales inside it by height */
  .invoice-doc .doc-logo { text-align: center; margin-bottom: 12px; min-height: 100px; display: flex; align-items: center; justify-content: center; }
    /* Wide enough that a horizontal lockup reaches the reserved height instead of floating in
     it; a stacked mark is still limited by height first and never gets this wide. */
  .invoice-doc .logo-stacked { max-height: 100px; max-width: 600px; width: auto; height: auto; }
  .invoice-doc .doc-header { display: flex; align-items: flex-start; }
  .invoice-doc .title-block { flex: 1 1 auto; }
  .invoice-doc .title-block .doc-type { font-size: 11px; text-transform: uppercase; letter-spacing: .14em; color: var(--muted); }
  .invoice-doc .title-block h1 { margin: 1px 0 2px; font-size: 20px; }
  .invoice-doc .title-block .event-dates { font-style: italic; }
  .invoice-doc .doc-meta { flex: 0 0 auto; text-align: right; margin-left: 18px; }
  .invoice-doc .doc-meta .status { display: inline-block; border: 1px solid var(--ink); padding: 1px 8px; font-size: 11px; text-transform: uppercase; letter-spacing: .08em; }
  .invoice-doc .doc-meta .doc-date { margin-top: 4px; font-size: 12px; }
  .invoice-doc .doc-meta .doc-date .lbl { color: var(--muted); }
  /* ---------- sections: gray title bars; hairline rules only at chapter starts ---------- */
  .invoice-doc .section { margin-top: 16px; break-inside: avoid-page; }
  /* chapter titles: the level above section bars — no background, wider tracking */
  .invoice-doc .chapter-title { font-size: 15px; font-weight: bold; text-align: center; text-transform: uppercase; letter-spacing: .18em; margin: 22px 0 10px; padding: 4px 0; background: var(--chapter-bar); print-color-adjust: exact; -webkit-print-color-adjust: exact; break-after: avoid-page; page-break-after: avoid; }
  .invoice-doc .chapter-title + .section { margin-top: 4px; }
  /* longhand margins only — a shorthand here would clobber the .inset side margins */
  .invoice-doc .section > h2.chapter-title { padding: 4px 0; margin-top: 0; margin-bottom: 10px; font-size: 15px; letter-spacing: .18em; }
  /* chapter separator: short centered double rule closing the PREVIOUS chapter, so at a page break the close-out mark stays on the prior page */
  .invoice-doc .section.rule { margin-top: 22px; }
  .invoice-doc .chapter-end::after { content: ""; display: block; width: 60%; min-width: 180px; margin: 20px auto 0; border-top: 4px double var(--label); }
  /* A closing rule with no chapter after it separates nothing — it just trails off the end of
     the document. The full invoice never hit this because Agreements closes it and carries no
     rule of its own; the wizard review step, which drops both Transactions and Agreements, ends
     on the Payment Schedule and did. */
  .invoice-doc .chapter-end:last-child::after { content: none; }
  /* The mirror case: the rule above the Payment Schedule is normally the Transactions chapter
     closing. With the ledger hidden there is no chapter above to close, so the schedule draws
     its own opening rule and keeps its place in the sequence. */
  .invoice-doc .chapter-start::before { content: ""; display: block; width: 60%; min-width: 180px; margin: 0 auto 20px; border-top: 4px double var(--label); }
  .invoice-doc .section > h2 { font-size: 12.5px; font-weight: bold; text-align: center; margin: 0 0 8px; padding: 1px 0; text-transform: uppercase; letter-spacing: .12em; }
  .invoice-doc .section > h2:not(.chapter-title) { color: var(--muted); }
  /* short centered underline lifts section titles off the data */
  .invoice-doc .section > h2:not(.chapter-title)::after { content: ""; display: block; width: 30%; min-width: 120px; margin: 2px auto 0; border-bottom: 1.5px solid var(--muted); }
  /* ---------- two-up blocks (flex; no CSS grid for WeasyPrint 64 safety) ---------- */
  .invoice-doc .two-up { display: flex; margin-top: 14px; }
  /* An even split, as the mockup has it. Both sides can carry a long unbreakable value — an
     email address on one, a group name on the other — and letting the columns size themselves
     made the block lopsided from one reservation to the next for little gain. min-width: 0 so
     a long value can shrink its column and wrap rather than push the row wider. */
  .invoice-doc .two-up > div { flex: 1 1 50%; min-width: 0; }
  .invoice-doc .two-up > div + div { margin-left: 32px; }
  .invoice-doc .block-head { font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--muted); border-bottom: 1px solid var(--rule); margin-bottom: 4px; padding-bottom: 2px; }
  .invoice-doc .kv { display: flex; margin: 0; padding: 1.5px 0; }
  .invoice-doc .kv dt { flex: 0 0 100px; font-weight: bold; color: var(--label); }
  .invoice-doc .kv dd { margin: 0; flex: 1 1 auto;
    /* An email address is one unbreakable word. break-word rather than anywhere, paired with
       min-width: 0 so the flex item is allowed to shrink: anywhere also drops the intrinsic
       minimum to a single character, which let the column collapse and split addresses
       mid-word on a wide screen that had room for them. This breaks only when it must. */
    min-width: 0;
    overflow-wrap: break-word; }
  .invoice-doc .kv dd.amt { text-align: right; font-variant-numeric: tabular-nums; }
  /* ---------- line items ---------- */
  .invoice-doc .li { display: flex; justify-content: space-between; padding: 2px 0; }
  .invoice-doc .li .desc { flex: 1 1 auto; }
  .invoice-doc .li .amt { flex: 0 0 100px; margin-left: 12px; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .invoice-doc .li.head { border-bottom: 1px solid var(--rule); font-weight: bold; color: var(--label); }
  .invoice-doc .li.total { border-top: 1px solid var(--ink); font-weight: bold; }
  /* The closing sum of the ledger, not another entry in it. One hairline is enough: the last
     transaction row already draws its own bottom border, so the two read as the double rule
     that marks a total elsewhere in the document — without a third weight of bold in a section
     that already has two. */
  .invoice-doc .li.subtotal {
    margin-top: 4px;
    border-top: 1px solid var(--rule-light);
  }
  /* Italic is a departure from the mockup, on purpose: a discount or deposit line and a
     category heading were both small and muted, so at a glance they read as the same kind of
     thing. Only these lines take it — plan names, revision numbers and the schedule's
     paid/remaining detail keep the plain muted style. */
  .invoice-doc .li .sub { display: block; font-size: 11.5px; color: var(--muted); font-style: italic; }
  /* One fixed indent, for the two places that nest exactly one level. Deeper hierarchies
     compute their own padding from node.depth, so there is no lvl2/3/4 to match them. */
  .invoice-doc .lvl1 { padding-left: 16px; }
  /* Names the person a run of lines belongs to, the way a room head names a room. */
  .invoice-doc .owner-line { font-weight: bold; padding-top: 4px; }
  /* The accommodation item names the charges listed under it, which is what a group line does
     further down the tree — same treatment, weighted because this one heads the whole room. */
  .invoice-doc .group-line.room-item { font-weight: bold; color: var(--label); }
  .invoice-doc .group-line { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; padding-top: 3px; }
  /* A standing note about a section, tucked up under its heading. */
  .invoice-doc .section-note { font-size: 11.5px; color: var(--muted); font-style: italic; margin: -4px 0 6px; text-align: center; }
  /* "There is nothing here" is a different thing, and it does not follow a heading — it
     follows the line the section opens with, whose border it was riding over on the note's
     negative top margin. */
  .invoice-doc .empty-note { font-size: 11.5px; color: var(--muted); font-style: italic; margin: 8px 0 6px; text-align: center; }
  .invoice-doc .room { margin: 8px 0 10px; break-inside: avoid-page; }
  .invoice-doc .room-head { display: flex; justify-content: space-between; border-bottom: 1px solid var(--rule); padding-bottom: 2px; margin-bottom: 3px; }
  .invoice-doc .room-head .name { font-weight: bold; }
  .invoice-doc .room-head .occ { color: var(--muted); font-style: italic; margin-left: 12px; }
  /* The separator is drawn between the pieces rather than typed into the markup, so stacking
     them on a narrow screen is a matter of dropping it rather than editing the template. */
  .invoice-doc .room-head .occ-part + .occ-part::before { content: "\00b7"; margin: 0 6px; }
  /* participant card: name + info line, then a labeled amounts strip */
  .invoice-doc .p-card { margin: 8px 0 12px; break-inside: avoid-page; }
  .invoice-doc .p-card .p-head { display: flex; justify-content: space-between; align-items: baseline; border-bottom: 1px solid var(--rule); padding-bottom: 2px; margin-bottom: 4px; }
  .invoice-doc .p-card .p-head .p-name { font-weight: bold; }
  .invoice-doc .p-card .p-head .p-info { font-size: 11.5px; color: var(--muted); text-align: right; margin-left: 12px; }
  /* Date of birth identifies the person, so it sits with the name rather than in the strip of
     booking detail on the other side, where it read as one more attribute of the stay. */
  .invoice-doc .p-card .p-head .p-dob { margin-left: 8px; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
  /* The same middle dot that separates the attributes on the line below, so the name and the
     date of birth read as two things rather than one run of text. */
  .invoice-doc .p-card .p-head .p-dob::before { content: "\00b7"; margin-right: 8px; }
  .invoice-doc .p-amounts { display: flex; justify-content: space-between; }
  .invoice-doc .p-amt { text-align: right; }
  .invoice-doc .p-amt + .p-amt { margin-left: 14px; }
  .invoice-doc .p-amt .lbl { display: block; font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }
  .invoice-doc .p-amt .val { font-variant-numeric: tabular-nums; white-space: nowrap; }
  .invoice-doc .p-amt.strong .val { font-weight: bold; }
  /* ---------- light table ---------- */
  .invoice-doc table.light { width: 100%; border-collapse: collapse; }
  /* bottom-aligned so a header that wraps to two lines keeps its baseline with the rest */
  .invoice-doc table.light th { text-align: left; vertical-align: bottom; color: var(--label); font-size: 11.5px; border-bottom: 1px solid var(--rule); padding: 2px 6px 2px 0; }
  .invoice-doc table.light td { padding: 2.5px 6px 2.5px 0; border-bottom: 1px solid var(--rule-light); vertical-align: top; }
  /* padding-right separates a right-aligned amount from whatever column follows it, which
     would otherwise sit right against the digits. The :last-child rule below is later at equal
     specificity, so an amount that IS the last column still goes flush to the edge. */
  .invoice-doc table.light td.num,
  .invoice-doc table.light th.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; padding-right: 10px; }
  /* The last column carries the money, and the Transactions table sits between the
     Total Amount and Balance Due lines, which are flex rows with no such padding. Cell
     padding-right would leave the column short of the edge those two lines set — the one
     misalignment this section exists to make visible. Higher specificity than the print
     block's padding shorthand, so it holds there too. */
  .invoice-doc table.light th:last-child,
  .invoice-doc table.light td:last-child { padding-right: 0; }
  .invoice-doc table.light td .sub { display: block; font-size: 11px; color: var(--muted); }
  .invoice-doc table.light th .sub { display: block; font-size: 10.5px; font-weight: normal; color: var(--muted); }
  .invoice-doc table.light tr.has-note td { border-bottom: none; }
  .invoice-doc table.light tr.note-row td { padding-top: 0; font-size: 11.5px; color: var(--muted); font-style: italic; }
  .invoice-doc table.light tr.note-row td b { font-style: normal; color: var(--label); }
  /* An amount that never collected. Struck rather than hidden or greyed: the figure is what the
     customer was told at the time and still belongs on the page, but it is not in the total
     below it, and a muted figure would read as a quiet one rather than a cancelled one. */
  .invoice-doc table.light td.uncollected { text-decoration: line-through; color: var(--muted); }
  /* non-ledger sections pull in from the edges, title bar included; the right margin stays reserved for summable amounts */
  .invoice-doc .section.inset > * { margin-left: 36px; margin-right: 36px; }
  /* tables must never be direct children of an inset section (margins/width on table elements are unreliable in WeasyPrint) — wrap them in a plain div instead */
  .invoice-doc .sched-groups { display: flex; flex-wrap: wrap; }
  .invoice-doc .sched-group { flex: 1 1 260px; margin: 8px 36px 12px 0; break-inside: avoid-page; }
  .invoice-doc .sched-group .who { font-weight: bold; margin-bottom: 2px; }
  .invoice-doc .sched-group .who .sub { font-weight: normal; font-size: 11.5px; color: var(--muted); }
  /* Drawn rather than typed, so it can go when the plan name drops onto its own line and a
     leading dash would just be hanging there. */
  .invoice-doc .sched-group .who .sub::before { content: "\2014\00a0"; }
  /* spec notes: screen-only, never part of the document */

.invoice-doc {
    /* The document is its own layout context: the small layout is chosen by how wide this box
       actually is, not by how wide the window is. On the wizard review step the left nav and the
       card padding take most of the viewport, so the document is squeezed long before the window
       looks narrow; on the standalone page the same box has the full width to itself. Keying off
       the container gets both right from one set of rules.

       WeasyPrint does not implement @container, so the print layout never stacks — which is the
       intended answer there anyway, since paper has the width. */
    container-type: inline-size;
    container-name: invoice;
    /* No font-family here on purpose. On the wizard review step this document is rendered
       inside the booking flow and inherits the app's own stack; the standalone page and the
       PDF get Noto Sans from the .invoice-page rule below. */
    color: var(--ink);
    font-size: 13px;
    line-height: 1.45;
    background: #fff;
    /* No sheet geometry here either — no max-width, no margin, no padding. Those describe a
       standalone sheet, and on the wizard review step this document is one panel inside the
       booking flow's own card, which supplies its own. They live on .invoice-page below. */
  }

  /* Inside the booking flow the document borrows that flow's own surface tokens, so its bars,
     card heads and borders are the same greys as the chrome around them and cannot drift from
     it later. Both are CoreUI's, inherited from :root where the bundle defines them; the
     fallbacks are the values they resolve to today, for the case where this stylesheet loads
     without the bundle.

     Scoped to the wizard on purpose. These are light screen greys — on paper they are close to
     invisible, and the document palette was deliberately raised off the light greys because
     they were too faint when printed. The standalone page and the PDF keep their own. */
  body:not(.invoice-page) .invoice-doc {
    --chapter-bar: var(--cui-tertiary-bg, #f3f4f7);
    --card-edge: var(--cui-border-color, #dbdfe6);
  }

  /* Sheet geometry, for the standalone document only — the invoice page and the printable
     template, which are the two things that carry .invoice-page on the body. The wizard review
     step has none of this: it is one panel inside the booking flow's card, which supplies its
     own measure and padding, and a sheet inside a card is two sets of margins.

     Declared here rather than beside the font rule further down so that the mobile and print
     blocks, which both override it, still come later in the file. At equal specificity source
     order decides, and stating it late silently beat both. */
  .invoice-page .invoice-doc {
    /* The sheet sets its own measure: a full-width invoice is unreadable, and nothing else
       constrains it on a standalone page. In print @page owns the width instead, so these are
       unset again in the print block. */
    max-width: 8.5in;
    margin: 16px auto;
    /* Matched to what print actually produces: @page contributes 0.3in/0.25in and the print
       block adds .2in at the sides, so the printed sheet carries roughly .3in top and bottom
       and .45in left and right. The screen sheet has no page box, so its padding is the whole
       margin and has to state those figures itself. */
    padding: .3in .45in;
    /* The gap above and below the sheet on its grey backdrop. Declared here rather than beside
       the backdrop further down so the narrow-screen block, which resets it to zero, still comes
       after it — at equal specificity source order decides, and stating it late meant a phone
       kept the desktop gutters while a rule two hundred lines earlier said otherwise. */
    margin-top: 24px;
    margin-bottom: 24px;
  }


@page { size: letter; margin: 0.3in 0.25in; }

@media print {
    /* compact typography: the app print block's 10pt scale, applied to this design */
    .invoice-doc .title-block h1 { font-size: 14pt; }
    .invoice-doc .title-block .doc-type { font-size: 8pt; }
    .invoice-doc .doc-meta .status { font-size: 8pt; }
    .invoice-doc .doc-meta .doc-date { font-size: 9pt; }
    .invoice-doc .doc-logo { min-height: 100px; margin-bottom: 12px; }
    .invoice-doc .logo-stacked { max-height: 100px; max-width: 520px; }
    .invoice-doc .two-up { margin-top: 5pt; }
    .invoice-doc .two-up > div + div { margin-left: 24px; }
    .invoice-doc .block-head { font-size: 8pt; margin-bottom: 2pt; }
    .invoice-doc .kv { padding: 0.25pt 0; }
    .invoice-doc .kv dt { flex-basis: 100px; }
    .invoice-doc .section { margin-top: 8.5pt; }
    .invoice-doc .chapter-title { font-size: 10pt; margin: 11pt 0 5pt; padding: 2pt 0; }
    .invoice-doc .section > h2.chapter-title { margin-top: 0; margin-bottom: 6pt; padding: 2pt 0; }
    .invoice-doc .chapter-title + .section { margin-top: 2pt; }
    .invoice-doc .section.rule { margin-top: 12pt; }
    .invoice-doc .chapter-end::after { margin-top: 7pt; }
    .invoice-doc .chapter-start::before { margin-bottom: 7pt; }
    .invoice-doc .section > h2:not(.chapter-title)::after { margin-top: 1pt; border-bottom-width: 1pt; }
    .invoice-doc .section > h2 { font-size: 8pt; margin-bottom: 4pt; padding: 1pt 0; }
    .invoice-doc .section-note { font-size: 8.5pt; margin: -2pt 0 4pt; }
    .invoice-doc .empty-note { font-size: 8.5pt; margin-top: 5pt; margin-bottom: 3pt; }
    /* vertical-only: a shorthand here would zero the .lvlN left indents */
    .invoice-doc .li { padding-top: 0.75pt; padding-bottom: 0.75pt; }
    .invoice-doc .li .sub { font-size: 7.5pt; }
    /* Names the person a run of lines belongs to, the way a room head names a room. */
  .invoice-doc .owner-line { font-weight: bold; padding-top: 4px; }
  /* The accommodation item names the charges listed under it, which is what a group line does
     further down the tree — same treatment, weighted because this one heads the whole room. */
  .invoice-doc .group-line.room-item { font-weight: bold; color: var(--label); }
  .invoice-doc .group-line { font-size: 8pt; padding-top: 1.5pt; }
    .invoice-doc .room { margin: 4pt 0 7pt; }
    .invoice-doc .p-card { margin: 3pt 0 6pt; }
    .invoice-doc .p-card .p-head { padding-bottom: 1pt; margin-bottom: 2.5pt; }
    .invoice-doc .p-card .p-head .p-info { font-size: 8pt; }
    .invoice-doc .p-amt .lbl { font-size: 7.5pt; }
    .invoice-doc table.light th { font-size: 8pt; padding-top: 1pt; padding-right: 4pt;
                                  padding-bottom: 1pt; padding-left: 0; }
    .invoice-doc table.light td { padding-top: 1.25pt; padding-right: 4pt;
                                  padding-bottom: 1.25pt; padding-left: 0; }
    .invoice-doc table.light td .sub,
  .invoice-doc table.light th .sub { font-size: 7.5pt; }
    /* longhand only — a shorthand here wipes the margin-right separating side-by-side groups */
    .invoice-doc .sched-group { margin-top: 3pt; margin-bottom: 4pt; }
    .invoice-doc .sched-group .who { margin-bottom: 1pt; }
    .invoice-doc .sched-group .who .sub { font-size: 8pt; }
}

/* The sheet's own margins, which only the standalone page has. An element cannot be restyled by
   a query on itself, so this one stays keyed to the viewport — it describes the page around the
   document rather than the document's layout. */
@media screen and (max-width: 640px) {
  .invoice-page .invoice-doc {
    margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0;
    padding-top: 16px; padding-right: 14px; padding-bottom: 16px; padding-left: 14px;
  }
}

/* Stacked layout, chosen by the document's own width. 640px is where the two-up and the tables
   stop having room for their columns; the wizard reaches it while the window is still wide,
   because the nav has taken the difference. */
@container invoice (max-width: 640px) {
    .invoice-doc .doc-header { flex-wrap: wrap; }
    .invoice-doc .doc-meta { text-align: left; }
    .invoice-doc .doc-logo { min-height: 0; margin-bottom: 12px; }
    /* max-width: 100% as well, or the raised desktop cap lets a wide lockup run past the
       edge of a narrow phone. */
    .invoice-doc .logo-stacked { max-height: 100px; max-width: 100%; }
    .invoice-doc .two-up { flex-direction: column; }
    .invoice-doc .two-up > div + div { margin-left: 0; margin-top: 12px; }
    .invoice-doc .section.inset > * { margin-left: 0; margin-right: 0; }
    /* A phone cannot carry the document's layout, so each participant becomes a bordered unit
       instead: the reader needs to see where one person's figures end and the next begin, which
       on the full-width version is done by the ruled name line and the space around it.
       The money edge is relaxed here too — every figure is right-aligned within its own cell
       rather than to one shared edge, because there is not enough width for both. */
    /* A participant and a room are each one thing the reader has to take in at once, and on a
       phone the ruled heading and surrounding space that do that at full width are not enough.
       Both become bordered cards with a tinted head naming what they are.
       0.375rem is CoreUI's own --cui-border-radius, copied rather than referenced since the
       bundle is not loaded here. overflow: hidden so the head's fill follows the corner. */
    .invoice-doc .p-card,
    .invoice-doc .room,
    .invoice-doc .owner-block {
      border: 1px solid var(--rule-light); border-radius: 0.375rem;
      overflow: hidden; margin: 0 0 10px;
    }
    /* The room's lines are padded by the card rather than individually: the option lines carry
       an inline left indent computed from their depth, which would override a padding set on
       them and leave the deepest ones flush against the border. The head spans the full width
       again by pulling back out of that padding. */
    .invoice-doc .room,
    .invoice-doc .owner-block { padding: 0 8px 6px; }
    .invoice-doc .room .room-head {
      flex-direction: column; align-items: flex-start;
      background: var(--chapter-bar); border-bottom: 0;
      margin: 0 -8px 6px; padding: 6px 8px;
      print-color-adjust: exact; -webkit-print-color-adjust: exact;
    }
    .invoice-doc .room .room-head .occ { margin-left: 0; margin-top: 2px; }
    /* Category, occupancy and occupants each take a line: run together they wrap at arbitrary
       points on a phone and read as one long phrase. */
    .invoice-doc .room .room-head .occ-part { display: block; }
    .invoice-doc .room .room-head .occ-part + .occ-part::before { content: none; }
    /* These two sections are lists rather than units, so they get no card — but their lines
       then start at the container edge while every carded section's start one border and one
       padding in, leaving the money edges disagreeing down the page. Inset to match. */
    /* Each schedule is its own unit, like a room or a participant: on a phone the groups sit
       one under another and a bare heading is not enough to show where one ends. */
    .invoice-doc .sched-groups { display: block; }
    .invoice-doc .sched-group {
      border: 1px solid var(--rule-light); border-radius: 0.375rem;
      overflow: hidden; margin: 0 0 10px; padding: 0 8px 6px;
    }
    .invoice-doc .sched-group .who {
      background: var(--chapter-bar);
      margin: 0 -8px 6px; padding: 6px 8px;
      print-color-adjust: exact; -webkit-print-color-adjust: exact;
    }
    .invoice-doc .sched-group .who .sub { display: block; margin-top: 2px; }
    .invoice-doc .sched-group .who .sub::before { content: none; }
    /* The schedule reads as line items here rather than as stacked label/value pairs: when is
       it due and how much, then how it stands. The column headings are kept — once at the top
       of the card rather than repeated on every row — because a date and a figure still need
       naming the first time. Status is left off: it sits on its own line and reads as a state
       without being told what it is. */
    .invoice-doc .sched-group table.light thead { display: block; }
    .invoice-doc .sched-group table.light thead tr { display: flex; padding-bottom: 2px; }
    /* No rule under the headings: the first row draws its own, and the two together were a
       doubled underline — one from the cell, one from the row. */
    .invoice-doc .sched-group table.light th { padding: 0; border-bottom: 0; }
    .invoice-doc .sched-group table.light th.num { margin-left: auto; text-align: right; }
    .invoice-doc .sched-group table.light th:nth-child(3) { display: none; }
    .invoice-doc .sched-group table.light tr { display: flex; flex-wrap: wrap; }
    /* The card's own edge closes the list, so the last payment's rule would draw a second line
       a few pixels above it. Only inside a card: uncarded, that rule is what ends the table. */
    .invoice-doc .sched-group table.light tr:last-child { border-bottom: 0; }
    .invoice-doc .sched-group table.light td { padding: 0; }
    .invoice-doc .sched-group table.light td::before { content: none; }
    .invoice-doc .sched-group table.light td[data-label="Due Date"] { flex: 1 1 auto; }
    .invoice-doc .sched-group table.light td[data-label="Amount"] {
      flex: 0 0 auto; margin-left: auto; text-align: right;
    }
    .invoice-doc .sched-group table.light td[data-label="Status"] {
      flex: 1 1 100%; color: var(--muted); margin-top: 1px;
    }
    /* Who has paid what, when a row is part paid across a party. Left aligned and indented
       under the status they qualify: right aligned they wrapped mid-phrase against the money
       edge, which is not their edge — no figure here sums with the column. */
    .invoice-doc .sched-group table.light td[data-label="Status"] .sub {
      text-align: left; padding-left: 12px;
    }
    .invoice-doc .section.lines-inset > .li,
    .invoice-doc .section.lines-inset > .group-line { padding-left: 9px; padding-right: 9px; }
    /* Same reason, one block further up: the Reservation Summary sits outside any section, so it
       keeps the container edge while every carded section's figures start a border and a padding
       in. Its Total and Balance Due are the first amounts on the page and the ones every figure
       below is read against, so they are the last that should sit apart. */
    .invoice-doc .two-up > div + div { padding-right: 9px; }
    /* And the ledger, for the same reason again: it is a bracketed list rather than a unit, so
       it takes no card, and its figures would otherwise sit a border and a padding right of
       every carded section above it. The bracketing inside the section already lines up — this
       moves the whole section to meet the rest of the document. */
    .invoice-doc .section.ledger > .li,
    .invoice-doc .section.ledger > div { padding-left: 9px; padding-right: 9px; }

    /* Stacked, the document draws cards either way — see above. Inside the booking flow they
       take that flow's own border and a small lift so they match the cards around them; the
       standalone document keeps its flat --rule-light edges, which is what prints. The heads
       need no override: --chapter-bar is already the flow's tint in this context. */
    body:not(.invoice-page) .invoice-doc .p-card,
    body:not(.invoice-page) .invoice-doc .room,
    body:not(.invoice-page) .invoice-doc .owner-block,
    body:not(.invoice-page) .invoice-doc .sched-group {
      border-color: var(--card-edge);
      box-shadow: 0 1px 3px rgba(0, 0, 0, .06);
    }
    .invoice-doc .owner-block .owner-line {
      background: var(--chapter-bar);
      margin: 0 -8px 6px; padding: 6px 8px;
      print-color-adjust: exact; -webkit-print-color-adjust: exact;
    }
    .invoice-doc .p-card .p-head {
      flex-direction: column; align-items: flex-start;
      background: var(--chapter-bar); border-bottom: 0;
      padding: 6px 8px; margin-bottom: 0;
      print-color-adjust: exact; -webkit-print-color-adjust: exact;
    }
    .invoice-doc .p-card .p-head .p-info { text-align: left; margin-left: 0; margin-top: 2px; }
    .invoice-doc .p-amounts { flex-wrap: wrap; justify-content: flex-start; }
    /* Three across, then the rest share the row beneath — with the discount pair dropped for a
       reservation that has none, the three that remain fill the top row and there is no second. */
    /* No rules inside the card: it is one unit, and the tinted head plus the space around each
       figure separate them well enough without drawing a grid over five numbers. */
    .invoice-doc .p-amt {
      flex: 0 0 33.333%; text-align: right; margin-left: 0;
      padding: 5px 8px;
    }
    /* Three columns throughout, so the second row lines up under the first: initial deposit
       sits below original total, and balance due takes the remaining two column widths. With
       no discount there are only three cells, none of them a fifth, so they fill one row. */
    .invoice-doc .p-amt:nth-child(5) { flex-basis: 66.667%; }
    .invoice-doc .p-amt + .p-amt { margin-left: 0; }
    .invoice-doc .p-amt .val { display: block; }
    .invoice-doc table.light thead { display: none; }
    /* --rule-light like every other separator on a phone: at --rule these were the darkest
       lines on the page, and the totals beneath them then looked like a different kind of rule
       when they are the same kind. */
    .invoice-doc table.light tr { display: block; border-bottom: 1px solid var(--rule-light); padding: 4px 0; }
    .invoice-doc table.light tr.has-note { border-bottom: none; padding-bottom: 0; }
    .invoice-doc table.light td { display: flex; flex-wrap: wrap; justify-content: space-between; border: 0; padding: 1px 0; }
    .invoice-doc table.light td .sub { flex: 1 1 100%; text-align: right; }
    .invoice-doc table.light td::before { content: attr(data-label); color: var(--label); font-size: 11px; font-weight: bold; padding-right: 10px; }
    /* Only an amount belongs on the money edge. Everything else is a value that happens to be
       right-aligned by the stacking, so it is held off the edge rather than sharing it. */
    .invoice-doc table.light td:not(.num) { padding-right: 10px; }
    .invoice-doc table.light td.num { text-align: right; }
    .invoice-doc table.light td:empty { display: none; }
    /* The cell is a flex container, which discards the whitespace between the label and the
       note, so the gap is set rather than typed. */
    .invoice-doc table.light tr.note-row td { justify-content: flex-start; }
    .invoice-doc table.light tr.note-row td b { margin-right: 6px; }
    .invoice-doc table.light tbody.agree-group { display: block; }
    /* No pseudo-element header here any more. It existed for the mockup's shape, where each
       signer of a shared agreement had their own row and only the first carried the rowspan'd
       name — so the later ones needed the tbody to reprint it. Collapsing matching
       acknowledgments into one row per agreement removed that case, and with one row per group
       the cell can simply be the heading. The attribute stays: it still says what the group is,
       and would be needed again if these rows ever stop being merged. */
    /* The agreement cell heads its own card: the name carries the weight and the revision sits
       beside it on the same line, qualifying it rather than naming it. */
    .invoice-doc table.light tbody.agree-group td[data-label="Agreement"] {
      justify-content: flex-start; align-items: baseline; padding-bottom: 3px;
    }
    .invoice-doc table.light tbody.agree-group td[data-label="Agreement"]::before { content: none; }
    .invoice-doc table.light tbody.agree-group td[data-label="Agreement"] .agreement-name {
      font-weight: bold; font-size: 12px;
    }
    .invoice-doc table.light tbody.agree-group td[data-label="Agreement"] .sub {
      flex: 0 0 auto; text-align: left; margin-left: 6px;
    }
}

  /* ---------- the standalone page ----------
     A backdrop and a shadow present the invoice as a sheet of paper rather than as a region of
     a web page, which is what it is. Deliberately hung off the shell's own body class rather
     than .invoice-doc: on the wizard review step the same document sits inside a card on a
     white page, where a second frame and a floating shadow would both be wrong, and the body
     there belongs to the whole public site. */
  /* The standalone document — the invoice page an employee opens, and the PDF that is emailed.
     Both carry this body class; the wizard review step does not, which is what keeps its
     typography on the app's stack. Noto is named first so it wins over whatever the viewer's
     system would have supplied, making "open and print" match "email PDF". */
  .invoice-page .invoice-doc {
    font-family: "Noto Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
                 "Liberation Sans", Arial, sans-serif;
  }

  .invoice-page { background-color: #d9d9d9; margin: 0; }
  .invoice-page .invoice-doc {
    box-shadow: 0 2px 14px rgba(0, 0, 0, .3);
  }


  /* Shown only when one person signed a row, so it qualifies that name rather than appearing
     to head a list of names. */
  .invoice-doc .party-role {
    display: inline; margin-left: 4px; font-size: 11px; color: var(--muted);
    text-transform: uppercase; letter-spacing: .06em; white-space: nowrap;
  }
  .invoice-doc .party-role::before { content: "\2022\00a0"; }

/* ---------- status treatment ----------
   The one sanctioned exception to the document's grayscale-only rule: a reservation that is not
   in Reservation status has to be impossible to miss.

   Values copied from the CoreUI light theme in
   static/vendor/coreui-pro-5.0.0-rc.0/coreui.min.css (--cui-danger / --cui-warning) rather than
   referenced, because this stylesheet loads without the CoreUI bundle on the standalone page.
   The mockup's #b3261e was a stand-in for these. */
  .invoice-doc {
    --status-danger: #e55353;   /* --cui-danger */
    --status-warning: #f9b115;  /* --cui-warning */
  }
  .invoice-doc .status-line {
    text-align: center; font-size: 22px; font-weight: bold;
    letter-spacing: .03em; margin: 12px 0 0;
    color: var(--status-warning);
  }
  .invoice-doc .status-line.is-cancelled { color: var(--status-danger); }
  .invoice-doc .doc-meta .status.warn { border-color: var(--status-warning); color: var(--status-warning); }
  /* Wins over .warn above on source order at equal specificity; deliberately does not
     require .warn, so the cancelled token holds whatever else is on the box. */
  .invoice-doc .doc-meta .status.is-cancelled { border-color: var(--status-danger); color: var(--status-danger); }

@media print {
    .invoice-page { background-color: #fff; }
    /* @page owns the width and the outer margins in print, so the sheet gives up the measure,
       the gutters and the desk shadow it carries on screen. */
    .invoice-page .invoice-doc {
      max-width: none;
      margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0;
      padding-top: 0; padding-right: .2in; padding-bottom: 0; padding-left: .2in;
      box-shadow: none;
    }
    .invoice-doc .status-line { font-size: 15pt; }
  }
