@font-face { font-family: "DM Sans"; font-style: normal; font-weight: 400; font-display: swap; src: url("../frontdesk/assets/fonts/dm-sans-latin-400-normal.woff2") format("woff2"); }
@font-face { font-family: "DM Sans"; font-style: normal; font-weight: 500; font-display: swap; src: url("../frontdesk/assets/fonts/dm-sans-latin-500-normal.woff2") format("woff2"); }
@font-face { font-family: "DM Sans"; font-style: normal; font-weight: 600; font-display: swap; src: url("../frontdesk/assets/fonts/dm-sans-latin-600-normal.woff2") format("woff2"); }
@font-face { font-family: "DM Sans"; font-style: normal; font-weight: 700; font-display: swap; src: url("../frontdesk/assets/fonts/dm-sans-latin-700-normal.woff2") format("woff2"); }
@font-face { font-family: "DM Sans"; font-style: normal; font-weight: 800; font-display: swap; src: url("../frontdesk/assets/fonts/dm-sans-latin-700-normal.woff2") format("woff2"); }
:root {
  font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: #1a2b22;
  background: #eff4f0;
  font-synthesis: none;
  --green: #2e7d5b;
  --green-dark: #245f46;
  --green-light: #4caf7d;
  --green-pale: #e8f5ee;
  --muted: #6b7d72;
  --border: #d8e4dc;
  --surface: #ffffff;
  /* Published so inspect.js can read the inset when clamping the sheet. */
  --safe-top: env(safe-area-inset-top, 0px);
  /* The native shell draws its header and tab bar over the webview, so the
     viewport still counts those bands but nothing may be placed in them. */
  --shell-top: 0px;
  --shell-bottom: 0px;
  /* The fixed chrome a centred flow card must clear: the web banner, or the
     app's floating glass bar and whatever sits at the bottom edge. */
  --chrome-top: 64px;
  --chrome-bottom: 0px;
}
* { box-sizing: border-box; }
/* A long press is how photos get reordered, so the chrome must not answer it
   with a text selection. Real content stays selectable below. */
body { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
input, textarea, [contenteditable], .report-note, .transcript, .comparison-banner, blockquote { -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; }
html { min-height: 100%; background: #eff4f0; }
body { min-height: 100vh; margin: 0; padding: calc(64px + env(safe-area-inset-top)) 0 calc(100px + env(safe-area-inset-bottom)); background: radial-gradient(circle at 50% -10%, #dceee3 0, transparent 36%), #eff4f0; -webkit-font-smoothing: antialiased; letter-spacing: -.01em; }
/* This is also the top edge of every web sheet. Sticky stopped participating
   once the body was scroll-locked at -scrollY, so opening Sign in near the end
   of a page could make the banner disappear. */
/* The site bar only. A bare `header` also caught the business name inside the
   report, pinning it over the bar on the web and hiding it in the app. */
body > header { position: fixed; z-index: 12; top: env(safe-area-inset-top); left: 0; right: 0; width: 100%; max-width: 1040px; margin: auto; padding: 0 20px; min-height: 64px; overflow: hidden; background: #ffffffeb; border: 1px solid #ffffffcc; border-top: 0; border-radius: 0 0 22px 22px; box-shadow: 0 8px 24px #2e7d5b0d; -webkit-backdrop-filter: blur(20px) saturate(150%); backdrop-filter: blur(20px) saturate(150%); }
.header-bar { min-height: 63px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.header-drawer { display: grid; grid-template-rows: 0fr; opacity: 0; transition: grid-template-rows 320ms cubic-bezier(.32,.72,0,1), opacity 180ms ease; }
.header-drawer-clip { min-height: 0; overflow: hidden; }
.header-drawer-content { position: relative; width: min(620px, 100%); margin: 0 auto; padding: 6px 0 22px; transform: translateY(-12px); opacity: 0; transition: transform 280ms cubic-bezier(.32,.72,0,1), opacity 180ms ease; }
.header-drawer-content h2 { margin: 0; padding-right: 42px; }
.header-drawer-content p { margin: 8px 0 12px; }
.header-drawer-close { position: absolute; top: 0; right: 0; width: 36px; min-height: 36px; padding: 0; display: grid; place-items: center; border-radius: 999px; color: var(--muted); }
html.auth-open .header-drawer { grid-template-rows: 1fr; opacity: 1; }
html.auth-open .header-drawer-content { transform: none; opacity: 1; }
html.auth-open .header-bar, html.auth-open main, html.auth-open nav { pointer-events: none; }
.brand { display: flex; gap: 8px; align-items: center; color: inherit; text-decoration: none; font-weight: 750; font-size: 18px; }
.brand-icon { display: block; width: 30px; height: 30px; border-radius: 8px; }
.brand-wordmark { display: block; width: 120px; height: auto; }
.brand span { font-weight: 450; color: var(--muted); }
main { max-width: 860px; margin: 18px auto; padding: 0 20px; }
h1 { font-size: clamp(31px, 5vw, 40px); line-height: 1.08; letter-spacing: -1.4px; margin: 14px 0; }
h2 { font-size: 22px; line-height: 1.15; letter-spacing: -.6px; }
p { line-height: 1.6; }
small, .muted { color: var(--muted); line-height: 1.5; }
.hero { max-width: 650px; margin: 50px auto; text-align: center; }
.hero h1 { font-size: clamp(42px, 7vw, 58px); letter-spacing: -2.2px; }
.eyebrow { text-transform: uppercase; letter-spacing: 2px; font-size: 11px; font-weight: 750; }
.card { background: #ffffffeb; border: 1px solid #ffffff; border-radius: 20px; padding: 22px; margin: 16px 0; box-shadow: 0 2px 6px #2e7d5b0f, 0 12px 30px #2e7d5b12; }
.demo { max-width: 530px; margin: 35px auto; text-align: left; }
.demo .eyebrow { color: var(--muted); }
.demo-step { margin: 14px 0 0; }
.demo-label { display: block; font-size: 11px; font-weight: 750; letter-spacing: 1.4px; text-transform: uppercase; color: var(--muted); }
.demo blockquote { margin: 6px 0 0; min-height: 76px; font-size: 15px; line-height: 1.5; }
/* The caret only belongs to the half that is still being spoken. */
.demo blockquote::after { content: ''; display: inline-block; width: 2px; height: 1em; margin-left: 2px; vertical-align: -2px; background: var(--green); animation: demo-caret 1s step-end infinite; }
@keyframes demo-caret { 50% { opacity: 0; } }
.demo-arrow { margin: 12px 0 0; text-align: center; font-size: 19px; color: #9fb4a5; opacity: 0; transition: opacity .3s ease; }
#demo-result { margin-top: 6px; opacity: 0; transform: translateY(6px); transition: opacity .35s ease, transform .35s ease; }
.demo-note { margin: 6px 0 0; font-size: 15px; line-height: 1.5; }
.demo-badge { display: inline-block; margin-top: 9px; padding: 4px 10px; border-radius: 999px; background: #e7efe9; color: var(--green-dark, #1f5c41); font-size: 12px; font-weight: 700; font-style: normal; }
.demo.is-in blockquote::after { opacity: 0; animation: none; }
.demo.is-in .demo-arrow { opacity: 1; }
.demo.is-in #demo-result { opacity: 1; transform: none; }
.row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.spread { justify-content: space-between; }
.stack { display: grid; gap: 16px; }
.grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px; }
.grid > label { min-width: 0; }
.property-field { min-width: 0; }
.property-field .inline-action { min-height: 34px; margin: 0; padding: 5px 2px; font-size: 12px; }
.property-choices { max-height: min(48vh, 420px); overflow-y: auto; padding: 2px; }
.property-choices button { width: 100%; text-align: left; }
label { font-size: 13px; font-weight: 650; display: block; }
input, select, textarea { font-family: inherit; font-size: 16px; line-height: 1.25; width: 100%; min-width: 0; max-width: 100%; border: 1.5px solid var(--border); background: #fff; padding: 13px 14px; border-radius: 12px; margin: 7px 0; color: inherit; outline: none; transition: border-color .16s, box-shadow .16s; }
input:focus, select:focus, textarea:focus { border-color: var(--green); box-shadow: 0 0 0 4px #e8f5ee; }
input[type="date"] { display: block; width: 100%; min-width: 0; max-width: 100%; -webkit-appearance: none; appearance: none; }
textarea { min-height: 105px; resize: vertical; }
button, .button { font: inherit; cursor: pointer; background: var(--green); color: #fff; border: 0; border-radius: 12px; padding: 14px 20px; display: inline-block; text-decoration: none; font-weight: 650; min-height: 46px; box-shadow: none; transition: transform .14s, background-color .14s, opacity .14s; -webkit-tap-highlight-color: transparent; }
button:active, .button:active, button.is-pressed, .button.is-pressed { transform: scale(.97); }
button:disabled { opacity: .5; cursor: wait; }
/* hidden always hides. Any rule that sets display (button above, .lead-box, nav) otherwise
   overrides it, and a hidden button stays on screen and tappable: the demo camera's Done
   showed from the start and skipped the note and the photo. */
[hidden] { display: none !important; }
.quiet { background: transparent; color: var(--green); padding: 10px 12px; box-shadow: none; }
.secondary { background: var(--green-pale); color: var(--green); box-shadow: none; }
.quiet:active, .quiet.is-pressed { background: #e4efe8; }
.secondary:active, .secondary.is-pressed { background: #d3e8dd; }
.danger:active, .danger.is-pressed { background: #f6e4e1; }
.danger { color: #aa382b; }
.wide { width: 100%; }
/* Label swaps for a spinner in place, so nothing reflows and a second tap
   cannot land while the first is still working. */
button.is-busy { color: transparent !important; pointer-events: none; position: relative; }
button.is-busy::after { content: ""; position: absolute; inset: 0; margin: auto; width: 17px; height: 17px; border: 2px solid #ffffff5c; border-top-color: #fff; border-radius: 50%; animation: inspect-spin .7s linear infinite; }
.quiet.is-busy::after, .secondary.is-busy::after { border-color: #2e7d5b33; border-top-color: var(--green); }
@keyframes inspect-spin { to { transform: rotate(360deg); } }
a { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; text-decoration-color: #c2d5cb; }
/* Every hover state lives here so a touch device never sees one: iOS holds
   :hover after a tap, which is what left buttons sitting dark until you tapped
   somewhere else. :active carries press feedback instead. */
@media (hover: hover) and (pointer: fine) {
  button:hover, .button:hover { background: var(--green-dark); }
  .quiet:hover { background: #edf5f0; }
  .secondary:hover { background: #dceee4; }
  a:hover { color: var(--green-dark); text-decoration-color: var(--green); }
  #dialog-close:hover { background: #edf5f0; color: var(--green); }
}
button:focus-visible, a:focus-visible { outline: 3px solid #74a581; outline-offset: 3px; }
.photo-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px; margin: 14px 0; }
.photo-grid img { width: 100%; height: 125px; object-fit: cover; border-radius: 10px; transition: transform .18s; }
.photo-grid figure { margin: 0; border-radius: 12px; position: relative; touch-action: pan-y; transition: opacity .12s; -webkit-tap-highlight-color: transparent; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
/* Feedback goes on the image, never the figure: the drag measures the figure's
   box to place the lifted tile, and a transform on it would measure short. */
.photo-grid figure:active img, .photo-grid figure.is-pressed img { transform: scale(.985); }
.photo-grid figure.is-drag-source { opacity: 0; }
.photo-ghost { position: fixed; z-index: 60; margin: 0; padding: 0; pointer-events: none; will-change: transform; border-radius: 12px; box-shadow: 0 18px 38px #173b2340; }
.photo-ghost img { display: block; width: 100%; height: 125px; object-fit: cover; border-radius: 10px; }
.photo-ghost .photo-x, .photo-ghost .photo-meta { display: none; }
.photo-grid figcaption { font-size: 11px; color: var(--muted); }
/* Removing a photo is the frequent action, so it sits on the tile rather than
   behind the overflow menu. */
.photo-x { position: absolute; z-index: 2; top: 6px; right: 6px; width: 28px; height: 28px; min-height: 28px; padding: 0; display: grid; place-items: center; font-size: 12px; line-height: 1; color: #fff; background: #17231ba8; border-radius: 999px; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.photo-x:active, .photo-x.is-pressed { transform: scale(.92); }
.photo-grid img { cursor: zoom-in; }
/* No plate behind the photo: contain letterboxes anything that is not the
   sheet's aspect, and a dark plate turned that into black bars. */
.photo-full { width: 100%; max-height: 62vh; object-fit: contain; border-radius: 12px; margin: 4px 0 14px; }
.photo-meta { display: flex; align-items: center; justify-content: space-between; gap: 6px; min-height: 34px; }
.photo-menu { position: relative; }
.photo-menu summary { list-style: none; cursor: pointer; color: var(--green); font-weight: 800; padding: 4px 8px; }
.photo-menu summary::-webkit-details-marker { display: none; }
.photo-menu > div { position: absolute; right: 0; z-index: 5; min-width: 150px; display: grid; padding: 6px; background: #fff; border: 1px solid var(--border); border-radius: 12px; box-shadow: 0 12px 32px #173b2328; }
.photo-menu button { text-align: left; white-space: nowrap; min-height: 36px; padding: 8px 10px; }
.drag-hint { margin: 12px 0 0; color: var(--muted); font-size: 12px; }
.room-footer { margin: 20px -4px -8px; padding-top: 14px; border-top: 1px solid var(--border); text-align: right; }
/* Voice leads the room card; typing is the escape hatch behind a disclosure.
   The disclosure renders open whenever the room already has an observation, so
   an accepted note is never hidden behind a collapsed summary. */
.note-lead { margin: 14px 0 10px; display: grid; gap: 7px; }
.note-lead p { margin: 0; font-size: 13px; text-align: center; }
.write-own { margin: 0 0 4px; }
.write-own summary { cursor: pointer; padding: 8px 2px; min-height: 40px; display: flex; align-items: center; color: var(--green); font-weight: 650; font-size: 14px; }
.write-own label { display: block; margin-top: 6px; }
.coverage-list { margin: 12px 0 10px; padding-left: 20px; display: grid; gap: 6px; font-size: 14px; line-height: 1.5; }
.capture-actions, .note-tools { margin-top: 8px; }
.date-field { min-width: 0; overflow: hidden; }
.issue { display: flex; align-items: center; gap: 9px; }
.issue input { width: auto; }
.report-note { white-space: pre-wrap; }
.report-photo { width: 100%; max-height: 600px; object-fit: contain; margin: 12px 0; }
.report-room { padding: 18px 0; border-top: 1px solid var(--border); }
.comparison-pair { margin: 10px 0 24px; border: 1px solid var(--border); border-radius: 16px; padding: 0 18px; background: #fbfdfb; }
.comparison-pair .report-room:first-child { border-top: 0; }
.compare-label { color: var(--green); font-size: 11px; font-weight: 750; letter-spacing: 1.2px; text-transform: uppercase; }
.comparison-banner { background: var(--green-pale); color: var(--green-dark); border-radius: 12px; padding: 12px 14px; margin: 16px 0; }
.signature-preview { border-top: 1px solid var(--border); padding: 20px 0; display: grid; gap: 8px; }
.signature-preview svg { width: min(100%, 360px); height: auto; background: #f6faf7; border: 1px solid var(--border); border-radius: 12px; }
.signature-preview path { fill: none; stroke: #1a2b22; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.signature-actions h2 { margin: 0 0 4px; }
#signature-pad { display: block; width: 100%; height: 130px; margin: 12px 0; border: 1.5px solid var(--border); border-radius: 12px; background: #fff; touch-action: none; }
.recording-state { display: flex; align-items: center; gap: 8px; }
.recording-dot { width: 10px; height: 10px; border-radius: 999px; background: #c63c32; animation: recording-pulse 1s infinite; }
/* Driven from the stream already being recorded, so it always moves — this is
   what a screen recording of someone talking actually has to show. */
.live-bars { display: flex; align-items: center; justify-content: center; gap: 4px; height: 46px; margin: 14px 0 10px; }
.live-bars span { width: 4px; height: 100%; border-radius: 999px; background: var(--green); opacity: .8; transform: scaleY(.12); transform-origin: center; transition: transform .07s linear; }
/* Captions are a bonus: absent in most webviews, so the box holds its height
   rather than making the sheet jump if they never arrive. */
.live-caption { margin: 0 0 12px; min-height: 60px; max-height: 96px; overflow-y: auto; padding: 10px 12px; background: #edf3ee; border-radius: 12px; font-size: 14.5px; line-height: 1.45; text-align: left; }
.transcript { white-space: pre-wrap; max-height: 180px; overflow: auto; }
@keyframes recording-pulse { 50% { opacity: .35; } }
.status { font-size: 12px; font-weight: 600; color: var(--green-dark); background: var(--green-pale); border: 1px solid #d5ecdf; border-radius: 999px; padding: 7px 11px; }
nav { position: fixed; z-index: 10; bottom: calc(8px + env(safe-area-inset-bottom)); left: 12px; right: 12px; min-height: 60px; overflow: hidden; isolation: isolate; background: linear-gradient(145deg, #ffffffb8, #e8f0e9a8); -webkit-backdrop-filter: blur(26px) saturate(180%); backdrop-filter: blur(26px) saturate(180%); border: 1px solid #ffffffcc; border-radius: 24px; box-shadow: 0 12px 32px #173b2324, inset 0 1px 0 #fff; display: flex; justify-content: center; padding: 7px; gap: 4px; }
nav::before { content: ""; position: absolute; z-index: -1; inset: 0; pointer-events: none; background: radial-gradient(circle at 18% 0, #ffffffc9, transparent 38%), linear-gradient(110deg, transparent 35%, #ffffff5c 52%, transparent 68%); }
nav button { flex: 1 1 0; min-width: 0; min-height: 44px; padding: 9px 6px; background: transparent; color: var(--green); border: 1px solid transparent; border-radius: 17px; font-size: 13px; }
nav button.is-active { background: #ffffff9e; border-color: #ffffffc7; box-shadow: 0 5px 16px #173b2314, inset 0 1px 0 #fff; }
/* Matches Front Desk: a thin pill that slides in from the right and leaves on
   its own, rather than a full-width bar that the keyboard used to sit on top of. */
#notice { position: fixed; z-index: 30; left: 16px; right: 16px; bottom: calc(var(--kb, 0px) + 100px + env(safe-area-inset-bottom)); display: flex; flex-direction: column; align-items: flex-end; gap: 7px; pointer-events: none; transition: bottom .18s ease; }
#notice:empty { display: none; }
/* Shown as a popover so it can sit above an open sheet (see raiseNotices);
   these undo the browser's popover box so it stays a plain toast stack. */
#notice[popover] { top: auto; margin: 0; padding: 0; border: 0; background: transparent; color: inherit; overflow: visible; width: auto; height: auto; }
.toast.in-sheet { max-width: none; margin: 0 0 12px; text-align: center; }
button.is-done { background: var(--green-dark); }
@keyframes note-updated { from { border-color: var(--green); background: #e8f5ee; } }
textarea.just-changed { animation: note-updated 1.4s ease-out; }
@media (prefers-reduced-motion: reduce) { textarea.just-changed { animation: none; } }
.toast { max-width: min(420px, 100%); background: #213b2f; color: #fff; border-radius: 11px; padding: 11px 16px; font-size: 12px; font-weight: 600; line-height: 1.45; box-shadow: 0 12px 32px #173b2333; animation: toast-in .2s ease, toast-out .3s ease 3.4s forwards; }
.toast.success { background: var(--green); }
.toast.error { background: #aa382b; }
@keyframes toast-in { from { transform: translateX(40px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
@keyframes toast-out { to { opacity: 0; transform: translateX(20px); } }
/* The layout viewport never resizes for the keyboard. JS publishes one top and
   one usable height from visualViewport, so Safari cannot resize the layout and
   then have us independently translate the sheet a second time. */
dialog { position: fixed; left: 50%; top: var(--sheet-top, 50%); transform: translate(-50%, -50%); margin: 0; border: 1px solid #e3ebe6; border-radius: 24px; padding: 26px; max-width: 480px; width: calc(100% - 28px); max-height: var(--sheet-max-height, calc(100svh - var(--shell-bottom) - var(--shell-top) - env(safe-area-inset-top) - 32px)); overflow: hidden; color: inherit; background: #fbfdfb; box-shadow: 0 24px 70px #173b2333; }
/* Only when open — a bare display:flex would override the UA's display:none
   and leave the sheet on screen permanently. The body scrolls rather than the
   dialog, so the absolutely-positioned close control cannot scroll away. */
dialog[open] { display: flex; flex-direction: column; }
html.sheet-open, html.sheet-open body { overflow: hidden; overscroll-behavior: none; }
/* iOS can pan the visual viewport even while a fixed body is scroll-locked.
   Counter that pan on the visible page pieces without turning body into a
   containing block for its fixed header. */
html.sheet-open body { position: fixed; left: 0; right: 0; width: 100%; }
html.sheet-open body > header, html.sheet-open main, html.sheet-open nav { transform: translateY(var(--viewport-pan, 0px)); }
#dialog-body { overflow-y: auto; overscroll-behavior: contain; min-height: 0; }
/* No blur, tint or dimming behind sheets. It remains a real modal backdrop, so
   taps cannot leak into the page underneath. */
dialog::backdrop { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
dialog h2 { margin-top: 0; padding-right: 38px; }
/* The sheet takes focus itself when it has no field, so opening one never lands
   a focus ring on whichever control happened to be first in the markup. */
dialog:focus, dialog:focus-visible { outline: none; }
#dialog-close { position: absolute; z-index: 2; top: 12px; right: 12px; width: 36px; min-height: 36px; padding: 0; display: grid; place-items: center; font-size: 15px; line-height: 1; border-radius: 999px; color: var(--muted); }
.auth-back { margin-top: 2px; }
.billing-toggle { display: flex; gap: 6px; padding: 5px; margin: 4px 0 18px; background: #e7efe9; border-radius: 15px; }
.billing-toggle button { flex: 1 1 0; min-height: 44px; padding: 9px 10px; font-size: 14px; background: transparent; color: var(--muted); border-radius: 11px; transition: background-color .2s ease, color .2s ease, box-shadow .2s ease, transform .12s ease; }
.billing-toggle button[aria-checked="true"] { background: #fff; color: var(--green-dark); box-shadow: 0 2px 8px #173b2317; }
.billing-toggle button:active, .billing-toggle button.is-pressed { transform: scale(.97); }
/* The price cross-fades so the toggle reads as having moved something. */
.price, .price-save { animation: price-in .22s ease; }
@keyframes price-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.price small { font-size: 15px; font-weight: 600; color: var(--muted); }
.price-save { color: var(--green); font-weight: 650; font-size: 14px; margin: 2px 0 14px; }
.offer-anchor { margin: -2px 0 16px; color: var(--muted); font-size: 14px; }
.offer-points { margin: 10px 0 14px; padding-left: 20px; display: grid; gap: 6px; font-size: 14px; }
.offer-reversal { margin: 0 0 10px; font-size: 13px; font-weight: 650; color: var(--muted); }
.more-actions summary { list-style: none; cursor: pointer; color: var(--muted); font-size: 13px; font-weight: 650; padding: 10px 2px; }
.more-actions summary::-webkit-details-marker { display: none; }
.more-actions[open] summary { color: var(--green); }
.more-actions > .stack { margin-top: 6px; }
.actions { justify-content: center; margin: 26px 0 8px; }
/* The finalized report's actions sit in flow at the end of the document rather
   than floating over its last line. */
.report-actions { margin: 22px 0 10px; }
/* The editor carries its own exits: signed out in the app neither the web header
   nor the native shell is on screen, so this row is the only way back. */
.screen-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 2px 0 4px; }
.screen-bar .quiet { padding: 8px 10px; font-size: 13px; min-height: 40px; }
.next-actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 18px 0 6px; }
.next-actions button { flex: 1 1 auto; }
.app-handoff-card { display: flex; align-items: center; justify-content: space-between; gap: 22px; margin-top: 24px; }
.app-handoff-card h2 { margin: 5px 0 4px; }
.app-handoff-card p { margin: 0; }
.app-handoff-card button { flex: 0 0 auto; }
.flow-screen { min-height: var(--flow-page-height, calc(100svh - 100px)); }
/* Cancels main's top margin, so the card's resting position is its sticky
   position and a centred card is centred whether or not the page is scrolled. */
.flow-screen { margin-top: -18px; }
/* Authentication contains the one input that every new user must touch. Keep it
   in normal document flow instead of a top-layer dialog over a fixed body: iOS
   can pan and scroll the page naturally without exposing a second coordinate
   system or a blank strip underneath the browser toolbar. */
.flow-frame { position: sticky; top: calc(var(--chrome-top) + env(safe-area-inset-top)); min-height: calc(100svh - var(--chrome-top) - env(safe-area-inset-top) - var(--chrome-bottom)); display: grid; place-items: center; padding: 18px 0; }
.flow-card { position: relative; width: min(480px, 100%); margin: 0; background: #fbfdfb; }
.flow-card h2 { margin-top: 0; padding-right: 38px; }
.flow-close { position: absolute; top: 10px; right: 10px; width: 36px; min-height: 36px; padding: 0; display: grid; place-items: center; color: var(--muted); border-radius: 999px; }
.danger-button { background: #aa382b; color: #fff; }
.property-row, .report-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; -webkit-tap-highlight-color: transparent; transition: transform .16s ease; }
.property-row:active, .report-row:active, .property-row.is-pressed, .report-row.is-pressed { transform: scale(.995); }
/* Both of these sat under a comfortable 44px target. */
.photo-menu summary { min-height: 44px; display: flex; align-items: center; justify-content: center; }
.skeleton { color: var(--muted); min-height: 86px; animation: skeleton-pulse 1.2s ease-in-out infinite alternate; }
@keyframes skeleton-pulse { to { opacity: .55; } }
/* Same identity as Front Desk's loading states, on an icon the native bundle
   already ships, so nothing new is downloaded. */
.loading { display: grid; place-items: center; gap: 13px; padding: 46px 0; color: var(--muted); font-size: 13px; }
.loading::before { content: ""; width: 38px; height: 38px; border-radius: 11px; background: url('/marketel-frontdesk-icon.png') center / cover no-repeat; box-shadow: 0 6px 18px rgba(30, 106, 76, .2); animation: frontdeskLogoBreathe 1.15s ease-in-out infinite; }
/* Signing in replaces the landing at once, so the wait reads as progress: the
   same logo, larger, in the middle of the screen. */
.loading.is-arriving { min-height: 56vh; gap: 16px; font-size: 15px; }
.loading.is-arriving::before { width: 60px; height: 60px; border-radius: 17px; }
@media (prefers-reduced-motion: reduce) { .loading::before { animation: none; } }
@keyframes frontdeskLogoBreathe { 0%, 100% { transform: translateY(0) scale(.96); opacity: .82; } 50% { transform: translateY(-2px) scale(1); opacity: 1; } }
.status-line { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin: 0 0 6px; }
.status-line .quiet { flex: 0 0 auto; padding: 7px 11px; font-size: 13px; min-height: 38px; }
/* Same glass recipe as the tab bar so the two read as one family. */
.price { font-size: 36px; font-weight: 750; }
blockquote { margin: 15px 0; background: #edf3ee; padding: 18px; border-radius: 10px; white-space: pre-wrap; }
.native-inspect-shell body { padding-top: calc(82px + env(safe-area-inset-top)); padding-bottom: calc(98px + env(safe-area-inset-bottom)); }
.native-inspect-shell body > header, .native-inspect-shell nav { display: none !important; }
/* The glass bar floats over every app screen now, signed in or not; only the
   tab bar waits for an account. The bar is 64pt tall, 6pt below the safe area,
   so 82px leaves the same 12pt gap under it that the tab bar gets above it. */
.native-inspect-shell { --shell-top: 82px; --chrome-top: 82px; --chrome-bottom: calc(12px + env(safe-area-inset-bottom)); }
.native-inspect-shell.inspect-authenticated { --shell-bottom: 98px; --chrome-bottom: calc(62px + env(safe-area-inset-bottom)); }
/* Most app users arrive from the web funnel with an account already, so their
   way back in is an outlined button of full weight, not a text link. */
.native-inspect-shell .hero #sign-in { margin-top: 12px; background: #ffffffe6; border: 1.5px solid #9cc9ae; }
.native-inspect-shell .hero #sign-in:active, .native-inspect-shell .hero #sign-in.is-pressed { background: #e8f5ee; }
/* In the app main has 16px of top padding instead of the margin. */
.native-inspect-shell .flow-screen { margin-top: -16px; }
/* A sheet tall enough to need the whole screen takes the shell with it. */
html.sheet-full { --shell-top: 0px; --shell-bottom: 0px; }
/* The plan sheet already hides the native header and tab bar. Give it the room
   that freed: a centred card still capped itself well below the screen, so the
   offer scrolled inside a mostly empty viewport. */
html.sheet-full dialog {
  left: 0; top: 0;
  transform: none;
  width: 100%;
  max-width: none;
  height: calc(100dvh - var(--kb, 0px));
  max-height: calc(100dvh - var(--kb, 0px));
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: calc(env(safe-area-inset-top, 0px) + 22px) 22px calc(env(safe-area-inset-bottom, 0px) + 20px);
  /* It takes the whole screen, so it has to arrive rather than appear. The
     global reduced-motion rule collapses this to nothing on its own. */
  animation: plan-in 280ms cubic-bezier(.32, .72, 0, 1) both;
}
@keyframes plan-in { from { opacity: 0; transform: translateY(22px) scale(.99); } to { opacity: 1; transform: none; } }
html.sheet-full #dialog-close { top: calc(env(safe-area-inset-top, 0px) + 12px); }
.native-inspect-shell main { margin-top: 0; padding-top: 16px; }
.native-inspect-shell:not(.inspect-authenticated) body { padding-bottom: calc(22px + env(safe-area-inset-bottom)); }
/* In the app the page runs up under the status bar and the shell paints no
   strip there any more. The glow is pinned to the screen, and a copy of the
   same paint covers just the status-bar band, so the top of the screen is one
   continuous colour at rest and while content scrolls beneath it. */
.native-inspect-shell body { background: transparent; }
.native-inspect-shell body::before, .native-inspect-shell body::after { content: ""; position: fixed; inset: 0; pointer-events: none; background: radial-gradient(circle at 50% -10%, #dceee3 0, transparent 36%), #eff4f0; }
.native-inspect-shell body::before { z-index: -1; }
.native-inspect-shell body::after { z-index: 11; clip-path: inset(0 0 calc(100% - env(safe-area-inset-top, 0px)) 0); }
/* Arriving from the app's tool chooser. The glass bar never moves, so only the
   page content rises in, in reading order. */
html.wedge-enter .hero > *, html.wedge-enter #app > :not(.hero) { animation: wedge-in 460ms cubic-bezier(.32,.72,0,1) backwards; }
html.wedge-enter .hero > :nth-child(2) { animation-delay: 45ms; }
html.wedge-enter .hero > :nth-child(3) { animation-delay: 90ms; }
html.wedge-enter .hero > :nth-child(4) { animation-delay: 135ms; }
html.wedge-enter .hero > :nth-child(5) { animation-delay: 170ms; }
html.wedge-enter .hero > :nth-child(n+6) { animation-delay: 200ms; }
@keyframes wedge-in { from { opacity: 0; transform: translateY(12px); } }
.native-inspect-shell:not(.inspect-authenticated) #notice { bottom: calc(var(--kb, 0px) + 24px + env(safe-area-inset-bottom)); }
/* The booking funnel's landing: one pain, one field, one button, one proof. */
.hero.golden h1 { font-size: clamp(36px, 6.4vw, 54px); }
.hero.golden h1 .green { color: var(--green); }
.lead-box { display: flex; gap: 8px; max-width: 520px; margin: 26px auto 8px; }
.lead-box input { flex: 1 1 auto; min-width: 0; min-height: 52px; font-size: 16px; }
.lead-box input.invalid { border-color: #aa382b; animation: lead-shake .32s ease; }
.lead-box button { flex: 0 0 auto; min-height: 52px; }
@keyframes lead-shake { 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }
.lead-note { margin: 4px 0 0; }
.proof { max-width: 460px; margin: 18px auto 6px; font-size: 14px; color: var(--muted); }
/* Setup: the flow card from the plan preview, one small step at a time. */
.setup-step { margin: 0 0 6px; font-size: 12px; font-weight: 750; letter-spacing: .12em; text-transform: uppercase; color: var(--green); }
.setup-screen .flow-card label { display: grid; gap: 6px; margin: 14px 0; }
.setup-screen .flow-card .button { display: flex; align-items: center; justify-content: center; gap: 6px; }
.logo-preview { display: flex; justify-content: center; margin: 10px 0; }
.logo-preview img { max-height: 72px; max-width: 200px; border-radius: 12px; }
.building { display: grid; place-items: center; text-align: center; padding: 18px 0; }
/* The business a report is sent under, above the product mark. */
.biz-header { display: flex; align-items: center; gap: 12px; margin: 0 0 14px; }
.biz-header img { max-height: 48px; max-width: 140px; border-radius: 10px; }
.biz-header strong { font-size: 20px; letter-spacing: -.3px; }
.reveal-actions { margin-top: 18px; }
/* Three ways to send, the best value preselected. */
.offer-options { display: grid; gap: 10px; margin: 16px 0 14px; }
.offer-option { display: grid; gap: 3px; text-align: left; width: 100%; background: #fff; color: inherit; border: 1.5px solid var(--border); border-radius: 16px; padding: 14px 16px; box-shadow: none; }
.offer-option strong { font-size: 19px; }
.offer-option small { color: var(--muted); font-weight: 500; }
.offer-option.is-selected { border-color: var(--green); background: var(--green-pale); }
.offer-option:active, .offer-option.is-pressed { transform: scale(.99); }
@media (max-width: 540px) {
  body > header { padding: 0 15px; }
  .header-drawer-content { padding-bottom: 18px; }
  .card { padding: 18px; }
  .grid { grid-template-columns: 1fr; }
  .hero { margin: 32px 0; }
  main { padding: 0 15px; }
  h1 { font-size: 34px; }
  .hero h1 { font-size: 44px; }
  .brand { font-size: 16px; }
  .brand-icon { width: 28px; height: 28px; }
  .brand-wordmark { width: 104px; }
  .lead-box { flex-direction: column; }
  .lead-box button { width: 100%; }
  .actions { left: 15px; right: 15px; width: auto; }
  .actions button { flex: 1 1 auto; }
  .app-handoff-card { display: grid; }
  .app-handoff-card button { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
  .loading::before { animation: none; opacity: .9; }
}

/* Uploading photos used to be a toast: it slid in from the edge, sat over the
   report, and said nothing about how far along it was. The work is blocking —
   losing the page mid-upload loses the photos — so it gets the same breathing
   Marketel mark every other wait in the product uses, over a veil that makes
   the page visibly unavailable rather than merely covered. */
.busy-veil { position: fixed; inset: 0; z-index: 70; display: grid; place-items: center; padding: 24px; background: #eff4f0e0; -webkit-backdrop-filter: blur(6px) saturate(130%); backdrop-filter: blur(6px) saturate(130%); animation: busyVeilIn .18s ease both; }
@keyframes busyVeilIn { from { opacity: 0; } to { opacity: 1; } }
.busy-veil .card { width: min(360px, 100%); margin: 0; text-align: center; }
.busy-veil .loading { padding: 8px 0 4px; }
.busy-veil h2 { margin: 0 0 4px; font-size: 19px; }
.busy-veil p { margin: 0; color: var(--muted); font-size: 13px; }
/* A determinate track only once there is more than one file to count. */
.busy-track { height: 5px; margin-top: 14px; border-radius: 999px; background: var(--green-pale); overflow: hidden; }
.busy-track span { display: block; height: 100%; border-radius: 999px; background: var(--green); transition: width .3s ease; }
@media (prefers-reduced-motion: reduce) {
  .busy-veil { animation: none; }
  .busy-track span { transition: none; }
}
/* The hint under each delivery choice. Tight to its button so the pair reads
   as one option rather than as a button and a loose sentence. */
.delivery-hint { margin: -4px 0 6px; font-size: 12px; }
/* Where the report says it was made. Quiet by design — it corroborates the
   property name rather than competing with it. */
.location-block { margin: 10px 0 14px; padding: 12px 14px; border: 1px solid var(--border); border-radius: 14px; background: var(--green-pale); }
.location-block p { margin: 2px 0; font-size: 13px; }
.location-block small { color: var(--muted); font-size: 11px; }

/* The half of the screen the camera sheet leaves uncovered. Large targets,
   because this is tapped one-handed while holding a phone up at a wall. */
.camera-companion { padding-top: 4px; }
/* Everything here has to read at arm's length, in sunlight, in the half of the
   screen the camera sheet leaves — and answer a thumb without being aimed at. */
.camera-companion h1 { font-size: 21px; margin: 0 0 6px; letter-spacing: -.6px; }
.camera-count { font-size: 13px; font-weight: 500; color: var(--muted); letter-spacing: 0; }
/* The shell steps aside while the camera is open, so its band is not reserved. */
.native-inspect-shell.camera-open body { padding-top: calc(env(safe-area-inset-top) + 6px); padding-bottom: 6px; }
.camera-open main { padding-top: 0; }
/* Rooms become chips so the prompts and the strip have room above the sheet. */
.camera-rooms { display: flex; gap: 8px; overflow-x: auto; margin-bottom: 10px; padding-bottom: 2px; -webkit-overflow-scrolling: touch; }
.camera-strip { display: flex; gap: 8px; overflow-x: auto; margin: 6px 0 4px; min-height: 8px; -webkit-overflow-scrolling: touch; }
.camera-strip figure { position: relative; flex: 0 0 auto; width: 46px; height: 46px; margin: 0; }
.camera-strip img { width: 100%; height: 100%; object-fit: cover; border-radius: 12px; }
.camera-strip .photo-x { top: -4px; right: -4px; }
.camera-strip p { margin: 0; }
/* Every shot carries its time under it, and a check-in's photo of the same
   room leads the strip, outlined, as the "before". */
.camera-strip figure { height: auto; }
.camera-strip img { height: 46px; }
.camera-strip figure small { display: block; margin-top: 2px; text-align: center; font-size: 10px; line-height: 1.2; color: var(--muted); font-variant-numeric: tabular-nums; }
.camera-strip figure.is-before button { display: block; width: 46px; height: 46px; min-height: 0; padding: 0; border: 2px solid var(--green); border-radius: 14px; background: none; overflow: hidden; }
.camera-strip figure.is-before img { border-radius: 11px; }
.camera-strip figure.is-before small { color: var(--green-dark); font-weight: 700; }
/* The before page: the check-in photo large, and one tap back to the camera. */
.before-page { padding: 4px 0 28px; }
.before-page #before-back { display: block; margin: 0 0 10px; }
.before-page .eyebrow { display: block; }
.before-page h1 { margin: 2px 0 12px; }
.before-photo { display: block; width: 100%; max-height: 62vh; object-fit: contain; border-radius: 16px; background: var(--green-pale); }
.before-thumbs { display: flex; gap: 8px; overflow-x: auto; margin-top: 10px; }
.before-thumbs button { flex: 0 0 auto; width: 56px; height: 56px; min-height: 0; padding: 0; border: 2px solid transparent; border-radius: 12px; overflow: hidden; background: none; }
.before-thumbs button.is-active { border-color: var(--green); }
.before-thumbs img { width: 100%; height: 100%; object-fit: cover; }
/* A property's last check-in, under its name. */
button.check-in-line { display: block; min-height: 32px; margin-top: 2px; padding: 0; font-size: 13px; color: var(--green-dark); text-align: left; }
p.check-in-line { margin: 4px 0 0; font-size: 13px; }
/* When a photo was taken, and when Marketel received it. */
.photo-caption { display: block; margin: 4px 0 14px; font-size: 12px; color: var(--muted); }
/* Placeholder rows: the page's own layout while its list is on the way. */
.skeleton-row { display: grid; gap: 10px; min-height: 76px; }
.skeleton-row span, .skeleton-line { display: block; height: 14px; border-radius: 7px; background: var(--green-pale); animation: skeleton-pulse 1.1s ease-in-out infinite alternate; }
.skeleton-row span:first-child { width: 46%; height: 16px; }
.skeleton-row span:last-child { width: 30%; }
.skeleton-line { width: 55%; margin: 4px 0; }
/* A deleted row folds away at once; the list is never reloaded around it. */
.report-row.is-leaving, .property-row.is-leaving { animation: row-leave .22s ease forwards; pointer-events: none; }
@keyframes row-leave { to { opacity: 0; transform: translateX(-14px) scale(.98); } }
.empty-state h2 { margin: 0 0 6px; }
/* Receipts and quotes sit under a finding's photos, smaller, apart. */
.receipts { margin: 6px 0 4px; }
.receipt-grid { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.receipt-grid figure { position: relative; width: 64px; height: 64px; margin: 0; }
.receipt-grid img { width: 100%; height: 100%; object-fit: cover; border-radius: 10px; border: 1px solid var(--border); }
.add-receipt { display: inline-flex; align-items: center; min-height: 40px; padding: 0 4px; font-size: 14px; font-weight: 650; color: var(--green-dark); cursor: pointer; }
.receipts-heading { margin: 14px 0 6px; font-size: 15px; }
.report-photo.receipt { max-height: 320px; object-fit: contain; }
/* Saved properties, one tap each. */
.property-chips { display: flex; gap: 8px; flex-wrap: wrap; margin: 4px 0 12px; }
.property-chips .chip { width: auto; min-height: 38px; padding: 7px 14px; border-radius: 999px; font-size: 14px; background: var(--green-pale); color: var(--green-dark); border: 1px solid var(--border); }
/* The filing window, for the host only. */
.deadline { margin: -2px 0 12px; font-size: 14px; font-weight: 650; color: var(--green-dark); }
.file-by { font-weight: 650; color: var(--green-dark); }
@media (prefers-reduced-motion: reduce) {
  .skeleton-row span, .skeleton-line { animation: none; }
  .report-row.is-leaving, .property-row.is-leaving { animation: none; opacity: 0; }
}
/* The recording is the point of this screen, so it is the biggest thing on it. */
.hud-note { min-height: 64px; padding: 12px 14px; margin: 0 0 8px; background: var(--surface); border: 1.5px solid var(--border); border-radius: 16px; font-size: 17px; line-height: 1.35; white-space: pre-wrap; overflow-y: auto; max-height: 104px; }
.hud-note.is-live { border-color: var(--green); background: var(--green-pale); }
.hud-actions { display: flex; justify-content: center; margin: 6px 0; }
/* Web: the photo you just added, then what it is. */
.entry-screen .screen-bar { margin-bottom: 8px; }
.entry-photos { display: flex; gap: 10px; overflow-x: auto; margin-bottom: 14px; }
.entry-photos figure { position: relative; flex: 0 0 auto; width: min(78vw, 320px); margin: 0; }
.entry-photos img { width: 100%; max-height: 320px; object-fit: cover; border-radius: 18px; }
.entry-note { display: block; margin-bottom: 12px; }
.entry-actions { margin-top: 4px; }
.finding-heading { font-size: 18px; margin: 0 0 10px; }
.camera-room { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex: 0 0 auto; width: auto; min-height: 40px; border-radius: 999px; padding: 9px 14px; text-align: left; background: var(--surface); color: inherit; border: 1px solid var(--border); border-radius: 14px; font-weight: 500; }
.camera-room strong { font-weight: 650; }
.camera-room span { color: var(--muted); font-size: 13px; font-weight: 450; }
.camera-room.is-active { background: var(--green); border-color: var(--green); color: #fff; }
.camera-room.is-active span { color: #ffffffc2; }
.camera-room.is-add { color: var(--green-dark); font-weight: 650; border-style: dashed; }

/* ——— The simulation funnel (?sim=1) ————————————————————————————————
   Four taps on a phone: pick, shutter, hold, pay. Everything here exists to
   make two of those taps feel like the app they are being sold — the shutter
   has to feel like taking a photo and the hold has to feel like speaking,
   because that feeling is the argument. */
.sim { padding-bottom: 28px; }
.sim-intro h1 { font-size: clamp(25px, 7vw, 33px); line-height: 1.12; letter-spacing: -.8px; margin: 6px 0 10px; }
.sim-intro .green { color: var(--green); }
.sim-fields { display: flex; gap: 10px; margin: 16px 0 22px; }
.sim-fields div { flex: 1 1 0; padding: 10px 12px; background: var(--surface); border: 1.5px solid var(--border); border-radius: 14px; }
.sim-fields small { display: block; color: var(--muted); font-size: 12px; margin-bottom: 2px; }
.sim-fields strong { font-weight: 650; font-size: 15px; }
.sim-prompt { font-size: 19px; margin: 0 0 12px; }
.sim-picks { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }
.sim-pick { display: block; padding: 0; background: var(--surface); border: 1.5px solid var(--border); border-radius: 16px; overflow: hidden; text-align: center; color: inherit; }
.sim-pick img { display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover; }
.sim-pick span { display: block; padding: 8px 5px; font-size: 12px; font-weight: 600; line-height: 1.25; }
.sim-pick:active, .sim-pick.is-pressed { transform: scale(.97); border-color: var(--green); }
.sim-foot { color: var(--muted); margin-top: 14px; }
.sim-stage .sim-foot { margin: 8px 0 0; font-size: 11px; }

/* The camera is a sheet across the bottom half and the HUD lives above it the
   whole time, because that is where they both are in the app. What they tap
   here is what they will tap on their phone. */
.sim-stage { padding-bottom: calc(52vh + 14px); padding-bottom: calc(52svh + 14px); }
/* svh is right on a phone, but a browser that does not know it drops the
   declaration and the sheet then sizes to its own content — which once buried
   the Hold to talk button entirely. The vh fallback comes first. */
.sim-sheet { position: fixed; left: 0; right: 0; bottom: 0; height: 52vh; height: 52svh; border-radius: 24px 24px 0 0; overflow: hidden; background: #0d120f; box-shadow: 0 -12px 34px #0f2a1e3d; z-index: 40; }
/* The viewfinder IS the sheet and the controls float over it, exactly as in
   NativeCamera.swift — giving the preview the leftover slice under a control
   row is what left it letterboxed. */
.sim-view { position: absolute; inset: 0; overflow: hidden; background: #000; transition: transform .12s ease; }
.sim-view.is-capturing { transform: scale(.965); }
.sim-feed { width: 100%; height: 100%; object-fit: cover; animation: sim-drift 11s ease-in-out infinite alternate; }
.sim-grain { position: absolute; inset: 0; pointer-events: none; opacity: .07; mix-blend-mode: overlay; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.sim-reticle { position: absolute; top: 50%; left: 50%; width: 76px; height: 76px; margin: -38px 0 0 -38px; border: 1.5px solid #ffffffe0; border-radius: 6px; opacity: 0; animation: sim-lock 1.9s ease .35s forwards; }
.sim-flash { position: absolute; inset: 0; background: #fff; opacity: 0; pointer-events: none; }
.sim-flash.is-on { animation: sim-flash .22s ease; }
/* White controls over an unpredictable photo need something behind them. */
.sim-sheet::before, .sim-sheet::after { content: ""; position: absolute; left: 0; right: 0; pointer-events: none; z-index: 1; }
.sim-sheet::before { top: 0; height: 84px; background: linear-gradient(#0b100dab, #0b100d00); }
.sim-sheet::after { bottom: 0; height: 190px; background: linear-gradient(#0b100d00, #0b100dc4 62%, #0b100de0); }
.sim-grabber { position: absolute; top: 9px; left: 50%; z-index: 2; width: 38px; height: 5px; margin-left: -19px; border-radius: 3px; background: #ffffff8a; }
.sim-done { position: absolute; top: 12px; right: 14px; z-index: 3; min-height: 36px; padding: 7px 16px; background: #ffffff2e; color: #fff; font-size: 15px; font-weight: 650; border-radius: 999px; -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
/* Strip, then what is being photographed, then the shutter — the message sits
   above the button rather than beside it. */
.sim-sheet-bar { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 0 16px calc(14px + env(safe-area-inset-bottom)); }
.sim-sheet-strip { align-self: flex-start; display: flex; gap: 6px; min-height: 40px; align-items: center; overflow: hidden; }
.sim-sheet-strip img { width: 40px; height: 40px; object-fit: cover; border-radius: 9px; border: 1.5px solid #ffffff5c; }
.sim-sheet-note { margin: 0; color: #fff; font-size: 13px; font-weight: 600; text-align: center; text-shadow: 0 1px 4px #000000a1; }
.sim-shutter { width: 68px; height: 68px; padding: 0; border-radius: 50%; background: #fff; border: 4px solid #ffffff6b; box-shadow: 0 2px 14px #0000004d; }
.sim-shutter:active, .sim-shutter.is-pressed { transform: scale(.92); }
.sim-shutter:disabled { opacity: .45; }
.sim-strip { display: flex; gap: 8px; align-items: center; min-height: 50px; margin: 8px 0 2px; }
.sim-strip p { margin: 0; }
.sim-shot { width: 46px; height: 46px; object-fit: cover; border-radius: 10px; opacity: 0; transform: scale(2.4) translateY(38px); transition: opacity .34s ease, transform .34s cubic-bezier(.2,.7,.3,1); }
.sim-shot.is-in { opacity: 1; transform: none; }

/* Their words arriving under their own finger. The raw line and the written
   one share the box so one replaces the other in place — that swap is the
   whole product, and it should happen where they are already looking. */
.sim-stage h1 { font-size: 20px; margin: 2px 0 8px; letter-spacing: -.6px; }
.sim-eyebrow { margin: 0; color: var(--muted); font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }
.sim-count { font-size: 13px; font-weight: 500; color: var(--muted); letter-spacing: 0; }
/* The hint, the raw line and the written note share one grid cell, so the box
   is always as tall as the tallest of them: the swap happens with nothing
   moving on the screen, and a faded-out hint cannot shove the transcript
   sideways the way an invisible inline span does. */
.sim-note { display: grid; min-height: 62px; max-height: 104px; overflow-y: auto; padding: 12px 14px; font-size: 16px; background: var(--surface); border: 1.5px solid var(--border); border-radius: 18px; font-size: 17px; line-height: 1.38; transition: background-color .4s ease, border-color .4s ease; }
.sim-note > * { grid-area: 1 / 1; align-self: start; transition: opacity .34s ease; }
.sim-hint-line { color: var(--muted); }
.sim-hint-line.is-gone { opacity: 0; }
.sim-written { opacity: 0; }
.sim-written p { margin: 0 0 6px; }
.sim-written small { color: var(--green); font-weight: 650; }
.sim-note.is-written { border-color: var(--green); background: var(--green-pale); }
.sim-note.is-written .sim-said, .sim-note.is-written .sim-hint-line { opacity: 0; }
.sim-note.is-written .sim-written { opacity: 1; }
/* Bar heights come from the sentence's own syllables, so this reads as a
   recording rather than an animation looping over a sine wave. */
.sim-wave { display: flex; align-items: center; justify-content: space-between; gap: 2px; height: 30px; margin: 8px 0 2px; transition: opacity .3s ease; }
.sim-wave i { flex: 1 1 0; height: 100%; background: var(--border); border-radius: 2px; transform: scaleY(.08); transform-origin: center; transition: transform .08s linear, background-color .12s ease; }
.sim-wave i.is-live { background: var(--green); }
.sim-wave.is-done { opacity: .35; }
/* Centred and tapped by them, with the worry answered underneath rather than
   a gesture to learn. */
.sim-actions { display: flex; justify-content: center; margin-top: 12px; }
/* Filled and pulsing, because a white circle reads as decoration and this is
   the one thing on the screen waiting to be pressed. */
.sim-mic { width: 66px; height: 66px; padding: 0; border-radius: 50%; display: grid; place-items: center; background: var(--green); color: #fff; border: none; }
.sim-mic:active, .sim-mic.is-pressed { transform: scale(.93); }
.sim-mic:not(.is-live):not(.is-done) { animation: sim-pulse 1.9s ease-in-out infinite; }
.sim-mic.is-live { background: var(--green-dark); color: #fff; animation: sim-pulse 1.1s ease-in-out infinite; }
.sim-mic.is-done { background: var(--green-pale); color: var(--green-dark); box-shadow: none; animation: none; opacity: 1; }
.sim-mic-hint { margin: 10px 0 14px; text-align: center; color: var(--green-dark); font-size: 14px; font-weight: 600; }
.sim-mic-hint.is-quiet { color: var(--muted); font-weight: 450; }
#sim-see { margin-top: 4px; }
.sim-talk-button.is-live { background: var(--green-dark); box-shadow: 0 0 0 6px #2e7d5b26; }
.sim-talk-button:disabled { opacity: 1; }

/* The sample document, then the price directly beneath it — the report is the
   argument and it should still be on screen while the ask is read. */
.sim-doc { position: relative; overflow: hidden; }
.sim-stamp { position: absolute; top: 34px; right: -42px; width: 190px; padding: 5px 0; transform: rotate(38deg); background: #2e7d5b1f; color: var(--green-dark); text-align: center; font-size: 12px; font-weight: 800; letter-spacing: .22em; }
.sim-offer { margin-top: 16px; }
.sim-offer h2 { margin-top: 0; }
/* Declining is not the end of it: the note that nothing was charged, and the
   free way to keep Marketel for the day it is needed. */
.sim-offer .sim-declined { margin: 0 0 6px; font-size: 14px; font-weight: 750; color: var(--green-dark); }
.sim-offer .sim-keep { margin: 6px 0 0; text-align: center; }
.sim-offer .sim-keep .quiet { font-size: 13px; white-space: normal; }
.payment-step { max-width: 620px; margin: 0 auto; padding-bottom: env(safe-area-inset-bottom); }
.payment-back { margin: 0 0 10px; }
.payment-progress { margin: 0 0 6px; color: var(--muted); font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.payment-step .embedded-payment { margin: 0; padding: 20px; text-align: left; }
.payment-step h1 { margin: 0 0 16px; font-size: 26px; letter-spacing: -.7px; outline: none; }
.checkout-review { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; margin: 7px 0 0; font-size: 12px; line-height: 1.35; }
.checkout-promise .checkout-review span { display: inline; font-size: 12px; line-height: 1.35; }
.checkout-promise .checkout-review .review-stars { color: var(--green-dark); font-size: 11px; }
.checkout-promise .checkout-review .checkout-review-quote { color: var(--green-dark); }
.checkout-promise .checkout-review .checkout-review-by { flex-basis: 100%; font-size: 11px; }
.checkout-next { margin: 0 6px 16px; color: var(--muted); font-size: 13px; }
.checkout-next h2 { margin: 0 0 4px; color: var(--green-dark); font-size: 14px; letter-spacing: 0; }
.checkout-next p { margin: 0 0 4px; line-height: 1.45; }
.checkout-next p:last-child { margin-bottom: 0; }
html.checkout-open body { padding-bottom: 20px; }
html.checkout-open #account-button { visibility: hidden; pointer-events: none; }
.embedded-payment-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; margin: 0 6px 12px; }
.checkout-secure { display: flex; align-items: center; gap: 6px; color: var(--green-dark); font-size: 13px; font-weight: 700; }
.checkout-stripe { display: inline-flex; align-items: center; gap: 5px; color: #475569; white-space: nowrap; }
.checkout-stripe small { font-size: 10px; }
.checkout-stripe strong { font-size: 20px; letter-spacing: -.7px; }
.embedded-payment-head .quiet { width: auto; min-height: 36px; margin: 0 -6px 0 0; padding: 6px 8px; font-size: 13px; }
.checkout-promise { display: flex; align-items: flex-start; gap: 10px; margin: 0 6px 12px; padding: 14px; background: var(--green-pale); border: 1px solid var(--border); border-radius: 14px; }
.checkout-promise .icon { flex-shrink: 0; color: var(--green); margin-top: 2px; }
.checkout-promise strong, .checkout-promise span { display: block; line-height: 1.5; }
.checkout-promise strong { font-size: 15px; }
.checkout-promise span { color: var(--muted); font-size: 12px; }
/* Keep the automatic balance terms ABOVE the card fields without burying
   those fields. The trial adds a line of disclosure, not a second pitch. */
.payment-step .paid-trial-payment h1 { margin-bottom: 8px; }
.paid-trial-payment .checkout-promise { padding: 10px; margin-bottom: 8px; }
.checkout-refund { margin: 0 10px 14px; }
.checkout-refund strong, .checkout-refund span { display: block; }
.checkout-refund strong { color: var(--green-dark); font-size: 13px; }
.checkout-refund span { margin-top: 3px; color: var(--muted); font-size: 12px; line-height: 1.5; }
.checkout-frame-shell { position: relative; min-height: 320px; }
#stripe-checkout { min-height: 320px; }
.checkout-loading { position: absolute; inset: 0; z-index: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; background: #fff; color: var(--muted); font-size: 14px; font-weight: 650; pointer-events: none; }
.checkout-spinner { width: 24px; height: 24px; border: 2px solid var(--border); border-top-color: var(--green); border-radius: 50%; animation: checkout-spin 900ms linear infinite; }
@keyframes checkout-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .checkout-spinner { animation: none; } }
#stripe-checkout.is-ready + .checkout-loading { display: none; }
.next-steps { margin: 16px 0 12px; padding: 12px 14px; border-radius: 12px; background: var(--green-pale); text-align: left; }
.next-steps h3 { margin: 0 0 8px; font-size: 14px; color: var(--green-dark); }
.next-steps ol { margin: 0; padding: 0; list-style: none; counter-reset: next; }
.next-steps li { position: relative; margin: 0 0 7px; padding-left: 28px; font-size: 13px; line-height: 1.45; counter-increment: next; }
.next-steps li:last-child { margin-bottom: 0; }
.next-steps li::before { content: counter(next); position: absolute; left: 0; top: 0; width: 20px; height: 20px; border-radius: 50%; background: var(--green-dark); color: #fff; font-size: 12px; font-weight: 700; text-align: center; line-height: 20px; }
.embedded-payment-note { margin: 8px 10px 0; text-align: center; color: var(--muted); }
html.checkout-open .sim-paybar { display: none; }
@media (max-width: 520px) {
  /* Stripe owns the padding and card-network icons INSIDE its iframe. Do not
     squeeze it inside main padding + card padding as well: at 390px that
     left only 338px and clipped the last card-number placeholder group.
     Give the secure form the full phone width; keep our copy inset. */
  html.checkout-open #app { padding-left: 0; padding-right: 0; }
  .payment-step .embedded-payment { padding: 16px 0; border-left: 0; border-right: 0; }
  .payment-step .payment-back { margin-left: 16px; margin-right: 16px; }
  .payment-step .payment-progress,
  .payment-step h1,
  .payment-step .checkout-promise,
  .payment-step .embedded-payment-head,
  .payment-step .checkout-refund,
  .payment-step .checkout-next { margin-left: 16px; margin-right: 16px; }
  .checkout-frame-shell, #stripe-checkout { width: 100%; min-width: 0; }
}
@media (max-width: 360px) {
  .payment-step h1 { font-size: 23px; }
}
.sim-trial-note { margin: -4px 0 12px; color: var(--muted); }

/* Nobody arriving from an ad needs the banner: they did not navigate here and
   they have no account to open. Taking it out is ~50px back at the top of
   every screen. The brand still signs the report card and the offer button,
   and simThanks() drops sim-mode before opening sign-in, because headerDrawer
   refuses to open against a header nobody can see. */
.sim-mode body > header, .sim-mode nav { display: none; }
.sim-mode body { padding-top: calc(14px + env(safe-area-inset-top)); padding-bottom: 0; }
.sim-mode main { margin-top: 0; }

/* A short phone has no room for the finding chips above the sheet. "Next
   finding" still walks the loop, which is the part that matters. */
/* An SE-sized phone has about 320px above the sheet, and the card waiting for
   the mic — note, waveform, mic and the line under it — ran under it. The
   camera gives some height back, the note is capped lower while it waits, and
   the footnote goes: the line under the mic already says the same thing. */
@media (max-height: 720px) {
  .sim-stage .sim-foot { display: none; }
  .sim-sheet { height: 46vh; height: 46svh; }
  .sim-stage { padding-bottom: calc(46vh + 14px); padding-bottom: calc(46svh + 14px); }
  /* Only while it is waiting for words: once written, the mic and waveform are
     gone and the finding gets its full height rather than a scroll bar. */
  .sim-note:not(.is-written) { max-height: 80px; }
  .sim-mic-hint { margin: 8px 0 6px; }
}

/* Whichever control is live wears the ring; the other is visibly out of play.
   Two live buttons with no stated order is the same as no instruction. */
.is-live-step { animation: sim-pulse 1.9s ease-in-out infinite; }
.sim-talk-button:disabled, .sim-shutter:disabled { opacity: .38; animation: none; }
.sim-talk-button:disabled { box-shadow: none; }
.sim-demo { display: inline-block; margin-left: 6px; padding: 2px 8px; border-radius: 999px; background: #2e7d5b1f; color: var(--green-dark); font-size: 10px; font-weight: 800; letter-spacing: .1em; vertical-align: middle; }

/* The price rides with the report. Before this the buy button sat 3.3 screens
   down, which on cold traffic is the same as not being there. */
.sim-paybar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; display: flex; align-items: center; gap: 12px; padding: 12px 16px calc(12px + env(safe-area-inset-bottom)); background: #fbfdfbf2; border-top: 1px solid var(--border); box-shadow: 0 -8px 24px #173b231a; -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); transition: transform .28s ease, opacity .28s ease; }
.sim-paybar.is-stood-down { transform: translateY(105%); opacity: 0; pointer-events: none; }
/* The price over its terms, so the button keeps one line of its own. */
.sim-paybar div { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-start; gap: 1px; }
.sim-paybar strong { font-size: 20px; font-weight: 750; line-height: 1.15; }
.sim-paybar small { color: var(--muted); font-weight: 600; font-size: 13px; line-height: 1.2; }
.sim-paybar button { flex: 1 1 auto; min-height: 50px; font-size: 16px; white-space: nowrap; }
.sim-paybar.has-guarantee { flex-wrap: wrap; row-gap: 6px; }
.sim-paybar .guarantee-badge { flex: 0 0 100%; display: flex; align-items: center; justify-content: center; gap: 6px; margin: 0; color: var(--green); font-size: 12px; font-weight: 700; line-height: 1.2; }
.sim-report { padding-bottom: 96px; }
/* Annual is a text switch in the small print rather than a segmented control:
   the sticky bar is the offer, and a second full choice under it is a fifth
   decision on a screen that has already made its case. */
.sim-plan-switch { display: inline; padding: 0; min-height: 0; font-size: inherit; font-weight: 650; text-decoration: underline; text-underline-offset: 2px; }
.sim-plan-switch:active, .sim-plan-switch.is-pressed { background: transparent; }
/* One field, on our page rather than Stripe's, so their page opens prefilled. */
.sim-email h1 { font-size: clamp(23px, 6.4vw, 30px); line-height: 1.15; letter-spacing: -.7px; margin: 6px 0 10px; }
.sim-email input { width: 100%; min-height: 54px; margin: 16px 0 12px; padding: 14px 16px; font-family: inherit; font-size: 16px; background: var(--surface); border: 1.5px solid var(--border); border-radius: 16px; }
.sim-email input:focus { outline: none; border-color: var(--green); }
.sim-email input.invalid { border-color: #b3261e; }
.sim-email .quiet { margin-top: 8px; }
/* Three full-bleed photos are what made the report card 2266px tall. The
   sample only has to read as the document; the real renderer is untouched. */
.sim-doc .report-photo { max-height: 200px; object-fit: cover; }
.sim-doc .report-room { margin-bottom: 4px; }
.sim-doc .report-room h2 { margin-bottom: 6px; }
.sim-doc .report-note { margin: 0 0 10px; }
/* "Camera capture" under every photo is provenance that matters on a real
   report and is noise on a sample. */
.sim-doc .report-photo + small { display: none; }

/* The one thing actually asked for, said out loud a beat after they hesitate.
   A halo alone still leaves someone guessing; the words remove the guess. */
.sim-shutter-wrap { position: relative; display: grid; place-items: center; }
.sim-coach { position: absolute; bottom: calc(100% + 12px); margin: 0; padding: 6px 12px; border-radius: 999px; background: #0b100dd9; color: #fff; font-size: 13px; font-weight: 650; white-space: nowrap; opacity: 0; transform: translateY(6px); transition: opacity .3s ease, transform .3s ease; }
.sim-coach.is-on { opacity: 1; transform: none; }
.sim-coach::after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -5px; border: 5px solid transparent; border-top-color: #0b100dd9; }
.sim-coach-ring { position: absolute; width: 68px; height: 68px; border-radius: 50%; border: 2px solid #ffffffcc; opacity: 0; pointer-events: none; }
.sim-coach-ring.is-on { opacity: 1; animation: sim-coach-tap 1.6s ease-in-out infinite; }
@keyframes sim-coach-tap { 0%, 100% { transform: scale(1.18); opacity: .9; } 45% { transform: scale(.9); opacity: .35; } }
@keyframes sim-pulse { 0%, 100% { box-shadow: 0 0 0 0 #2e7d5b5c; } 55% { box-shadow: 0 0 0 11px #2e7d5b00; } }

@keyframes sim-drift { from { transform: scale(1.02); } to { transform: scale(1.05) translate3d(-1%, .8%, 0); } }
@keyframes sim-flash { from { opacity: .92; } to { opacity: 0; } }
@keyframes sim-lock { 0% { opacity: 0; transform: scale(1.5); } 40% { opacity: .95; transform: scale(1); } 70% { opacity: .95; transform: scale(.92); } 100% { opacity: .4; transform: scale(.92); } }
/* The JS already skips its own timings under reduced motion; this covers the
   decoration it does not control. */
@media (prefers-reduced-motion: reduce) {
  .sim-feed { animation: none; }
  .sim-reticle { animation: none; opacity: .4; }
  .sim-shot { transition: none; opacity: 1; transform: none; }
  .sim-coach-ring.is-on { animation: none; }
  .sim-mic.is-live { animation: none; }
}

/* The card the camera hands over to. It rises and settles rather than the page
   blinking, because the sheet below it never moved. */
.camera-companion.is-entering { animation: hud-in .34s cubic-bezier(.2,.7,.3,1) both; }
@keyframes hud-in { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
/* The shot just taken, large, beside the microphone: does it look good? */
.hud-stage { display: flex; align-items: center; gap: 12px; margin: 6px 0 6px; }
.hud-stage .hud-actions { margin: 0; flex: 0 0 auto; }
.hud-preview { position: relative; flex: 1 1 auto; min-width: 0; height: 128px; border-radius: 16px; overflow: hidden; background: var(--surface); border: 1.5px solid var(--border); display: grid; place-items: center; }
.hud-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hud-preview .photo-x { top: 6px; right: 6px; }
.hud-preview small { position: absolute; left: 8px; bottom: 8px; padding: 2px 8px; border-radius: 999px; background: #0d1a13b8; color: #fff; font-size: 11px; font-variant-numeric: tabular-nums; }
.hud-preview.is-empty { border-style: dashed; }
.hud-preview.is-empty p { margin: 0; padding: 0 12px; text-align: center; }
.hud-preview.is-fresh { animation: photo-pop .44s cubic-bezier(.2,.9,.3,1.25) both; }
.camera-strip .strip-pick { display: block; width: 46px; height: 46px; min-height: 0; padding: 0; border: 2px solid transparent; border-radius: 14px; background: none; overflow: hidden; }
.camera-strip .strip-pick.is-active { border-color: var(--green); }
.camera-strip .strip-pick img { border-radius: 11px; }
/* The page after the camera, and where an open report lands. */
.finding-card .finding-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 4px; }
.finding-card .finding-head .finding-heading { margin: 0; }
.finding-card textarea { min-height: 84px; }
.review-photos { display: flex; flex-wrap: wrap; gap: 10px; margin: 12px 0; }
.review-photos figure { position: relative; width: 96px; margin: 0; }
.review-photos figure img { width: 96px; height: 96px; object-fit: cover; border-radius: 14px; display: block; }
.review-photos .photo-meta { padding: 0; }
.review-photos figcaption { margin-top: 3px; text-align: center; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.review-photos .photo-add { width: 96px; height: 96px; min-height: 0; padding: 0; display: grid; place-content: center; gap: 2px; border: 2px dashed var(--border); border-radius: 14px; background: var(--surface); color: var(--green-dark); }
.review-photos .photo-add span { font-size: 28px; line-height: 1; font-weight: 500; }
.review-photos label.photo-add { cursor: pointer; }
.review-photos .photo-add .icon { margin: 0 auto; }
.review-photos .photo-add small { color: var(--green-dark); font-weight: 650; }
.finding-card .polish { align-self: flex-start; }
.review-dates { padding: 14px 16px; }
.review-dates summary { cursor: pointer; font-weight: 650; }
.review-dates .grid { margin-top: 12px; }
.review-property .property-chips { margin: 4px 0 10px; }
/* The shot just taken pops into the large preview, so a photo taken is a
   photo seen. Only the new one moves; the page does not blink. */
@keyframes photo-pop { 0% { opacity: 0; transform: scale(.3) translateY(18px); } 55% { opacity: 1; transform: scale(1.1); } 100% { opacity: 1; transform: none; } }
/* The button was always a tap-to-toggle calling itself "Hold to talk". It is a
   microphone, so it looks like one, and it says what it is doing while it is on. */
.hud-mic { flex: 0 0 auto; width: 66px; height: 66px; padding: 0; border-radius: 50%; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
.hud-mic.is-live { background: #b3261e; animation: hud-mic-live 1.5s ease-in-out infinite; }
@keyframes hud-mic-live { 0%, 100% { box-shadow: 0 0 0 0 #b3261e52; } 60% { box-shadow: 0 0 0 12px #b3261e00; } }
@media (prefers-reduced-motion: reduce) {
  .camera-companion.is-entering { animation: none; }
  .hud-preview.is-fresh { animation: none; }
  .hud-mic.is-live { animation: none; }
}

/* Desktop: the landing leads with the simulation (goldenLanding). */
/* `display: flex` on .lead-box would otherwise beat the hidden attribute. */
.demo-cta-box { display: flex; flex-direction: column; align-items: center; gap: 6px; max-width: 520px; margin: 26px auto 8px; }
/* Desktop: the simulation in a phone-sized frame (simFrame). The transform
   makes the frame the containing block for the fixed camera sheet, pay bar and
   notices, so they stay inside the phone instead of spanning the window. */
html.sim-framed body { padding: 18px 0 24px; background: #e3ece6; }
html.sim-framed #app { width: 390px; max-width: calc(100vw - 32px); height: min(844px, calc(100vh - 96px)); margin: 0 auto; padding: 22px 16px 28px; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; background: #eff4f0; border: 10px solid #1a2b22; border-radius: 44px; box-shadow: 0 30px 80px #173b2340; transform: translateZ(0); scrollbar-width: none; }
html.sim-framed #app::-webkit-scrollbar { display: none; }
html.sim-framed .sim-sheet { height: 52%; }
#sim-frame-back { display: block; width: 390px; max-width: calc(100vw - 32px); margin: 0 auto 10px; text-align: left; }

/* Desktop split (simSide): the phone on the left, the report building on the
   right, and at the end the offer beside it rather than inside the phone. */
html.sim-framed.sim-split body { padding-left: 24px; padding-right: 24px; display: grid; grid-template-columns: 390px minmax(280px, 460px); justify-content: center; column-gap: clamp(24px, 4vw, 64px); align-content: start; }
html.sim-framed.sim-split #sim-frame-back { grid-row: 1; grid-column: 1; width: auto; margin: 0 0 10px; }
html.sim-framed.sim-split #app { grid-row: 2; grid-column: 1; margin: 0; }
.sim-side { grid-row: 2; grid-column: 2; align-self: center; max-height: min(844px, calc(100vh - 96px)); overflow-y: auto; padding: 4px; }
.sim-split .sim-paybar { display: none; }
.sim-split .sim-report { padding-bottom: 28px; }
.sim-side-steps { list-style: none; counter-reset: step; display: flex; flex-wrap: nowrap; gap: 6px; padding: 0; margin: 0 0 16px; }
.sim-side-steps li { counter-increment: step; display: flex; align-items: center; gap: 7px; white-space: nowrap; padding: 6px 11px 6px 7px; border-radius: 999px; background: #fff; border: 1px solid var(--border); color: var(--muted); font-size: 13px; font-weight: 650; transition: color .2s, border-color .2s, box-shadow .2s; }
.sim-side-steps li::before { content: counter(step); display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--green-pale); color: var(--green); font-size: 11px; font-weight: 750; }
.sim-side-steps li.is-now { color: var(--green-dark); border-color: var(--green); box-shadow: 0 0 0 3px #e8f5ee; }
.sim-side-steps li.is-done { color: var(--green-dark); }
.sim-side-steps li.is-done::before { content: "\2713"; background: var(--green); color: #fff; }
.sim-side-doc { margin: 0; }
.sim-side-doc h2 { margin: 6px 0 2px; font-size: 26px; letter-spacing: -.4px; }
.sim-side-room { margin-top: 16px; padding: 16px; border: 1px solid var(--border); border-radius: 16px; }
.sim-side-room h3 { margin: 0 0 6px; font-size: 18px; }
.sim-side-note { margin: 0 0 12px; line-height: 1.5; min-height: 1.5em; }
.sim-side-note.is-empty { color: var(--muted); font-style: italic; }
.sim-side-note.is-live { color: var(--muted); }
.sim-side-photo { position: relative; margin: 0; border-radius: 12px; overflow: hidden; aspect-ratio: 4 / 3; background: var(--green-pale); }
.sim-side-photo img { display: block; width: 100%; height: 100%; object-fit: cover; animation: side-photo-in .35s ease; }
.sim-side-photo figcaption { position: absolute; left: 10px; bottom: 10px; padding: 4px 9px; border-radius: 999px; background: #1a2b22cc; color: #fff; font-size: 12px; font-weight: 700; }
.sim-side-photo.is-empty { display: grid; place-items: center; background: transparent; border: 1.5px dashed var(--border); color: var(--muted); font-size: 14px; }
.sim-side-deadline { margin: 14px 0 0; color: var(--green-dark); font-size: 14px; font-weight: 700; }
.sim-side-ready { margin: 0 0 4px; font-size: 28px; letter-spacing: -.4px; }
@media (max-width: 1000px) { .sim-side-steps { flex-wrap: wrap; } }
@keyframes side-photo-in { from { opacity: 0; transform: scale(1.03); } }
@media (prefers-reduced-motion: reduce) { .sim-side-photo img { animation: none; } }

/* Under the demo's offer: screens of the real app (simAppProof). */
.sim-app-proof { margin-top: 18px; }
.sim-app-proof h3 { margin: 2px 0 10px; font-size: 18px; }
.sim-app-proof > p { margin: 6px 0 0; }
.sim-screens { display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; padding: 2px 2px 8px; overscroll-behavior-x: contain; scrollbar-width: none; }
.sim-screens::-webkit-scrollbar { display: none; }
.sim-screens figure { flex: 0 0 54%; margin: 0; scroll-snap-align: start; }
.sim-screens img { display: block; width: 100%; height: auto; border-radius: 18px; border: 1px solid var(--border); background: var(--green-pale); box-shadow: 0 6px 18px #173b2318; }
.sim-screens figcaption { margin-top: 8px; font-size: 13px; font-weight: 650; line-height: 1.35; }
.sim-screens-wrap { position: relative; }
.sim-screens figure { cursor: pointer; }
/* Positioned without a transform: a pressed button scales, and that would jump. */
.sim-screens-arrow { position: absolute; top: calc(42% - 20px); z-index: 2; width: 40px; height: 40px; min-height: 40px; padding: 0; display: grid; place-items: center; border-radius: 50%; border: 1px solid var(--border); background: #ffffffee; color: var(--green-dark); font-size: 26px; line-height: 1; box-shadow: 0 4px 14px #173b2324; }
.sim-screens-arrow.is-prev { left: 6px; }
.sim-screens-arrow.is-next { right: 6px; }
.sim-screens-dots { display: flex; justify-content: center; gap: 2px; margin: 2px 0 0; }
.sim-dot { width: 24px; height: 24px; min-height: 24px; padding: 0; display: grid; place-items: center; border: 0; border-radius: 50%; background: transparent; }
.sim-dot::after { content: ""; width: 8px; height: 8px; border-radius: 999px; background: var(--border); transition: width .2s, background .2s; }
.sim-dot.is-on::after { width: 20px; background: var(--green); }
@media (prefers-reduced-motion: reduce) { .sim-dot::after { transition: none; } }
@media (hover: hover) and (pointer: fine) { .sim-screens-arrow:hover { background: #fff; color: var(--green); } .sim-dot:hover { background: transparent; } .sim-dot:hover::after { background: var(--green-light); } }

/* The demo's report page ends in one way on (simReport); the offer is its own page. */
.sim-next { margin-top: 16px; text-align: center; }
.sim-next p { margin: 6px 0 0; }
.sim-nextbar button { flex: 1 1 auto; min-height: 50px; font-size: 16px; }
.sim-back-report { margin: 0 0 4px -12px; }
.sim-offer-page { padding-bottom: 96px; }
/* The video landing: the job, a thin moving tape of real reviews, then a
   recording sized to the leftover phone screen, then the full offer card. */
.offer-landing { display: grid; gap: 14px; padding-bottom: 96px; min-width: 0; }
.offer-intro { text-align: center; }
.offer-intro h1 { margin: 8px 0 8px; font-size: clamp(27px, 7.2vw, 44px); letter-spacing: -1.1px; }
.offer-intro h1 .green { color: var(--green); }
.offer-intro p { margin: 0; }
.offer-intro h1, .offer-intro p { text-wrap: balance; }
.offer-intro .offer-trust { margin-top: 10px; }
.offer-intro .guarantee-badge { display: inline-flex; align-items: center; gap: 7px; margin: 10px 0 0; color: var(--green); font-size: 15px; font-weight: 700; }
.guarantee-badge .icon { flex: 0 0 auto; }
.guarantee { margin: 16px 0 2px; text-align: left; }
.guarantee-title { display: flex; align-items: center; gap: 8px; margin: 0; color: #1a2b22; font-size: 16px; font-weight: 750; letter-spacing: -0.2px; line-height: 1.25; }
.guarantee-title .icon { flex: 0 0 auto; color: var(--green); }
.guarantee-line { margin: 6px 0 0; color: var(--muted); font-size: 14px; font-weight: 500; line-height: 1.4; }
.offer-video { position: relative; margin: 0; justify-self: center; width: 100%; max-width: 440px; text-align: center; }
.offer-video video { display: block; margin: 0 auto; width: auto; max-width: 100%; height: min(calc(100svh - 300px), 720px); aspect-ratio: 720 / 1556; object-fit: cover; border-radius: 16px; background: #dfe9e2; box-shadow: 0 18px 44px #173b2340; }
.sim-thanks #sim-get-app { margin-top: 10px; }
.offer-fine { margin: 10px 0 0; text-align: center; color: var(--muted); font-size: 14px; font-weight: 600; }
.sim-offer.is-tight { padding: 18px 18px 16px; text-align: center; }
.sim-offer.is-tight #sim-buy { margin: 0; }
.pick-label { margin: 0; flex: 0 0 auto; font-size: 17px; font-weight: 700; letter-spacing: -0.2px; text-align: center; }
.pick-bar { display: flex; gap: 10px; width: 100%; flex: 0 0 auto; }
.pick-bar button { min-height: 52px; margin: 0; font-size: 17px; }
.pick-bar #pick-yes { flex: 1.1 1 0; white-space: nowrap; padding-left: 8px; padding-right: 8px; }
.pick-bar #pick-no { flex: 1 1 0; white-space: nowrap; padding-left: 8px; padding-right: 8px; background: #ffffffe6; border: 1px solid var(--border); font-size: clamp(14px, 4vw, 16px); }
.pick-reasons { display: grid; gap: 10px; width: 100%; }
.pick-reasons button { min-height: 52px; margin: 0; font-size: 16px; background: #ffffffe6; border: 1px solid var(--border); }
.pick-reasons .quiet { min-height: 42px; background: #ffffff8c; border-color: transparent; }
.offer-landing.is-pick.is-asking::before { background: #e8f0eaf5; transition: background .2s ease; }
.offer-landing.is-pick .offer-video.is-asking { justify-content: center; }
.offer-landing.is-pick .offer-video.is-asking video { display: none; }
.offer-landing.is-pick .offer-video.is-asking .pick-label { font-size: 21px; margin-bottom: 4px; }
html.pick-open, html.pick-open body { overflow: hidden; overscroll-behavior: none; }
/* Step one on a phone: the recording floats over the page, which shows blurred
   behind it, and is as big as the screen allows. */
.offer-landing.is-pick::before, .offer-landing.pick-leaving::before { content: ""; position: fixed; z-index: 44; left: 0; right: 0; bottom: 0; top: calc(env(safe-area-inset-top) + 64px); background: #e8f0ea99; -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px); transition: opacity .22s ease; }
.offer-landing.is-pick .offer-video { position: fixed; z-index: 46; left: 14px; right: 14px; top: calc(env(safe-area-inset-top) + 82px); bottom: calc(14px + env(safe-area-inset-bottom)); display: flex; flex-direction: column; align-items: center; gap: 10px; margin: 0; padding: 0; width: auto; max-width: none; transition: opacity .22s ease, transform .22s ease; }
.offer-landing.is-pick .offer-video video { flex: 1 1 0; min-height: 0; width: auto; height: auto; max-width: 100%; border-radius: 26px; }
.offer-landing.pick-leaving::before { opacity: 0; }
.offer-landing.pick-leaving .offer-video { opacity: 0; transform: scale(.97); }
.offer-landing.is-pick .offer-video-title, .offer-landing.is-pick .offer-video figcaption, .offer-landing.is-pick .offer-tape, .offer-landing.is-pick ~ .sim-paybar, .offer-landing.pick-leaving ~ .sim-paybar { display: none; }
.offer-landing.is-pick { padding-bottom: 0; }
@media (prefers-reduced-motion: reduce) { .offer-landing.is-pick .offer-video, .offer-landing.is-pick::before { transition: none; } }
.video-play { position: absolute; z-index: 2; width: 72px; height: 72px; margin: -36px 0 0 -36px; padding: 0; display: grid; place-items: center; border-radius: 50%; background: #ffffffe6; box-shadow: 0 10px 30px #173b2352; }
.video-play svg { width: 34px; height: 34px; margin-left: 4px; fill: var(--green); }
.offer-video-title { margin: 0 0 10px; font-size: 17px; font-weight: 700; text-align: center; letter-spacing: -0.2px; }
.offer-video figcaption { margin-top: 8px; text-align: center; font-size: 12px; color: var(--muted); }
.offer-buy .sim-offer { margin-top: 0; }
.sim-offer .offer-points { margin: 18px 2px 14px; }
.offer-points { list-style: none; margin: 16px 4px 8px; padding: 0; display: grid; gap: 8px; }
.offer-points li { position: relative; padding-left: 26px; line-height: 1.35; }
.offer-points li::before { content: "✓"; position: absolute; left: 0; color: var(--green-dark); font-weight: 900; }
/* Social proof: stars under the job, then a short moving tape of real quotes. */
.offer-trust { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 2px 2px 4px; flex-wrap: wrap; }
.review-stars { color: var(--green); letter-spacing: 1px; font-size: 15px; line-height: 1; white-space: nowrap; }
.review-stars-off { color: var(--border); }
.offer-trust-text { color: var(--muted); font-size: 14px; font-weight: 600; }
.offer-tape { width: 100%; min-width: 0; max-width: 100%; overflow: hidden; mask-image: linear-gradient(90deg, transparent, #000 24px, #000 calc(100% - 24px), transparent); }
.offer-tape-track { display: flex; width: max-content; animation: offer-tape 90s linear infinite; }
.offer-tape-run { display: flex; gap: 10px; padding-right: 10px; }
.tape-card { flex: 0 0 220px; margin: 0; padding: 10px 12px; background: var(--surface); border: 1px solid var(--border); border-radius: 14px; }
.tape-card .review-stars { display: block; margin-bottom: 4px; font-size: 13px; }
.tape-card blockquote { margin: 0; padding: 0; background: none; border-radius: 0; white-space: normal; font-size: 13px; line-height: 1.35; letter-spacing: -.15px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tape-card figcaption { margin-top: 6px; display: flex; flex-direction: column; gap: 0; }
.review-name { font-weight: 700; font-size: 12px; }
.review-role { color: var(--muted); font-size: 11px; }
@keyframes offer-tape { to { transform: translateX(-50%); } }
@media (hover: hover) and (pointer: fine) { .offer-tape:hover .offer-tape-track { animation-play-state: paused; } }
@media (prefers-reduced-motion: reduce) {
  .offer-tape-track { animation: none; }
  .offer-tape-run + .offer-tape-run { display: none; }
}
@media (min-width: 880px) {
  .offer-landing { grid-template-columns: auto minmax(0, 440px); grid-template-areas: "video intro" "video tape" "video buy"; justify-content: center; column-gap: 48px; align-content: start; }
  .offer-intro { grid-area: intro; text-align: left; align-self: end; }
  .offer-tape { grid-area: tape; }
  .offer-video { grid-area: video; position: sticky; top: 90px; align-self: start; width: auto; max-width: none; }
  .offer-video video { height: min(72vh, 640px); width: auto; }
  .offer-buy { grid-area: buy; }
  .offer-landing ~ .sim-paybar { display: none; }
  .offer-landing.is-pick::before { display: none; }
  .offer-landing.is-pick .offer-video { position: sticky; top: 90px; left: auto; right: auto; bottom: auto; z-index: auto; display: block; padding: 0; background: none; border: 0; box-shadow: none; }
  .offer-landing.is-pick .offer-video video { height: min(64vh, 600px); width: auto; flex: none; }
  .offer-landing.is-pick .offer-buy { display: none; }
  .pick-label { margin-bottom: 10px; }
  .pick-bar { margin-top: 12px; }
}

/* The launch price: the real alternative it replaces, and the fixed moment it
   ends. Tabular figures so the clock does not shuffle as it ticks. */
.price-anchor { margin: 0 0 2px; color: var(--muted); font-size: 15px; }
.price-anchor s { text-decoration-thickness: 2px; }
.launch-clock { margin: 6px 0 12px; font-size: 14px; font-weight: 600; color: #aa382b; }
.launch-clock strong, .sim-paybar small { font-variant-numeric: tabular-nums; }
.sim-paybar .bar-was { font-size: 14px; font-weight: 600; color: var(--muted); margin-right: 3px; text-decoration-thickness: 2px; }
.sim-paybar small.bar-clock { color: #aa382b; }

/* "How do I cancel?": a plain, obviously tappable answer with the real screens. */
.cancel-help { margin: 12px 0; border: 1.5px solid var(--green); border-radius: 12px; background: #fff; text-align: left; }
.cancel-help > summary { list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 48px; padding: 0 14px; color: var(--green-dark); font-weight: 700; font-size: 15px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.cancel-help > summary::-webkit-details-marker { display: none; }
.cancel-help > summary::after { content: '+'; flex: 0 0 auto; width: 24px; height: 24px; line-height: 22px; text-align: center; border-radius: 50%; background: var(--green-pale); font-size: 18px; }
.cancel-help[open] > summary::after { content: '−'; }
.cancel-help-body { padding: 0 14px 14px; font-size: 14px; line-height: 1.5; }
.cancel-help-body p { margin: 0 0 8px; }
.cancel-help-body ol { margin: 0 0 10px; padding: 0; list-style: none; counter-reset: cancel; }
.cancel-help-body li { position: relative; margin: 0 0 12px; padding-left: 28px; counter-increment: cancel; }
.cancel-help-body li::before { content: counter(cancel); position: absolute; left: 0; top: 0; width: 20px; height: 20px; border-radius: 50%; background: var(--green-dark); color: #fff; font-size: 12px; font-weight: 700; line-height: 20px; text-align: center; }
.cancel-help-body li img { display: block; width: 100%; max-width: 320px; height: auto; margin-top: 8px; border: 1px solid var(--border); border-radius: 10px; }
.checkout-refund .cancel-help { margin: 10px 0 0; }

.checkout-promise .cancel-help-link { color: inherit; text-decoration: underline; text-underline-offset: 2px; font-weight: 700; }

.sim-thanks .paid-trial-where { margin: 10px 0 6px; font-size: 14px; line-height: 1.45; }
.sim-thanks #paid-trial-manage { display: block; padding: 13px 14px; border: 1.5px solid var(--green); border-radius: 12px; color: var(--green-dark); font-weight: 700; text-align: center; text-decoration: none; }
