/* The @font-face rules are NOT in this file on purpose: they live in
   /assets/fonts/fonts.css and are inlined at the top of every page by
   build/critical_css.py. Declaring a font again when this stylesheet
   arrives after the first paint made the browser switch to it late and
   shift the whole page (PageSpeed layout shift 1.0, 2 Oct 2026). */
:root{
    /* Single-accent system: one brand color (amber/rust) + warm neutrals.
       Red is reserved strictly for semantic use: negative/deducted values
       and the demo-mode warning, never decorative. */
    --ink:#1c1917;
    --ink-soft:#57534e;
    --line:#e7e5e4;
    --bg:#fafaf9;
    --card:#ffffff;
    --brand:#b45309;
    --brand-dark:#92400e;
    --brand-soft:#fef3e2;
    --accent:#b45309;
    --gold:#b45309;
    --gold-soft:#fef3e2;
    --danger:#b91c1c;
  /* Structure tokens, added 1 October 2026. Orange was carrying borders, focus
     rings, icons and chart bars as well as the commercial actions, so none of
     it read as a signal any more. Structure now uses ink; orange is kept for
     the paid action, the active step, the headline figure and legal notices. */
  --structure:#44403c;
  --structure-soft:#78716c;
  --focus:#1c1917;
    --radius:10px;
    --shadow:0 1px 2px rgba(28,25,23,.04), 0 10px 24px -10px rgba(28,25,23,.08);
    --accent-edge:inset 0 3px 0 0 var(--brand);
    font-size:16px;
  }
  *{box-sizing:border-box;}
  html{scroll-behavior:smooth;scroll-padding-top:120px;}
  body{
    margin:0;
    font-family:'Inter',system-ui,-apple-system,Segoe UI,sans-serif;
    color:var(--ink);
    background:var(--bg);
    line-height:1.5;
  }
  .mono{font-family:'IBM Plex Mono',ui-monospace,monospace;}
  img,svg{max-width:100%;display:block;}
  a{color:var(--brand);}
  .wrap{max-width:1180px;margin:0 auto;padding:0 20px;}

  /* Header */
  header.site{
    position:sticky;top:0;z-index:40;
    background:rgba(255,255,255,.92);
    backdrop-filter:saturate(180%) blur(8px);
    border-bottom:1px solid var(--line);
  }
  .nav-row{display:flex;align-items:center;justify-content:space-between;padding:12px 0;
    column-gap:16px;row-gap:6px;flex-wrap:wrap;}
  .brand{display:flex;align-items:center;gap:10px;font-weight:800;font-size:1.25rem;letter-spacing:-.02em;color:var(--ink);text-decoration:none;}
  /* The mark is an <img> now, not a glyph in a CSS-drawn box: the border,
     background, colour, centring and font rules all existed to place the
     sigma and have gone with it. width/height are also set as HTML attributes
     on the tag so the box is reserved before the image loads - the header is
     above the fold and this is the one image on the critical path. */
  /* The mark is an <img> now, not a glyph in a CSS-drawn box: the border,
     background, colour, centring and font rules all existed to place the
     sigma and have gone with it. width/height are also set as HTML attributes
     on the tag so the box is reserved before the image loads - the header is
     above the fold and this is the one image on the critical path. */
  .brand-mark{
    height:48px;width:49px;  /* explicit: width:auto counted as an unsized image */
    display:block;flex-shrink:0;
  }
  .brand-word{display:flex;flex-direction:column;line-height:1.05;}
  .brand-name{display:block;white-space:nowrap;}
  .brand-accent{color:var(--brand);}
  .brand-sub{font-size:.65rem;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft);display:block;margin-top:2px;}
  /* The calculator tabs get their own full-width row at every width.
     .wrap caps content at 1180px, so brand + Resources + CTA squeezed the tab
     strip into the leftover space and pushed "Construction Injury" onto a line
     of its own - identical at 1600px and 1024px, because the cap and not the
     viewport was the constraint. Giving the strip its own row fits all five on
     one line, and keeps site navigation (top row) visually separate from view
     switchers (second row), which behave differently despite looking alike.
     Mirrors what the <=870px rule already did. */
  /* The two nav rows live in .nav-stack, right-aligned, with the CTA to the
     right of both. Previously the tab strip claimed its own full-width row
     (order:3 / flex-basis:100%), which put the CTA above it. */
  .nav-stack{display:flex;flex-direction:column;align-items:flex-end;
    gap:6px;flex:0 1 auto;min-width:0;margin-left:auto;}
  .res-nav{justify-content:flex-end;}
  .btn{
    display:inline-flex;align-items:center;justify-content:center;gap:8px;
    font-weight:700;font-size:.9rem;padding:10px 18px;border-radius:10px;
    border:1px solid transparent;cursor:pointer;text-decoration:none;white-space:nowrap;
    transition:transform .05s ease, box-shadow .15s ease;
  }
  .btn:active{transform:translateY(1px);}
  .btn-primary{background:var(--brand);color:#fff;box-shadow:0 6px 16px rgba(29,78,216,.25);}
  .btn-primary:hover{background:var(--brand-dark);}
  .btn-ghost{background:#fff;border-color:var(--line);color:var(--ink);}
  .btn-ghost:hover{border-color:var(--structure);color:var(--ink);}
  .btn-gold{background:var(--gold);color:#fff;}
  .btn-gold:hover{background:#92400e;}
  .btn-sm{padding:7px 12px;font-size:.78rem;border-radius:8px;}
  /* A full-width button has no reason to refuse to wrap, and .btn is
     white-space:nowrap in this file while state-pages.css sets it to
     normal. "See a sample Delay & Overhead report (PDF)" inside
     .lock-card is 266px of nowrap text and was the single element
     pushing all five calculator pages past a phone viewport. Line ~503's
     `.sample-link .btn-block` was this fix applied to one instance
     instead of to the class. */
  .btn-block{width:100%;white-space:normal;}

  /* Hero */
  .hero{padding:52px 0 28px;}
  .eyebrow{
    display:inline-flex;align-items:center;gap:6px;
    background:var(--brand-soft);color:var(--brand-dark);
    font-size:.72rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
    padding:6px 12px;border-radius:999px;margin-bottom:16px;
  }
  h1{font-size:clamp(1.7rem,3.4vw,2.6rem);line-height:1.14;letter-spacing:-.02em;margin:0 0 14px;font-weight:800;}
  .hero .wrap{text-align:left;}
  .hero h1{max-width:none;}
  .hero p.lead{font-size:1.06rem;color:var(--ink-soft);max-width:none;margin:0 0 22px;}
  .hero-cta-row{display:flex;gap:12px;flex-wrap:wrap;align-items:center;margin-bottom:10px;}
  .trust-row{display:flex;flex-wrap:wrap;gap:18px;margin-top:22px;font-size:.82rem;color:var(--ink-soft);}
  .trust-row span{display:flex;align-items:center;gap:6px;}
  .dot{width:6px;height:6px;border-radius:50%;background:var(--accent);flex-shrink:0;}

  /* Calculator shell */
  /* Horizontal padding must match .wrap (0 20px): this class sits on the same
     element as .wrap and would otherwise reset it, pushing the calculator
     containers 20px left of the hero text above. */
  .calc-section{padding:18px 20px 28px;}
  .tab-panel{display:none;}
  .tab-panel.active{display:block;}

  .calc-head{margin-bottom:18px;}
  .calc-head h2{font-size:1.4rem;margin:0 0 6px;letter-spacing:-.01em;}
  .calc-head p{color:var(--ink-soft);margin:0;font-size:.95rem;max-width:720px;}
  .formula-pills{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px;}
  .formula-pill{
    font-size:.72rem;font-weight:600;color:var(--brand-dark);background:var(--brand-soft);
    border:1px solid #fde3c0;padding:4px 10px;border-radius:999px;
  }

  .cm-import-widget{background:var(--card);border:1px dashed var(--line);border-radius:var(--radius);box-shadow:var(--shadow), var(--accent-edge);padding:14px 16px;margin-top:14px;}
  .cm-import-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap;}
  .cm-import-row .btn{white-space:nowrap;}
  .calc-head .cm-import-privacy{font-size:.78rem;color:var(--ink-soft);margin:6px 0 0;max-width:none;}
  .cm-import-status{display:none;margin-top:10px;font-size:.85rem;}
  .cm-import-ok.cm-import-warn.cm-import-note{border-radius:8px;padding:8px 10px;margin-bottom:6px;}
  .cm-import-ok:last-child.cm-import-warn:last-child.cm-import-note:last-child{margin-bottom:0;}
  .cm-import-ok{background:#f0fdf4;border:1px solid #bbf7d0;color:#166534;}
  .cm-import-warn{background:#fffbeb;border:1px solid #fde68a;color:#92400e;}
  .cm-import-note{background:#f8fafc;border:1px solid var(--line);color:var(--ink-soft);}
  @keyframes cmImportedPulse{0%{background:#fef9c3;}100%{background:transparent;}}
  input.cm-imported-field{animation:cmImportedPulse 4s ease-out;border-color:#ca8a04 !important;}

  .calc-grid{display:grid;grid-template-columns:1fr;gap:20px;}
  /* Grid items default to min-width:auto, so a single wide child (a long
     input label) can blow the 1fr track past the viewport on a 360px
     phone. Let the tracks shrink and scroll the offending child instead. */
  .calc-grid > *{min-width:0;}
  @media(min-width:920px){
    /* The inputs column was capped at 420px while the results column took
       everything else, which squeezed two side-by-side fields to about 188px
       each and forced labels to wrap. The weighting is reversed: the form gets
       the room, the figures keep enough width to stay legible. */
    .calc-grid{grid-template-columns:minmax(0,1fr) minmax(380px,460px);align-items:stretch;}
    /* Let the Full Line-Item Breakdown card grow to the bottom of the input column. */
    .results-col{display:flex;flex-direction:column;}
    .results-col > .lock-wrap{flex:1 1 auto;}
  }

  .card{
    background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
    box-shadow:var(--shadow), var(--accent-edge);padding:20px;
  }
  .card + .card{margin-top:20px;}
  .card h3{font-size:.95rem;margin:0 0 14px;font-weight:700;}
  .card h3 small{display:block;font-weight:500;color:var(--ink-soft);font-size:.78rem;margin-top:2px;}

  .field{margin-bottom:14px;}
  .field label{
    display:flex;justify-content:space-between;gap:8px;font-size:.82rem;font-weight:600;margin-bottom:6px;color:var(--ink);
    align-items:flex-start;
  }
  .field label .label-text{display:inline-flex;align-items:center;gap:6px;}
  .field label .hint{font-weight:500;color:var(--ink-soft);font-size:.72rem;white-space:nowrap;padding-top:1px;}
  .field input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=range]):not(.ec-email-input),
  .field select{
    width:100%;padding:9px 11px;border:1px solid var(--line);border-radius:8px;
    font-size:.92rem;font-family:inherit;background:#fff;color:var(--ink);
  }
  .field input:not([type=checkbox]):not([type=radio]):not([type=file]):not([type=range]):not(.ec-email-input):focus,
  .field select:focus{outline:2px solid var(--brand);outline-offset:1px;}
  .field-row{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
  /* Grid items are min-width:auto, so each track is at least its
     content's min-content width; a long select option then sets the
     floor no matter what width:100% says. Both halves are needed: let
     the tracks shrink, and stack below 520px - the breakpoint the rest
     of this file already uses. */
  .field-row > *{min-width:0;}
  .field select, .field input[type=number]{max-width:100%;}
  @media (max-width:520px){
    .field-row{grid-template-columns:1fr;}
  }
  .range-row{display:flex;align-items:center;gap:10px;}
  .range-row input[type=range]{flex:1;accent-color:var(--brand);}
  .range-val{font-family:'IBM Plex Mono',monospace;font-size:.82rem;font-weight:600;min-width:48px;text-align:right;}

  /* Info tooltip button + expandable panel */
  .info-btn{
    display:inline-flex;align-items:center;justify-content:center;
    width:16px;height:16px;border-radius:50%;
    background:var(--brand-soft);color:var(--brand-dark);border:1px solid #fde3c0;
    font-size:.66rem;font-weight:800;font-style:normal;line-height:1;cursor:pointer;
    flex-shrink:0;padding:0;font-family:'IBM Plex Mono',monospace;
  }
  .info-btn:hover{background:var(--brand);color:#fff;}
  .info-btn.active{background:var(--brand);color:#fff;}
  .info-btn:focus-visible{outline:2px solid var(--brand);outline-offset:2px;}
  .info-panel{
    display:none;
    font-size:.78rem;line-height:1.55;color:var(--ink-soft);
    background:var(--brand-soft);border:1px solid #fde3c0;border-radius:8px;
    padding:9px 11px;margin-top:7px;
  }
  .info-panel.open{display:block;}
  .info-panel strong{color:var(--ink);}

  /* Results side */
  .results-top{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-bottom:16px;}
  @media(max-width:520px){.results-top{grid-template-columns:1fr;}}
  /* One card carries the headline figure, so one card carries the colour. The
     others are the same calculation in different states and read better calm. */
  .stat-card{
    background:linear-gradient(180deg, var(--brand-soft) 0%, #fff 65%);color:var(--ink);border:1px solid var(--line);
    border-left:3px solid var(--brand);
    border-radius:var(--radius);padding:18px 20px;box-shadow:var(--shadow);
  }
  .stat-card .label{font-size:.72rem;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-soft);font-weight:600;}
  .stat-card .value{font-size:1.7rem;font-weight:800;margin-top:6px;font-family:'IBM Plex Mono',monospace;letter-spacing:-.01em;color:var(--brand-dark);}
  /* 1fr columns grew to fit the widest figure, so an eight-figure net pushed
     the second card past the column edge. Columns now share the width; a
     figure too long for its card is stepped down by cmFitStatValues() in
     app.js, only as far as it needs and never below 1.1rem. */
  .stat-card{min-width:0;}
  .stat-card .value{white-space:nowrap;}
  /* Where three figures share the grid, the headline card takes the full
     width on top, matching the exports, which lead on the same figure. */
  .results-top:has(> .stat-card:nth-child(3)) > .stat-card:not(.alt){grid-column:1 / -1;order:-1;}
  .stat-card.alt{background:var(--bg);border-left:3px solid var(--structure-soft);}
  .stat-card.alt .value{color:var(--ink);}

  .chart-wrap{position:relative;height:220px;}
  .cm-amt-locked{letter-spacing:2px;color:var(--ink-soft);user-select:none;}
  .cm-bar-flag{display:inline-block;margin-top:4px;color:#b91c1c;font-weight:700;}
  .state-ref-userate{margin:-4px 0 14px;}
  .stat-for{display:block;font-weight:400;text-transform:none;letter-spacing:0;
    font-size:.72rem;color:var(--ink-soft);margin-top:2px;}
  /* Formula deep-dive and citation guidance under each calculator. Plain
     crawlable prose: someone arriving from "how to calculate unabsorbed home
     office overhead" lands on input boxes and needs the method explained
     before they will trust the output enough to pay for it. */
  .method-note{max-width:820px;margin:34px auto 0;padding:24px 0 0;
    border-top:1px solid var(--line);}
  .method-note h3{margin:0 0 12px;font-size:1.15rem;}
  .method-note h4{margin:22px 0 8px;font-size:.98rem;}
  .method-note p{margin:0 0 12px;color:var(--ink-soft);font-size:.93rem;line-height:1.65;}
  .method-note ul{margin:0 0 12px;padding-left:20px;}
  .method-note li{margin:6px 0;color:var(--ink-soft);font-size:.92rem;line-height:1.6;}
  .method-note li strong{color:var(--ink);}
  .method-note-tail{font-style:italic;}
  @media print{.method-note{display:none !important;}}
  .pw-note{margin:8px 0 0;font-size:.85rem;line-height:1.5;color:var(--brand-dark);
    background:var(--brand-soft);border:1px solid #f3d3ab;border-radius:8px;padding:9px 11px;}
  .cm-status-banner{margin:12px 0 0;padding:12px 14px;border-radius:10px;
    font-size:.88rem;line-height:1.5;border:1px solid;}
  .cm-status-banner.barred{background:#fef2f2;border-color:#fecaca;color:#7f1d1d;}
  .cm-status-banner.capped{background:var(--brand-soft);border-color:#f3d3ab;color:var(--brand-dark);}
  .cm-status-banner.note{background:#f8fafc;border-color:var(--line);color:var(--ink-soft);}
  .cm-status-cite{display:block;margin-top:6px;font-size:.78rem;opacity:.85;}
  .cm-cl-group{margin:0 0 14px;}
  .cm-cl-group h4{margin:0 0 6px;font-size:.82rem;font-weight:700;letter-spacing:.04em;
    text-transform:uppercase;color:var(--brand-dark);}
  .cm-cl-row{display:flex;align-items:flex-start;gap:9px;padding:5px 0;font-size:.9rem;
    color:var(--ink);cursor:pointer;border-bottom:1px solid var(--line);}
  .cm-cl-row:last-child{border-bottom:none;}
  .cm-cl-row input{margin-top:2px;accent-color:var(--brand);flex:0 0 auto;}
  .cm-cl-row span{flex:1 1 auto;}
  .cm-cl-del{background:none;border:none;color:var(--ink-soft);cursor:pointer;font-size:1.1rem;
    line-height:1;padding:0 4px;}
  .cm-cl-del:hover{color:var(--brand);}
  .cm-cl-count{margin:12px 0 0;font-size:.82rem;color:var(--ink-soft);}
  .cm-cl-print-note{display:none;}
  .cm-cl-for{font-weight:400;color:var(--ink-soft);font-size:.86rem;}
  /* Same markup and styling as /state-rules/, /samples/ and /checklists/,
     which carry these rules via state-rules/assets/state-pages.css. Keep the
     two in step if either changes. */
  .res-nav{display:flex;gap:4px;flex-wrap:wrap;}
  .res-nav a{padding:7px 11px;border-radius:8px;text-decoration:none;
    font-size:.82rem;font-weight:700;color:var(--ink-soft);white-space:nowrap;}
  .res-nav a:hover{background:var(--brand-soft);color:var(--brand-dark);}
  .res-nav a[aria-current="page"]{background:var(--brand-soft);color:var(--brand-dark);}
  @media print{.res-nav{display:none !important;}}
  .cm-cl-add{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap;}
  .cm-cl-add input{flex:1 1 260px;padding:9px 11px;border:1px solid var(--line);
    border-radius:8px;font:inherit;font-size:.9rem;}
  .cm-cl-add input:focus{outline:2px solid var(--brand);outline-offset:1px;}
  .cm-fallback-chart{position:absolute;inset:0;display:flex;flex-direction:column;
    justify-content:center;gap:12px;padding:4px 2px;}
  .cm-fb-row{display:grid;grid-template-columns:minmax(96px,34%) 1fr auto;align-items:center;gap:10px;}
  .cm-fb-label{font-size:.78rem;color:var(--ink-soft);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
  .cm-fb-track{background:#f1f5f9;border-radius:6px;height:18px;overflow:hidden;}
  .cm-fb-bar{display:block;height:100%;border-radius:6px;}
  .cm-fb-bar.locked{filter:blur(3px);opacity:.75;}
  .cm-fb-val{font-size:.78rem;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;}
  .cm-fb-val.locked{color:var(--ink-soft);font-weight:600;}

  /* Line item breakdown + paywall lock */
  .breakdown{margin-top:16px;}
  .breakdown table{width:100%;border-collapse:collapse;font-size:.87rem;}
  .breakdown th{text-align:left;color:var(--ink-soft);font-weight:600;font-size:.72rem;text-transform:uppercase;letter-spacing:.04em;padding:8px 6px;border-bottom:1px solid var(--line);}
  .breakdown td{padding:9px 6px;border-bottom:1px solid #f1f5f9;}
  .breakdown td.num{font-family:'IBM Plex Mono',monospace;text-align:right;font-weight:600;}
  .breakdown tr.total td{font-weight:800;border-top:2px solid var(--ink);border-bottom:none;}

  .lock-wrap{position:relative;}
  /* The whole-table blur is gone: renderTable() now blurs individual rows
     (.cm-row-locked) so the first line items stay readable. */
  /* Previously an absolutely-positioned scrim covering the whole card, which
     washed out the revealed rows along with the locked ones and defeated the
     point of revealing them. Now it sits in normal flow beneath the table. */
  .lock-overlay{
    display:none;position:static;background:none;
    align-items:center;justify-content:center;padding:14px 0 2px;
  }
  .lock-wrap.locked .lock-overlay{display:flex;}
  .lock-card{
    text-align:center;background:#fff;border:1px solid var(--line);border-radius:12px;
    padding:16px 20px;box-shadow:var(--shadow);max-width:360px;width:100%;
  }
  .lock-card .lock-icon{font-size:1.3rem;margin-bottom:6px;}
  .lock-card p{font-size:.82rem;color:var(--ink-soft);margin:4px 0 12px;}

  .watermark{
    position:absolute;top:8px;right:10px;font-size:.62rem;font-weight:700;letter-spacing:.06em;
    color:#cbd5e1;text-transform:uppercase;border:1px solid #e2e8f0;padding:3px 8px;border-radius:6px;
  }

  .export-row{display:flex;gap:10px;flex-wrap:wrap;margin-top:20px;align-items:center;justify-content:flex-end;}
  @media(min-width:920px){.export-row{flex-wrap:nowrap;}}
  @media(max-width:919px){.export-row{justify-content:flex-start;}}
  .export-brand-hint{margin:8px 0 0;font-size:.8rem;color:var(--ink-soft);text-align:right;}
  @media(max-width:919px){.export-brand-hint{text-align:left;}}
  .export-brand-hint a{color:var(--brand);font-weight:600;text-decoration:underline;text-underline-offset:2px;}

  .citation-box{
    margin-top:14px;font-size:.78rem;color:var(--ink-soft);background:var(--gold-soft);
    border:1px solid #fde68a;border-radius:10px;padding:10px 12px;
  }
  .citation-box strong{color:#92400e;}

  /* Pricing */
  .pricing-section{padding:50px 0;background:#fff;border-top:1px solid var(--line);border-bottom:1px solid var(--line);}
  .pricing-head{text-align:center;max-width:640px;margin:0 auto 32px;}
  .pricing-head h2{font-size:1.6rem;margin:0 0 10px;}
  .pricing-head p{color:var(--ink-soft);margin:0;}
  .compare-table-wrap{overflow-x:auto;}
  table.compare{width:100%;border-collapse:collapse;min-width:640px;}
  table.compare th, table.compare td{padding:14px 16px;border-bottom:1px solid var(--line);font-size:.88rem;}
  table.compare th{text-align:left;font-size:.72rem;text-transform:uppercase;letter-spacing:.05em;color:var(--ink-soft);}
  table.compare th.plan{text-align:center;color:var(--ink);font-size:.95rem;}
  table.compare td.plan{text-align:center;}
  table.compare td.plan .yes{color:var(--accent);font-weight:700;}
  table.compare td.plan .no{color:#cbd5e1;}
  .plan-price{font-size:1.3rem;font-weight:800;font-family:'IBM Plex Mono',monospace;}

  .pricing-footnote{text-align:center;font-size:.82rem;color:var(--ink-soft);max-width:560px;margin:18px auto 0;font-style:italic;}
  .pricing-cta{display:flex;gap:14px;justify-content:center;margin-top:28px;flex-wrap:wrap;}

  /* FAQ */
  .faq-section{padding:50px 20px;}
  .faq-section h2{font-size:1.5rem;margin:0 0 24px;text-align:center;}
  details.faq-item{border-bottom:1px solid var(--line);padding:16px 0;}
  details.faq-item summary{cursor:pointer;font-weight:700;font-size:.95rem;list-style:none;display:flex;justify-content:space-between;gap:12px;}
  details.faq-item summary::-webkit-details-marker{display:none;}
  details.faq-item summary::after{content:'+';font-weight:400;color:var(--ink-soft);}
  details.faq-item[open] summary::after{content:'–';}
  details.faq-item p{color:var(--ink-soft);margin:10px 0 0;font-size:.9rem;}

  footer.site{padding:36px 0;color:var(--ink-soft);font-size:.8rem;border-top:1px solid var(--line);}
  footer.site .foot-row{display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:14px;}
  footer.site .disclaimer{max-width:900px;line-height:1.6;}

  /* Modal */
  /* align-items:flex-start, NOT center. A flex child centred in a container it
     is taller than overflows both ends, and the part above the container can
     never be scrolled to - scrolling only reaches what is below the scroll
     origin. Starting at the top and letting `margin:auto` on .modal do the
     centring keeps it centred whenever it fits and reachable when it does not.
     overscroll-behavior:contain stops a flick at the end of the modal from
     scrolling the page behind it. */
  .modal-backdrop{
    display:none;position:fixed;inset:0;background:rgba(15,23,42,.55);
    align-items:flex-start;justify-content:center;z-index:100;padding:20px;
    overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  }
  .modal-backdrop.open{display:flex;}
  .modal{
    background:#fff;border-radius:16px;max-width:440px;width:100%;padding:26px;
    box-shadow:0 20px 60px rgba(0,0,0,.3);position:relative;
    /* Centres vertically while it fits, and yields to the top of the scroll
       area once it does not. Paired with .modal-backdrop's flex-start. */
    margin:auto;
  }
  .modal-close{position:absolute;top:14px;right:16px;border:none;background:none;font-size:1.2rem;cursor:pointer;color:var(--ink-soft);}
  .modal h3{margin:0 0 6px;font-size:1.2rem;}
  .modal p.sub{color:var(--ink-soft);font-size:.88rem;margin:0 0 18px;}
  .plan-option{
    border:1.5px solid var(--line);border-radius:12px;padding:14px 16px;margin-bottom:10px;cursor:pointer;
    display:flex;justify-content:space-between;align-items:center;transition:border-color .15s;
  }
  .plan-option:hover{border-color:var(--structure-soft);}
  .plan-option.selected{border-color:var(--brand);background:var(--brand-soft);}
  .plan-option .ptitle{font-weight:700;font-size:.92rem;}
  .plan-option .pdesc{font-size:.76rem;color:var(--ink-soft);}
  .plan-option .pprice{font-weight:800;font-family:'IBM Plex Mono',monospace;font-size:1.05rem;}
  .field-note{font-size:.74rem;color:var(--ink-soft);margin-top:10px;}
  .icon-badge{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:8px;background:var(--brand-soft);font-size:.95rem;line-height:1;margin-right:8px;vertical-align:-6px;}
  .logo-upload{border:1px dashed var(--line);border-radius:10px;padding:10px;font-size:.8rem;color:var(--ink-soft);margin-top:10px;}
  .print-brand-header{display:none;}
  .branding-panel{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow), var(--accent-edge);padding:16px 20px;margin:18px auto;max-width:1180px;}
  .branding-panel h3{margin:0 0 4px;font-size:1rem;}
  .branding-panel .bp-sub{font-size:.8rem;color:var(--ink-soft);margin:0 0 14px;}
  .branding-grid{display:grid;grid-template-columns:1fr 1fr;gap:20px;}
  @media (max-width:720px){.branding-grid{grid-template-columns:1fr;}}
  .branding-field label{display:block;font-size:.78rem;font-weight:600;color:var(--ink-soft);margin-bottom:6px;}
  .branding-field input[type="text"],
  .branding-field textarea{width:100%;border:1px solid var(--line);border-radius:8px;padding:8px 10px;font:inherit;font-size:.85rem;box-sizing:border-box;}
  .branding-field textarea{min-height:64px;resize:vertical;}
  .branding-field input[type="file"]{font-size:.8rem;}
  .brand-logo-preview{display:flex;align-items:center;gap:10px;margin-top:10px;}
  .brand-logo-preview img{max-height:52px;max-width:200px;border:1px solid var(--line);border-radius:6px;padding:4px;background:#fff;}
  .brand-skip-row{display:flex;gap:6px;align-items:flex-start;margin-top:10px;font-size:.78rem;color:var(--ink-soft);}
  .brand-skip-row input{margin-top:2px;}
  .brand-note{font-size:.74rem;color:var(--ink-soft);margin-top:12px;line-height:1.5;}
  .branding-or-divider{display:flex;align-items:center;gap:12px;margin-top:22px;}
  .branding-or-divider::before,
  .branding-or-divider::after{content:'';flex:1;height:1px;background:var(--line);}
  .branding-or-divider span{font-size:.72rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--brand-dark);background:var(--brand-soft);border:1px solid var(--line);border-radius:999px;padding:4px 12px;white-space:nowrap;}
  .branding-letterhead{margin-top:16px;padding-top:2px;}
  .branding-letterhead > label{display:block;font-size:.78rem;font-weight:600;color:var(--ink-soft);margin-bottom:6px;}
  .branding-letterhead-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
  .branding-letterhead-row select{border:1px solid var(--line);border-radius:8px;padding:6px 8px;font:inherit;font-size:.82rem;}
  .branding-letterhead .brand-logo-preview img{max-height:90px;}
  .branding-letterhead .field-note{max-width:none;}

  /* ---------- State Reference panel (statutory interest + ACV rule lookup) ---------- */
  .state-ref-panel{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);box-shadow:var(--shadow), var(--accent-edge);padding:16px 20px;margin:18px auto;max-width:1180px;}
  .state-ref-panel h3{margin:0 0 4px;font-size:1rem;}
  .state-ref-panel .bp-sub{font-size:.8rem;color:var(--ink-soft);margin:0 0 14px;}
  .state-ref-select-row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:14px;}
  .state-ref-select-row select{border:1px solid var(--line);border-radius:8px;padding:8px 10px;font:inherit;font-size:.9rem;min-width:220px;}
  .state-ref-status{font-size:.78rem;color:var(--ink-soft);}
  .state-ref-status.pending{color:var(--brand-dark);font-weight:600;}
  .state-ref-cards{display:grid;grid-template-columns:1fr 1fr;gap:16px;}
  @media (max-width:720px){.state-ref-cards{grid-template-columns:1fr;}}
  .state-ref-card{border:1px solid var(--line);border-radius:10px;padding:14px 16px;background:var(--bg);}
  .state-ref-card h4{margin:0 0 8px;font-size:.85rem;text-transform:uppercase;letter-spacing:.03em;color:var(--brand-dark);}
  .state-ref-card .srv-main{font-size:.95rem;font-weight:700;color:var(--ink);margin-bottom:4px;}
  .state-ref-card .srv-detail{font-size:.82rem;color:var(--ink-soft);line-height:1.5;margin-bottom:8px;}
  .state-ref-card .srv-citation{font-size:.76rem;color:var(--ink-soft);font-style:italic;margin-bottom:8px;}
  .state-ref-card .srv-note{font-size:.74rem;color:var(--brand-dark);background:var(--brand-soft);border-radius:6px;padding:6px 8px;margin-bottom:8px;line-height:1.4;}
  .state-ref-card .srv-lastchecked{font-size:.7rem;color:var(--ink-soft);margin-bottom:8px;}
  .state-ref-card .srv-lastchecked--unset{color:var(--ink-soft);font-style:italic;}
  .state-ref-card a.srv-link{font-size:.8rem;font-weight:600;color:var(--brand-dark);text-decoration:none;}
  .state-ref-card a.srv-link:hover{text-decoration:underline;}
  .state-ref-empty{font-size:.85rem;color:var(--ink-soft);padding:20px;text-align:center;border:1px dashed var(--line);border-radius:10px;}
  /* A notice, not an absence. .state-ref-empty is centred in a dashed box
     because it marks missing research; borrowing it for the jurisdiction note
     rendered a 561px centred placeholder inside a 1178px panel. See
     build/patch_jurisdiction_note.py. */
  .state-ref-jurisdiction{
    grid-column:1 / -1;margin:0 0 0.75rem;padding:12px 16px;
    font-size:.85rem;line-height:1.55;color:var(--ink);
    background:var(--brand-soft);border:1px solid var(--line);
    border-left:3px solid var(--brand-dark);border-radius:10px;
  }
  .state-ref-disclaimer{font-size:.74rem;color:var(--ink-soft);margin-top:14px;line-height:1.5;}
  .state-ref-jump{font-size:.78rem;color:var(--brand-dark);text-decoration:none;font-weight:600;}
  .state-ref-jump:hover{text-decoration:underline;}
  .srv-locked{font-size:.8rem;color:var(--ink-soft);background:var(--bg);border:1px dashed var(--line);border-radius:8px;padding:10px 12px;margin-bottom:4px;}
  .srv-locked button{margin-top:6px;background:none;border:none;color:var(--brand-dark);font-weight:700;font-size:.8rem;cursor:pointer;padding:0;text-decoration:underline;}
  .state-ref-quicktable-wrap{margin-top:22px;border-top:1px solid var(--line);padding-top:16px;}
  .state-ref-quicktable-wrap h4{margin:0 0 4px;font-size:.9rem;}
  .state-ref-quicktable-wrap .bp-sub{margin:0 0 12px;}
  .state-ref-quicktable{width:100%;border-collapse:collapse;font-size:.78rem;}
  .state-ref-quicktable th{text-align:left;padding:6px 8px;border-bottom:2px solid var(--line);color:var(--ink-soft);font-size:.72rem;text-transform:uppercase;letter-spacing:.02em;position:sticky;top:0;background:var(--card);}
  .state-ref-quicktable td{padding:6px 8px;border-bottom:1px solid var(--line);vertical-align:top;color:var(--ink);}
  .state-ref-quicktable tr:hover td{background:var(--bg);}
  .state-ref-quicktable-scroll{max-height:420px;overflow-y:auto;border:1px solid var(--line);border-radius:10px;}
  .state-ref-use-rate{display:block;width:100%;margin-top:-8px;font-size:.78rem;padding:8px 10px;}
  .state-ref-unlock-banner{grid-column:1 / -1;background:var(--brand-soft);border:1px solid var(--brand-dark);border-radius:10px;padding:12px 16px;font-size:.85rem;color:var(--ink);display:flex;align-items:center;gap:12px;flex-wrap:wrap;justify-content:space-between;}
  .state-ref-unlock-banner button{white-space:nowrap;}
  /* The prose has to be ONE element. Without this wrapper the banner's three
     bare text nodes each become an anonymous flex item, so space-between has
     four items to spread rather than two and the heading ends up 689px from
     the button it belongs to (measured at 900px). See
     build/patch_unlock_banner_layout.py. */
  .state-ref-unlock-banner .srub-text{flex:1 1 300px;margin:0;line-height:1.5;}
  .qt-pending{color:var(--ink-soft);font-style:italic;}
  .qt-pending-tag{color:var(--brand-dark);font-style:italic;font-weight:600;}
  /* Construction Site Injury calculator (calc5) */
  .ci-scope-note{font-size:.8rem;color:var(--ink-soft);background:var(--brand-soft);border-radius:8px;padding:10px 14px;margin-top:12px;line-height:1.55;}
  .ci-gate-card{border-left:3px solid var(--brand-dark);}
  .ci-employee-notice{border-left:3px solid var(--danger,#b91c1c);background:#fff8f7;}
  .ci-employee-notice h3{color:var(--danger,#b91c1c);}
  .ci-employee-notice p{font-size:.86rem;line-height:1.6;color:var(--ink-soft);}
  .ci-export-note{margin-top:10px;font-size:.74rem;}
  .ci-status-badge{display:inline-block;font-size:.7rem;font-weight:700;letter-spacing:.02em;text-transform:uppercase;padding:2px 8px;border-radius:999px;margin-left:8px;vertical-align:middle;}
  .ci-status-badge--pending{background:#fff3cd;color:#7a5b00;border:1px solid #ffe08a;}
  .ci-status-badge--not-yet{background:#eef0f2;color:#5a6472;border:1px solid #d8dce1;display:block;width:fit-content;margin:0 0 6px 0;}
  .ci-card-pending{border-left:3px solid #ffe08a;}
  .ci-card-empty{opacity:.85;}
  .ci-pending-note{font-style:italic;}
  .pw-error{color:var(--danger,#b91c1c);font-size:.8rem;margin:8px 0 0;display:none;}
  .pw-divider{display:flex;align-items:center;gap:10px;margin:20px 0 12px;color:var(--ink-soft);font-size:.78rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;}
  .pw-divider::before,
  .pw-divider::after{content:"";flex:1;height:1px;background:var(--line);}
  .pw-restore-row{display:flex;gap:8px;}
  .pw-restore-row .ec-email-input{flex:1;}
  .pw-manage-link{
    display:block;width:100%;text-align:center;background:none;border:none;cursor:pointer;
    font:inherit;font-size:.82rem;color:var(--ink-soft);text-decoration:underline;
    margin-top:14px;padding:0;
  }
  .pw-manage-link:hover{color:var(--brand-dark);}
  /* ---------- Report mockup preview (paywall), static illustration, no real
     customer data, so there's nothing here worth screenshotting-to-steal ---------- */
  .report-mockup{border:1px solid var(--line);border-radius:10px;overflow:hidden;margin:14px 0;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.06);}
  .report-mockup-tabs{display:flex;gap:2px;background:var(--ink,#1c1917);padding:4px 4px 0;overflow-x:auto;}
  .report-mockup-tabs span{font-size:.62rem;color:#fff;background:rgba(255,255,255,.12);padding:4px 8px;border-radius:4px 4px 0 0;white-space:nowrap;font-weight:600;}
  .report-mockup-tabs span.active{background:#fff;color:var(--ink,#1c1917);}
  .report-mockup-body{padding:14px 16px;}
  .report-mockup-title{font-size:.85rem;font-weight:800;color:var(--ink,#1c1917);}
  .report-mockup-sub{font-size:.68rem;font-weight:700;color:var(--brand-dark,#92400e);margin-top:2px;}
  .report-mockup-trust{font-size:.62rem;color:var(--ink-soft);margin-top:4px;font-style:italic;}
  .report-mockup-grid{display:grid;grid-template-columns:1fr auto;gap:4px 10px;margin-top:10px;font-size:.68rem;}
  .report-mockup-grid .rmlabel{color:var(--ink-soft);}
  .report-mockup-grid .rmval{color:#2563eb;font-weight:700;text-align:right;}
  .report-mockup-key{margin-top:12px;padding-top:10px;border-top:1px dashed var(--line);}
  .report-mockup-key .rmklabel{font-size:.62rem;color:var(--ink-soft);text-transform:uppercase;letter-spacing:.04em;}
  .report-mockup-key .rmkval{font-size:1.3rem;font-weight:800;color:var(--brand-dark,#92400e);}
  .sample-link{display:block;width:100%;text-align:center;margin-top:8px;}
  .cm-import-more-btn{
    background:none;border:none;padding:0;margin-left:4px;cursor:pointer;
    color:var(--brand);font:inherit;font-weight:600;text-decoration:underline;
  }
  .cm-import-detail{margin-top:6px !important;}
  /* .btn sets white-space:nowrap, which is right for short inline buttons but
     makes these full-width ones overflow the viewport on a 320px phone: the
     box is 100% wide but its unwrappable text is not. Block-level buttons can
     wrap safely, since nothing sits beside them. */
  .sample-link .btn-block{white-space:normal;}

  /* Footer legal links + Legal Documentation modal */
  footer.site .foot-links{display:flex;gap:18px;flex-wrap:wrap;margin-bottom:14px;}
  footer.site .foot-links button{
    background:none;border:none;padding:0;font:inherit;font-size:.8rem;color:var(--ink-soft);
    cursor:pointer;text-decoration:underline;text-underline-offset:2px;
  }
  footer.site .foot-links button:hover{color:var(--brand);}
  .also-from{
    margin-top:20px;padding-top:18px;border-top:1px solid var(--line);
    display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  }
  .also-from-label{
    font-size:.68rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-soft);
    white-space:nowrap;
  }
  .also-from a{
    display:inline-flex;align-items:baseline;gap:6px;text-decoration:none;
  }
  .also-from .afw-name{
    font-weight:700;color:var(--brand-dark);font-size:.85rem;
    border-bottom:1px solid transparent;transition:border-color .15s;
  }
  .also-from a:hover .afw-name{border-color:var(--brand-dark);}
  .also-from .afw-desc{color:var(--ink-soft);font-size:.8rem;}
  .also-from .afw-arrow{
    color:var(--brand);font-size:.85rem;transition:transform .15s;display:inline-block;
  }
  .also-from a:hover .afw-arrow{transform:translateX(3px);}

  /* Email capture (address-for-download gate) */
  .email-capture-trigger{
    display:flex;align-items:center;gap:6px;background:none;border:none;cursor:pointer;
    font:inherit;font-size:.82rem;font-weight:600;color:var(--brand-dark);
    padding:0 0 14px;margin:-4px 0 0;
  }
  .email-capture-trigger:hover{text-decoration:underline;}
  .ec-field-label{display:block;font-size:.82rem;font-weight:600;margin-bottom:6px;color:var(--ink);}
  .ec-email-input{
    width:100%;padding:10px 12px;border:1.5px solid var(--line);border-radius:8px;
    font:inherit;font-size:.9rem;box-sizing:border-box;
  }
  .ec-email-input:focus{outline:2px solid var(--brand);outline-offset:1px;}
  .ec-consent-row{
    display:flex;gap:8px;align-items:flex-start;font-size:.78rem;color:var(--ink-soft);
    margin:14px 0 16px;line-height:1.5;
  }
  .ec-consent-row input{margin-top:3px;flex-shrink:0;}
  .ec-success{color:var(--brand-dark);font-weight:600;font-size:.88rem;margin-top:10px;display:none;}
  .modal.legal-modal{max-width:640px;max-height:82vh;display:flex;flex-direction:column;padding:26px 0 0;}
  .legal-modal .legal-head{padding:0 26px;}
  .legal-tabs{display:flex;gap:6px;padding:14px 26px 0;border-bottom:1px solid var(--line);flex-wrap:wrap;}
  .legal-tabs button{
    background:none;border:none;border-bottom:2px solid transparent;padding:8px 4px;margin-right:14px;
    font:inherit;font-size:.85rem;font-weight:600;color:var(--ink-soft);cursor:pointer;
  }
  .legal-tabs button.active{color:var(--brand);border-bottom-color:var(--brand);}
  .legal-body{overflow-y:auto;padding:20px 26px 26px;font-size:.86rem;line-height:1.65;color:var(--ink);}
  .legal-panel{display:none;}
  .legal-panel.active{display:block;}
  .legal-panel h4{font-size:.95rem;margin:20px 0 6px;}
  .legal-panel h4:first-child{margin-top:0;}
  .legal-panel p{margin:0 0 12px;}
  .legal-panel ul{margin:0 0 12px;padding-left:20px;}
  .legal-panel li{margin-bottom:6px;}
  .legal-updated{color:var(--ink-soft);font-size:.78rem;margin-bottom:16px !important;}
  .contact-email-line{font-weight:700;font-size:1rem;margin:6px 0 16px !important;}

  /* Ad slots (Google AdSense). No units on this page by design; these rules
     are kept so the per-state content pages can reuse the same markup. */
  .ad-slot{
    max-width:1180px;margin:28px auto;padding:0 20px;
  }
  .ad-slot-inner{
    border:1px dashed #cbd5e1;border-radius:10px;background:#f1f5f9;
    min-height:100px;display:flex;flex-direction:column;align-items:center;justify-content:center;
    padding:10px;overflow:hidden;
  }
  .ad-label{
    font-size:.62rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
    color:var(--ink-soft);margin-bottom:6px;
  }
  .ad-slot.ad-slot-tab{margin:28px 0 0;padding:0;}
  .ad-slot.ad-slot-banner .ad-slot-inner{min-height:90px;max-height:120px;}


  /* ---- Collapsed reference panels (Report Branding, State Reference) ----
     These moved below the calculator so the tool itself is the first thing a
     visitor reaches. Closed by default; cmJumpToStateRef() force-opens the
     State Reference one when a calculator links into it. */
  details.cm-collapse{
    background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
    box-shadow:var(--shadow);margin:18px auto;max-width:1180px;padding:0;
  }
  details.cm-collapse > summary{
    cursor:pointer;list-style:none;display:flex;align-items:center;gap:8px;
    /* A flex row that cannot wrap: the checklist's OPTIONAL pill sat
       past the right edge at 360px. */
    flex-wrap:wrap;
    padding:14px 20px;font-weight:700;font-size:.95rem;color:var(--ink);
  }
  details.cm-collapse > summary::-webkit-details-marker{display:none;}
  details.cm-collapse > summary::after{
    content:'+';margin-left:auto;font-weight:400;font-size:1.15rem;color:var(--ink-soft);
  }
  details.cm-collapse[open] > summary::after{content:'\2013';}
  details.cm-collapse[open] > summary{border-bottom:1px solid var(--line);}
  details.cm-collapse > summary:hover{background:var(--brand-soft);}
  .cm-collapse-hint{
    font-size:.68rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
    color:var(--brand);background:var(--brand-soft);border-radius:999px;padding:3px 9px;
  }
  .cm-collapse-body{padding:4px 0 6px;}
  .cm-collapse-body .branding-panel,
  .cm-collapse-body .state-ref-panel{
    border:none;box-shadow:none;margin:0;max-width:none;padding:8px 20px 16px;
  }
  .cm-collapse-body .branding-panel > h3,
  .cm-collapse-body .state-ref-panel > h3{display:none;}

  /* ---- Paywall: partial reveal instead of a full blur ----
     Blurring 100% of the breakdown reads as "nothing here". Showing the first
     line items with real numbers, then blurring the rest, shows what is being
     bought. renderTable() applies .cm-row-locked. */
  .lock-wrap.locked .breakdown tr.cm-row-locked td{
    filter:blur(5px);user-select:none;pointer-events:none;
  }
  .lock-wrap.locked .citation-box{filter:blur(4px);user-select:none;pointer-events:none;}
  .breakdown tr.cm-more-row td{
    font-size:.78rem;font-weight:600;color:var(--brand);
    background:var(--brand-soft);text-align:center;padding:8px 6px;
  }
  .lock-card .lock-anchor{
    font-size:.82rem;color:var(--ink);background:var(--brand-soft);
    border-radius:8px;padding:8px 10px;margin:0 0 10px;
  }
  .lock-card .lock-anchor strong{color:var(--brand-dark);}
  /* The flagged-state opt-in. Deliberately quiet: it raises the ACV figure, so
     it should read as a considered choice after reading the notice, not as a
     switch to flip for a bigger number. */
  .cm-ld-conflict{border-left:3px solid #d6d3d1;padding-left:10px;}
  .cm-ld-sides{display:block;margin:6px 0 0;}
  .cm-ld-side{display:block;margin:3px 0;padding-left:14px;text-indent:-14px;}
  .cm-ld-side::before{content:"\2022  ";}
  .cm-ld-why{display:block;margin-top:6px;font-style:italic;}
  .cm-optin{
    display:flex;align-items:flex-start;gap:8px;margin-top:8px;
    font-size:.8rem;line-height:1.45;color:#57534e;cursor:pointer;
  }
  .cm-optin input{margin-top:3px;flex:0 0 auto;}
  /* Shown only to a single-report customer, on a calculator they did not buy.
     Green rather than amber: this is reassurance, not a pitch. */
  .lock-card .lock-owned{
    font-size:.82rem;color:#14532d;background:#dcfce7;border:1px solid #86efac;
    border-radius:8px;padding:8px 10px;margin:0 0 10px;text-align:left;
  }
  .lock-card .lock-owned strong{color:#14532d;}

  /* ---- Post-calculation sticky CTA ----
     Hidden until the visitor actually edits an input, so a first-time reader
     is never greeted by it, and never shown to a paid visitor. */
  .cm-sticky-cta{
    position:fixed;left:0;right:0;bottom:0;z-index:85;display:none;
    background:var(--ink);border-top:2px solid var(--brand);
    box-shadow:0 -8px 24px rgba(0,0,0,.18);
  }
  .cm-sticky-cta.show{display:block;}
  .cm-sticky-inner{
    max-width:1180px;margin:0 auto;padding:11px 20px;
    display:flex;align-items:center;gap:16px;flex-wrap:wrap;
  }
  .cm-sticky-label{font-size:.78rem;color:#d6d3d1;flex:0 0 auto;}
  .cm-sticky-total{
    font-family:'IBM Plex Mono',monospace;font-weight:700;font-size:1.05rem;color:#fff;
  }
  .cm-sticky-spacer{flex:1 1 auto;}
  .cm-sticky-cta .btn-ghost{background:transparent;color:#f5f5f4;border:1px solid rgba(255,255,255,.35);}
  .cm-sticky-cta .btn-ghost:hover{background:rgba(255,255,255,.08);}
  .cm-sticky-dismiss{
    background:transparent;border:none;color:#a8a29e;font-size:1.1rem;cursor:pointer;
    padding:0 2px;line-height:1;
  }
  .cm-sticky-dismiss:hover{color:#fff;}
  body.cm-sticky-open{padding-bottom:64px;}
  body.cm-sticky-open .ai-chat-launcher{bottom:78px;}
  body.cm-sticky-open .ai-chat-panel{bottom:146px;}
  @media (max-width:640px){
    .cm-sticky-label{display:none;}
    .cm-sticky-inner{gap:10px;padding:9px 14px;}
  }


  /* Small-screen overflow fix (pre-existing, not related to the layout pass).
     The Smart Import trigger is a .btn, and .btn sets white-space:nowrap, so
     its long label ("Import from a file (.xlsx .csv .pdf, ...)") measured
     414px wide and forced the whole document to ~431px on a 390px phone,
     giving every page a small horizontal scroll. Let it wrap below 520px. */
  @media (max-width:520px){
    .cm-import-row{flex-wrap:wrap;}
    .cm-import-row label.btn{white-space:normal;text-align:left;min-width:0;width:100%;}
    /* Same class of problem: the "OR, use a full letterhead template instead"
       divider label is nowrap and measured 497px. */
    .branding-or-divider span{white-space:normal;text-align:center;}
    /* .nav-row is a nowrap flex row (brand + 5 calculator tabs + the header
       CTA); on a phone that measured 422px against a 390px viewport. Let the
       row wrap and let the tab strip scroll horizontally on its own. */
    .nav-row{flex-wrap:wrap;gap:10px;}
    .nav-row > .btn{order:2;}
    .nav-stack{flex:1 1 100%;align-items:stretch;}
    .res-nav{justify-content:flex-start;}
    .brand{flex:1 1 auto;min-width:0;}
    /* Narrowest phones (320px): the fixed-width paywall card and the
       nowrap field hints were the last two things wider than the screen. */
    .lock-card{max-width:100%;}
    .field label .hint{white-space:normal;}
  }

  .cookie-banner{position:fixed;left:0;right:0;bottom:0;z-index:80;background:var(--ink);border-top:1px solid rgba(255,255,255,.1);box-shadow:0 -8px 24px rgba(0,0,0,.15);}
  .cookie-banner-inner{max-width:1180px;margin:0 auto;padding:14px 20px;display:flex;align-items:center;gap:20px;flex-wrap:wrap;}
  .cookie-banner-inner p{margin:0;flex:1 1 420px;font-size:.82rem;line-height:1.5;color:#f5f5f4;}
  .cookie-banner-inner p a{color:#fde68a;}
  .cookie-banner-actions{display:flex;gap:10px;flex-wrap:wrap;}
  .cookie-banner .btn-ghost{background:transparent;color:#f5f5f4;border:1px solid rgba(255,255,255,.35);}
  .cookie-banner .btn-ghost:hover{background:rgba(255,255,255,.08);}

  .ai-chat-launcher{
    position:fixed;right:20px;bottom:20px;z-index:90;width:56px;height:56px;border-radius:50%;
    background:var(--brand);color:#fff;border:none;box-shadow:0 10px 24px -6px rgba(28,25,23,.35);
    cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:1.5rem;
    transition:transform .15s ease;
  }
  .ai-chat-launcher:hover{transform:scale(1.06);}
  .ai-chat-panel{
    position:fixed;right:20px;bottom:88px;z-index:90;width:340px;max-width:calc(100vw - 32px);
    max-height:min(520px, calc(100vh - 120px));display:none;flex-direction:column;
    background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
    box-shadow:var(--shadow);overflow:hidden;
  }
  .ai-chat-panel.open{display:flex;}
  .ai-chat-header{
    background:var(--brand);color:#fff;padding:12px 14px;display:flex;align-items:center;
    justify-content:space-between;gap:10px;
  }
  .ai-chat-header strong{font-size:.92rem;}
  .ai-chat-header span{display:block;font-size:.7rem;opacity:.85;font-weight:400;}
  .ai-chat-close{background:transparent;border:none;color:#fff;font-size:1.1rem;cursor:pointer;line-height:1;padding:4px;}
  .ai-chat-disclaimer{
    font-size:.68rem;line-height:1.4;color:var(--ink-soft);background:var(--gold-soft);
    padding:8px 12px;border-bottom:1px solid var(--line);
  }
  .ai-chat-messages{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:10px;min-height:180px;}
  .ai-chat-msg{max-width:88%;padding:8px 11px;border-radius:12px;font-size:.84rem;line-height:1.45;white-space:pre-wrap;}
  .ai-chat-msg.user{align-self:flex-end;background:var(--brand);color:#fff;border-bottom-right-radius:3px;}
  .ai-chat-msg.assistant{align-self:flex-start;background:var(--bg);border:1px solid var(--line);color:var(--ink);border-bottom-left-radius:3px;}
  .ai-chat-msg.assistant.error{border-color:var(--danger);color:var(--danger);}
  .ai-chat-typing{align-self:flex-start;font-size:.78rem;color:var(--ink-soft);padding:2px 4px;}
  .ai-chat-input-row{display:flex;gap:8px;padding:10px;border-top:1px solid var(--line);}
  .ai-chat-input-row textarea{
    flex:1;resize:none;border:1px solid var(--line);border-radius:8px;padding:8px 10px;
    font:inherit;font-size:.84rem;max-height:80px;
  }
  .ai-chat-input-row button{
    background:var(--brand);color:#fff;border:none;border-radius:8px;padding:0 14px;
    font-weight:600;cursor:pointer;font-size:.84rem;
  }
  .ai-chat-input-row button:disabled{opacity:.5;cursor:default;}
  @media print{ .ai-chat-launcher .ai-chat-panel{display:none !important;} }

  .print-locked-note{display:none;}
  .print-letterhead-bg{display:none;}
  @media print{
    header.site, .pricing-section, .faq-section, footer.site,
    /* The export card is screen furniture, but the checklist now lives inside
       it and does print, so it is pulled out of the hidden block rather than
       disappearing with its container. */
    .cm-export-card > .cm-export-title, .cm-export-card .cm-tier-label,
    .cm-export-card .cm-tier-detail, .cm-export-card .cm-tier-actions,
    .cm-export-card .cm-brand-row, .cm-export-card .cm-check-summary,
    .lock-overlay, .export-row, nav.calc-nav, .hero-cta-row,
    .demo-badge, .info-panel, .info-btn, .ad-slot, .modal-backdrop,
    .branding-panel, .state-ref-panel, .cookie-banner,
    details.cm-collapse .cm-sticky-cta{display:none !important;}
    /* ...but the supporting-documents checklist is part of the deliverable, so
       it prints. Without this it was hidden twice over: by the blanket rule
       above, and by being a closed <details> (a collapsed details renders no
       content at all, which is why cmOpenChecklistForPrint below forces it
       open on beforeprint and restores the visitor's state afterwards). */
    details#checklistDetails{
      display:block !important;break-inside:avoid;page-break-inside:avoid;
      border:none;box-shadow:none;border-radius:0;margin:22px 0 0;padding:14px 0 0;
      border-top:1px solid #d6d3d1;
    }
    details#checklistDetails > summary{
      list-style:none;padding:0 0 4px;font-size:1rem;font-weight:700;color:#1c1917;
    }
    details#checklistDetails > summary::after{content:'' !important;}
    details#checklistDetails > summary .pill{display:none !important;}
    details#checklistDetails .cm-collapse-body{padding:0;}
    /* Native checkboxes print inconsistently across browsers, so swap them for
       glyphs driven by the .done class rather than :checked/:has(). */
    .cm-cl-row input[type=checkbox]{display:none !important;}
    .cm-cl-row::before{
      content:'\2610';font-size:1rem;line-height:1;color:#92400e;margin-right:8px;
    }
    .cm-cl-row.done::before{content:'\2611';}
    .cm-cl-row{border-bottom:1px solid #ececec;padding:4px 0;font-size:.86rem;}
    .cm-cl-group h4{color:#92400e;margin-top:10px;}
    /* Interactive-only affordances have no meaning on paper. */
    .cm-cl-add, .cm-cl-del, .cm-cl-count,
    .cm-cl-screen-note{display:none !important;}
    /* Screen copy explains a browser feature; print copy addresses the reader
       of the document. */
    .cm-cl-print-note{display:block !important;font-size:.82rem;font-style:italic;
      color:#57534e;margin:0 0 10px;}
    details#checklistDetails > summary span[aria-hidden]{display:none !important;}
    .print-brand-header{display:flex !important;align-items:center;gap:12px;margin-bottom:16px;}
    .print-brand-header img{max-height:54px;max-width:220px;}
    .print-brand-header span{font-weight:700;font-size:1.1rem;color:#1c1917;}
    /* Full-page letterhead background; position:fixed repeats it on every printed page in
       Chrome/Chromium print rendering. Sits behind all content (negative z-index). */
    .print-letterhead-bg{display:block;position:fixed;top:0;left:0;width:100%;height:100%;object-fit:cover;z-index:-1;}
    /* Paid-only content stays hidden when printing too; printing must not
       be a way to bypass the paywall (the on-screen blur previously reset
       to none for print, which meant Ctrl+P revealed the full, unpaid
       breakdown in clear text). */
    .lock-wrap.locked .breakdown{display:none !important;}
    .lock-wrap.locked .print-locked-note{
      display:block !important;font-size:.85rem;font-style:italic;color:#57534e;
      border:1px solid #d6d3d1;border-radius:8px;padding:12px 14px;margin:10px 0;
    }
    body{background:#fff;}
  }

/* ==========================================================================
   Added by the calculator split.
   ========================================================================== */

/* ---- header nav: <a> instead of <button> -------------------------------
   The calculators moved off "/" so the header's calculator strip had to stop
   being <button data-tab> and become <a href>. app.css only ever styled
   `nav.tabs-top button`, so the anchors fell through to the global link rule
   and rendered as underlined orange text.

   These declarations are copied VERBATIM from state-rules/assets/state-pages.css,
   which already solved this for the sub-pages -- including the line-height pin
   below, which exists because an <a> and a <button> with the same padding
   produce control boxes 7px apart and a header 10px deeper.

   This is now a THIRD copy of the header rules. It is deliberate and temporary:
   the point of the /assets/header.css extraction is to delete all three and
   leave one. Do not add a fourth. */
  .nav-spacer{flex:1 1 auto;}
  nav.calc-nav{display:flex;gap:4px;flex-wrap:wrap;justify-content:flex-end;max-width:100%;}
  nav.calc-nav a{border:none;background:transparent;color:var(--ink-soft);
    font-size:.85rem;font-weight:600;padding:8px 12px;border-radius:8px;
    text-decoration:none;white-space:nowrap;}
  nav.calc-nav a:hover{background:var(--brand-soft);color:var(--brand);}
  nav.calc-nav a[aria-current="page"]{background:var(--brand-soft);color:var(--brand);}
  header.site .res-nav a,
  header.site nav.calc-nav a,
  header.site .btn{line-height:1.15;display:inline-flex;align-items:center;}
  @media(max-width:870px){
    nav.calc-nav{flex-wrap:nowrap;overflow-x:auto;justify-content:flex-start;
      -webkit-overflow-scrolling:touch;scrollbar-width:none;padding-bottom:2px;}
    nav.calc-nav::-webkit-scrollbar{display:none;}
    nav.calc-nav a{flex:0 0 auto;}
    header.site .brand{flex:1 1 100%;}
    header.site .nav-spacer{display:none;}
  }
  @media print{nav.calc-nav{display:none !important;}}

/* ---- page furniture ----------------------------------------------------
   .calc-section carries `padding:18px 20px 28px` on top of .wrap's own 20px,
   so calculator content sits 40px in from the viewport edge. Everything added
   above and below it matches that inset, or the h1 does not line up with the
   calculator heading directly beneath it.

   NOTE: do not put a max-width on an element that also carries .wrap. .wrap is
   `margin:0 auto`, so a narrower max-width on the same element re-centres the
   block instead of narrowing it in place -- which is what indented the intro
   copy on the first build. */
  .crumbs{font-size:13px;color:var(--ink-soft);padding:18px 20px 0;}
  .crumbs a{color:var(--ink-soft);text-decoration:none;}
  .crumbs a:hover{color:var(--brand-dark);text-decoration:underline;}
  .crumb-sep{opacity:.5;margin:0 2px;}
  @media print{.crumbs{display:none !important;}}

  .page-intro{padding:22px 20px 10px;}
  .page-intro > *:first-child{margin-top:0;}
  .page-intro p{font-size:16px;line-height:1.7;}
  .page-intro ul{line-height:1.7;}
  .page-intro h1{margin-bottom:14px;}
  .tool-support{display:flex;flex-wrap:wrap;gap:10px;margin:18px 0 4px;}


/* ---- width caps carried over from the single-page layout ----------------
   On "/" the calculator sat inside a page that also held four other tabs, a
   pricing table and the 50-state panel, so .calc-head p was capped at 720px
   and .method-note at 820px-and-centred to keep line length readable against
   all that. On a dedicated page there is nothing else competing for the
   column, and the capped copy stops short of the calculator containers
   directly beneath it. Both now run the full content width.

   These two OVERRIDE rules that exist in the source stylesheet, which is why
   they are declared in css_changes.py -- check_css_drift.py fails the build on
   any change to app.css that is not declared there. */
  .calc-head p{max-width:none;}
  .method-note{max-width:none;margin:34px 0 0;}


/* ---- comparison table plan headers -------------------------------------
   The header cell stacks the amount over the billing term. Written as two
   block spans rather than one string, because "$19 one-time" rendered as
   "$19 ONCEONE CALCULATOR" the first time it was tried with unstyled inline
   spans. check_css_drift.py now fails the build if these are missing. */
  table.compare th.plan .plan-name{display:block;font-size:.7rem;font-weight:700;
    letter-spacing:.04em;color:var(--ink);text-transform:none;margin-bottom:3px;}
  table.compare th.plan .plan-amt{display:block;font-size:1.15rem;line-height:1.2;
    color:var(--ink);letter-spacing:-.01em;}
  table.compare th.plan .plan-per{display:block;margin-top:2px;font-size:.68rem;
    font-weight:600;letter-spacing:.04em;color:var(--ink-soft);text-transform:none;}

/* ---- "/mo" suffix on the paywall price ---------------------------------- */
  .pper{font-size:.58em;font-weight:600;opacity:.75;margin-left:1px;}

/* ---- pricing explainer -------------------------------------------------- */
  .pricing-explainer{max-width:760px;margin:0 auto 26px;padding:18px 20px;
    border:1px solid var(--line);border-radius:12px;background:#fff;}
  .pricing-explainer h3{margin:0 0 10px;font-size:16px;}
  .pricing-explainer p{margin:0 0 10px;font-size:14.5px;line-height:1.65;color:var(--ink-soft);}
  .pricing-explainer p:last-child{margin-bottom:0;}

/* ---- calculator cards --------------------------------------------------- */
  .cards-section{padding:6px 20px 18px;}
  .calc-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:16px;margin:14px 0 8px;}
  .calc-card{display:flex;flex-direction:column;gap:10px;padding:22px;border:1px solid var(--line);
    border-radius:14px;background:#fff;text-decoration:none;color:inherit;
    transition:box-shadow .15s,border-color .15s;}
  .calc-card:hover{border-color:var(--structure);box-shadow:0 6px 22px rgba(15,42,70,.09);}
  .calc-card h3{margin:0;font-size:17px;line-height:1.3;color:var(--ink);}
  .calc-card p{margin:0;font-size:14px;line-height:1.55;color:var(--ink-soft);flex:1;}
  .calc-card .card-cta{font-weight:600;font-size:14px;color:var(--brand-dark);}
  .calc-card .card-cta::after{content:" \2192";}

/* ---- content width caps ------------------------------------------------
   Several blocks were capped narrower than .wrap (1180px) and centred, which
   on the pricing page pushed the comparison table below the fold: a 640px
   heading, a 760px explainer and a 560px footnote stacked up to a screenful of
   whitespace before the first price. Body content now runs the full column. */
  .pricing-head{max-width:none;margin:0 auto 22px;}
  .pricing-explainer{max-width:none;}
  .pricing-footnote{max-width:none;}
  .calc-head p{max-width:none;}
  footer.site .disclaimer{max-width:none;}


/* The header is position:sticky at every width. On a phone that is not a
   convenience, it is a tax: measured 8 Sep 2026, the header is 192px on a
   390px iPhone (23% of the screen) and 225px on a 360px Android (28%) -
   brand row, two nav rows and the CTA, pinned there for the whole visit.
   It costs twice over, because AdSense viewability is measured on what is
   actually on screen. Sticky earns its place on desktop, where the same
   header is 92px and 10% of the viewport; below the breakpoint where the nav
   stacks, it does not. The CTA also sits in the page body and at the end of
   every calculator, so nothing becomes unreachable. */
@media (max-width:520px){
  header.site{position:static;}
}




  /* Invoice details on the paywall. Collapsed by default: a $19 purchase is not
     gated behind fields most buyers do not need, but the ones who expense this
     must not have to email and ask for an invoice afterwards. */
  details.pw-invoice{border:1px solid var(--line);border-radius:8px;margin-top:14px;
    background:var(--bg);}
  details.pw-invoice > summary{cursor:pointer;list-style:none;padding:10px 14px;
    font-size:.85rem;font-weight:700;color:var(--ink);display:flex;
    align-items:center;gap:8px;}
  details.pw-invoice > summary::-webkit-details-marker{display:none;}
  details.pw-invoice > summary::after{content:'+';margin-left:auto;font-weight:400;
    font-size:1.05rem;color:var(--ink-soft);}
  details.pw-invoice[open] > summary::after{content:'\2013';}
  details.pw-invoice > summary:hover{color:var(--brand);}
  details.pw-invoice > *:not(summary){padding:0 14px;}
  details.pw-invoice > *:last-child{padding-bottom:14px;}
  .pw-invoice-note{font-size:.76rem;color:var(--ink-soft);margin:0 0 10px;line-height:1.5;}
  /* The site's .field label is a flex row (label text on the left, an optional
     hint on the right), and a <br> inside a flex container does nothing. These
     labels carry a deliberate line break, so they are plain blocks. */
  details.pw-invoice .field label{display:block;}
  /* Bottom-align the pair. Without this the input under a one-line label sits
     higher than the input under a two-line label, which is visible as soon as
     the two labels differ in height at any width. Pushing each input down with
     margin-top:auto puts them on the same plane no matter how the labels wrap. */
  details.pw-invoice .field-row{align-items:stretch;}
  details.pw-invoice .field-row > .field{display:flex;flex-direction:column;margin-bottom:0;}
  details.pw-invoice .field-row > .field > input{margin-top:auto;}

  /* The report mockup is decorative (aria-hidden) and the tallest block in the
     paywall. On a short viewport it is the difference between the price and the
     checkout button being visible together or the buyer scrolling to find the
     button at all. Measured: it is worth ~250px. */
  @media (max-height:940px){
    #paywallModal .report-mockup{display:none;}
  }
  /* Below this the modal is the whole screen anyway; the rounded card floating
     on a dark sheet wastes ~40px of height on padding and corners. */
  @media (max-width:480px){
    .modal-backdrop{padding:0;}
    .modal{border-radius:0;min-height:100%;padding:22px 18px;}
  }

  /* ---- calculator fields: one plane, info button at the end ----
     Added 8 Sep 2026. See build/patch_field_alignment.py for the reasoning. */

  /* The info button is nested inside .label-text, so it follows the last word
     of the label and strands itself mid-sentence whenever the label wraps.
     display:contents promotes .label-text's children to children of the label
     itself, which is what lets them be positioned at all - you cannot float or
     order across a nesting level.

     The label becomes a block and the button floats right. A flex row would
     also park the button at the right edge, but it reserves that width on
     EVERY line, so the label text loses ~28px on all of them and wraps more.
     A float only displaces the first line and lets the rest run full width.
     Measured across all five calculators at 1360px: floats give 37 one-line
     labels and no three-line labels, against 31 and 3 for flex, and 31 and 9
     for a wrapping flex row. */
  .field label{display:block;}
  .field label .label-text{display:contents;}
  .field label .info-btn{float:right;margin-left:6px;}
  .field label .hint{float:right;margin-left:8px;}
  /* Contain the floats. Without this, a label whose text fills the first line
     pushes the button onto a second line that the label does not grow to
     cover, and the "i" hangs in the gap below - seen on the injury
     calculator's employee question at 700px and its damages cap at 390px.
     Measured across 275 labels at five widths: this removes both escapes and
     costs 1.1px of average label height. */
  .field label::after{content:'';display:block;clear:both;}

  /* [hidden] is (0,0,1,0); `.field label` is (0,0,1,1), so the rule above would
     override the hidden attribute. The live case is #c3_flagOptInWrap, the
     flagged-rule opt-in on the ACV calculator: it is shown only for the four
     flagged states and is disabled otherwise, so overriding `hidden` put a
     dead, legally-significant tickbox in front of every visitor. Conditional
     controls must stay hidden. */
  .field label[hidden],
  .field-row > .field[hidden]{display:none;}

  /* Fallback for browsers without subgrid: bottom-align the controls so a
     one-line label beside a two-line one does not leave one input higher than
     its neighbour. */
  .field-row > .field{display:flex;flex-direction:column;}
  .field-row > .field > input,
  .field-row > .field > select{margin-top:auto;}

  /* Subgrid does it properly. The label row, the control row and the info-panel
     row belong to the .field-row, so the controls align on label height alone -
     and OPENING AN INFO PANEL NO LONGER SHIFTS THE CONTROL BESIDE IT, which the
     bottom-align fallback cannot avoid: it pushes each control to the bottom of
     its own cell, and an open panel makes one cell taller than the other.
     Measured: all 39 .field-row > .field are label+control or
     label+control+panel, so three rows covers every one of them. */
  @supports (grid-template-rows: subgrid){
    .field-row{grid-template-rows:auto auto auto;}
    .field-row > .field{display:grid;grid-template-rows:subgrid;grid-row:span 3;}
    .field-row > .field > input,
    .field-row > .field > select{margin-top:0;}
  }

  /* A row holding a single field spanned one of two columns and rendered at
     half width - #c5_multiplierRow, whose partner fields are a sibling row
     the method selector toggles. */
  .field-row > .field:only-child{grid-column:1 / -1;}

  /* ---- the client-side guarantee, above the fold ----
     Added 9 Sep 2026. See build/patch_privacy_note.py for the audit behind
     the wording. Styled off .trust-row so it reads as part of the hero's
     supporting rank rather than as a badge or a banner. */
  .privacy-note{
    display:flex;align-items:flex-start;gap:7px;
    margin:14px 0 0;
    font-size:.82rem;line-height:1.45;color:var(--ink-soft);
  }
  .pn-lock{
    width:13px;height:13px;flex-shrink:0;
    /* Optical alignment to the first line's cap height, not its box. */
    margin-top:.18em;color:var(--accent);
  }
  /* On the homepage the note sits between the CTA row and the method chips,
     both of which bring their own spacing. */
  .hero .privacy-note{margin-top:16px;}
  .hero .privacy-note + .trust-row{margin-top:14px;}

  /* ---- pricing CTA: in the column it buys ----
     Added 9 Sep 2026. See build/patch_pricing_cta.py for the measurements.
     One presentation per breakpoint, never both: below 700px
     .compare-table-wrap scrolls sideways -- the table has a 640px floor, so it
     starts clipping at a 660px viewport, and on a 390px phone the All Access
     column ends 270px past the right edge, so an in-table button would
     hide the $49 CTA behind a horizontal scroll with no affordance. */
  tr.cta-row{display:none;}
  @media (min-width:700px){
    tr.cta-row{display:table-row;}
    tr.cta-row td{border-top:0;padding-top:2px;padding-bottom:16px;}
    tr.cta-row .btn{
      width:100%;justify-content:center;text-align:center;
      padding-left:8px;padding-right:8px;white-space:nowrap;
    }
    .pricing-cta{display:none;}
  }

  /* ---- pricing: cards below the breakpoint, table above ----
     Added 9 Sep 2026. See build/patch_pricing_cards.py.

     The comparison table has a 640px floor inside an overflow-x:auto wrapper,
     so below 700px it scrolled sideways with no affordance and the All Access
     column sat 270px off the right edge of a 390px phone. Exactly one of the
     two is ever displayed; display:none takes the other out of the
     accessibility tree too, so a screen reader gets one copy. */
  .plan-cards{display:grid;gap:16px;margin:8px 0 4px;}
  @media (min-width:700px){
    .plan-cards{display:none;}
  }
  @media (max-width:699px){
    .compare-table-wrap{display:none;}
  }
  .plan-card{
    background:var(--card);border:1px solid var(--line);
    border-radius:var(--radius);box-shadow:var(--shadow);
    padding:18px 16px;
  }
  .plan-card.featured{border-color:var(--brand);box-shadow:var(--shadow), var(--accent-edge);}
  .pc-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;margin-bottom:2px;}
  .pc-name{font-weight:800;font-size:1.05rem;}
  .pc-amt{
    font-family:'IBM Plex Mono',monospace;font-weight:800;font-size:1.35rem;
    margin-left:auto;
  }
  .pc-per{flex-basis:100%;font-size:.78rem;color:var(--ink-soft);}
  .pc-list{list-style:none;margin:14px 0 0;padding:0;}
  .pc-list li{
    display:flex;gap:12px;align-items:flex-start;justify-content:space-between;
    padding:9px 0;border-top:1px solid var(--line);font-size:.86rem;
  }
  .pc-list li:first-child{border-top:0;}
  .pc-feat{flex:1 1 44%;min-width:0;color:var(--ink-soft);}
  .pc-val{flex-shrink:0;text-align:right;max-width:56%;font-weight:600;}
  /* A row this plan does not have is greyed rather than removed: the gap
     between the $19 and the $49 is what the buyer came here to read. */
  .pc-val.na{font-weight:400;opacity:.5;}
  .pc-cta{margin-top:16px;}
  .pc-cta .btn{width:100%;justify-content:center;}

  /* The standalone centred pair under the table is now superseded at every
     width: the in-table row covers 700px and up, and each card carries its own
     button below that. Left in the markup rather than deleted so the change is
     one line to reverse. */
  .pricing-cta{display:none;}

  /* ---- paywall proof strip ----
     Added 9 Sep 2026. Replaces .report-mockup INSIDE the paywall, which was
     ~250px and therefore hidden below a 940px viewport -- on 7 of 9 measured
     device sizes the modal had no depiction of the product at all. This is
     ~100px and never hides. See build/patch_paywall_proof.py. */
  .pw-proof{
    border:1px solid var(--line);border-radius:12px;
    background:var(--brand-soft);padding:12px 14px;margin:0 0 16px;
  }
  .pw-proof-files{display:flex;flex-wrap:wrap;gap:8px;}
  .pw-proof .pf{
    display:flex;align-items:center;gap:7px;flex:1 1 auto;min-width:0;
    font-size:.76rem;color:var(--ink-soft);line-height:1.25;
  }
  .pw-proof .pf b{
    flex-shrink:0;font-family:'IBM Plex Mono',monospace;font-size:.66rem;
    letter-spacing:.03em;color:#fff;background:var(--brand);
    padding:3px 6px;border-radius:5px;
  }
  .pw-proof-note{
    margin:10px 0 0;font-size:.75rem;line-height:1.45;color:var(--ink-soft);
  }
  /* The sample link, demoted from a ghost button to a text line and moved
     below the CTA. As a button it competed with "Continue to Secure Checkout";
     above the plan chooser it was a fork in the road before the decision. */
  .pw-sample-line{
    margin:10px 0 0;text-align:center;
    font-size:.76rem;color:var(--ink-soft);
  }
  .pw-sample-line a{color:var(--brand);font-weight:600;}

  /* The refund line, under the CTA. Carries a little more weight than the
     sample link beside it because it removes a reason not to buy rather than
     offering somewhere else to go. See build/patch_refund_guarantee.py --
     the wording is a policy commitment, not decoration. */
  .pw-guarantee{
    margin:6px 0 0;text-align:center;
    font-size:.76rem;color:var(--ink-soft);
  }
  .pw-guarantee::before{content:'\2713';color:var(--brand);margin-right:5px;font-weight:700;}

  /* ---- Report Branding: prepared-by / prepared-for ----
     Added 9 Sep 2026. The exports carried these blocks from the start with
     nothing wired to them; see build/patch_preparer_fields.py. */
  .branding-party{margin:18px 0 0;}
  .branding-party-intro{
    margin:0 0 12px;font-size:.82rem;line-height:1.5;color:var(--ink-soft);
  }
  .branding-party-cols{
    display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  }
  .branding-party-col{
    border:1px solid var(--line);border-radius:10px;
    padding:12px 14px 14px;margin:0;min-width:0;
  }
  .branding-party-col legend{
    padding:0 6px;font-size:.72rem;font-weight:700;letter-spacing:.06em;
    text-transform:uppercase;color:var(--brand-dark,#92400e);
  }
  .branding-party-col label{
    display:block;margin:10px 0 4px;font-size:.78rem;font-weight:600;
    color:var(--ink);
  }
  .branding-party-col label:first-of-type{margin-top:2px;}
  .branding-party-col input{width:100%;box-sizing:border-box;}

  /* Sign in: the ACTION at the end of a row of links.
     Divided from the four navigation entries with a rule and a little air, so
     it does not read as a fifth page. Same muted weight as its siblings: this
     has to be findable, not shouty -- most visitors never need it. */
  .res-nav a.res-signin{margin-left:9px;padding-left:13px;
    border-left:1px solid var(--line);color:var(--ink);}
  .res-nav a.res-signin:hover{color:var(--brand-dark);}
  .res-nav a.res-signin[data-signed-in="1"]{color:var(--brand-dark);}
  /* Below 520px the four links already fill the row, so this one wraps whatever
     is done to it. Pushing it right with margin-left:auto leaves it floating
     alone on a line looking like a stray button; left-aligned and without the
     divider it reads as the second line of the same list. Measured at 420px:
     the header is 225px either way, so this is purely about it looking
     deliberate. */
  @media(max-width:520px){
    .res-nav a.res-signin{margin-left:0;padding-left:11px;border-left:none;}
  }

/* ============================================================
   Calculator step flow, added 30 September 2026.
   Wrapper styling only: every existing card, field, info button
   and panel keeps its own class and its own behaviour.
   ============================================================ */
.cm-steps{display:flex;gap:8px;margin:0 0 14px;}
.cm-step{flex:1;border:1px solid var(--line);border-radius:8px;padding:8px 11px;
  font-size:.78rem;color:var(--ink-soft);background:#fff;
  transition:background .18s,border-color .18s,color .18s,opacity .18s;}
.cm-step b{display:block;font-size:.64rem;text-transform:uppercase;letter-spacing:.08em;opacity:.8;}
.cm-step.active{border-color:var(--brand);background:var(--brand-soft);color:var(--brand-dark);font-weight:600;}
.cm-step.done{border-color:#15803d;background:#dcfce7;color:#14532d;font-weight:600;}
.cm-step.done b::after{content:' \2713';color:#15803d;font-weight:800;}
/* A dead end is not a completed step: answering "yes" in step 1 means this
   calculator does not apply, so the bubble warns and the rest dims. */
.cm-step.stop{border-color:var(--danger);background:#fef2f2;color:#7f1d1d;font-weight:600;}
.cm-step.stop b::after{content:' \2715';color:var(--danger);font-weight:800;}
.cm-step.muted{opacity:.45;}
.cm-dim{opacity:.5;pointer-events:none;}

.cm-example-note{display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap;
  background:var(--brand-soft);border:1px solid #fcd9a4;border-radius:8px;
  padding:9px 12px;font-size:.8rem;color:var(--brand-dark);margin:0 0 14px;}
.cm-linkbtn{background:none;border:0;color:var(--brand-dark);font:inherit;font-weight:700;
  text-decoration:underline;cursor:pointer;padding:0;}
.cm-step-hint{font-size:.78rem;color:var(--ink-soft);margin:10px 0 0;min-height:1.2em;}

.cm-step3{border:1px solid var(--line);border-radius:var(--radius);background:var(--card);
  box-shadow:var(--shadow);margin-top:16px;}
.cm-step3>summary{padding:14px 16px;font-weight:600;font-size:.9rem;cursor:pointer;list-style:none;}
.cm-step3>summary::-webkit-details-marker{display:none;}
.cm-step3>summary::after{content:'+';float:right;color:var(--structure);font-weight:700;}
.cm-step3[open]>summary::after{content:'\2013';}
.cm-step3-body{padding:0 4px 4px;}
.cm-step3-body .card{box-shadow:none;border:0;padding:6px 12px 2px;}
.cm-step3-body .card+.card{margin-top:0;}

/* Info button: brand outline, parked at the end of the label row. */
.field label .info-btn{width:20px;height:20px;font-size:.72rem;
  background:#fff;color:var(--structure);border:1px solid var(--structure-soft);}
.field label .info-btn:hover{border-color:var(--structure);color:var(--ink);}
.field label .info-btn.active{background:var(--structure);border-color:var(--structure);color:#fff;}

/* Two fields in a row line up as a unit. Each field shares the row's track
   grid, so the label band, the control band and the panel band are the same
   height in both columns however the label text wraps. Browsers without
   subgrid fall back to reserved heights, which covers the common cases. */
/* Fields in a row share the row's three bands: label, control, panel. Subgrid
   makes each band the same height in both columns, so the controls line up
   whatever the label wrap and two open panels start and finish together.
   Every field now has the same three children, because explanatory notes were
   moved out to row level, which is what makes a fixed span safe. */
.field-row{align-items:stretch;grid-template-rows:auto auto 1fr;}
.field-row>.field{display:grid;min-width:0;grid-template-columns:minmax(0,1fr);grid-template-rows:auto auto 1fr;align-content:start;}
/* The column has to be declared as well as the rows. Without it the field's
   single implicit column is sized to the control's intrinsic width, so a number
   input on a narrow track overflowed its own field by about 15px and took the
   pinned info button out of line with it. */
@supports (grid-template-rows: subgrid){
  .field-row>.field{grid-row:span 3;grid-template-rows:subgrid;}
}
@supports not (grid-template-rows: subgrid){
  .field-row>.field>label{min-height:60px;display:flex;align-items:flex-end;}
}
.field-row>.field>input,.field-row>.field>select{height:44px;align-self:start;width:100%;max-width:100%;min-width:0;justify-self:stretch;box-sizing:border-box;}
/* An input carries an intrinsic minimum width from its size attribute, which can
   push it past its own grid cell on a narrow column. Zero it so the cell governs,
   otherwise the control runs wider than the field and the pinned info button no
   longer lines up with its right edge. */
.field-row>.field>.info-panel{align-self:stretch;}
.cm-row-note{grid-column:1 / -1;margin-top:10px;}
.field-row>.field>label{display:flex;align-items:flex-start;margin-bottom:0;}
/* RULE, applies to every calculator and every field, whatever sits inside the
   label: the info button is pinned to the right edge of the field, which is the
   right edge of the control beneath it, because controls are width:100%. Pinning
   it rather than pushing it with margins means a trailing hint, a wrapped label
   or a different inner structure cannot shift it. The label reserves 28px so
   text never runs under the button. Do not set float or margin on .info-btn
   anywhere else; this block is the single source. */
.field{position:relative;}
.field>label{display:block;width:100%;padding-right:28px;}
.field>label>.label-text{display:inline;}
.field>label .info-btn{position:absolute;top:0;right:0;float:none;margin:0;}
.field-row>.field>input,.field-row>.field>select{height:44px;align-self:start;width:100%;max-width:100%;min-width:0;justify-self:stretch;box-sizing:border-box;}
/* An input carries an intrinsic minimum width from its size attribute, which can
   push it past its own grid cell on a narrow column. Zero it so the cell governs,
   otherwise the control runs wider than the field and the pinned info button no
   longer lines up with its right edge. */
.field-row>.field>.info-panel{align-self:stretch;}
.field-row>.field:only-child{grid-column:1 / -1;}

/* The three result cards were pinned to the top on desktop and followed the
   reader down the page. Three tall cards are too much furniture to carry, so
   the column scrolls with the page again. On a phone the compact bar still
   mirrors the headline figure, which is where the figure actually gets lost. */
@media(max-width:919px){
  /* On a phone the answer belongs above the form, not five screens below it. */
  .calc-grid{display:flex;flex-direction:column;}
  .calc-grid>.results-col{order:-1;}
  .calc-grid>.results-col>.results-top{margin-bottom:18px;}
  .calc-grid>.results-col>.card,.calc-grid>.results-col>.lock-wrap{order:2;}
}

/* Mobile header: the stacked version runs to 173px, so sticking it would eat a
   fifth of the screen. The live rule already unsticks below 520px; this extends
   it to the width where the header starts stacking. */
@media(max-width:870px){
  header.site{position:static;}
  nav.calc-nav{padding-right:24px;
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent 100%);
    mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent 100%);
    scroll-snap-type:x proximity;}
  nav.calc-nav a{scroll-snap-align:start;}
  .nav-stack{position:relative;}
}
.cm-scroll-hint{position:absolute;right:0;bottom:1px;width:20px;height:20px;border-radius:999px;
  background:#fff;border:1px solid var(--line);color:var(--brand-dark);
  display:none;align-items:center;justify-content:center;font-size:.7rem;font-weight:700;
  pointer-events:none;box-shadow:0 1px 3px rgba(28,25,23,.12);opacity:0;transition:opacity .18s ease;}
.cm-scroll-hint.on{display:flex;opacity:1;}
@media(min-width:871px){.cm-scroll-hint{display:none !important;}}

/* Mobile: the figure sits above the form, so it scrolls away while the visitor
   edits. This bar brings it back, and only once the card has left the screen. */
.cm-mini-bar{position:fixed;left:0;right:0;bottom:0;z-index:70;display:none;
  background:#fff;border-top:1px solid var(--line);box-shadow:0 -8px 24px -12px rgba(28,25,23,.25);
  padding:9px 16px calc(9px + env(safe-area-inset-bottom,0px));
  transform:translateY(110%);transition:transform .18s ease;}
.cm-mini-bar .cm-mini-in{display:flex;align-items:center;justify-content:space-between;gap:12px;max-width:520px;margin:0 auto;}
.cm-mini-bar .cm-mini-k{font-size:.62rem;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-soft);}
.cm-mini-bar .cm-mini-v{font-size:1.25rem;font-weight:700;color:var(--brand-dark);font-family:'IBM Plex Mono',monospace;}
.cm-mini-bar.show{transform:translateY(0);}
@media(max-width:919px){.cm-mini-bar{display:block;}body.cm-has-mini{padding-bottom:88px;}}

@media print{
  /* Progress furniture is screen guidance, not part of a printed report. The
     Step 3 body prints in full even when collapsed, so a PDF never drops the
     inputs behind an accordion. */
  .cm-steps,.cm-example-note,.cm-step-hint,.cm-mini-bar,.cm-scroll-hint{display:none !important;}
  .cm-step3{border:0 !important;box-shadow:none !important;margin-top:0 !important;}
  .cm-step3>summary{display:none !important;}
  .cm-step3>.cm-step3-body{display:block !important;padding:0 !important;}
  .cm-step3-body .card{padding:0 !important;}
}

/* Paywall branding proof. An inline SVG rather than an image: no extra request,
   it scales cleanly and the logo zone can carry the buyer's own name once set. */
.pw-brand-proof{display:flex;gap:14px;align-items:flex-start;margin-top:12px;
  border:1px solid var(--line);border-radius:10px;padding:12px 14px;background:#fff;}
.pw-brand-doc{flex:0 0 auto;width:72px;height:92px;display:block;}
.pw-brand-zone{fill:var(--brand-soft);stroke:var(--brand);stroke-width:1;stroke-dasharray:3 2;}
.pw-brand-mark{font:700 7px 'Inter',sans-serif;fill:var(--brand-dark);letter-spacing:.06em;}
.pw-brand-copy strong{display:block;font-size:.9rem;margin-bottom:3px;}
.pw-brand-copy p{margin:0 0 5px;font-size:.8rem;color:var(--ink-soft);line-height:1.5;}
.pw-brand-free{color:var(--ink-soft);font-style:italic;}
/* Post-purchase branding step. Two fields and a real Skip button, because a
   buyer who just wants the report must be able to reach it in one click. */
.cm-brandstep-actions{display:flex;gap:10px;margin-top:14px;}
.cm-brandstep-actions .btn{flex:1 1 0;margin:0;}
.cm-brandstep-note{font-size:.76rem;color:var(--ink-soft);margin:10px 0 0;}

/* The state rule block belongs inside Step 2, under the fields that produce it,
   titled so it reads as an explanation rather than loose text. It spans the
   card and moves down naturally when an information panel above it opens. */
.cm-rule-note{border:1px solid var(--line);border-left:3px solid var(--brand);
  border-radius:8px;background:#faf9f7;padding:12px 14px;margin-top:16px;}
.cm-rule-note[hidden]{display:none;}
.cm-rule-note-title{margin:0 0 6px;font-size:.84rem;font-weight:700;color:var(--ink);}
.cm-rule-note .field-note{margin:0;}
.cm-rule-note .field-note strong{color:var(--ink);}

/* Export card. One titled block rather than a row of buttons, a sentence and a
   stray accordion. The free tier reads first and stays neutral; the paid tier
   keeps the commercial colour and holds the branding control, because branding
   belongs to the thing it affects. */
.cm-export-card{border:1px solid var(--line);border-radius:var(--radius);background:var(--card);
  box-shadow:var(--shadow);padding:18px 20px;margin-top:18px;}
.cm-export-title{margin:0 0 14px;font-size:1rem;font-weight:700;}
.cm-export-tier+.cm-export-tier{margin-top:16px;padding-top:16px;border-top:1px solid var(--line);}
.cm-tier-paid{background:linear-gradient(180deg,var(--brand-soft) 0%,#fff 70%);
  border-radius:10px;padding:14px;margin-left:-14px;margin-right:-14px;}
.cm-tier-label{margin:0 0 2px;font-size:.72rem;font-weight:700;text-transform:uppercase;
  letter-spacing:.08em;color:var(--ink-soft);display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.cm-tier-badge{background:#fff;border:1px solid #fcd9a4;color:var(--brand-dark);
  border-radius:4px;padding:2px 6px;font-size:.62rem;letter-spacing:.05em;}
.cm-tier-detail{margin:0 0 10px;font-size:.82rem;color:var(--ink-soft);}
.cm-tier-actions{display:flex;gap:8px;flex-wrap:wrap;}
.cm-tier-actions .btn{flex:0 1 auto;}
@media(max-width:560px){.cm-tier-actions{flex-direction:column;}.cm-tier-actions .btn{width:100%;}}
.cm-brand-row{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;
  margin-top:12px;padding:11px 13px;border:1px solid var(--line);border-radius:8px;background:#fff;
  text-align:left;cursor:pointer;font:inherit;}
.cm-brand-row:hover{border-color:var(--structure);}
.cm-brand-row-main{display:flex;flex-direction:column;gap:2px;min-width:0;}
.cm-brand-row-title{font-size:.86rem;font-weight:600;color:var(--ink);}
.cm-brand-row-sub{font-size:.76rem;color:var(--ink-soft);}
.cm-brand-row-action{flex:0 0 auto;font-size:.78rem;font-weight:700;color:var(--brand-dark);
  text-decoration:underline;}
.cm-brand-row.is-saved{border-color:#bbf7d0;background:#f6fef9;}
.cm-brand-row.is-saved .cm-brand-row-title::before{content:'\2713';color:#15803d;margin-right:6px;font-weight:800;}
/* Quick setup first, the rest of the letterhead behind its own disclosure, so a
   logo and a company name take seconds and the other twelve fields stay out of
   the way until someone wants them. */
.cm-brand-full>summary{cursor:pointer;font-weight:600;font-size:.86rem;padding:10px 0;list-style:none;}
.cm-brand-full>summary::-webkit-details-marker{display:none;}
.cm-brand-full>summary::after{content:'+';float:right;color:var(--structure);font-weight:700;}
.cm-brand-full[open]>summary::after{content:'\2013';}
/* Belt and braces: the user agent already hides a closed details element's
   content, but stating it means the collapse cannot be defeated by any
   inherited display rule, and it is testable rather than assumed. */
.cm-brand-full:not([open])>*:not(summary){display:none;}

/* Range and scenarios. A figure to the dollar reads as a prediction, so the
   range sits with it and the table shows what moves when the softest
   assumption moves. */
.cm-range-line{margin:10px 0 0;font-size:.84rem;color:var(--ink-soft);}
.cm-range-line strong{display:block;color:var(--ink);font-size:.95rem;margin-bottom:2px;}
.cm-range-line span{display:block;}
.cm-range-line:empty{display:none;}
.cm-scenarios{margin-top:14px;border:1px solid var(--line);border-radius:10px;background:#fff;padding:12px 14px;}
.cm-scen-title{margin:0 0 8px;font-size:.78rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:var(--ink-soft);}
.cm-scen-table{width:100%;border-collapse:collapse;font-size:.84rem;}
.cm-scen-table th{text-align:left;font-size:.7rem;text-transform:uppercase;letter-spacing:.06em;
  color:var(--ink-soft);font-weight:700;padding:0 0 6px;}
.cm-scen-table th+th,.cm-scen-table td+td{text-align:right;}
.cm-scen-table td{padding:7px 0;border-top:1px dotted var(--line);vertical-align:top;}
.cm-scen-table tr.is-base td{font-weight:700;background:var(--brand-soft);}
.cm-scen-table tr.is-base td:first-child{border-radius:6px 0 0 6px;padding-left:8px;}
.cm-scen-table tr.is-base td:last-child{border-radius:0 6px 6px 0;padding-right:8px;}
.cm-scen-note{display:block;font-weight:400;font-size:.72rem;color:var(--ink-soft);}
.cm-scen-foot{margin:8px 0 0;font-size:.72rem;color:var(--ink-soft);}
.cm-narrative{margin:12px 0 0;font-size:.86rem;line-height:1.6;color:var(--ink-soft);
  border-left:3px solid var(--brand);background:#faf9f7;border-radius:0 8px 8px 0;padding:10px 12px;}
.cm-narrative strong{color:var(--ink);}
.cm-narrative:empty{display:none;}

@media print{
  /* The range, the scenario table and the plain-English summary are part of the
     analysis, not screen furniture, so they print. */
  .cm-scenarios{break-inside:avoid;page-break-inside:avoid;}
  .cm-narrative{border-left-color:#78350f;}
}

/* One line of permanent guidance on the fields people get wrong, inside the
   label block so the field keeps its three parts and the row alignment holds.
   The information button still carries the full explanation. */
.cm-field-help{display:block;font-weight:400;font-size:.74rem;line-height:1.35;
  color:var(--ink-soft);margin-top:3px;}

/* Visible focus. The inputs had outline:none with nothing in its place, so a
   keyboard user could not see where they were. Focus-visible keeps it off for
   mouse clicks. */
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible,
input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:3px solid var(--focus);outline-offset:2px;border-color:var(--focus);}
a:focus-visible,button:focus-visible,summary:focus-visible,[tabindex]:focus-visible{
  outline:3px solid var(--focus);outline-offset:2px;border-radius:4px;}
.btn:focus-visible{outline:3px solid var(--ink);outline-offset:2px;}

/* A scenario table with three identical rows is noise, so it is replaced by the
   reason the figure cannot move. */
.cm-scenarios.is-flat .cm-scen-table,
.cm-scenarios.is-flat .cm-scen-foot{display:none;}
.cm-scen-flat{margin:0;font-size:.8rem;color:var(--ink-soft);}

/* The checklist row sits beside the branding row in the paid tier. Both are the
   two things a buyer must set before exporting, so they read as a pair. */
.cm-check-row{margin-top:8px;}
.cm-check-row.is-saved{border-color:#bbf7d0;background:#f6fef9;}

/* Checklist, now nested inside the paid tier of the export card. It reads like
   the branding row until it is opened, so the two things a buyer must set
   before exporting sit together. */
.cm-check-nested{margin-top:8px;border:1px solid var(--line);border-radius:8px;background:#fff;}
.cm-check-nested[open]{border-color:var(--structure);}
.cm-check-summary{list-style:none;cursor:pointer;padding:11px 13px;display:block;position:relative;padding-right:46px;}
.cm-check-summary::-webkit-details-marker{display:none;}
.cm-check-summary::after{content:'Open';position:absolute;right:13px;top:13px;
  font-size:.78rem;font-weight:700;color:var(--brand-dark);text-decoration:underline;}
.cm-check-nested[open] .cm-check-summary::after{content:'Close';}
.cm-check-nested.is-saved{border-color:#bbf7d0;background:#f6fef9;}
.cm-check-nested .cm-collapse-body{padding:0 13px 13px;border-top:1px solid var(--line);}
.cm-check-nested .cm-brand-row-title{display:block;font-size:.86rem;font-weight:600;color:var(--ink);}
.cm-check-nested .cm-brand-row-sub{display:block;font-size:.76rem;color:var(--ink-soft);margin-top:2px;}

@media print{
  /* Only the checklist survives from the export card. */
  .cm-export-card{border:0;box-shadow:none;padding:0;margin:0;}
  .cm-tier-paid{background:none;padding:0;margin:0;}
  .cm-check-nested{border:0;}
  .cm-check-nested .cm-collapse-body{display:block !important;padding:0;border:0;}
}

/* A paid breakdown is not a preview. */
.lock-wrap:not(.locked) > .watermark{display:none;}
/* A negative amount wrapped its minus sign onto a line of its own. Amount
   cells only: applied to every last cell it also caught the full-width
   teaser row on locked breakdowns, which then ran 171px out of its card. */
.breakdown td.num{white-space:nowrap;}
.breakdown{overflow-x:auto;}
/* [hidden] must win over the flex display set on the note. */
.cm-example-note[hidden]{display:none;}
/* Cards in a row share a height; the figure sits on the bottom edge so two
   figures side by side line up even when one label wraps to more lines. */
.results-top > .stat-card{display:flex;flex-direction:column;}
.results-top > .stat-card > .value{margin-top:auto;padding-top:6px;}

/* Print, revisited after the injury calculator's redesign went live
   (1 Oct 2026). The two-column grid kept its desktop widths on paper and was
   scaled down to fit, the branding panel printed, and the article below the
   calculator added three pages of reading that is not part of the
   calculation. On paper: one column, inputs then results, and only the
   calculation, its explanation and the checklist. */
@media print{
  .calc-grid{display:block !important;}
  .calc-grid > *{width:auto !important;max-width:none !important;margin-bottom:14px;}
  details#brandingDetails, .tool-support, #calculator ~ section.page-intro,
  #calculator ~ section.faq-section{display:none !important;}
  .results-top{grid-template-columns:repeat(3,minmax(0,1fr)) !important;}
  .results-top > .stat-card:not(.alt){grid-column:auto !important;order:0 !important;}
  .card{box-shadow:none !important;}
  .cm-status-banner{break-inside:avoid;page-break-inside:avoid;}
}
@media print{
  .email-capture-trigger{display:none !important;}
  .chart-wrap, .card:has(> .chart-wrap){break-inside:avoid;page-break-inside:avoid;}
}
/* Step 3 is a collapsed <details> on screen, and a closed details prints
   nothing, so the printed calculation dropped every Step 3 input. Opened for
   print by script (beforeprint) and, where the browser supports it, by CSS. */
@media print{
  details.cm-step3::details-content{content-visibility:visible !important;display:block !important;}
}
/* Smart Import now sits inside Step 2: it is a way of filling the numbers,
   not a step of its own. */
.cm-import-in-step{margin:2px 0 12px;padding:10px 12px;border:1px dashed var(--line);border-radius:10px;background:#fafaf9;}
.cm-import-in-step .cm-import-privacy{margin:6px 0 0;font-size:.76rem;}
/* An unowned calculator's paid tier: one honest call to action instead of
   three export buttons that only open the paywall. */
.cm-tier-locked-note{margin:8px 0 0;font-size:.8rem;color:var(--ink-soft);}
.cm-gate-nudge{margin:10px 0 0;font-size:.82rem;color:#7f1d1d;}
/* [hidden] has to beat the button display rules, or the export buttons on an
   unowned calculator stayed on screen beside the call to action. */
.cm-tier-actions button[hidden]{display:none !important;}
/* Worked examples under the calculators (SEO pass, 1 Oct 2026). */
.cm-example-table{width:100%;border-collapse:collapse;font-size:.9rem;margin:12px 0 14px;display:block;overflow-x:auto;}
.cm-example-table th{text-align:left;font-size:.74rem;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft);padding:8px;border-bottom:1px solid var(--line);}
.cm-example-table td{padding:8px;border-bottom:1px solid var(--line);vertical-align:top;}
.cm-example-table td:last-child{text-align:right;white-space:nowrap;font-family:'IBM Plex Mono',monospace;}
.cm-example-table .cm-ex-sub td{font-weight:600;}
.cm-example-table .cm-ex-total td{font-weight:800;border-top:2px solid var(--ink);}
/* Import review table and page picker (2 Oct 2026). */
.cm-imp-review{margin-top:8px;}
.cm-imp-head{margin:0 0 6px;font-size:.82rem;font-weight:600;}
.cm-imp-table{overflow-x:auto;}
.cm-imp-table table{width:100%;border-collapse:collapse;font-size:.8rem;}
.cm-imp-table th{text-align:left;font-size:.7rem;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-soft);padding:4px 6px;border-bottom:1px solid var(--line);}
.cm-imp-table td{padding:5px 6px;border-bottom:1px solid var(--line);vertical-align:middle;}
.cm-imp-table td.num{text-align:right;white-space:nowrap;font-family:'IBM Plex Mono',monospace;}
.cm-imp-table select{font-size:.78rem;max-width:210px;}
.cm-imp-tag{display:inline-block;margin-left:4px;padding:0 6px;border-radius:9px;font-size:.68rem;font-weight:600;}
.cm-imp-tag.fix{background:#fef3c7;color:#92400e;}
.cm-imp-tag.calc{background:#e0f2fe;color:#075985;}
.cm-imp-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:8px;}
.cm-imp-pp-note{font-size:.75rem;color:var(--ink-soft);}
.cm-imp-pages{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px;max-height:320px;overflow:auto;}
.cm-imp-page{display:flex;flex-direction:column;align-items:center;gap:3px;font-size:.72rem;cursor:pointer;}
.cm-imp-page canvas{border:1px solid var(--line);border-radius:4px;max-width:120px;height:auto;}
/* Print, checked on all five step-pattern calculators (2 Oct 2026). */
@media print{
  /* The import tool is a screen control. */
  .cm-import-widget{display:none !important;}
  /* Step 3's summary is hidden in print, so its fields ran on with no
     heading under Step 2. Give the printed section its own title. */
  .cm-step3>.cm-step3-body::before{
    content:'Step 3. Refinements used in this estimate';display:block;
    font-size:1rem;font-weight:700;color:#1c1917;margin:18px 0 8px;
    padding-top:12px;border-top:1px solid #d6d3d1;
  }
  /* The checklist kept its items but lost its title (the summary row is a
     screen control and is hidden with the export card's other controls). */
  .cm-export-card details#checklistDetails > summary.cm-check-summary{
    display:block !important;list-style:none;padding:0 0 4px;
  }
  .cm-export-card details#checklistDetails > summary.cm-check-summary > *{display:none !important;}
  .cm-export-card details#checklistDetails > summary.cm-check-summary::before{
    content:'Supporting documents checklist';font-size:1rem;font-weight:700;color:#1c1917;
  }
  .cm-export-card details#checklistDetails > summary.cm-check-summary::marker{content:'';}
  /* Keep each step card, result card, scenario table and status banner on one page. */
  /* Small blocks only: keeping a whole step card together left half a page
     blank on phone-width prints. */
  .results-top, .stat-card, .breakdown tr, .cm-c1-sens, .cm-scenarios{break-inside:avoid;page-break-inside:avoid;}
  /* Screen-only notes and blurred previews of what a paid report adds. */
  .cm-tier-locked-note, .lock-wrap.locked .citation-box, .lock-wrap.locked .watermark{display:none !important;}
  /* The planning-range lines ran together. */
  [id$="_rangeLine"] > *{display:block;margin-top:2px;}
  /* An empty date printed as "mm/dd/yyyy". */
  input.cm-print-empty{color:transparent !important;}
}
