/* Paperdash — design system v3. Figtree, Forest accent, Ink/Cream surfaces.
   Consolidated from styles.css + styles-v2.css. Source of truth for all UI.
   Follows Paperdash Style Guide v1.0. */

/* ── Google Fonts preload handled in HTML <head> ── */
/* Figtree: 400, 500, 600, 700, 800 */

:root {
  /* Green scale */
  --accent:         #4A7A5C;  /* Forest — primary */
  --accent-bright:  #6B9B82;  /* Sage — lighter */
  --accent-deep:    #3A6248;  /* Deep */
  --accent-tint:    #EAF0EC;  /* Tint */
  --accent-softer:  #F2F7F4;  /* Very light tint */

  /* Dark surfaces */
  --header:         #1C1C18;  /* Ink / BG — surface-900 */
  --header-card:    #252520;  /* Card on dark — surface-800 */
  --header-elevated:#2E2E28;  /* Elevated — surface-700 */
  --header-hover:   #3A3A34;  /* Hover — surface-600 */
  --header-line:    rgba(255,255,255,0.08);
  --header-icon-bg: #252520;

  /* Light surfaces */
  --parchment:      #F0EDE6;  /* Cream — light bg */
  --card:           #FAFAF7;  /* White — card surface */
  --field:          #FAFAF7;

  /* Text */
  --ink:            #1C1C18;  /* Primary text */
  --ink-soft:       #5E5E58;  /* Secondary text — ink-60 */
  --steel:          #5E5E58;  /* Same as ink-soft */
  --steel-light:    #9A9890;  /* Muted — ink-40 */

  /* Borders */
  --line:           #C8C5BC;  /* Border — ink-20 */
  --line-soft:      #E2DFD8;  /* Soft border */

  /* Status & semantic */
  --status-sent:    #3E6FA6;  /* Slate blue */
  --status-draft:   #787470;  /* Stone */
  --status-unpaid:  #C44040;  /* Red */
  --status-low:     #B07A1E;  /* Amber — running low, not yet blocked */
  --status-paid:    #4A7A5C;  /* Forest */

  /* System */
  --radius:         14px;
  --focus:          0 0 0 3px rgba(74,122,92,.18);
  --body:           'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  /* Body/label text weight — established by onboarding (.ob-p / #onboarding-screen label).
     Reused across every other screen's body copy and field labels so the whole app
     reads at one visual weight instead of onboarding looking heavier than the rest. */
  --body-copy-size:  16px;
  --body-copy-color: var(--ink);
}

/* ── Charcoal theme ── */
[data-theme="charcoal"] {
  --accent:#2D2D2D; --accent-bright:#9A9A9A; --accent-tint:#EBEBEB; --accent-softer:#F5F5F5;
  --focus:0 0 0 3px rgba(45,45,45,.12);
  --header:#111111; --header-card:#1A1A1A; --header-icon-bg:#222222;
}
/* ── Slate theme ── */
[data-theme="slate"] {
  --accent:#4A6C7A; --accent-bright:#5A7C8A; --accent-tint:#E5EEF1; --accent-softer:#F0F5F7;
  --focus:0 0 0 3px rgba(74,108,122,.14);
  --header:#14191C; --header-card:#1C252A; --header-icon-bg:#232F34;
}
/* ── Navy theme (muted, earthy — deliberately desaturated, not bright) ── */
[data-theme="navy"] {
  --accent:#33495C; --accent-bright:#4E6A7C; --accent-tint:#E9EDEF; --accent-softer:#F2F5F6;
  --focus:0 0 0 3px rgba(51,73,92,.14);
  --header:#12171B; --header-card:#1A2126; --header-icon-bg:#212A30;
}

/* Legacy token aliases — keeps app.js working without changes */
:root {
  --duke:        var(--accent);
  --duke-bright: var(--accent-bright);
  --duke-soft:   var(--accent-tint);
  --duke-softer: var(--accent-softer);
  --bg:          var(--parchment);
  --ok:          var(--accent);
  --warn:        var(--ink);
}

/* ── Reset ── */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
[hidden] { display: none !important; }

html, body {
  margin: 0; padding: 0;
  background: var(--parchment);
  color: var(--ink);
  font-family: var(--body);
  font-size: 24px;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

/* ============ LOGIN / SPLASH ============ */
.lock {
  min-height: 100dvh; display: flex; align-items: center; justify-content: center;
  padding: env(safe-area-inset-top) 28px 48px;
  background: var(--header);
}
.lock-inner { width: 100%; max-width: 340px; text-align: center; }
.lock-logo { width: 80px; height: 80px; }
.lock-name {
  font-family: var(--body); font-weight: 800; letter-spacing: -0.5px;
  font-size: 42px; margin-top: 18px; color: var(--accent-bright);
}
.lock-prompt { color: rgba(255,255,255,0.62); margin: 10px 0 26px; font-size: 26px; font-weight: 400; }
.pin-error { color: #F87171; font-size: 20px; min-height: 18px; margin: 8px 0 0; font-weight: 500; }

/* ============ TOPBAR ============ */
.topbar {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: calc(env(safe-area-inset-top) + 12px) 16px 12px;
  background: var(--header);
  border-bottom: 1px solid var(--header-line);
}
/* The logo is the only elastic item in the bar, so it has to be the one that
   gives. An img has an intrinsic min-width that flexbox will not shrink past,
   which pushed the form topbar 8px wider than a 375px viewport and scrolled
   the whole page sideways. min-width:0 releases that floor; object-fit keeps
   the mark undistorted as it scales down. Fixes every topbar content
   combination, including the one where the Guided button is showing. */
.topbar-logo { height: 45px; min-width: 0; flex: 0 1 auto; object-fit: contain; }
.topbar > .icon-btn, .form-topbar-right { flex-shrink: 0; }
/* Standard interior-screen header: back/nav on the left, title centered, actions
   on the right. Only Home carries the Paperdash logo — on every other screen the
   logo competed with the title for the center and pushed navigation into a
   lopsided cluster. Grid rather than flex because the two side slots hold
   different content widths, and `space-between` centers the title on the
   leftover space, not on the bar. minmax(0,·) so a long side item ellipsizes
   instead of silently widening the grid past the viewport. */
.topbar-nav {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
}
.topbar-nav > :first-child { justify-self: start; }
.topbar-nav > :last-child  { justify-self: end; }
.topbar-nav > .preview-title { justify-self: center; text-align: center; }
/* .form-topbar-right can hold two buttons (Guided resume + New). justify-self:
   end sizes a grid item to its own content instead of stretching it to the
   column, so when that content is wider than the column it overflows LEFT
   past the column boundary and under the centered title instead of shrinking.
   Stretch to the column, then right-align the buttons inside with flexbox,
   so the flex-shrink on resume-guided-btn actually has a box to shrink within. */
.topbar-nav > .form-topbar-right { justify-self: stretch; justify-content: flex-end; }
.preview-title {
  font-family: var(--body); font-weight: 600; color: var(--parchment); font-size: 23px;
}
.btn-ghost-sm {
  font-family: var(--body); font-weight: 600; letter-spacing: 0;
  font-size: 20px; color: rgba(255,255,255,0.85);
  background: rgba(255,255,255,0.10);
  border: 1px solid rgba(255,255,255,0.14); border-radius: 9px; padding: 8px 14px; cursor: pointer;
  white-space: nowrap;
}
.btn-ghost-sm:active { background: rgba(255,255,255,0.16); }
.form-topbar-right { display: flex; gap: 6px; align-items: center; flex-wrap: nowrap; min-width: 0; flex-shrink: 0; }
.resume-guided-btn {
  background: rgba(74,122,92,0.35); border-color: rgba(74,122,92,0.5); color: #fff;
  flex-shrink: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 16px; padding: 7px 10px;
}
/* "New" wipes the open document with no undo, so it must never read as a peer
   CTA next to Guided's resume button. Fixed-size icon (not a text pill) so its
   footprint never grows and can't push the header into overlapping the
   centered title — the bug behind it before was a text button whose width
   varied with its own label. */
.icon-btn-sm {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 10px; flex-shrink: 0;
  color: rgba(255,255,255,0.55);
  background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.12); cursor: pointer;
}
.icon-btn-sm [data-ico] svg { width: 20px; height: 20px; }
.icon-btn-sm:active { background: rgba(255,255,255,0.14); }
/* Armed state after the first tap: reads as a real warning, not a hover tint. */
.icon-btn-sm.confirming { color: #F87171; border-color: rgba(248,113,113,0.5); background: rgba(248,113,113,0.12); }

/* icon buttons in topbar — light on dark */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 60px; height: 60px; border-radius: 14px;
  color: rgba(255,255,255,0.7);
  background: var(--header-icon-bg); border: 1px solid var(--header-line); cursor: pointer;
}
/* Descendant selector is load-bearing: these glyphs sit inside a [data-ico] span, and a
   plain `.icon-btn svg` ties on specificity with `[data-ico] svg` (both 0,1,1) and loses
   on source order, silently rendering at 26px. Keep a class in front of [data-ico]. */
.icon-btn [data-ico] svg { width: 36px; height: 36px; }
/* Bare glyph fallback. Only [data-ico] children had a size, so an inline svg
   dropped straight into an .icon-btn rendered unsized. Specificity keeps the
   [data-ico] rule (0,2,1) ahead of this one (0,1,1), so wrapped icons are
   untouched. */
.icon-btn svg { width: 30px; height: 30px; }
.icon-btn svg { stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* .icon-btn is a TOPBAR component: its colors assume the dark header. Dropped
   onto a light sheet the glyph is near-white on near-white, which is why this
   close button was invisible. Re-color it for the surface it actually sits on
   and size it to a comfortable tap target. */
.modal-head .icon-btn {
  width: 44px; height: 44px; border-radius: 12px;
  color: var(--steel); background: var(--accent-softer); border: 1px solid var(--line);
  /* .modal-head is a flex row and the title next to this button is long enough to
     squeeze it: without this the 44px box renders ~36px wide, so the "square"
     close target arrives as a narrow rectangle with a cramped glyph. */
  flex-shrink: 0;
}
.modal-head .icon-btn svg { width: 22px; height: 22px; stroke-width: 2.25; }
.modal-head .icon-btn:active { background: var(--accent-tint); color: var(--accent-deep); }
.icon-btn:active { background: var(--header-elevated); }

/* ============ EDITOR ============ */
.editor { padding: 18px 16px; max-width: 640px; margin: 0 auto; }
.card {
  background: var(--card);
  border: 1.5px solid var(--line);
  border-radius: var(--radius);
  padding: 20px; margin-bottom: 16px;
  box-shadow: 0 2px 8px rgba(0,0,0,.06);
}
.card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.card-title { font-size: 21px; font-weight: 700; color: var(--ink); margin: 0 0 16px; }
.card-head .card-title { margin-bottom: 4px; }
.card-sub { font-size: var(--body-copy-size); color: var(--body-copy-color); margin-bottom: 14px; font-weight: 400; }

.field { margin-bottom: 16px; }
.field:last-child { margin-bottom: 0; }
.field-row { display: flex; gap: 12px; }
.field-row .field { flex: 1; }
.field.narrow { max-width: 130px; }
label { display: block; font-size: var(--body-copy-size); color: var(--body-copy-color); font-weight: 700; margin-bottom: 7px; }
input[type=text], input[type=date], input[type=tel], input[type=email], input[type=number], textarea {
  width: 100%; font-family: var(--body); font-size: 24px; font-weight: 400; color: var(--ink);
  background: var(--field); border: 1.5px solid var(--line); border-radius: 10px;
  padding: 12px 14px; outline: none; transition: border-color .12s, box-shadow .12s;
}
/* WebKit gives input[type=date] an intrinsic min-width that scales with
   font-size; at 24px it exceeds the card and width:100% cannot shrink past it,
   so the field overflows. min-width:0 releases that floor. */
input[type=date] { min-width: 0; max-width: 100%; -webkit-appearance: none; appearance: none; }
input[type=date]::-webkit-date-and-time-value { text-align: left; margin: 0; }
.field, .field-row .field { min-width: 0; }
textarea { resize: vertical; line-height: 1.5; }
input:focus, textarea:focus { border-color: var(--accent-bright); box-shadow: var(--focus); }
::placeholder { color: var(--steel-light); }
.hint { font-size: 14px; line-height: 1.4; color: var(--steel-light); margin: 6px 0 0; font-weight: 400; }
/* A tip is guidance we actually want read — give it accent color + a soft pill so it
   reads as highlighted, unlike the muted grey of ordinary field hints. */
.hint.tip {
  color: var(--accent-deep); font-weight: 600;
  background: var(--accent-softer); border-left: 3px solid var(--accent);
  border-radius: 0 8px 8px 0; padding: 8px 12px; margin-top: 8px;
}

/* ============ LOGO UPLOAD ============ */
.logo-upload-wrap { display: flex; align-items: center; gap: 16px; margin-bottom: 4px; }
.logo-upload-zone {
  width: 80px; height: 80px; border-radius: 12px; flex-shrink: 0;
  border: 1.5px dashed var(--line); background: var(--field);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; overflow: hidden; transition: border-color .12s;
}
.logo-upload-zone:hover, .logo-upload-zone:focus { border-color: var(--accent); outline: none; box-shadow: var(--focus); }
.logo-upload-zone img { width: 100%; height: 100%; object-fit: contain; }
.logo-upload-initials { font-size: 36px; font-weight: 700; color: var(--accent); letter-spacing: -0.5px; }
.logo-upload-actions { display: flex; flex-direction: column; gap: 8px; }
.logo-upload-hint { font-size: 18px; color: var(--steel-light); }

.money-input { display: flex; align-items: center; background: var(--field); border: 1.5px solid var(--line); border-radius: 10px; overflow: hidden; }
.money-input:focus-within { border-color: var(--accent-bright); box-shadow: var(--focus); }
.money-input span { padding: 0 4px 0 14px; color: var(--steel); font-weight: 400; }
.money-input input { border: none; box-shadow: none !important; background: transparent; padding-left: 4px; }
.money-input.sm { flex: 0 0 120px; }

/* ============ BLOCK ============ */
.block {
  background: var(--parchment); border: 1.5px solid var(--line);
  border-radius: 12px; padding: 16px; margin-bottom: 12px;
}
.block-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.block-num { font-weight: 700; color: var(--accent); font-size: 20px; }
.btn-remove {
  font-size: 18px; font-weight: 500;
  color: var(--steel); background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; padding: 6px 11px; cursor: pointer;
}
.btn-remove:active { color: var(--ink); border-color: var(--steel-light); }
.btn-remove.icon { border: none; background: transparent; font-size: 30px; padding: 0 8px; line-height: 1; }

.segment { display: flex; background: var(--parchment); border: 1.5px solid var(--line); border-radius: 10px; padding: 3px; gap: 3px; }
.segment button {
  flex: 1; font-family: var(--body); font-size: 20px; font-weight: 500; color: var(--steel);
  background: transparent; border: none; border-radius: 8px; padding: 9px 0; cursor: pointer;
}
.segment button.on { background: var(--accent); color: #fff; font-weight: 600; }

.switch { display: flex; align-items: center; gap: 10px; margin-top: 14px; cursor: pointer; }
.switch input { position: absolute; opacity: 0; pointer-events: none; }
.switch-track { width: 44px; height: 26px; border-radius: 13px; background: #D2CFC7; border: 1px solid var(--line); position: relative; transition: .15s; flex: 0 0 auto; }
.switch-thumb { position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.14); transition: .15s; }
.switch input:checked + .switch-track { background: var(--accent); border-color: var(--accent); }
.switch input:checked + .switch-track .switch-thumb { left: 20px; }
.switch-label { font-size: 15px; white-space: nowrap; color: var(--ink-soft); font-weight: 400; }

.block-foot, .totalbar-nums .tb-row { display: flex; align-items: center; justify-content: space-between; }
.block-foot {
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line);
  font-size: 18px; color: var(--steel); font-weight: 400;
}
.block-foot strong { font-size: 23px; font-weight: 600; color: var(--ink); }

/* ============ EXTRA ============ */
.extra { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
.extra .x-label { flex: 1; }

/* ============ ADD BUTTON ============ */
.btn-add {
  width: 100%; font-family: var(--body);
  font-weight: 600; font-size: 20px; color: var(--accent);
  background: var(--accent-softer); border: 1.5px dashed rgba(74,122,92,.32); border-radius: 10px;
  padding: 13px; cursor: pointer; margin-top: 4px; display: flex; align-items: center; justify-content: center; gap: 6px;
}
.btn-add:active { background: var(--accent-tint); }

/* ============ DEFAULTS ============ */
.defaults summary { font-weight: 600; font-size: 20px; color: var(--ink); cursor: pointer; list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.defaults summary::-webkit-details-marker { display: none; }
.defaults summary::after { content: "▾"; color: var(--steel-light); font-size: 22px; line-height: 1; }
.defaults[open] summary::after { content: "▴"; }
.defaults > .field-row { margin-top: 16px; }
.spacer { height: 10px; }

/* ============ TOTAL BAR ============ */
.totalbar {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px calc(env(safe-area-inset-bottom) + 14px);
  background: var(--header);
  border-top: 1px solid var(--header-line);
  box-shadow: 0 -4px 20px rgba(0,0,0,.2);
}
.totalbar-nums { flex: 1; min-width: 0; overflow: hidden; }
.tb-row { display: flex; align-items: center; justify-content: space-between; }
.tb-row span { font-size: 18px; color: rgba(255,255,255,0.5); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
.tb-row strong { font-size: clamp(22px, 6.5vw, 45px); font-weight: 800; color: #fff; letter-spacing: -0.5px; }
.tb-balance strong { color: rgba(255,255,255,0.85); font-size: clamp(22px, 7vw, 33px); }
.tb-row + .tb-row { margin-top: 3px; }
/* Stack label above amount instead of side-by-side — a squeezed side-by-side
   row wraps the label onto two lines on narrow phones, and the wrapped line
   collides with the vertically-centered Preview button next to it. Stacking
   removes the horizontal contest entirely regardless of screen width. */
.totalbar-nums .tb-row { flex-direction: column; align-items: flex-start; justify-content: center; gap: 1px; min-width: 0; }
.totalbar-nums .tb-row span { white-space: nowrap; }
.totalbar-nums .tb-row strong { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.btn-primary {
  font-family: var(--body); font-weight: 700;
  font-size: clamp(18px, 5vw, 26px); color: #fff;
  background: var(--accent);
  border: none; border-radius: 999px; padding: 17px clamp(22px, 6vw, 34px); cursor: pointer;
  box-shadow: 0 3px 12px rgba(74,122,92,.28);
  transition: background .12s, transform .08s;
  white-space: nowrap;
  flex-shrink: 0;
}
.btn-primary:active { transform: translateY(1px); background: var(--accent-deep); }
.btn-primary.wide { width: 100%; }

/* ============ PREVIEW / READY SCREEN ============ */
#preview-screen { display: flex; flex-direction: column; height: 100dvh; }
.preview-bar { justify-content: space-between; }

/* align-items:center on a scroll container is a trap: once the content is
   taller than the stage, centering pushes the top of the card into overflow
   ABOVE the scroll origin, where it cannot be scrolled to. The customer name
   ends up parked under the sticky header with no way to reach it. Auto margins
   center the same way when there is spare room but collapse to zero when there
   is not, so the top edge always stays reachable. */
.ready-stage {
  flex: 1; display: flex; align-items: flex-start; justify-content: center;
  padding: 28px 24px 40px; overflow-y: auto;
  background: var(--parchment);
}
/* Horizontal auto margins only, so a short document sits at the top of the
   stage rather than floating in the middle of it. This is a look choice, not
   a clipping fix: measured on a 22-line document, `margin: auto` and
   `margin: 0 auto` are identical (card top 28px below the stage top, nothing
   clipped). Auto margins absorb free space BEFORE alignment applies and
   resolve to zero when there is none, which is exactly why they cannot
   overflow the start edge the way align-items:center does — that is the bug
   this rule and the flex-start above it were introduced to fix. */
.wo-ready { text-align: center; max-width: 380px; width: 100%; margin: 0 auto; }
.wo-check {
  width: 60px; height: 60px; border-radius: 50%;
  background: var(--accent-tint); display: flex; align-items: center; justify-content: center;
  margin: 0 auto 22px; color: var(--accent);
}
.wo-check svg { width: 30px; height: 30px; stroke: currentColor; fill: none; stroke-width: 2.25; }
.wo-label { font-size: 17px; color: var(--steel); margin: 0 0 12px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; }
.wo-customer { font-size: 33px; font-weight: 700; color: var(--ink); margin: 0 0 12px; letter-spacing: -0.3px; }
.wo-total { font-size: 54px; font-weight: 800; color: var(--accent); margin-bottom: 10px; letter-spacing: -0.5px; }
.wo-meta { font-size: 20px; color: var(--steel); margin: 0 0 30px; font-weight: 400; }
/* Each address line is its own block, so the break lands between street and
   city/state/zip instead of wherever the character count runs out. */
.wo-addr-line { display: block; line-height: 1.4; }
.wo-detail {
  background: var(--card); border: 1.5px solid var(--line); border-radius: 12px;
  padding: 4px 0; text-align: left;
}
.wo-detail-row {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 11px 16px; border-bottom: 1px solid var(--line-soft);
  font-size: 20px;
}
.wo-detail-row:last-child { border-bottom: none; }
.wo-detail-row .k { color: var(--steel); font-size: 17px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.wo-detail-row .v { color: var(--ink); font-weight: 600; text-align: right; }
/* The running total the deposit and balance rows are computed from — it reads
   as a summary line, not another line item, so it gets its own weight. */
.wo-row-total .k, .wo-row-total .v { color: var(--ink); font-weight: 700; }
/* Money already in reads green, money still owed reads red. The total stays
   neutral so the balance is the one figure that draws the eye. */
.wo-row-deposit .v { color: var(--status-paid); font-weight: 700; }
.wo-row-balance .k { color: var(--ink); }
.wo-row-balance .v { color: var(--status-unpaid); font-weight: 800; }
.wo-row-total { border-top: 1.5px solid var(--line); }
/* Payment methods stack one per line — a run-on string of them is unreadable
   and gives the customer nothing to scan. */
.wo-pay-line { display: block; line-height: 1.5; }
.wo-pay-line + .wo-pay-line { margin-top: 2px; }

/* Cost derivation under a line item. Nested inside the description cell so
   the existing desc/amount flex row is untouched — wrapping it as a third
   flex child instead pushes the amount onto its own line. Resets the .k
   uppercase treatment, which is for labels, not figures. */
.wo-breakdown:first-of-type { margin-top: 5px; }
.wo-breakdown {
  display: block; margin-top: 3px;
  font-size: 15px; font-weight: 500; color: var(--steel);
  text-transform: none; letter-spacing: 0; line-height: 1.45;
  font-variant-numeric: tabular-nums;
}

/* ---- Inline preview editing ---- */
.edit-hint {
  display: flex; align-items: center; gap: 7px; padding: 8px 14px;
  background: var(--accent-tint); border-radius: 10px; margin-bottom: 18px;
  font-size: 18px; color: var(--accent-deep); font-weight: 500;
  transition: opacity 0.4s;
}
.edit-hint svg { flex-shrink: 0; }
.edit-hint.faded { opacity: 0; pointer-events: none; }

.tappable { cursor: pointer; border-radius: 8px; transition: background 0.12s; position: relative; }
.tappable:active { background: rgba(74,122,92,0.08); }

.field-editing {
  background: var(--card); border: 1.5px solid var(--accent); border-radius: 10px;
  box-shadow: 0 0 0 3px rgba(74,122,92,.13); padding: 6px 10px;
}
.field-editing input,
.field-editing textarea {
  font-family: inherit; font-size: 24px; color: var(--ink); background: transparent;
  border: none; outline: none; width: 100%; resize: none; line-height: 1.5;
}
.field-editing .done-inline {
  font-size: 18px; font-weight: 600; color: var(--accent); background: var(--accent-tint);
  border: none; border-radius: 6px; padding: 7px 16px; cursor: pointer;
  font-family: inherit;
}
.field-editing .remove-line {
  font-size: 18px; color: #C44040; background: none; border: none;
  cursor: pointer; font-family: inherit; padding: 7px 4px;
}

/* An editing row stops being a two-column summary line and expands in place
   into a full-width panel. Without this the injected fields and the action
   buttons stay flex siblings of the row, and the description gets squeezed
   into whatever sliver the buttons leave — a text box too small to tap into. */
.wo-detail-row.field-editing { display: block; }

/* Fields stack. A description is a sentence, not a word, so it gets real room
   rather than one line it has to be scrolled through on a phone. */
.line-edit-fields { display: flex; flex-direction: column; gap: 12px; width: 100%; }
.line-edit-lbl {
  display: flex; flex-direction: column; gap: 5px;
  font-size: 13px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--steel);
}
/* Inputs get a visible box: an underline-less transparent field inside an
   already-outlined row reads as static text and doesn't invite a tap. */
.field-editing .line-edit-desc,
.field-editing .line-edit-amt,
.field-editing .le-flat,
.field-editing .le-hours,
.field-editing .le-rate,
.field-editing .le-material,
.field-editing .le-markup {
  border: 1.5px solid var(--line); border-radius: 9px;
  background: var(--card); padding: 11px 12px;
  font-size: 17px !important; font-weight: 500; color: var(--ink);
  width: 100%; box-sizing: border-box; line-height: 1.5;
}
.field-editing .line-edit-desc { min-height: 5.2em; resize: vertical; }

/* minmax(0,1fr), never 1fr: a bare 1fr floors at the content's own width, so a
   long value would push the grid wider than the row instead of wrapping. */
.line-edit-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }

/* Labor is either hours x rate or a flat charge. Same choice the form offers,
   so a line means the same thing wherever it was entered. */
.le-mode { display: flex; gap: 6px; }
.le-mode button {
  flex: 1 1 0; min-width: 0; font: inherit; font-size: 14px; font-weight: 600;
  padding: 9px 6px; border-radius: 8px; cursor: pointer;
  border: 1.5px solid var(--line); background: var(--card); color: var(--steel);
}
.le-mode button.on { border-color: var(--accent); background: var(--accent-tint); color: var(--accent); }

/* The amount is derived now, not typed, so it is shown rather than edited. */
.le-total {
  display: flex; justify-content: space-between; align-items: baseline;
  padding-top: 11px; margin-top: 2px; border-top: 1.5px solid var(--line);
  font-size: 14px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--steel);
}
.le-total-v {
  font-size: 21px; font-weight: 700; color: var(--ink);
  letter-spacing: 0; text-transform: none; font-variant-numeric: tabular-nums;
}
.field-editing .line-edit-amt,
.field-editing .le-flat,
.field-editing .le-hours,
.field-editing .le-rate,
.field-editing .le-material,
.field-editing .le-markup { font-weight: 700; }
.field-editing .line-edit-desc:focus,
.field-editing .line-edit-amt:focus,
.field-editing .le-flat:focus,
.field-editing .le-hours:focus,
.field-editing .le-rate:focus,
.field-editing .le-material:focus,
.field-editing .le-markup:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px rgba(74,122,92,.13);
}
/* Remove and Done sit at opposite ends with a hard minimum gap, so a
   destructive tap is never adjacent to the confirm tap. */
.line-edit-actions {
  display: flex; justify-content: space-between; align-items: center;
  gap: 24px; margin-top: 10px;
}

.wo-add-line {
  display: flex; align-items: center; gap: 7px; width: 100%;
  font-size: 20px; font-weight: 500; color: var(--accent); background: none;
  border: 1.5px dashed var(--accent-tint); border-radius: 10px;
  padding: 10px 16px; cursor: pointer; font-family: inherit; margin: 4px 0 2px;
  text-align: left;
}
.wo-add-line:active { background: var(--accent-tint); }

.actionbar {
  display: flex; gap: 8px; padding: 14px 16px calc(env(safe-area-inset-bottom) + 14px);
  background: var(--parchment); border-top: 1.5px solid var(--line);
}
.btn-action {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px;
  font-family: var(--body); font-weight: 600; font-size: 18px;
  color: var(--accent); background: var(--accent-softer);
  border: 1.5px solid var(--accent-tint); border-radius: 12px; padding: 14px 4px; cursor: pointer;
}
.btn-action svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.btn-action:active { background: var(--accent-tint); border-color: var(--accent); transform: translateY(1px); }

@media (min-width: 720px) {
  .ready-stage { padding: 48px; }
}

/* ============ LINED ICONS ============ */
[data-ico] { display: inline-flex; align-items: center; justify-content: center; }
/* Icon scale is anchored to the home doc-type tiles: a 38px glyph in a 64px tile (~0.6). */
/* Icon scale is anchored to the home doc-type tiles: a 38px glyph in a 64px tile (~0.6).
   Sized in px, not em: these spans inherit wildly different font-sizes, so an em-based
   glyph silently shrinks wherever it lands. */
[data-ico] svg { width: 26px; height: 26px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.btn-action [data-ico] svg { width: 30px; height: 30px; }
/* NOTE: .choice-ico carries data-ico itself — this must stay a compound selector, not a descendant one. */
.choice-ico[data-ico] svg { width: 38px; height: 38px; }

.link-btn {
  margin-top: 22px; background: none; border: none; color: rgba(255,255,255,0.4);
  font-size: 21px; font-weight: 400; text-decoration: underline; cursor: pointer;
}
.link-btn:active { color: var(--accent-bright); }

/* ============ LOGIN CODE SCREEN ============ */
.reset-confirm { text-align: center; }
.reset-title { color: var(--parchment); font-size: 33px; font-weight: 700; margin: 18px 0 8px; }
.reset-body { color: rgba(255,255,255,0.62); font-size: 24px; line-height: 1.55; margin: 0 0 24px; font-weight: 400; }

/* ============ HOME / CHOOSER ============ */
.home { padding: 10px 16px 20px; max-width: 560px; margin: 0 auto; }
.home-greet { font-size: 17px; font-weight: 800; color: var(--steel); margin: 0 2px 12px; letter-spacing: .05em; text-transform: uppercase; }
.home-doc-counter {
  font-size: 13px; font-weight: 600; color: var(--ink-soft);
  margin: -6px 2px 16px;
}
/* Amber is a heads-up with runway left; red is reserved for spent, which is
   also the point the upgrade prompt takes over. Reusing the unpaid red for
   "1 left" spent the strongest signal in the palette before the wall. */
.home-doc-counter.low  { color: var(--status-low); font-weight: 700; }
.home-doc-counter.out  { color: var(--status-unpaid); font-weight: 700; }

.doc-type-picker { display: flex; gap: 8px; margin: 0 0 24px; }
/* Form-screen doc-type bar — mirrors Home's picker-above-content layout so both
   screens teach the same place to look. Its own row rather than a field inside
   the Customer card: type governs the whole document, not the customer. */
.typebar {
  display: flex; align-items: center; gap: 13px;
  background: var(--card); border: 1.5px solid var(--line); border-radius: var(--radius);
  padding: 13px 15px; margin-bottom: 16px; box-shadow: 0 2px 8px rgba(0,0,0,.06);
}
.typebar-label { font-size: 15px; font-weight: 700; color: var(--ink); white-space: nowrap; }
.typebar .doc-type-picker { flex: 1; margin: 0; }
.typebar .doc-type-btn { font-size: 16px; padding: 9px 0; }
.doc-type-btn {
  flex: 1; padding: 11px 0; border-radius: 10px; border: 1.5px solid var(--line);
  background: var(--card); color: var(--steel); font-size: 23px; font-weight: 600;
  cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.doc-type-btn.active {
  background: var(--accent-tint); color: var(--accent); border-color: var(--accent);
}

/* minmax(0, 1fr), not 1fr: a bare 1fr means minmax(auto, 1fr), and `auto` floors
   the column at its content's min-content width. Because .choice-text strong is
   white-space: nowrap, that floor is the full untruncated title, so the first
   column grew to fit "Guided, step by step" and pushed the grid to 454px inside
   a 375px phone — the page scrolled sideways and the right column ran off the
   screen. It also meant the text-overflow: ellipsis below could never fire,
   since the column always grew rather than clipping. */
.choice-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 28px; }
/* THE TILES ARE SQUARES. aspect-ratio: 1 is not negotiable and must not be
   removed to make text fit. Every piece of content below is sized to fit inside
   that square: if copy overflows, shrink the type, the icon, or the copy — never
   let the tile grow taller. Letting titles and descriptions wrap freely is
   exactly what turned these into tall rectangles before. */
.choice {
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
  gap: 8px; width: 100%; aspect-ratio: 1; overflow: hidden; text-align: left;
  background: var(--card); border: 1.5px solid var(--line);
  border-radius: 14px; padding: 14px; cursor: pointer;
  box-shadow: 0 2px 8px rgba(0,0,0,.06); transition: box-shadow .12s, transform .08s;
}
.choice:active { transform: translateY(1px); box-shadow: none; }
.choice-ico {
  flex: 0 0 52px; width: 52px; height: 52px; border-radius: 14px;
  background: var(--accent-tint); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
}
/* Glyph tracks the smaller tile icon box, holding the ~0.6 ratio the icon scale
   is anchored to (was 38px in a 64px box). */
.choice-ico[data-ico] svg { width: 30px; height: 30px; }
.choice-text { display: flex; flex-direction: column; gap: 3px; width: 100%; }
/* 20px, not 24px: the title has to fit the square alongside the icon and the
   description. At 24px the labels either clipped mid-word ("Snap a n…") or,
   once allowed to wrap, pushed the tile into a tall rectangle. 20px fits every
   current title on one line inside a half-width tile, and the two-line clamp is
   only a backstop for a future longer string. */
.choice-text strong {
  font-size: 20px; color: var(--ink); font-weight: 700; line-height: 1.2;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* Fixed 13px rather than --body-copy-size, and clamped to 2: the description is
   the flexible part of the square's budget, so it is sized to whatever is left
   after the icon and title. Do not raise this to buy more room for copy —
   shorten the copy instead. */
.choice-text small {
  font-size: 13px; color: var(--body-copy-color); line-height: 1.35; font-weight: 500;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.resume-banner {
  display: flex; align-items: center; gap: 8px; width: 100%; justify-content: center;
  margin-bottom: 20px; padding: 12px 14px; border-radius: 10px; cursor: pointer;
  /* Solid fill, not a soft tint: the tinted version read as decoration next to the
     other accent-tinted surfaces on Home and got skipped. Forest (--accent) is the
     CTA color; --accent-bright is sage and is reserved for the logo bars. */
  background: var(--accent); border: none;
  color: #fff; font-weight: 600; font-size: 15px; white-space: nowrap;
}
.resume-banner svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2; flex-shrink: 0; }

/* ============ GUIDED WALKTHROUGH ============ */
#guided-screen { display: flex; flex-direction: column; min-height: 100dvh; }
.guided-bar { gap: 12px; }
.guided-mid { flex: 1; display: flex; flex-direction: column; gap: 6px; }
.progress { height: 4px; border-radius: 2px; background: rgba(255,255,255,0.15); overflow: hidden; }
.progress-fill { height: 100%; width: 0; background: var(--accent-bright); border-radius: 2px; transition: width .3s ease; }
.step-ct { font-size: 17px; text-align: center; color: rgba(255,255,255,0.4); font-weight: 500; }
.guided { flex: 1; padding: 32px 20px 12px; padding-bottom: 92px; max-width: 560px; margin: 0 auto; width: 100%; }
.g-step { font-size: 17px; color: var(--accent); margin-bottom: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; }
.g-q { font-size: 36px; font-weight: 700; color: var(--ink); line-height: 1.25; margin: 0 0 12px; letter-spacing: -.3px; }
.g-help { font-size: var(--body-copy-size); color: var(--body-copy-color); margin: 10px 0 0; line-height: 1.6; font-weight: 400; }
.g-help .mic-word { color: var(--accent); font-weight: 600; }
.g-input {
  width: 100%; font-family: var(--body); font-size: 27px; font-weight: 400; color: var(--ink);
  background: var(--card); border: 1.5px solid var(--line); border-radius: 12px;
  padding: 15px 16px; outline: none; transition: border-color .12s, box-shadow .12s;
}
.g-input:focus { border-color: var(--accent-bright); box-shadow: var(--focus); }
.g-input.sm { font-size: 23px; padding: 11px 13px; border-radius: 10px; }
textarea.g-input { min-height: 120px; line-height: 1.5; resize: none; }
.g-money {
  display: flex; align-items: center; background: var(--card);
  border: 1.5px solid var(--line); border-radius: 12px; padding: 4px 16px;
}
.g-money:focus-within { border-color: var(--accent-bright); box-shadow: var(--focus); }
.g-money span { font-size: 33px; font-weight: 400; color: var(--steel-light); }
.g-money input[type=text] { flex: 1; border: none !important; background: transparent !important; outline: none; box-shadow: none; font-size: 36px; font-weight: 700; color: var(--ink); padding: 10px 8px; width: 100%; }
.g-money.sm { padding: 2px 13px; border-radius: 10px; }
.g-money.sm span { font-size: 22px; }
.g-money.sm input[type=text] { font-size: 23px; padding: 8px 6px; }
/* The rate/markup field that sits under the primary hours/cost field on the
   guided labor and material cards. Deliberately smaller than the primary so
   the card still reads as one main question with a pre-filled default under
   it, not two questions of equal weight. */
.g-second-field { margin-top: 16px; }
.g-second-field label {
  display: block; margin-bottom: 6px; font-size: 13px; font-weight: 600;
  color: var(--steel-light); letter-spacing: .01em;
}
.g-money .g-unit { font-size: 20px; font-weight: 600; }
.g-money .g-suffix { font-size: 18px; }

.g-ai { margin-top: 18px; }
.g-aibtn {
  display: inline-flex; align-items: center; gap: 7px; font-weight: 600; font-size: 20px;
  color: var(--accent); background: var(--accent-softer); border: 1.5px solid var(--accent-tint);
  border-radius: 10px; padding: 11px 16px; cursor: pointer;
}
.g-aibtn[disabled] { opacity: .5; cursor: default; }
.g-aibtn svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; }
.g-ai-status { font-size: 18px; color: var(--steel); margin-top: 8px; font-weight: 400; }

.g-choices { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.g-bigbtn {
  font-family: var(--body); font-weight: 600;
  font-size: 23px; padding: 16px; border-radius: 12px; cursor: pointer;
  border: 1.5px solid var(--accent); background: var(--card); color: var(--accent); transition: .1s;
}
.g-bigbtn.primary { background: var(--accent); color: #fff; }
.g-bigbtn:active { transform: translateY(1px); opacity: .9; }
.g-skip { display: block; margin: 18px auto 0; background: none; border: none; color: var(--steel-light); font-size: 20px; text-decoration: underline; cursor: pointer; }

.guided-foot {
  position: fixed; bottom: 0; left: 0; right: 0;
  padding: 14px 20px calc(env(safe-area-inset-bottom) + 14px);
  background: var(--parchment);
  border-top: 1.5px solid var(--line);
}

/* ============ REVIEW CARD ============ */
.g-review {
  background: var(--card); border: 1.5px solid var(--line); border-radius: 14px;
  padding: 4px 0; margin-bottom: 16px; overflow: hidden;
}
.g-rev-row {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 12px 16px; border-bottom: 1px solid var(--line-soft);
}
.g-rev-row:last-child { border-bottom: none; }
.g-rev-row .k { font-size: 17px; color: var(--steel); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; flex: 0 0 76px; padding-top: 2px; }
.rev-v { flex: 1; display: flex; flex-direction: column; gap: 3px; }
.rev-val { font-size: 21px; color: var(--ink); line-height: 1.4; font-weight: 400; }
.rev-amt { font-size: 20px; color: var(--steel); font-weight: 400; }
.rev-total-val { font-size: 30px; color: var(--accent); font-weight: 800; }
/* Matches the preview's balance-due treatment: outstanding money is the one
   figure on the screen that should read as owed. Previously this asked for
   var(--warn) inline, which is defined as var(--ink) and so rendered as
   ordinary text while looking deliberate in the source. */
.rev-balance { font-size: 27px; font-weight: 700; color: var(--status-unpaid); }
.rev-btns { display: flex; gap: 8px; margin-top: 6px; }
.rev-edit-btn {
  font-size: 18px; font-weight: 600; color: var(--accent); background: var(--accent-tint);
  border: none; border-radius: 7px; padding: 5px 11px; cursor: pointer;
}
.rev-del-btn {
  font-size: 23px; font-weight: 400; color: var(--steel-light); background: var(--line-soft);
  border: none; border-radius: 7px; padding: 2px 10px; cursor: pointer; line-height: 1.4;
}
.rev-del-btn:active { color: var(--ink); background: var(--line); }
.rev-edit-row { display: flex; gap: 10px; margin-top: 8px; }
.rev-money-mini { flex: 1; }
.rev-money-mini label { font-size: 18px; color: var(--steel); font-weight: 600; margin-bottom: 5px; display: block; }
.rev-save-row { display: flex; gap: 8px; margin-top: 10px; }
.rev-save-row .btn-ghost-sm { flex: 1; text-align: center; }
.rev-add-job {
  width: 100%; font-size: 20px; font-weight: 600; color: var(--accent);
  background: transparent; border: 1.5px dashed rgba(74,122,92,.32); border-radius: 10px;
  padding: 12px; cursor: pointer; margin-bottom: 14px;
}
.rev-add-job:active { background: var(--accent-softer); }

/* ============ CONFIRM TOAST ============ */
.confirm-toast {
  position: fixed; left: 50%; bottom: 96px; transform: translateX(-50%);
  background: rgba(28,28,24,.95); color: #fff; font-size: 20px; font-weight: 600;
  padding: 11px 20px; border-radius: 999px; box-shadow: 0 4px 16px rgba(0,0,0,.3); z-index: 30;
  white-space: nowrap;
}

/* ---- Phone login fields ---- */
.login-field { width: 100%; text-align: left; margin: 20px 0 14px; }
.login-field label { display: block; font-size: 23px; font-weight: 700; color: rgba(255,255,255,0.62); margin-bottom: 7px; }
.login-field input { width: 100%; font-size: 26px; font-weight: 400; padding: 13px 14px; border: 1.5px solid rgba(255,255,255,0.12); border-radius: 12px; background: rgba(255,255,255,0.07); color: var(--parchment); }
.login-field input:focus { outline: none; border-color: var(--accent-bright); box-shadow: var(--focus); }
.login-or { display: flex; align-items: center; gap: 12px; width: 100%; margin: 16px 0 12px; color: rgba(255,255,255,0.3); font-size: 18px; }
.login-or::before, .login-or::after { content: ''; flex: 1; height: 1px; background: rgba(255,255,255,0.1); }
.acct-linked { display: flex; align-items: center; gap: 8px; font-size: 21px; color: rgba(255,255,255,0.5); }
.acct-linked-check { color: var(--accent-bright); font-weight: 700; }
#recaptcha-container { position: fixed; bottom: 0; left: 0; }

/* ===================================================================
   ACCOUNT · BILLING · REFERRAL
   =================================================================== */
.modal {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(0,0,0,.5);
  display: flex; align-items: flex-end; justify-content: center;
}
.modal[hidden] { display: none; }
.modal-card {
  background: var(--card); width: 100%; max-width: 520px;
  border-radius: 18px 18px 0 0;
  padding: 18px 18px calc(22px + env(safe-area-inset-bottom));
  max-height: 90vh; overflow-y: auto;
  box-shadow: 0 -8px 30px rgba(0,0,0,.2);
}
@media (min-width: 560px) {
  .modal { align-items: center; }
  .modal-card { border-radius: 18px; }
}
.modal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.modal-title { font-size: 27px; font-weight: 700; color: var(--ink); margin: 0; }

/* AI-drafted send message sheet */
.msg-textarea {
  width: 100%; margin: 10px 0 14px; padding: 12px 14px;
  border: 1.5px solid var(--line); border-radius: 14px;
  background: var(--card); color: var(--ink);
  font: inherit; font-size: 24px; line-height: 1.45; resize: vertical;
  min-height: 120px;
}
.msg-textarea:focus { outline: none; border-color: var(--accent); }
/* Single-line recipient/subject fields on the send sheets. Same shell as the
   textarea so the sheet reads as one form. */
.send-field {
  width: 100%; margin: 10px 0 0; padding: 12px 14px;
  border: 1.5px solid var(--line); border-radius: 14px;
  background: var(--card); color: var(--ink);
  font: inherit; font-size: 24px; line-height: 1.45;
}
.send-field:focus { outline: none; border-color: var(--accent); }
.send-field:disabled { color: var(--ink-soft); background: var(--parchment); }
.msg-textarea:disabled { color: var(--ink-soft); background: var(--parchment); }
/* Tappable mirror of the share link that's embedded in the message text. */
.msg-link {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 14px; padding: 11px 12px;
  border: 1px solid var(--line-soft); border-radius: 10px;
  background: var(--parchment);
  color: var(--accent); font-size: 14px; font-weight: 600;
  text-decoration: none;
}
.msg-link:active { opacity: 0.7; }
.msg-link svg {
  width: 16px; height: 16px; flex-shrink: 0;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.msg-link span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}

.msg-actions { display: flex; flex-direction: column; gap: 10px; }
.msg-actions .btn-primary, .msg-actions .btn-outline { margin-top: 0; }

.acct-plan {
  background: var(--parchment); border: 1.5px solid var(--line);
  border-radius: var(--radius); padding: 14px; margin: 10px 0 4px;
}
.acct-badge {
  display: inline-block; font-size: 17px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: #fff; background: var(--accent);
  border-radius: 999px; padding: 4px 12px;
}
.acct-badge.free { color: var(--accent); background: var(--accent-tint); }
.acct-plan-note { color: var(--steel); font-size: 20px; margin: 9px 0 0; }

.acct-section { margin-top: 22px; }
.acct-h { font-size: 21px; font-weight: 700; color: var(--ink); margin: 0 0 4px; }
.acct-sub { font-size: var(--body-copy-size); color: var(--body-copy-color); margin: 0 0 12px; }
.acct-fine { font-size: 18px; color: var(--steel-light); margin: 8px 0 0; }
.acct-credits { font-size: 20px; font-weight: 600; color: var(--accent); margin: 12px 0 0; }
.acct-link {
  font-size: 20px; color: var(--ink); background: var(--parchment);
  border: 1.5px solid var(--line); border-radius: 10px;
  padding: 11px 12px; margin-bottom: 10px; word-break: break-all;
}

.btn-outline {
  display: block; width: 100%; box-sizing: border-box;
  background: transparent; color: var(--accent);
  border: 1.5px solid var(--accent); border-radius: 999px;
  padding: 15px; font-size: 26px; font-weight: 600; font-family: var(--body);
  cursor: pointer; margin-top: 10px;
}
.btn-outline:active { background: var(--accent-tint); }
#acct-signout { margin-top: 22px; display: block; width: 100%; text-align: center; }

.upgrade-banner {
  display: block; width: 100%; text-align: left;
  background: var(--accent-tint); border: 1.5px solid var(--accent);
  border-radius: var(--radius); padding: 13px 15px; margin-bottom: 16px;
  cursor: pointer; font-family: var(--body);
}
.upgrade-banner strong { display: block; font-size: 21px; font-weight: 700; color: var(--ink); }
.upgrade-banner small { display: block; font-size: 18px; color: var(--steel); margin-top: 3px; }

/* ============ UPGRADE SHEET ============ */
.upg-card { padding-bottom: calc(28px + env(safe-area-inset-bottom)); }
.upg-used-msg { font-size: 24px; font-weight: 700; color: var(--ink); }
.upg-value { font-size: var(--body-copy-size); color: var(--body-copy-color); margin: 6px 0 20px; }
.upg-plans { display: flex; flex-direction: column; gap: 10px; }
.upg-plans .btn-primary, .upg-plans .btn-outline { margin-top: 0; }
.upg-save { font-size: 17px; font-weight: 600; opacity: .8; margin-left: 6px; }
.upg-referral { font-size: 18px; color: var(--steel-light); margin: 18px 0 0; text-align: center; }
.upg-referral .link-btn { font-size: 18px; color: var(--steel); }

/* ============ ONBOARDING / PREFERENCES ============ */
.queue-banner {
  display: flex; align-items: center; gap: 10px; width: 100%; justify-content: center;
  margin-top: 10px; margin-bottom: 4px; padding: 14px 16px; border-radius: 12px; cursor: pointer;
  background: var(--accent-tint); border: 1.5px solid var(--accent-tint); color: var(--ink-soft);
  font-weight: 600; font-size: 20px; text-align: center; line-height: 1.4;
}
.queue-banner svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; flex: 0 0 auto; }

#onboarding-screen { display: flex; flex-direction: column; min-height: 100dvh; }
.onboard {
  flex: 1; display: flex; flex-direction: column; justify-content: center;
  padding: 32px 22px 12px; padding-bottom: 108px; max-width: 480px; margin: 0 auto; width: 100%;
}
.ob-hero { text-align: center; }
.ob-logo { width: 72px; height: 72px; margin: 0 auto 18px; display: block; }
.ob-hero .wo-check { margin: 0 auto 18px; }
.ob-h { font-size: 36px; font-weight: 700; color: var(--ink); margin: 0 0 10px; line-height: 1.25; }
.ob-p { font-size: 24px; font-weight: 400; color: var(--ink); margin: 0 0 12px; line-height: 1.6; }
.ob-hero .ob-p { max-width: 340px; margin-left: auto; margin-right: auto; }
.ob-body .field { margin-top: 16px; }
.ob-install-hint { margin-top: 20px; text-align: center; }
.ob-install-hint svg:not(.install-diagram) { width: 26px; height: 26px; stroke: var(--accent); fill: none; stroke-width: 2; transform: rotate(90deg); }
.ob-install-hint svg.install-diagram { width: 100%; max-width: 280px; display: block; margin: 0 auto; transform: none; }
#onboard-foot { display: flex; flex-direction: column; align-items: center; gap: 4px; }
#onboard-foot .link-btn { margin-top: 2px; color: var(--steel); font-size: 23px; }

/* Onboarding: larger, higher-contrast form text (light background)
   label font-size now matches globally via --body-copy-size — see :root. */
#onboarding-screen .pref-opt { font-size: 21px; }
#onboarding-screen .logo-upload-hint { font-size: 21px; color: var(--steel); }
#onboarding-screen .btn-ghost-sm {
  font-size: 23px; color: var(--accent);
  background: var(--accent-softer); border-color: var(--accent-tint);
}

.ob-legal { font-size: 18px; color: var(--steel-light); max-width: 320px; margin: 14px auto 0; line-height: 1.5; }
.legal-link { color: var(--accent); text-decoration: underline; }

.legal-row { display: flex; align-items: center; justify-content: space-between; padding: 12px 0; font-size: 21px; color: var(--ink); text-decoration: none; }
.legal-row + .legal-row { border-top: 1px solid rgba(0,0,0,.06); }
.legal-row svg { width: 16px; height: 16px; stroke: var(--steel-light); fill: none; stroke-width: 2; }

#prefs-screen { display: flex; flex-direction: column; min-height: 100dvh; }
#prefs-body { flex: 1; padding-bottom: 96px; }
.prefs-savebar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 6; max-width: none; }
.prefs-savebar .btn-primary { width: 100%; }
.pref-opt { color: var(--steel-light); font-weight: 400; font-size: 18px; }
.pref-link { font-size: 18px; color: var(--steel); word-break: break-all; margin: 0 0 6px; }
.pref-seg { max-width: none; }
.pref-seg button { flex: 1; }
.pref-seg-wrap { flex-wrap: wrap; }
.pref-seg-wrap button { flex: 1 1 40%; }
.theme-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; vertical-align: middle; flex-shrink: 0; }

.pm-row { display: flex; align-items: center; gap: 10px; padding: 11px 0; cursor: pointer; font-size: 24px; color: var(--ink); }
.pm-row input { width: 20px; height: 20px; accent-color: var(--accent); flex: 0 0 auto; }
.pm-sub {
  width: 100%; margin: 0 0 8px 30px; max-width: calc(100% - 30px);
  font-size: 23px; padding: 10px 12px; border: 1.5px solid var(--line); border-radius: 9px; background: var(--field);
}
/* Standalone custom-method field: no checkbox above it, so it aligns to the
   left edge like the checkbox rows instead of inheriting the 30px sub-indent. */
.pm-custom-label { display: block; font-size: 24px; color: var(--ink); padding: 11px 0 6px; }
.pm-custom-input { margin-left: 0; max-width: 100%; }

/* ============ DOCUMENTS (history) ============ */
#docs-screen { position: relative; min-height: 100dvh; }
.docs-count { font-size: 20px; font-weight: 600; color: var(--steel); margin: 2px 2px 16px; }
.docs-loading { font-size: 20px; color: var(--steel-light); text-align: center; padding: 40px 0; }

.docs-empty { text-align: center; padding: 48px 20px; }
.docs-empty-h { font-size: 23px; font-weight: 700; color: var(--ink); margin: 0 0 8px; }
.docs-empty-p { font-size: var(--body-copy-size); color: var(--body-copy-color); margin: 0 auto; max-width: 300px; line-height: 1.6; }

.docs-list { display: flex; flex-direction: column; gap: 10px; }
.doc-row {
  display: flex; align-items: stretch; gap: 4px;
  background: var(--card); border: 1.5px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
  box-shadow: 0 2px 6px rgba(0,0,0,.06);
}
.doc-open {
  flex: 1; min-width: 0; text-align: left; background: transparent; border: none;
  padding: 14px 4px 14px 16px; cursor: pointer; font-family: var(--body);
}
.doc-open:active { background: var(--line-soft); }
.doc-row-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.doc-name { font-size: 23px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-total { font-size: 23px; font-weight: 700; color: var(--accent); flex: 0 0 auto; }
.doc-row-bot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 6px; }
.doc-date { font-size: 18px; color: var(--steel); font-weight: 400; }
.doc-num  { font-size: 17px; color: var(--steel); font-weight: 600; letter-spacing: 0.03em; margin-left: auto; }

/* Status chips — semantic colors per style guide */
.doc-chip {
  font-size: 17px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  border-radius: 6px; padding: 4px 10px;
  color: var(--steel); background: var(--line-soft); border: 1px solid var(--line);
}
.doc-chip-sent   { color: #2C527D; background: rgba(62,111,166,0.12); border-color: rgba(62,111,166,0.25); }
/* Viewed sits between sent and paid, so it reads warmer than sent without
   claiming the paid green. */
.doc-chip-viewed { color: #7A5B18; background: rgba(190,145,45,0.14); border-color: rgba(190,145,45,0.30); }
.doc-chip-paid   { color: #fff; background: var(--status-paid); border-color: var(--status-paid); }
.doc-chip-queued { color: var(--ink-soft); background: var(--accent-softer); border-color: var(--accent-tint); }
.doc-chip-draft  { color: var(--status-draft); background: rgba(120,116,112,0.10); border-color: rgba(120,116,112,0.2); }
.doc-chip-toggle { cursor: pointer; font-family: inherit; }
#form-status-badge { padding: 0 0 12px; }
#form-status-badge .doc-chip { pointer-events: none; }

.doc-del {
  flex: 0 0 auto; width: 48px; background: transparent; border: none; border-left: 1.5px solid var(--line);
  color: var(--steel-light); cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.doc-del:active { background: var(--line-soft); color: var(--ink); }
.doc-del svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

.doc-row.confirming { padding: 14px 16px; }
.doc-confirm { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; flex-wrap: wrap; }
.doc-confirm-q { font-size: 20px; font-weight: 600; color: var(--ink); }
.doc-confirm-btns { display: flex; gap: 8px; }
.doc-confirm-yes { color: #fff; background: var(--accent); border-color: var(--accent); }

/* Floating + button */
.fab {
  position: fixed; right: 20px; bottom: calc(env(safe-area-inset-bottom) + 20px); z-index: 7;
  width: 60px; height: 60px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--accent); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 24px rgba(74,122,92,.36);
}
.fab:active { transform: translateY(1px); background: var(--accent-deep); }
.fab svg { width: 28px; height: 28px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.fab.is-open { transform: rotate(45deg); }
.fab.is-open:active { transform: rotate(45deg) translateY(1px); }

/* Floating + button — speed-dial menu (New Invoice / New Estimate / Repeat Last Job) */
.fab-menu {
  position: fixed; right: 20px; bottom: calc(env(safe-area-inset-bottom) + 92px); z-index: 7;
  display: flex; flex-direction: column; gap: 10px; align-items: flex-end;
}
.fab-menu-item {
  display: flex; align-items: center; gap: 10px; background: var(--card); border: 1px solid var(--line-soft);
  border-radius: 999px; padding: 12px 18px 12px 12px; font-family: var(--body); font-size: 15px; font-weight: 600;
  color: var(--ink); box-shadow: 0 6px 18px rgba(0,0,0,.14); cursor: pointer; white-space: nowrap;
}
.fab-menu-item:active { background: var(--accent-softer); }
.fab-menu-dot {
  width: 28px; height: 28px; border-radius: 50%; background: var(--accent-tint); color: var(--accent);
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
.fab-menu-dot svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Camera mode */
.camera-grid { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.cam-thumb { position: relative; width: calc(50% - 5px); border-radius: 12px; overflow: hidden; aspect-ratio: 4/3; background: var(--parchment); border: 1.5px solid var(--line); }
.cam-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cam-remove { position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; border-radius: 50%; border: none; background: rgba(0,0,0,.55); color: #fff; font-size: 24px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; }

/* ============ TALK MODE — MIC RECORDING UI ============ */
#talk-screen { display: flex; flex-direction: column; height: 100dvh; }
#talk-mic-ui { flex: 1; display: flex; flex-direction: column; min-height: 0; }

.talk-mic-body {
  flex: 1; display: flex; flex-direction: column; padding: 20px 20px 0;
  overflow-y: auto; min-height: 0;
}
.talk-live-hint { font-size: var(--body-copy-size); color: var(--body-copy-color); line-height: 1.6; margin-bottom: 16px; text-align: center; }
.talk-transcript-wrap {
  flex: 1; background: var(--accent-softer); border: 1.5px solid var(--accent-tint);
  border-radius: 14px; padding: 16px; overflow-y: auto; min-height: 120px;
}
.talk-transcript-text { font-size: 24px; color: var(--ink); line-height: 1.6; white-space: pre-wrap; margin: 0; }
.talk-transcript-text:empty::before {
  content: 'Your words will appear here as you speak…';
  color: var(--steel-light); font-style: italic;
}

.talk-mic-bar {
  flex-shrink: 0; padding: 16px 20px 32px; background: var(--card);
  border-top: 1px solid var(--line-soft); display: flex; flex-direction: column;
  align-items: center; gap: 14px;
}

.talk-waveform { display: flex; align-items: center; justify-content: center; gap: 5px; height: 28px; }
.talk-waveform span { width: 4px; border-radius: 2px; background: var(--line); height: 8px; transition: background .2s; }
.talk-waveform.is-active span { background: var(--accent); animation: waveBar 1s ease-in-out infinite; }
.talk-waveform.is-active span:nth-child(1) { animation-delay: 0s;   animation-duration: 0.9s; }
.talk-waveform.is-active span:nth-child(2) { animation-delay: .18s; animation-duration: 1.1s; }
.talk-waveform.is-active span:nth-child(3) { animation-delay: .36s; animation-duration: 0.8s; }
.talk-waveform.is-active span:nth-child(4) { animation-delay: .54s; animation-duration: 1.0s; }
.talk-waveform.is-active span:nth-child(5) { animation-delay: .72s; animation-duration: 0.95s; }
@keyframes waveBar {
  0%, 100% { height: 6px; }
  50%       { height: 22px; }
}

.talk-mic-btn {
  width: 72px; height: 72px; border-radius: 50%;
  background: var(--accent); border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 16px rgba(74,122,92,.32); transition: transform .15s, background .15s;
}
.talk-mic-btn:active { transform: scale(.94); }
.talk-mic-btn svg { width: 28px; height: 28px; stroke: #fff; fill: none; stroke-width: 2; }
.talk-mic-btn.is-recording {
  background: #C44040;
  box-shadow: 0 4px 16px rgba(196,64,64,.35), 0 0 0 8px rgba(196,64,64,.12);
  animation: micPulse 1.6s ease-in-out infinite;
}
@keyframes micPulse {
  0%, 100% { box-shadow: 0 4px 16px rgba(196,64,64,.35), 0 0 0 8px rgba(196,64,64,.10); }
  50%       { box-shadow: 0 4px 16px rgba(196,64,64,.35), 0 0 0 14px rgba(196,64,64,.05); }
}

.talk-timer { font-size: 20px; font-weight: 500; color: var(--steel); font-variant-numeric: tabular-nums; }
.talk-mic-polish-btn { width: 100%; justify-content: center; font-size: 21px; padding: 13px 16px; }

/* ============ AI PROCESSING (SHIMMER SKELETON) ============ */
.talk-processing-card { background: var(--card); border: 1px solid var(--line-soft); border-radius: 14px; padding: 20px; margin-top: 4px; }
.talk-processing-label {
  font-size: 20px; font-weight: 600; color: var(--accent); margin-bottom: 16px;
  display: flex; align-items: center; gap: 10px;
}
.dot-pulse { display: flex; gap: 4px; align-items: center; }
.dot-pulse span { width: 5px; height: 5px; background: var(--accent); border-radius: 50%; animation: dotPulse 1.2s ease-in-out infinite; }
.dot-pulse span:nth-child(2) { animation-delay: .2s; }
.dot-pulse span:nth-child(3) { animation-delay: .4s; }
@keyframes dotPulse {
  0%, 80%, 100% { opacity: .25; transform: scale(.85); }
  40%           { opacity: 1;   transform: scale(1); }
}

@keyframes shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position:  400px 0; }
}
.skel {
  background: linear-gradient(90deg, var(--line-soft) 25%, var(--line) 50%, var(--line-soft) 75%);
  background-size: 800px 100%; animation: shimmer 1.4s infinite; border-radius: 6px;
}
.skel-line { height: 13px; margin-bottom: 10px; }
.skel-line:last-of-type { margin-bottom: 0; }
.talk-skel-amounts { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line-soft); }
.talk-skel-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }
.talk-skel-row:last-child { margin-bottom: 0; }
.talk-skel-lbl { height: 11px; width: 48px; }
.talk-skel-amt { height: 13px; width: 64px; }

/* ============ POLISHED RESULT CARD ============ */
.talk-result-body { flex: 1; overflow-y: auto; }
.talk-result-card { background: var(--card); border: 1px solid var(--line-soft); border-radius: 14px; padding: 20px; }
.talk-result-label {
  font-size: 17px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 14px; display: flex; align-items: center; gap: 8px;
}
.talk-result-label svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2; }
.talk-result-line { font-size: 21px; color: var(--ink); line-height: 1.6; padding: 9px 0; border-bottom: 1px solid var(--line-soft); }
.talk-result-line:last-child { border-bottom: none; }

/* Structured AI result review, shared by Talk and Camera. Customer details sit
   in their own group above the itemized work so the contractor can eyeball an
   extracted name, address, or deposit before it reaches the form. */
.job-result-group { margin-top: 14px; }
.job-result-row {
  display: flex; align-items: baseline; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--line-soft);
}
.job-result-row:last-child { border-bottom: none; }
.job-result-key {
  flex: 0 0 auto; min-width: 96px;
  font-size: 15px; font-weight: 600; color: var(--body-copy-color);
}
.job-result-val {
  flex: 1 1 auto; min-width: 0;
  font-size: 19px; font-weight: 600; color: var(--ink); overflow-wrap: anywhere;
}
.job-result-item { padding: 11px 0; border-bottom: 1px solid var(--line-soft); }
.job-result-item:last-child { border-bottom: none; }
.job-result-desc { font-size: 21px; color: var(--ink); line-height: 1.5; }
.job-result-meta {
  margin-top: 4px; font-size: 15px; font-weight: 600; color: var(--body-copy-color);
}
.job-result-note {
  margin-top: 14px; padding: 11px 13px; border-radius: 10px;
  background: var(--accent-tint); color: var(--accent);
  font-size: 15px; font-weight: 600; line-height: 1.45;
}
.job-result-hint {
  margin-top: 14px; font-size: 15px; line-height: 1.45; color: var(--body-copy-color);
}
.talk-result-bar {
  flex-shrink: 0; display: flex; align-items: center; gap: 10px;
  padding: 12px 20px 32px; background: var(--card); border-top: 1px solid var(--line-soft);
}
/* Edit vs. forward pair: same box height so the row reads as one unit, but the
   forward action keeps the fill, the width and the weight so it's unambiguously
   the one to tap. Applies anywhere these two sit side by side. */
.talk-result-bar .btn-ghost-sm {
  flex: 0 0 auto; color: var(--steel); background: transparent;
  border-color: var(--line); font-weight: 600; font-size: 18px;
  padding: 13px 18px; border-radius: 999px;
}
.talk-result-bar .btn-ghost-sm:active { background: var(--accent-tint); }
.talk-confirm-btn { flex: 1; justify-content: center; font-size: 21px; font-weight: 700; padding: 13px 16px; }

/* ============ CAMERA ERROR STATE ============ */
.camera-error-btns { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }
.camera-error-btns .g-aibtn { width: 100%; justify-content: center; }
.camera-switch-btn {
  width: 100%; font-size: 21px; padding: 13px 16px; text-align: center;
  color: var(--steel); background: var(--accent-softer); border-color: var(--accent-tint);
}
.camera-switch-btn:active { background: var(--accent-tint); }

/* ============ NO-SIGNAL STATE ============ */
.talk-nosignal-card { text-align: center; }
.talk-alt-btns { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }
.talk-alt-btn {
  font-family: var(--body); font-size: 21px; font-weight: 500; color: var(--accent);
  background: var(--accent-softer); border: 1.5px solid var(--accent-tint);
  border-radius: 12px; padding: 14px 16px; cursor: pointer; text-align: left;
  display: flex; align-items: center; gap: 10px;
}
.talk-alt-btn svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; flex-shrink: 0; }
.talk-alt-btn:active { background: var(--accent-tint); }

/* ============ ADD-TO-HOME-SCREEN ANIMATED WALKTHROUGH ============
   Ported from prototypes/add-to-home-loops.html (approved 2026-07-06).
   Classes prefixed a2h- to avoid collisions with the rest of the app
   (the prototype's own .home/.phone/.screen names are already in use here). */
.ob-install-preview {
  display: flex; align-items: center; gap: 14px; margin-top: 18px;
  padding: 14px 16px; border-radius: 14px; cursor: pointer;
  background: var(--card); border: 1.5px solid var(--line); text-align: left;
  width: 100%;
}
.ob-install-preview:active { background: var(--accent-softer); }
.ob-install-preview-thumb {
  flex: 0 0 auto; width: 46px; height: 46px; border-radius: 12px;
  background: var(--accent); display: flex; align-items: center; justify-content: center;
  position: relative;
}
.ob-install-preview-thumb svg { width: 20px; height: 20px; stroke: #fff; fill: none; stroke-width: 2; margin-left: 2px; }
.ob-install-preview-text { flex: 1; }
.ob-install-preview-text b { display: block; font-size: 23px; color: var(--ink); font-weight: 700; }
.ob-install-preview-text span { display: block; font-size: 20px; color: var(--steel); margin-top: 2px; }
.ob-install-preview-arrow { flex: 0 0 auto; color: var(--steel-light); }
.ob-install-preview-arrow svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 2; }

#a2h-modal { align-items: center; overflow-y: auto; }
#a2h-modal .modal-card {
  max-width: none; width: 100%; background: transparent; box-shadow: none;
  display: flex; flex-direction: column; align-items: center; padding: 0;
  max-height: none; overflow: visible; border-radius: 0;
}
#a2h-modal-close {
  position: absolute; top: calc(env(safe-area-inset-top) + 14px); right: 16px; z-index: 10;
  width: 36px; height: 36px; border-radius: 50%; background: rgba(28,28,24,.55);
  display: flex; align-items: center; justify-content: center; border: none; cursor: pointer;
}
#a2h-modal-close svg { width: 18px; height: 18px; stroke: #fff; fill: none; stroke-width: 2.2; stroke-linecap: round; }
.a2h-modal-scale {
  transform: scale(var(--a2h-fit, 1)); transform-origin: top center;
  margin-top: calc(env(safe-area-inset-top) + 56px);
}
.a2h-modal-caption { max-width: 300px; margin: 8px auto calc(env(safe-area-inset-bottom) + 24px); text-align: center; }
/* Both the caption and the in-phone step list render over the dark modal
   backdrop (rgba(0,0,0,.5)) — force light text so they stay readable there,
   overriding the dark on-light colors baked into the ported prototype CSS. */
#a2h-modal .a2h-modal-caption,
#a2h-modal .a2h-steps { color: rgba(255,255,255,.92); }
#a2h-modal .a2h-steps b { color: #fff; }

#a2h-modal{
    --a2h-accent:#4A7A5C; --a2h-accent-deep:#3A6248; --a2h-sage:#6B9B82; --a2h-tint:#E6EFE9;
    --a2h-ink:#1C1C18; --a2h-ink-soft:#5E5E58; --a2h-muted:#9A9890;
    --a2h-surface:#F5F5F3; --a2h-rule:#E4E3DE; --a2h-white:#fff; --a2h-charcoal:#1C1C18;
    --a2h-ios-blue:#0a84ff;
    --a2h-loop: 16s;               /* master loop length — both phones share it */
  }
  *{box-sizing:border-box}
          .a2h-col{width:270px}
  .a2h-col h2{font-size: 23px; text-align:center; margin:0 0 14px; color:var(--a2h-accent-deep)}

  .a2h-mark{width:100%; height:100%; display:block}

  .a2h-phone{position:relative; width:270px; height:552px; margin:0 auto; background:#111; border-radius:40px; padding:12px; box-shadow:0 12px 40px rgba(0,0,0,.18)}
  .a2h-screen{position:relative; width:100%; height:100%; border-radius:30px; overflow:hidden; background:var(--a2h-white)}
  .a2h-notch{position:absolute; top:0; left:50%; transform:translateX(-50%); width:110px; height:22px; background:#111; border-radius:0 0 16px 16px; z-index:40}

  .a2h-webpage{position:absolute; inset:0; display:flex; flex-direction:column}
  .wp-  .a2h-wp-fav{width:60px; height:60px; border-radius:15px; margin:24px auto 14px; background:#F1F6F3; padding:11px; box-shadow:0 1px 4px rgba(0,0,0,.06)}
  .a2h-wp-title{font-size: 26px; font-weight:700; margin:0 0 6px}
  .a2h-wp-url{font-size: 18px; color:var(--a2h-muted)}
  .a2h-wp-line{height:9px; border-radius:5px; background:var(--a2h-surface); margin:16px 26px}
  .a2h-wp-line.s{margin:10px 60px}

  .a2h-finger{position:absolute; width:30px; height:30px; border-radius:50%; background:radial-gradient(circle at 35% 30%, rgba(0,0,0,.34), rgba(0,0,0,.17)); z-index:60; opacity:0; pointer-events:none; box-shadow:0 2px 6px rgba(0,0,0,.2)}

  .a2h-home{position:absolute; inset:0; z-index:35; opacity:0; display:flex; flex-direction:column; align-items:center; padding-top:70px}
  .a2h-home.a2h-ios-bg{background:linear-gradient(160deg,#6d9a80,#3a6248)}
  .a2h-home.a2h-and-bg{background:linear-gradient(160deg,#5b7f9a,#33475b)}
  .a2h-home-grid{display:grid; grid-template-columns:repeat(4,1fr); gap:22px 18px; padding:0 22px; width:100%}
  .a2h-home-icon{width:48px; height:48px; border-radius:12px; background:rgba(255,255,255,.22)}
  .a2h-home-icon.a2h-pd{background:var(--a2h-charcoal); padding:8px; box-shadow:0 4px 12px rgba(0,0,0,.35); transform:scale(0)}
  .a2h-home-label{color:#fff; font-size: 15px; text-align:center; margin-top:4px; text-shadow:0 1px 2px rgba(0,0,0,.3)}
  .a2h-pd-wrap{display:flex; flex-direction:column; align-items:center}

  /* ================= iOS ================= */
  .a2h-ios-bottombar{position:absolute; bottom:0; left:0; right:0; height:56px; z-index:20; background:#f7f7f8; border-top:1px solid #e2e2e4; display:flex; align-items:center; gap:8px; padding:0 12px}
  .a2h-ios-addr{flex:1; height:36px; background:#e9e9eb; border-radius:11px; display:flex; align-items:center; justify-content:center; gap:5px; font-size: 21px; color:var(--a2h-ink); font-weight:500}
  .a2h-ios-addr .a2h-lock{width:11px; height:11px; opacity:.5}
  .a2h-ios-more{width:38px; height:36px; border-radius:11px; background:#e9e9eb; display:flex; align-items:center; justify-content:center; position:relative}
  .a2h-ios-more .a2h-dots{display:flex; gap:3px}
  .a2h-ios-more .a2h-dots i{width:4px; height:4px; border-radius:50%; background:#3c3c43}
  .a2h-tap-ring{position:absolute; width:44px; height:44px; border-radius:50%; border:2px solid var(--a2h-ios-blue); left:50%; top:50%; transform:translate(-50%,-50%) scale(.4); opacity:0}

  .a2h-ios-more-menu{position:absolute; right:8px; bottom:64px; z-index:30; width:214px; background:#f6f6f8; border-radius:14px; overflow:hidden; box-shadow:0 8px 30px rgba(0,0,0,.18); transform:translateY(12px) scale(.96); opacity:0; transform-origin:bottom right}
  .a2h-mm-row{display:flex; align-items:center; justify-content:space-between; padding:12px 14px; font-size: 23px; font-weight:500; background:#fff; border-bottom:1px solid #ededf0}
  .a2h-mm-row .a2h-mi{width:20px; height:20px; color:var(--a2h-ink); display:flex; align-items:center; justify-content:center}
  .a2h-mm-row.a2h-highlight{background:#e6efe9; box-shadow:inset 0 0 0 2px var(--a2h-accent)}
  .a2h-mm-foot{display:flex; background:#fff}
  .a2h-mm-foot span{flex:1; text-align:center; padding:12px 0; font-size: 21px; font-weight:600; color:var(--a2h-ios-blue)}
  .a2h-mm-foot span:first-child{border-right:1px solid #ededf0}

  .a2h-ios-share{position:absolute; left:8px; right:8px; bottom:8px; z-index:32; background:#f2f2f5; border-radius:16px; padding:14px 9px 10px; transform:translateY(120%); box-shadow:0 -6px 24px rgba(0,0,0,.14)}
  .a2h-sh-head{display:flex; align-items:flex-start; gap:12px; background:#fff; border-radius:12px; padding:12px; margin-bottom:8px}
  .a2h-sh-fav{width:44px; height:44px; border-radius:10px; background:#F1F6F3; padding:8px; flex:0 0 auto}
  .a2h-sh-meta{display:flex; flex-direction:column; gap:1px; flex:1; min-width:0}
  .a2h-sh-meta b{font-size: 23px}
  .a2h-sh-meta span{font-size: 18px; color:var(--a2h-muted)}
  .a2h-sh-opts{align-self:flex-start; margin-top:5px; background:#eaeaef; color:var(--a2h-ink)!important; font-size: 18px!important; font-weight:600; padding:3px 10px; border-radius:11px}
  .a2h-sh-x{width:24px; height:24px; flex:0 0 auto}
  .a2h-sh-apps{display:flex; gap:8px; padding:12px 2px 10px; overflow:hidden; justify-content:space-between}
  .a2h-sh-app{display:flex; flex-direction:column; align-items:center; gap:5px; font-size: 14px; color:var(--a2h-ink-soft); flex:0 0 auto; width:47px}
  .a2h-sh-app .a2h-ai{width:44px; height:44px; border-radius:11px; display:flex; align-items:center; justify-content:center}
  .a2h-sh-app .a2h-ai svg{width:23px; height:23px}
  .a2h-sh-actions{display:flex; gap:8px; padding:2px 2px 12px; overflow:hidden; justify-content:space-between}
  .a2h-sh-act{display:flex; flex-direction:column; align-items:center; gap:5px; font-size: 14px; color:var(--a2h-ink-soft); flex:0 0 auto; width:47px; position:relative; line-height:1.15}
  .a2h-sh-act .a2h-ac{width:44px; height:44px; border-radius:50%; background:#e6e6ea; display:flex; align-items:center; justify-content:center}
  .a2h-sh-act .a2h-ac svg{width:21px; height:21px}
  .a2h-sh-act.a2h-viewmore .a2h-ac{position:relative}
  .a2h-sh-act.a2h-viewmore .a2h-ring{position:absolute; inset:-4px; border-radius:50%; border:2px solid var(--a2h-accent); opacity:0}
  /* the revealed list — hidden until View More is tapped */
  .a2h-sh-list{display:flex; flex-direction:column; border-top:1px solid #e2e2e5; margin-top:6px; overflow:hidden; max-height:0; opacity:0}
  .a2h-sh-item{display:flex; align-items:center; justify-content:space-between; background:#fff; padding:13px 14px; font-size: 23px; font-weight:500; border-bottom:1px solid #ededf0}
  .a2h-sh-item:first-child{border-radius:12px 12px 0 0}
  .a2h-sh-item:last-child{border-radius:0 0 12px 12px; border-bottom:0}
  .a2h-sh-item .a2h-si{width:24px; height:24px; color:var(--a2h-ink); display:flex; align-items:center; justify-content:center}
  .a2h-sh-item.a2h-dim{opacity:.55}
  .a2h-sh-item.a2h-highlight{background:#e6efe9; box-shadow:inset 0 0 0 2px var(--a2h-accent); border-radius:12px}

  /* iOS confirmation screen */
  .a2h-ios-confirm{position:absolute; inset:0 0 0 0; top:26px; z-index:34; background:#efeff4; border-radius:14px 14px 0 0; transform:translateY(100%); box-shadow:0 -8px 30px rgba(0,0,0,.16)}
  .a2h-cf-bar{display:flex; align-items:center; justify-content:space-between; padding:16px 14px}
  .a2h-cf-x{width:30px; height:30px; border-radius:50%; background:#fff; display:flex; align-items:center; justify-content:center}
  .a2h-cf-title{font-size: 23px; font-weight:700}
  .a2h-cf-add{background:var(--a2h-ios-blue); color:#fff; font-size: 21px; font-weight:600; padding:6px 16px; border-radius:16px; position:relative}
  .a2h-cf-add .a2h-ring{position:absolute; inset:-5px; border-radius:20px; border:2px solid #fff; box-shadow:0 0 0 2px var(--a2h-accent); opacity:0}
  .a2h-cf-row{display:flex; align-items:center; gap:12px; background:#fff; margin:8px 0 0; padding:12px 14px}
  .a2h-cf-ic{width:44px; height:44px; border-radius:10px; background:#F1F6F3; padding:8px; flex:0 0 auto}
  .a2h-cf-name{flex:1}
  .a2h-cf-name b{font-size: 23px; display:block}
  .a2h-cf-name span{font-size: 18px; color:var(--a2h-muted)}
  .a2h-cf-webapp{display:flex; align-items:center; justify-content:space-between; background:#fff; margin-top:8px; padding:14px}
  .a2h-cf-webapp span{font-size: 23px}
  .a2h-cf-toggle{width:42px; height:26px; border-radius:13px; background:#34c759; position:relative}
  .a2h-cf-toggle::after{content:""; position:absolute; width:22px; height:22px; border-radius:50%; background:#fff; top:2px; right:2px}
  .a2h-cf-help{font-size: 18px; color:var(--a2h-muted); padding:10px 16px}

  /* ================= Android ================= */
  .a2h-and-topbar{height:46px; background:#fff; border-bottom:1px solid #ececec; display:flex; align-items:center; padding:0 12px; gap:10px; position:relative; z-index:20}
  .a2h-and-url{flex:1; height:28px; background:#f1f3f4; border-radius:14px; display:flex; align-items:center; padding:0 12px; font-size: 18px; color:var(--a2h-ink-soft)}
  .a2h-and-menu-btn{position:relative; width:24px; height:24px; display:flex; flex-direction:column; align-items:center; justify-content:center}
  .a2h-and-menu-btn .a2h-dot{width:4px; height:4px; border-radius:50%; background:#5f6368; margin:1.5px 0}
  .a2h-and-menu{position:absolute; top:8px; right:8px; z-index:30; width:198px; background:#fff; border-radius:8px; padding:4px 0; box-shadow:0 6px 24px rgba(0,0,0,.22); transform-origin:top right; transform:scale(0); opacity:0}
  .a2h-and-item{font-size: 20px; padding:9px 16px; display:flex; align-items:center; gap:12px; position:relative}
  .a2h-and-item .a2h-aico{width:18px; height:18px; color:#5f6368; display:flex; align-items:center; justify-content:center; flex:0 0 auto}
  .a2h-and-item.a2h-highlight{background:#e6efe9}
  .a2h-and-sep{height:1px; background:#eee; margin:4px 0}

  /* Android confirmation dialog */
  .a2h-and-dim{position:absolute; inset:0; z-index:33; background:rgba(0,0,0,.35); opacity:0}
  .a2h-and-dialog{position:absolute; z-index:34; left:24px; right:24px; top:200px; background:#fff; border-radius:14px; padding:18px 18px 10px; box-shadow:0 12px 40px rgba(0,0,0,.3); transform:scale(.9); opacity:0}
  .a2h-ad-title{font-size: 26px; font-weight:600; margin:0 0 16px}
  .a2h-ad-site{display:flex; align-items:center; gap:12px; margin-bottom:16px}
  .a2h-ad-ic{width:38px; height:38px; border-radius:9px; background:#F1F6F3; padding:7px; flex:0 0 auto}
  .a2h-ad-site b{font-size: 21px; display:block}
  .a2h-ad-site span{font-size: 18px; color:var(--a2h-muted)}
  .a2h-ad-btns{display:flex; justify-content:flex-end; gap:8px}
  .a2h-ad-btn{font-size: 21px; font-weight:600; padding:8px 14px; border-radius:8px; color:#1a73e8; position:relative}
  .a2h-ad-btn.a2h-add .a2h-ring{position:absolute; inset:-3px; border-radius:10px; border:2px solid var(--a2h-accent); opacity:0}

  /* ===== caption ===== */
  .a2h-steps{margin:18px 4px 0; font-size: 20px; color:var(--a2h-ink-soft); line-height:1.55}
  .a2h-steps b{color:var(--a2h-ink)}
    
  /* =========================================================
     iOS TIMELINE (16s)
     beats: ••• → menu → Share → sheet(collapsed) → View More →
            list → Add to Home Screen → confirm → Add → home
     ========================================================= */
  .a2h-ios .a2h-finger{ animation: iosFinger var(--a2h-loop) infinite; }
  @keyframes iosFinger{
    0%   {opacity:0; left:238px; top:520px}
    3%   {opacity:1; left:238px; top:512px}   /* over ••• */
    7%   {opacity:1; left:238px; top:520px}   /* tap ••• */
    11%  {opacity:1; left:238px; top:512px}
    15%  {opacity:0}
    /* to Share (top row of menu, center ~221px) */
    19%  {opacity:0; left:80px; top:210px}
    23%  {opacity:1; left:80px; top:206px}
    26%  {opacity:1; left:80px; top:212px}    /* tap Share */
    29%  {opacity:1; left:80px; top:206px}
    33%  {opacity:0}
    /* to View More chevron (4th action circle, center ~208x, ~442y) */
    38%  {opacity:0; left:194px; top:431px}
    42%  {opacity:1; left:194px; top:427px}
    45%  {opacity:1; left:194px; top:433px}   /* tap View More */
    48%  {opacity:1; left:194px; top:427px}
    51%  {opacity:0}
    /* down to Add to Home Screen (revealed list, row center ~485px) */
    56%  {opacity:0; left:70px; top:474px}
    60%  {opacity:1; left:70px; top:470px}
    63%  {opacity:1; left:70px; top:476px}    /* tap Add to Home Screen */
    66%  {opacity:1; left:70px; top:470px}
    69%  {opacity:0}
    /* to the blue Add button on confirm (center ~202x, ~60y) */
    74%  {opacity:0; left:187px; top:49px}
    78%  {opacity:1; left:187px; top:45px}
    81%  {opacity:1; left:187px; top:51px}    /* tap Add */
    84%  {opacity:1; left:187px; top:45px}
    87%  {opacity:0}
    100% {opacity:0}
  }
  .a2h-ios .a2h-tap-ring{ animation: iosRing var(--a2h-loop) infinite; }
  @keyframes iosRing{
    0%{opacity:0; transform:translate(-50%,-50%) scale(.4)}
    4%{opacity:.9}
    9%{opacity:0; transform:translate(-50%,-50%) scale(1.5)}
    100%{opacity:0}
  }
  .a2h-ios .a2h-ios-more-menu{ animation: iosMore var(--a2h-loop) infinite; }
  @keyframes iosMore{
    0%,10%   {opacity:0; transform:translateY(12px) scale(.96)}
    13%,27%  {opacity:1; transform:translateY(0) scale(1)}
    31%,100% {opacity:0; transform:translateY(12px) scale(.96)}
  }
  .a2h-ios .a2h-mm-row.a2h-highlight{ animation: iosMmHi var(--a2h-loop) infinite; }
  @keyframes iosMmHi{
    0%,21%   {background:#fff}
    24%,29%  {background:#e6efe9}
    32%,100% {background:#fff}
  }
  /* share sheet: up after Share tap (31%), away when confirm appears (69%) */
  .a2h-ios .a2h-ios-share{ animation: iosShare var(--a2h-loop) infinite; }
  @keyframes iosShare{
    0%,30%   {transform:translateY(120%)}
    35%,66%  {transform:translateY(0)}
    71%,100% {transform:translateY(120%)}
  }
  /* View More tap ring */
  .a2h-ios .a2h-sh-act.a2h-viewmore .a2h-ring{ animation: iosVm var(--a2h-loop) infinite; }
  @keyframes iosVm{
    0%,42%  {opacity:0}
    45%     {opacity:1}
    49%,100%{opacity:0}
  }
  /* list reveal after View More (48%) */
  .a2h-ios .a2h-sh-list{ animation: iosList var(--a2h-loop) infinite; }
  @keyframes iosList{
    0%,47%   {max-height:0; opacity:0}
    52%,68%  {max-height:320px; opacity:1}
    72%,100% {max-height:0; opacity:0}
  }
  .a2h-ios .a2h-sh-item.a2h-highlight{ animation: iosShHi var(--a2h-loop) infinite; }
  @keyframes iosShHi{
    0%,58%   {background:#fff}
    62%,67%  {background:#e6efe9}
    70%,100% {background:#fff}
  }
  /* confirmation slides up (69%), away before home (87%) */
  .a2h-ios .a2h-ios-confirm{ animation: iosConfirm var(--a2h-loop) infinite; }
  @keyframes iosConfirm{
    0%,68%   {transform:translateY(100%)}
    73%,85%  {transform:translateY(0)}
    89%,100% {transform:translateY(100%)}
  }
  .a2h-ios .a2h-cf-add .a2h-ring{ animation: iosCfRing var(--a2h-loop) infinite; }
  @keyframes iosCfRing{
    0%,79%  {opacity:0}
    82%     {opacity:1}
    86%,100%{opacity:0}
  }
  .a2h-ios .a2h-home{ animation: iosHome var(--a2h-loop) infinite; }
  @keyframes iosHome{
    0%,87%  {opacity:0; pointer-events:none}
    91%,97% {opacity:1}
    100%    {opacity:0}
  }
  .a2h-ios .a2h-home-icon.a2h-pd{ animation: pdPop var(--a2h-loop) infinite; }
  @keyframes pdPop{
    0%,88%  {transform:scale(0)}
    93%     {transform:scale(1.18)}
    96%,98% {transform:scale(1)}
    100%    {transform:scale(0)}
  }

  /* =========================================================
     ANDROID TIMELINE (16s)
     beats: ⋮ → menu → Add to Home screen → dialog → Add → home
     ========================================================= */
  .a2h-and .a2h-finger{ animation: andFinger var(--a2h-loop) infinite; }
  @keyframes andFinger{
    0%   {opacity:0; left:207px; top:12px}
    4%   {opacity:1; left:207px; top:8px}     /* over ⋮ (center ~222,23) */
    9%   {opacity:1; left:207px; top:14px}    /* tap ⋮ */
    14%  {opacity:0; left:207px; top:8px}
    /* down to Add to Home screen row */
    30%  {opacity:0; left:185px; top:246px}
    35%  {opacity:1; left:185px; top:242px}
    42%  {opacity:1; left:185px; top:248px}   /* tap */
    47%  {opacity:1; left:185px; top:242px}
    52%  {opacity:0}
    /* to Add on dialog (center ~176,324) */
    64%  {opacity:0; left:161px; top:313px}
    69%  {opacity:1; left:161px; top:309px}
    73%  {opacity:1; left:161px; top:315px}   /* tap Add */
    77%  {opacity:1; left:161px; top:309px}
    81%  {opacity:0}
    100% {opacity:0}
  }
  .a2h-and .a2h-and-menu{ animation: andMenu var(--a2h-loop) infinite; }
  @keyframes andMenu{
    0%,11%   {transform:scale(0); opacity:0}
    16%,50%  {transform:scale(1); opacity:1}
    55%,100% {transform:scale(0); opacity:0}
  }
  .a2h-and .a2h-and-item.a2h-highlight{ animation: andHi var(--a2h-loop) infinite; }
  @keyframes andHi{
    0%,37%   {background:#fff}
    42%,49%  {background:#e6efe9}
    54%,100% {background:#fff}
  }
  .a2h-and .a2h-and-dim{ animation: andDim var(--a2h-loop) infinite; }
  @keyframes andDim{
    0%,52%   {opacity:0}
    57%,79%  {opacity:1}
    83%,100% {opacity:0}
  }
  .a2h-and .a2h-and-dialog{ animation: andDialog var(--a2h-loop) infinite; }
  @keyframes andDialog{
    0%,52%   {transform:scale(.9); opacity:0}
    57%,79%  {transform:scale(1); opacity:1}
    83%,100% {transform:scale(.9); opacity:0}
  }
  .a2h-and .a2h-ad-btn.a2h-add .a2h-ring{ animation: andAddRing var(--a2h-loop) infinite; }
  @keyframes andAddRing{
    0%,70%  {opacity:0}
    73%     {opacity:1}
    78%,100%{opacity:0}
  }
  .a2h-and .a2h-home{ animation: andHome var(--a2h-loop) infinite; }
  @keyframes andHome{
    0%,82%  {opacity:0}
    87%,97% {opacity:1}
    100%    {opacity:0}
  }
  .a2h-and .a2h-home-icon.a2h-pd{ animation: pdPop var(--a2h-loop) infinite; }

  @media (prefers-reduced-motion: reduce){
    .a2h-finger,.a2h-ios-more-menu,.a2h-ios-share,.a2h-sh-list,.a2h-ios-confirm,.a2h-and-menu,.a2h-and-dim,.a2h-and-dialog,.a2h-home,.a2h-tap-ring,
    .a2h-mm-row.a2h-highlight,.a2h-sh-item.a2h-highlight,.a2h-sh-act.a2h-viewmore .a2h-ring,.a2h-cf-add .a2h-ring,.a2h-and-item.a2h-highlight,.a2h-ad-btn.a2h-add .a2h-ring,.a2h-home-icon.a2h-pd{ animation:none !important; }
  }

/* ============ HOME DASHBOARD (stats + recent jobs) ============ */
.dash-stats-label {
  font-size: 15px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--steel); font-weight: 700; margin: 4px 2px 8px;
}
.dash-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 24px; }
.dash-stat {
  position: relative; text-align: left; font-family: var(--body);
  background: var(--accent-softer); border: none; border-radius: var(--radius);
  padding: 12px 10px; cursor: pointer; display: flex; flex-direction: column;
}
.dash-stat:active { background: var(--accent-tint); }
.dash-stat-label {
  font-size: 15px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--steel); font-weight: 700; margin-bottom: 4px;
}
.dash-stat-value { font-size: 22px; font-weight: 800; color: var(--ink); }
.dash-stat-caret { position: absolute; top: 9px; right: 10px; font-size: 15px; font-weight: 900; color: var(--accent); line-height: 1; }
.dash-stat-revenue .dash-stat-value { color: var(--accent); }
.dash-stat-unpaid .dash-stat-caret { color: var(--status-unpaid); }
.dash-stat-unpaid .dash-stat-value { color: var(--status-unpaid); }

.dash-section-head { display: flex; align-items: center; justify-content: space-between; margin: 28px 2px 12px; }
.dash-section-head h2 { font-size: 17px; text-transform: uppercase; letter-spacing: .05em; color: var(--steel); font-weight: 800; margin: 0; }
.dash-all-link { font-family: var(--body); font-size: 20px; color: var(--accent); font-weight: 700; background: none; border: none; padding: 0; cursor: pointer; }

/* ============ STAT DRILL-DOWN SHEET ============ */
.dash-sheet-backdrop {
  position: fixed; inset: 0; background: rgba(28,28,24,.4);
  opacity: 0; pointer-events: none; transition: opacity .2s; z-index: 40;
}
.dash-sheet-backdrop.open { opacity: 1; pointer-events: auto; }
.dash-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; max-width: 560px; margin: 0 auto;
  background: var(--card); border-radius: 22px 22px 0 0; padding: 10px 20px calc(28px + env(safe-area-inset-bottom));
  transform: translateY(100%); transition: transform .25s ease; z-index: 41;
  box-shadow: 0 -10px 30px rgba(0,0,0,.15);
  max-height: 86vh; overflow-y: auto;
}
.dash-sheet.open { transform: translateY(0); }
.dash-sheet-handle { width: 36px; height: 4px; background: var(--line); border-radius: 4px; margin: 4px auto 14px; }
.dash-sheet h3 { margin: 0 0 2px; font-size: 20px; color: var(--ink); }
.dash-sheet-total { font-size: 30px; font-weight: 800; color: var(--accent); margin: 2px 0 16px; }
.dash-sheet-filter-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.dash-sheet-sub { font-size: 15px; color: var(--steel); text-transform: uppercase; letter-spacing: .04em; font-weight: 700; }
.dash-year-select {
  font-family: var(--body); border: 1.5px solid var(--line); background: var(--card);
  border-radius: 8px; padding: 5px 9px; font-size: 17px; font-weight: 700; color: var(--ink);
}
/* Fixed-width columns that scroll horizontally instead of squeezing as months
   accumulate — 12+ months stays exactly as legible as 2. Auto-scrolled to the
   newest month on open (see renderStatBars). */
.dash-bars {
  display: flex; align-items: flex-end; gap: 10px; height: 140px; margin-bottom: 6px;
  overflow-x: auto; overflow-y: hidden; scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch; padding: 0 2px 4px;
}
.dash-bar-col { flex: 0 0 40px; width: 40px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; cursor: pointer; }
.dash-bar-col .v { font-size: 12px; font-weight: 800; color: var(--ink); margin-bottom: 4px; opacity: .85; white-space: nowrap; }
.dash-bar-col.active .v { opacity: 1; }
.dash-bar { width: 100%; border-radius: 5px 5px 2px 2px; background: var(--accent); transition: opacity .15s; }
.dash-bar-col .m { font-size: 14px; color: var(--steel); margin-top: 5px; }
.dash-bar-col.active .m { color: var(--ink); font-weight: 700; }
.dash-sheet-detail { border-top: 1px solid var(--line); margin-top: 10px; padding-top: 10px; }
.dash-detail-head { font-size: 15px; font-weight: 800; color: var(--ink); margin-bottom: 8px; }
.dash-detail-empty { font-size: 14px; color: var(--steel); margin: 0; }
.dash-sheet-close {
  /* Keyed to the home entry-point tiles: a 30px glyph in a 52px box (~0.58). Those tiles
     are the app's reference proportion — match them rather than inventing a new ratio. */
  position: absolute; top: 12px; right: 14px; width: 52px; height: 52px; border-radius: 50%;
  background: var(--accent-softer); color: var(--ink-soft); border: none; display: flex;
  align-items: center; justify-content: center; font-size: 30px; line-height: 1; cursor: pointer;
  z-index: 2;
}

/* ===================================================================
   VOICE INTERVIEW MODE — hands-free toggle inside Guided walkthrough
   =================================================================== */
.hf-toggle-btn { color: var(--ink-soft); transition: color .15s, background .15s; }
.hf-toggle-btn[aria-pressed="true"] { color: var(--accent-bright); background: var(--accent-softer); }
.hf-toggle-btn svg { width: 22px; height: 22px; }

.hf-overlay {
  position: fixed; inset: 0; z-index: 40;
  /* Opaque, full-screen waveform, ChatGPT-voice-mode style. An earlier
     version kept this translucent so the guided card's question text
     showed through, per the original spec. Real-device testing found
     seeing the form's mismatched labels/placeholders behind the orb read
     as visually confusing, not reassuring, so #guided-card is hidden
     outright (see .hf-card-hidden) and this is opaque again. */
  background: var(--bg);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px; padding: 24px;
}
/* Hidden, not just visually covered, while the hands-free overlay is up --
   see hfOverlayShow()/hfOverlayHide(). */
.hf-card-hidden { display: none; }
.hf-overlay[hidden] { display: none; }
#hf-waveform { width: 220px; height: 220px; }
.hf-status { font-size: 24px; color: var(--ink-soft); margin: 0; text-align: center; }
.hf-stop-btn { margin-top: 8px; }

/* First-run consent sheet reuses .modal / .modal-card; these are its own
   content rules since it has no header icon row like the other sheets. */
#hf-consent-sheet .modal-body p { font-size: 22px; line-height: 1.5; color: var(--ink); margin: 0 0 10px; }
#hf-consent-sheet .modal-actions { margin-top: 14px; }
