/* Styling for the pricing overlay only. Served by the pricing service, never by
 * the public one. Borrows the configurator's own custom properties so the panel
 * belongs to the page rather than sitting on top of it — if the brand colours
 * change in app.css, this follows without being touched.
 *
 * No inline styles anywhere: the CSP is `style-src 'self'` with no
 * 'unsafe-inline', deliberately, and adding an exception for a price panel
 * would be a poor trade. */

.pricing-panel {
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line, #d8d4cf);
  border-radius: 6px;
  background: var(--surface, #fff);
}

.pricing-panel h3 {
  margin: 0 0 8px;
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-soft, #5a5a5a);
}

/* ── sign in ──────────────────────────────────────────────────────────── */

.pricing-signin { display: flex; flex-direction: column; gap: 6px; }
.pricing-signin input {
  padding: 7px 9px;
  font: inherit;
  font-size: 13px;
  border: 1px solid var(--line, #d8d4cf);
  border-radius: 4px;
  background: var(--surface, #fff);
  color: var(--ink, #1a1a1a);
}
.pricing-signin .btn { margin-top: 2px; }

.pricing-error {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--danger, #a33);
}

/* ── the quote ────────────────────────────────────────────────────────── */



.pricing-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--line, #d8d4cf);
  font-size: 15px;
  font-weight: 600;
}
.pricing-total .pt-value { font-variant-numeric: tabular-nums; }

/* A doors-only figure must not read like a total. Same number, visibly not the
 * same claim — this is the case where a rep could otherwise quote a price that
 * excludes freight without noticing. */
.pricing-total.is-partial { font-weight: 500; color: var(--ink-soft, #5a5a5a); }
.pricing-total.is-partial .pt-label { font-style: italic; }

.pricing-note {
  margin: 6px 0 0;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--ink-soft, #5a5a5a);
}
.pricing-validity {
  margin: 4px 0 0;
  font-size: 11px;
  color: var(--ink-faint, #8a8a8a);
}

.pricing-refusal { margin: 0; font-size: 13px; color: var(--ink, #1a1a1a); }
.pricing-fallback,
.pricing-empty {
  margin: 6px 0 0;
  font-size: 12px;
  color: var(--ink-soft, #5a5a5a);
}

/* The IHS admin picker. Deliberately plain — it is a staff control on a
   customer-facing panel, so it should read as machinery rather than as part of
   the product. Hidden entirely for anyone who is not an ihs_admin. */
.pricing-asclient {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 10px 0 2px;
  padding-top: 10px;
  border-top: 1px solid var(--line, #d8d4cf);
}
.pricing-aslabel {
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-soft, #5a5a5a);
}
.pricing-select {
  flex: 1;
  min-width: 0;
  font: inherit;
  font-size: 13px;
  padding: 5px 8px;
  border: 1px solid var(--line, #d8d4cf);
  border-radius: 6px;
  background: none;
  color: inherit;
}

/* A number an admin may look at but must not quote. Stated plainly rather than
   coloured like an error: the figure is arithmetically right, the customer row
   is simply unfinished. Only an admin ever sees one. */
.pricing-warn {
  margin: 0 0 8px;
  padding: 6px 8px;
  font-size: 12px;
  line-height: 1.45;
  border: 1px solid var(--line, #d8d4cf);
  border-radius: 6px;
  color: var(--ink-soft, #5a5a5a);
}

/* A DOOR'S PRICE, INSIDE THAT DOOR'S OWN ROW (Jon, 2026-08-24). A separate
   priced list repeated the job line for line — three doors read twice, once
   without prices and once with. Sits at the end of the row, right-aligned, so
   the numbers stack down the sheet and can be read as a column.
   `tabular-nums` so the digits line up; a price column that jitters is harder
   to scan than one that does not. */
.jobline-price {
  margin-left: auto;
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* NO GREY ON THE GREY ROW (Jon, 21 Oct 2026): every word on a job row is black. */
.jp-unit {
  font-size: 12px;
  color: var(--ink, #1a1a1a);
}
.jp-ext {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink, #1a1a1a);
  min-width: 74px;
  text-align: right;
}

/* A COMPANY WITH GLASS PRICES HAS A PRICE ON A GLASS DOOR, so the shared page's
   "priced individually, contact us" note comes off for it (`markGlassPrices`). */
html.has-glass-prices #glassNote { display: none !important; }

/* HOW A GLASS PRICE WAS WORKED OUT, under the row, for IHS staff only. Full
   width so it wraps onto its own line of the flex row; quiet, like the other
   notes about a price. */
/* A door IHS has not agreed to yet (slice 4, Jon 18 Oct 2026): one calm grey line under it. */
.jobline-caveat {
  flex: 0 0 100%;
  font-size: 11px;
  color: var(--ink, #1a1a1a);
  padding: 0 2px;
}
.jobline-how {
  flex: 0 0 100%;
  font-size: 11px;
  font-style: italic;
  color: var(--ink, #1a1a1a);
  padding: 0 2px;
}

/* A DOOR THE PRICE LIST CANNOT REACH. Words, not a number, and quiet enough to
 * read as a note beside the priced rows rather than as an error on them — the
 * other doors in the job are still correctly priced. Italic for the same reason
 * `.pricing-total.is-partial` is: same column, visibly not the same claim. */
.jobline-price.is-unpriced .jp-byhand {
  font-size: 12px;
  font-style: italic;
  color: var(--ink, #1a1a1a);
  min-width: 74px;
  text-align: right;
}

/* THE BASE PRICE OF A DOOR WITH A SPECIAL REQUEST (Jon, 21 Oct 2026: "a RED price or
 * an asterisk that notes this is the base price"). Red, with the asterisk in the text. */
.jobline-price.is-base .jp-unit,
.jobline-price.is-base .jp-ext,
.pricing-note.is-base { color: var(--danger, #b3261e); }

/* A PRICE IHS SET BY HAND (2026-09-17).
 *
 * The figure in the row IS the control -- there is no pencil and no caption --
 * so for staff it has to look touchable without shouting: the cursor changes,
 * and hovering underlines the money the way a link would. A customer's page
 * never gets this class, because the server never calls their session staff. */
.jobline-price.is-editable { cursor: pointer; border-radius: 5px; }
.jobline-price.is-editable:hover .jp-ext,
.jobline-price.is-editable:hover .jp-byhand {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.jobline-price.is-editable:focus-visible {
  outline: 2px solid var(--accent, #8a6a3a);
  outline-offset: 2px;
}

/* SAME COLUMN, VISIBLY NOT THE SAME CLAIM -- the rule `.is-unpriced` above
 * follows. A typed price that reads exactly like a price the list gave is a
 * number nobody thinks to ask about, and this one somebody has to be able to
 * account for. So the words come first, then the list price it replaced, then
 * the money. */
.jp-hand {
  font-size: 11px;
  font-style: italic;
  letter-spacing: 0.02em;
  color: var(--accent, #8a6a3a);
}
/* What the list said. Struck through, quiet: it is context, not a price. */
.jp-was {
  font-size: 11px;
  color: var(--ink, #1a1a1a);
  text-decoration: line-through;
}

/* The job is short a price. Louder than the freight note above it, because a
 * subtotal missing a door is a worse thing to miss than a freight condition. */
.pricing-note.is-partial { color: var(--ink, #1a1a1a); font-weight: 500; }
/* PRICED SO FAR (22 Oct 2026): plain black, as the line above it; it is not a total and says so in words. */
.pricing-note.is-sofar { color: var(--ink, #1a1a1a); }
/* How many lines somebody typed. Quiet -- it is a fact about the total, not a
 * warning about it; the total is correct. Staff only. */
.pricing-note.is-hand { color: var(--accent, #8a6a3a); }

/* A price somebody typed that is not on the job any more. This one IS a
 * warning: the total is short money a person decided on. Weighted like
 * `.is-partial` above, which says the same kind of thing about a door the list
 * could not reach. Staff only. */
.pricing-note.is-adrift { color: var(--ink, #1a1a1a); font-weight: 500; }

/* A FROZEN QUOTE (23 Oct 2026): the line saying the price is held, black and a little heavier so a
 * customer reads it, with its button right under it. */
.pricing-note.is-frozen { color: var(--ink, #1a1a1a); font-weight: 500; }
.pricing-freeze { display: flex; flex-direction: column; gap: .4rem; margin-top: .25rem; }
.pricing-freeze[hidden] { display: none; }
.pricing-freeze-date { display: flex; flex-direction: column; gap: .2rem; font-size: .85rem; color: var(--ink, #1a1a1a); }
/* A job held by a frozen quote: its count, remove and option controls are switched off by the page. */
.job-frozen .jobline .qbtn[disabled], .job-frozen .jobline .rowopts[disabled] { opacity: .45; cursor: not-allowed; }

/* FREIGHT QUOTED SEPARATELY (Jon, 12 Oct 2026: "larger, bolder and red"). The
 * job is under the company's prepaid count, so the total is doors only; the
 * sentence that says so was the quietest thing in the panel. The other freight
 * sentences (FOB, freight included, prepaid met) stay as they were. */
.pricing-note.is-freight {
  font-size: 14px;
  font-weight: 700;
  color: var(--danger, #b3261e);
}
/* WHY THERE IS NO JOB TOTAL (R-20, Jon 15 Oct 2026: "this way there can be no
   mistakes"): as loud as the freight line, right under "No job total". */
.pricing-note.is-why { font-size: 14px; font-weight: 700; color: var(--danger, #b3261e); margin-top: 4px; }

/* FREIGHT WITHOUT A FREIGHT RULE (Jon, 22 Oct 2026, "1, 3, 4"): how many more doors make the
   job prepaid, in black under the red line, and the button that sends the job to sales. */
.pricing-note.is-nudge { font-weight: 700; color: #000; margin-top: 4px; }
.freight-ask-btn { margin: 8px 0 4px; }

/* THE ROW'S ITEM NUMBER, IHS staff only (2026-09-24). Its own line under the
 * spec, and the control for typing over it -- touchable the way the price is,
 * without a caption. A typed number reads "Set by hand" with the worked-out
 * one struck beside it, the same claim `.jp-hand` makes about a price. */
.jobline-item {
  flex: 1 0 100%;
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--ink-soft, #5a5a5a);
  cursor: pointer;
  border-radius: 4px;
}
.jobline-item:hover .ji-num {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.jobline-item:focus-visible {
  outline: 2px solid var(--accent, #8a6a3a);
  outline-offset: 2px;
}
.ji-hand { font-style: italic; color: var(--accent, #8a6a3a); }
/* The row's leading item number, for staff the way to type over it: touchable
   like the price, no caption (2026-09-24). */
.rowtext.is-item-control { cursor: pointer; }
.rowtext.is-item-control:hover { text-decoration: underline; text-underline-offset: 2px; }
.rowtext.is-item-control:focus-visible { outline: 2px solid var(--accent, #8a6a3a); outline-offset: 2px; }
.jobline-item.is-hand .ji-num { color: var(--ink, #1a1a1a); }
.ji-was { color: var(--ink-faint, #8a8a8a); text-decoration: line-through; }

/* THE HAND-PRICE DIALOG. Narrow, because it asks two questions. The list
 * price above the boxes is the server's answer, not the page's arithmetic. */
.sheet.priceedit { max-width: 420px; }
.priceedit-body { display: grid; gap: 12px; }
.priceedit-list { margin: 0; color: var(--ink-soft, #5a5a5a); font-size: 13px; }
.priceedit-field { display: grid; gap: 4px; font-size: 13px; }
.priceedit-field > span { color: var(--ink-soft, #5a5a5a); }
.priceedit-field input {
  font: inherit;
  padding: 7px 9px;
  border: 1px solid var(--line, #d8d4cf);
  border-radius: 6px;
  background: var(--paper, #fff);
  color: var(--ink, #1a1a1a);
}
/* `.sheet-foot` already gives it the padding and the top rule; this only
   pushes the two buttons to the right, where the page's other sheets put
   them. */
.priceedit-foot { justify-content: flex-end; }

/* WHO IS SIGNED IN, in the top bar. Quiet: it is a fact about you, not a
   control you use often. The address is the point -- an IHS admin can be
   pricing as anybody, so knowing whose prices are on screen starts with knowing
   who you are. */
.navwho {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-right: 12px;
}
.navwho-name {
  font-size: 13px;
  color: var(--ink-soft, #5a5a5a);
  max-width: 22ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The sign-in sheet, opened from the top bar. Deliberately plain and small --
   two fields and a way out. */
dialog.sheet.signin {
  border: 1px solid var(--line, #d8d4cf);
  border-radius: 10px;
  padding: 0;
  max-width: 340px;
  width: calc(100% - 32px);
}
dialog.sheet.signin::backdrop { background: rgba(0, 0, 0, .35); }
.signin-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 20px;
}
.signin-form h2 {
  margin: 0 0 4px;
  font-size: 17px;
  font-weight: 500;
}
.signin-form input {
  font: inherit;
  font-size: 14px;
  padding: 9px 10px;
  border: 1px solid var(--line, #d8d4cf);
  border-radius: 6px;
  background: none;
  color: inherit;
}
.signin-actions {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}
.signin-actions .btn { flex: 1; }

/* The prices-on-the-drawings tick-box, under the download link in the
   drawings dialog. Off on every open of that dialog (pricing.js); hidden when
   there is no price to include. */
.pricing-onsheet {
  display: flex; align-items: center; gap: .5rem;
  margin-top: .6rem; font-size: .9rem; cursor: pointer;
}
.pricing-onsheet input { width: 1rem; height: 1rem; margin: 0; }
/* The three choices a company with the markup box gets (R-24 slice 3). */
.pricing-onsheet-choice { margin-top: .4rem; }
.pricing-onsheet-choice .pricing-onsheet { margin-top: .3rem; }
.pricing-onsheet input:disabled + span { color: var(--ink-faint, #8a8a8a); }
.pricing-onsheet-why { font-size: .8rem; color: var(--ink-faint, #8a8a8a); }
.pricing-onsheet-why::before { content: "\00b7  "; }
/* The line that says which drawing the link gives. Quiet: it answers a worry,
   it does not ask for a click. */
.pricing-onsheet-note { margin: .25rem 0 0; font-size: .85rem; color: var(--ink-soft, #555); }
/* RED while the quote box is ticked (Jon, 2026-10-01): dealer pricing is on it. */
.pricing-onsheet-note.is-warn { color: #b00020; font-weight: 600; }
/* THE BUTTONS ON THE DRAWINGS SCREEN SIT IN ONE TIDY ROW (Jon, 2026-10-01).
   Download, the staff-only Download DXF and Send used to flow as inline blocks, so
   a third button wrapped onto a line of its own, pushed in by a margin. A flex row
   wraps by whole buttons and lines them up on the left; the sentences around them
   (the ready line, the tick-box, the two notes) each take a full line. `hidden`
   must still hide it, which an author `display` would otherwise undo. */
#dlWrap { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
#dlWrap[hidden] { display: none; }
#dlWrap > p, #dlWrap > label, #dlWrap > .pricing-onsheet-choice { flex: 0 0 100%; margin: 0; }
#dlWrap > .btn[hidden] { display: none; }
/* One gap for every button (the staff DXF button carried its own margin), and a
   dialog just wide enough for all three staff buttons on one row. */
#dlWrap > .btn { margin: 0; }
.sheet.lead { width: min(560px, 94vw); }
.pricing-sendnote { margin: .4rem 0 0; font-size: .85rem; color: var(--ink-soft, #555); }
.pricing-sendnote.is-refusal { color: #8a1c1c; }

/* ── saved quotes ─────────────────────────────────────────────────────── */
.pricing-savequote { margin-top: .75rem; display: flex; flex-direction: column; gap: .4rem; }
.pricing-savenote { margin: 0; font-size: .85rem; color: var(--ink-soft, #555); }
.pricing-savenote.is-refusal { color: #8a1c1c; }
.sheet.quotes { max-width: 560px; }
/* The company's markup, for its manager (R-24 slice 4). */
.sheet.company-markup { max-width: 440px; }
.company-markup-body { display: flex; flex-direction: column; gap: .7rem; align-items: flex-start; }
.company-markup-body .pricing-empty { margin: 0; }
.quotes-body { display: flex; flex-direction: column; gap: .5rem; }
.quote-row {
  display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto auto;
  gap: .15rem .75rem; align-items: center;
  padding: .6rem .75rem; border: 1px solid var(--line, #e2e2e2); border-radius: 8px;
}
.quote-main { display: flex; gap: .6rem; align-items: baseline; }
.quote-project { color: var(--ink-soft, #555); }
.quote-meta { grid-column: 1; font-size: .8rem; color: var(--ink-faint, #777); }
.quote-row .btn { grid-column: 2; grid-row: 1 / span 2; }
/* Quote versions (Jon, 14 Oct 2026): the earlier versions of a job fold under
   its newest quote, a step in and quieter. */
.quote-fold { align-self: flex-start; background: none; border: 0; padding: 0 .75rem;
  font: inherit; font-size: .8rem; color: var(--ink-soft, #555); text-decoration: underline;
  cursor: pointer; }
.quote-older { display: flex; flex-direction: column; gap: .5rem; margin-left: 1.25rem; }
.quote-row.is-earlier { background: var(--surface-alt, #f6f6f4); }
.quote-tag { font-size: .75rem; color: var(--ink-faint, #777); }
/* The search box over the Company quotes list (23 Oct 2026): it stays at the top while the list scrolls. */
.quotes-search { position: sticky; top: 0; z-index: 1; width: 100%; box-sizing: border-box;
  padding: .6rem .75rem; font: inherit; font-size: 16px; color: var(--ink, #1a1a1a);
  background: #fff; border: 1px solid var(--line, #d8d4cf); border-radius: 6px; }
.quotes-search:focus { outline: 2px solid var(--ink, #1a1a1a); outline-offset: 1px; }
.quotes-found { margin: 0; font-size: .85rem; color: var(--ink, #1a1a1a); }
.quotes-found:empty { display: none; }
.quotes-list { display: flex; flex-direction: column; gap: .5rem; }
/* A quote holding a door IHS has not agreed to yet (slice 4): "IHS to confirm". */
.quote-tag.is-confirm { color: var(--ink-soft, #5c5c5a); font-weight: 600; }

/* "Send me a link" / "I have a password": a plain text switch under the
   sign-in form (2026-09-16). */
.signin-form .linklike { background: none; border: 0; color: #4a4a48; text-decoration: underline;
  cursor: pointer; font: inherit; font-size: 13px; padding: 6px 0 0; align-self: flex-start; }
.signin-form .pricing-note { color: #1c5a2a; background: #e8f3ea; padding: 8px 10px; border-radius: 6px; margin: 0; }
.navwho-note { font-size: 12px; color: #d9e9dc; margin-left: 8px; }

/* REQUEST ACCESS (2026-10-02): the sign-in sheet's cousin. The `website` box is a
   trap for programs and must never be visible or reachable by a person: off-screen,
   not display:none (some programs skip a hidden box and fill the rest). */
dialog.sheet.signin.ask { max-width: 380px; }
.signin-form .ask-intro { margin: 0; font-size: 13px; color: #4a4a48; }
.signin-form textarea {
  font: inherit; font-size: 14px; padding: 9px 10px; resize: vertical;
  border: 1px solid var(--line, #d8d4cf); border-radius: 6px; background: none; color: inherit;
}
.signin-form .ask-hp {
  position: absolute; left: -9999px; top: auto; width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
}

/* ── THE DEALER'S MARKUP FOR THEIR OWN CUSTOMER (R-24, Jon 15 Oct 2026) ──────
   Under the totals: the job's markup, then what our price, their customer's
   price and what they keep come to. On each door's row, under our price, their
   customer's price with the door's own box. Quiet, like the rest of the panel;
   the customer's figures read in the same column as ours. */
.pricing-markup {
  margin: 12px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--line, #d8d4cf);
}
.pm-head {
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-soft, #5a5a5a);
  margin-bottom: 6px;
}
.pm-row { display: flex; gap: 8px; align-items: center; }
.pm-val, .pm-kind, .jm-box {
  font: inherit;
  font-size: 13px;
  padding: 5px 8px;
  border: 1px solid var(--line, #d8d4cf);
  border-radius: 6px;
  background: none;
  color: inherit;
}
.pm-val { width: 90px; }
.pm-fixed { margin: 0; font-size: 13px; color: var(--ink, #1a1a1a); }
.pm-err { margin: 6px 0 0; font-size: 12px; color: var(--danger, #b3261e); }
.pm-sums { margin-top: 8px; }
.pm-sum {
  display: flex;
  justify-content: space-between;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  padding: 2px 0;
}
.pm-sum.is-customer { font-weight: 600; font-size: 14px; }
.pm-sum.is-keep { color: var(--ink-soft, #5a5a5a); }

.jobline-markup {
  flex: 0 0 100%;
  display: flex;
  justify-content: flex-end;
  align-items: baseline;
  gap: 10px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.jm-label { font-size: 12px; color: var(--ink, #1a1a1a); }
.jm-box { width: 70px; padding: 2px 6px; font-size: 12px; text-align: right; }
.jm-unit { font-size: 12px; color: var(--ink, #1a1a1a); }
.jm-ext { font-size: 14px; font-weight: 600; min-width: 74px; text-align: right; }


/* WHERE TO BUY (Jon, 22 Oct 2026, WHERE_TO_BUY_PLAN.md). Its button sits beside
   Request access on a visitor's job window, and beside How-To in the top bar. The
   bar was sized for one button (app.css, max-width 560px), so at phone width the
   bar's copy hides and the Menu row carries it. `hidden` must still hide it. */
.pricing-asks { display: flex; flex-wrap: wrap; gap: .5rem; }
.btn.where-bar[hidden] { display: none; }
@media (max-width: 560px) {
  .btn.where-bar { display: none; }
}
.signin-form .where-doors { margin-top: 0; font-size: 13px; }
.signin-form .where-call { font-size: 12px; }
.signin-form .where-doors[hidden] { display: none; }

/* READY FOR A PRICE (22 Oct 2026): the tick beside Save quote, for a salesperson who sees no price. */
.pricing-ready { display: flex; align-items: center; gap: .5rem; font-size: .9rem; color: var(--ink, #1a1a1a); }
.pricing-ready[hidden] { display: none; }

/* THE ONE WARNING LOOK (Jon, 30 Oct 2026: "All warnings should be easier to see and stand out"; of three
   on offer, "I like the tint + bar", at the size warnings were before). A pale red block, a red bar down the
   left edge and a "!" in a red circle, in the same words as before. It is a block, not a popup: one that sits
   in a card or under a field stays until the number is fixed, and a bubble still fades (Jon, 22 Oct 2026).
   Defined here for everything with the `err` class, and again, with these same lines, in the stylesheets of
   the classes that do not carry it (builder.css, pricing.css, admin.css, welcome.css). The big "Not one we
   make" panel (.blocked) is quiet on purpose and is not part of this. */
.pricing-error:not([hidden]):not(:empty),
.pm-err:not([hidden]):not(:empty),
.pricing-sendnote.is-refusal:not([hidden]):not(:empty),
.pricing-savenote.is-refusal:not([hidden]):not(:empty),
.pricing-onsheet-note.is-warn:not([hidden]):not(:empty) {
  position: relative;
  display: block; box-sizing: border-box;
  margin: 6px 0; padding: 8px 12px 8px 36px;
  font-size: 12px; font-weight: 600; line-height: 1.4; text-align: left;
  color: var(--warn-ink, #7a1712); background: var(--warn-bg, #fdecea);
  border: 0; border-left: 5px solid var(--warn-bar, #c62828); border-radius: 6px;
}
.pricing-error:not([hidden]):not(:empty)::before,
.pm-err:not([hidden]):not(:empty)::before,
.pricing-sendnote.is-refusal:not([hidden]):not(:empty)::before,
.pricing-savenote.is-refusal:not([hidden]):not(:empty)::before,
.pricing-onsheet-note.is-warn:not([hidden]):not(:empty)::before {
  content: "!"; position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--warn-bar, #c62828); color: #fff;
  font: 700 12px/18px system-ui, -apple-system, sans-serif; text-align: center;
}
