/* ==========================================================================
   Sierra Action Planner — Realtor audience skin.
   Builds ENTIRELY on the tokens + components defined in planner.css (linked
   first). Nothing here redefines a token or a shared component; it only adds
   the realtor-specific layout (landing, template picker, plan renderer,
   dashboard) using the same variables so it reads as one design system.
   ========================================================================== */

/* ---- generic realtor page shell ---------------------------------------- */
.agents-main { max-width: var(--maxw); margin: 0 auto; padding: clamp(26px,4vw,44px) clamp(16px,4vw,32px) 64px; }
.ag-footer { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--muted); border-top: 1px solid var(--border); padding: 18px clamp(16px,4vw,32px); max-width: var(--maxw); margin: 0 auto; }
.ag-footer a { color: var(--muted); }
.ag-footer a:hover { color: var(--forest-green); }

/* ---- landing hero (reuses the dark tk-hero band tokens) ---------------- */
.ag-hero { position: relative; overflow: hidden; background: radial-gradient(120% 130% at 12% 0%, #1E4636 0%, #163C2E 46%, #102D22 100%); color: #F3EDE0; }
/* Hand-drawn topographic contour lines: a quiet nod to land and parcels, no
   gradient blobs or photography. Purely decorative, sits behind the content. */
.ag-hero-topo { position: absolute; top: -14%; right: -8%; width: min(66%, 760px); height: auto; pointer-events: none; opacity: 0.22; }
.ag-hero-inner { position: relative; z-index: 1; max-width: var(--maxw); margin: 0 auto; padding: clamp(40px,6vw,76px) clamp(16px,4vw,32px) clamp(34px,5vw,56px); animation: slt-rise 0.6s ease both; }
@media (prefers-reduced-motion: reduce) { .ag-hero-inner { animation: none; } }
.ag-hero-eyebrow { display: inline-flex; align-items: center; gap: 8px; background: rgba(199,145,63,0.16); border: 1px solid rgba(199,145,63,0.4); color: #EBCB8F; border-radius: 999px; padding: 6px 14px; font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.ag-hero-h1 { font-family: 'Newsreader', serif; font-weight: 500; font-size: clamp(30px,5vw,52px); line-height: 1.06; letter-spacing: -0.01em; margin: 18px 0 0; color: #FBF7EE; max-width: 15ch; }
.ag-hero-h1 em { font-style: italic; color: #EBCB8F; }
.ag-hero-sub { font-size: clamp(15px,1.7vw,19px); line-height: 1.55; color: #CFD8CF; margin: 18px 0 0; max-width: 46ch; }
.ag-hero-cta { margin-top: 28px; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.ag-btn-gold { display: inline-flex; align-items: center; gap: 8px; background: var(--cedar-accent); color: var(--cream); border: none; border-radius: 999px; padding: 14px 26px; font-family: inherit; font-size: 15px; font-weight: 800; cursor: pointer; box-shadow: 0 16px 34px -18px rgba(0,0,0,0.7); transition: background 0.15s, transform 0.15s; text-decoration: none; }
.ag-btn-gold:hover { background: #9c4526; transform: translateY(-1px); }
.ag-hero-note { font-size: 13px; color: #A9BCAE; }

/* ---- section headings on parchment ------------------------------------- */
.ag-band { padding: clamp(30px,4vw,52px) 0; }
.ag-intro { max-width: 52ch; }
.ag-eyebrow { display: inline-block; font-size: 11.5px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: var(--cedar-2); }
.ag-h2 { font-family: 'Newsreader', serif; font-weight: 600; font-size: clamp(24px,3.4vw,36px); line-height: 1.1; color: var(--forest-green); margin: 10px 0 0; }
.ag-lead { font-size: clamp(14.5px,1.6vw,17px); line-height: 1.6; color: var(--ink-soft); margin: 14px 0 0; }

/* ---- template picker cards --------------------------------------------- */
.ag-picker-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; margin-top: 26px; }
.ag-tcard { position: relative; overflow: hidden; text-align: left; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-card); box-shadow: var(--shadow-card); padding: 26px 22px 20px; display: flex; flex-direction: column; gap: 12px; cursor: pointer; font-family: inherit; transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s; }
.ag-tcard:hover { transform: translateY(-3px); border-color: var(--green-tint-border); box-shadow: 0 1px 2px rgba(20,40,30,0.05), 0 26px 48px -30px rgba(20,40,30,0.5); }
.ag-tcard:focus-visible { outline: 2px solid var(--green-2); outline-offset: 3px; }
/* A colour-coded accent bar makes each of the four deal types instantly
   distinct, in the fixed picker order (land · farm · escrow · estate). */
.ag-tcard::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 5px; background: var(--ag-accent, var(--green-mid)); }
.ag-picker-grid .ag-tcard:nth-child(1) { --ag-accent: #24614A; }
.ag-picker-grid .ag-tcard:nth-child(2) { --ag-accent: #B4552F; }
.ag-picker-grid .ag-tcard:nth-child(3) { --ag-accent: #C7913F; }
.ag-picker-grid .ag-tcard:nth-child(4) { --ag-accent: #1E4636; }
.ag-tcard-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ag-badge { align-self: flex-start; font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.05em; color: #1E4636; background: #EAF1EA; border: 1px solid #CFE0D3; border-radius: 999px; padding: 3px 10px; white-space: nowrap; }
.ag-badge-repeat { color: #7a5a12; background: #FBF3E4; border-color: var(--gold-soft); }
.ag-chip-dur { font-size: 12px; font-weight: 700; color: var(--muted-2); background: #F6F1E6; border-radius: 999px; padding: 4px 11px; white-space: nowrap; }
.ag-tcard-name { font-family: 'Newsreader', serif; font-weight: 600; font-size: 20px; line-height: 1.2; color: var(--forest-green); margin: 0; }
.ag-tcard-sub { font-size: 13.5px; color: #6E685E; line-height: 1.5; margin: 0; flex: 1; }
.ag-tcard-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 12px; font-weight: 700; color: var(--muted); border-top: 1px solid var(--border-soft); padding-top: 12px; }
.ag-tcard-cta { display: inline-flex; align-items: center; gap: 6px; align-self: flex-start; color: var(--ag-accent, var(--cedar-accent)); font-size: 13.5px; font-weight: 800; }
.ag-repeat-flag { display: inline-flex; align-items: center; gap: 5px; color: #8a5a17; font-weight: 700; }

/* "Build your own" (custom) picker card — a dashed, cedar-accented invitation
   that reads as distinct from the four fixed templates. */
.ag-tcard-custom { border-style: dashed; border-color: var(--gold-soft); cursor: default; }
.ag-tcard-custom:hover { transform: none; }
.ag-picker-grid .ag-tcard-custom::before { background: var(--cedar-accent); }
.ag-badge-custom { color: #8a5a17; background: #FBF3E4; border-color: var(--gold-soft); }
.ag-tcard-custom-cta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 4px; }
.ag-tcard-build { padding: 11px 20px; font-size: 14px; }

/* ---- trust line + CTA band --------------------------------------------- */
.ag-trust { margin-top: 34px; background: var(--card-2); border: 1px solid var(--border); border-radius: 16px; padding: 20px 24px; font-size: 14px; line-height: 1.6; color: var(--ink-soft); }
.ag-trust strong { color: var(--forest-green); }

/* ==========================================================================
   Setup modal (label + dates + quick set + live preview)
   ========================================================================== */
.ag-modal { position: fixed; inset: 0; z-index: 200; display: flex; align-items: flex-start; justify-content: center; padding: clamp(16px,5vh,64px) 16px; background: rgba(16,45,34,0.5); backdrop-filter: blur(4px); overflow-y: auto; }
.ag-modal[hidden] { display: none; }
.ag-modal-card { width: 100%; max-width: 560px; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-card); box-shadow: 0 40px 80px -30px rgba(16,45,34,0.6); padding: clamp(22px,3vw,30px); animation: slt-rise 0.25s ease both; }
.ag-modal-eyebrow { font-size: 11.5px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--cedar-2); }
.ag-modal-title { font-family: 'Newsreader', serif; font-weight: 600; font-size: clamp(22px,3vw,28px); color: var(--forest-green); margin: 6px 0 2px; line-height: 1.15; }
.ag-modal-sub { font-size: 13.5px; color: var(--ink-soft); line-height: 1.5; margin: 0 0 18px; }
.ag-field { margin-top: 16px; }
.ag-field-label { display: block; font-size: 12.5px; font-weight: 800; letter-spacing: 0.02em; color: var(--forest-green); margin-bottom: 7px; }
.ag-input { width: 100%; padding: 13px; border: 1.5px solid var(--border-2); border-radius: 10px; font-size: 15px; font-family: inherit; background: #fff; color: var(--dark-text); transition: border 0.15s; }
.ag-input:focus { outline: none; border-color: var(--green-2); }
.ag-dates { display: flex; flex-wrap: wrap; gap: 14px; }
.ag-dates > div { flex: 1 1 190px; min-width: 0; }
.ag-quick { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.ag-quick-btn { background: #F6F1E6; border: 1px solid var(--border-2); color: var(--green-2); border-radius: 999px; padding: 7px 14px; font-size: 12.5px; font-weight: 700; cursor: pointer; font-family: inherit; transition: background 0.15s, border-color 0.15s, color 0.15s; }
.ag-quick-btn:hover { background: var(--green-tint); border-color: var(--green-tint-border); }
.ag-quick-btn.is-active { background: var(--forest-green); color: var(--cream); border-color: var(--forest-green); }
.ag-preview { margin-top: 18px; background: var(--green-tint); border: 1px solid var(--green-tint-border); border-radius: 12px; padding: 13px 15px; font-size: 13.5px; color: var(--green-2); line-height: 1.5; }
.ag-preview strong { color: var(--forest-green); }
.ag-modal-actions { display: flex; gap: 10px; margin-top: 22px; flex-wrap: wrap; }
.ag-modal-cancel { background: none; border: 1px solid var(--border-2); color: var(--muted); border-radius: 10px; padding: 13px 18px; font-weight: 700; font-size: 14px; cursor: pointer; font-family: inherit; }
.ag-modal-cancel:hover { background: #EFE9DB; }

/* ==========================================================================
   Plan renderer (agents-plan.html)
   ========================================================================== */
.ag-planhead { background: var(--card); border: 1px solid var(--border); border-left: 5px solid var(--cedar-accent); border-radius: 16px; box-shadow: var(--shadow-card); padding: clamp(18px,2.4vw,26px); }
.ag-planhead-top { display: flex; flex-wrap: wrap; gap: 14px 20px; align-items: flex-start; justify-content: space-between; }
.ag-planhead-badge { font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.05em; color: #1E4636; background: #EAF1EA; border: 1px solid #CFE0D3; border-radius: 999px; padding: 3px 10px; }
.ag-plan-label { font-family: 'Newsreader', serif; font-weight: 600; font-size: clamp(22px,3vw,30px); color: var(--forest-green); margin: 10px 0 2px; line-height: 1.15; border: none; background: transparent; width: 100%; font-family: 'Newsreader', serif; }
.ag-plan-label-input { border: 1.5px dashed transparent; border-radius: 8px; margin-left: -8px; padding: 2px 8px; }
.ag-plan-label-input:hover { border-color: var(--border-2); }
.ag-plan-label-input:focus { outline: none; border-color: var(--green-2); border-style: solid; background: #fff; }
.ag-plan-tname { font-size: 13.5px; color: var(--muted); margin: 0; }
.ag-plan-progress { display: flex; align-items: center; gap: 14px; min-width: 220px; flex: 1 1 220px; max-width: 360px; }
.ag-dates-row { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 18px; }

/* Hourly vs daily — "right here, where it says start, is a radio button?
   Hourly or daily?" Sits directly above the dates it governs and borrows the
   pill shape of .ag-chart-toggle, so the two custom-plan switches on this page
   read as the same kind of control. The <input type="radio"> is real and only
   visually hidden: it is what makes the arrow keys, the label click and the
   screen-reader grouping work without a line of JavaScript. */
.ag-timemode { display: inline-flex; align-items: center; gap: 0; flex-wrap: wrap; border: 1.5px solid var(--border-2); border-radius: 999px; padding: 3px; margin-top: 18px; }
.ag-tm-lbl { font-size: 11.5px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; color: var(--faint); padding: 0 11px 0 9px; }
.ag-tm-opt { display: inline-flex; align-items: center; border-radius: 999px; padding: 6px 15px; cursor: pointer; font-size: 12.5px; font-weight: 700; color: var(--muted); }
.ag-tm-opt input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.ag-tm-opt.is-on { background: var(--forest-green); color: #FCF4EA; }
.ag-tm-opt:has(input:focus-visible) { outline: 2px solid var(--cedar-2); outline-offset: 2px; }
/* Day, then the two ends of the working window: three fields where daily has
   two, so the day box keeps the wider basis and the clock boxes share a row of
   their own on a phone. */
.ag-hours-row > div { flex: 1 1 150px; }
.ag-hours-row > div:first-child { flex: 1 1 190px; }

/* Plan notes — the free-text box under the date range, every audience. Sits in
   the same column rhythm as .ag-dates-row above it, and resizes vertically only
   so a long note cannot drag the field out past the card's edge. */
/* The report-date control sits with the other plan-level fields; the stamp it
   produces is print-only, like the notes prose. */
.ag-report-date { margin-top: 14px; }
.ag-report-date-hint { margin: 5px 0 0; font-size: 11.5px; color: #6B655B; }
.ag-report-stamp { display: none; margin: 0 0 4px; font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--cedar-2); }
.ag-plan-notes { margin-top: 14px; }

/* Per-phase notes. Quieter than the plan-level box — it sits inside a phase
   card that already has a heading, milestones and an attachments row, so it
   reads as one more row rather than a second form. */
.ag-phase-notes { margin-top: 12px; }
.ag-phase-notes-label { font-size: 11.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--cedar-2); margin-bottom: 5px; }
.ag-phase-notes .ag-notes-input { min-height: 58px; font-size: 14px; padding: 10px 12px; }
.ag-phase-notes-print { margin-top: 12px; }
.ag-notes-input { resize: vertical; min-height: 76px; line-height: 1.5; }

/* The printed form of the same note. Emitted alongside the textarea and hidden
   on screen — @media print and report mode swap which of the pair is visible.
   Emitting only one of them is what made a note print as nothing: the Print
   button hides editable controls, so a note that existed ONLY as a textarea had
   no printable form, while Download PDF (report mode) rendered it correctly. */
.ag-plan-notes-print { display: none; }
.ag-plan-notes-print { margin-top: 16px; padding: 12px 14px; border: 1px solid var(--border-2); border-radius: 10px; background: #FBF8F2; }
.ag-pn-title { font-size: 11.5px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--cedar-2); margin-bottom: 5px; }
.ag-pn-body { font-size: 14px; line-height: 1.6; color: var(--dark-text); white-space: pre-wrap; }
.ag-dates-row > div { flex: 1 1 190px; min-width: 0; }
.ag-status-line { margin-top: 14px; font-size: 13px; color: var(--cedar-2); font-weight: 600; }
.ag-status-line strong { color: var(--forest-green); }

/* saved / guest chip on the plan head */
.ag-savechip { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 800; letter-spacing: 0.03em; text-transform: uppercase; border-radius: 999px; padding: 4px 11px; }
.ag-savechip-guest { color: #8a5a17; background: #FBF3E4; border: 1px solid var(--gold-soft); }
.ag-savechip-saved { color: #1E4636; background: #EAF1EA; border: 1px solid #CFE0D3; }
.ag-savechip-saving { color: var(--muted); background: #F0EADD; border: 1px solid var(--border-2); }
/* Refused by the account, not merely unsigned-in. Reads as a problem, because
   it is one: the plan exists on this device and nowhere else. */
.ag-savechip-blocked { color: #8C2F1E; background: #FBEAE6; border: 1px solid #E7C3BA; }
/* Sits above the page and stays until dismissed. It reports silent data loss —
   a plan that exists on this device and nowhere else — so it does not fade. */
.ag-sync-banner { position: fixed; z-index: 60; left: 50%; transform: translateX(-50%); bottom: 18px; max-width: min(680px, calc(100vw - 32px)); display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; border-radius: 12px; background: #FBEAE6; border: 1px solid #E7C3BA; box-shadow: 0 8px 28px rgba(20,12,8,0.16); }
.ag-sync-banner-msg { margin: 0; font-size: 13.5px; line-height: 1.5; color: #6E2416; }
.ag-sync-banner-x { flex: none; margin-left: auto; border: 0; background: none; font-size: 18px; line-height: 1; cursor: pointer; color: #8C2F1E; padding: 0 2px; }
.ag-sync-banner-x:focus-visible { outline: 2px solid #8C2F1E; outline-offset: 2px; }
@media print { .ag-sync-banner { display: none; } }

/* timeline card */
.ag-card { background: var(--card); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow-card); padding: clamp(18px,2.4vw,26px); }
.ag-card-title { font-family: 'Newsreader', serif; font-weight: 600; font-size: clamp(18px,2vw,22px); color: var(--forest-green); margin: 0 0 4px; }
.ag-card-sub { font-size: 13px; color: var(--muted); margin: 0 0 16px; }

/* phase cards + milestone rows (reuse .task-section/.task-item look) */
.ag-phase { background: var(--card); border: 1px solid var(--border); border-left: 5px solid var(--green-mid); border-radius: 16px; box-shadow: var(--shadow-card); padding: clamp(16px,2.2vw,24px); }
.ag-phase.is-done { border-left-color: var(--gold); }
.ag-phase-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.ag-phase-num { font-family: 'Newsreader', serif; font-size: 15px; font-weight: 700; color: var(--cedar-accent); flex-shrink: 0; }
.ag-phase-name { font-family: 'Newsreader', serif; font-weight: 600; font-size: clamp(17px,2vw,21px); color: var(--forest-green); margin: 0; line-height: 1.2; }
.ag-phase-count { margin-left: auto; font-size: 12px; font-weight: 800; color: var(--green-mid); background: var(--green-tint); border: 1px solid var(--green-tint-border); border-radius: 999px; padding: 4px 11px; white-space: nowrap; }
.ag-phase-focus { font-size: 13px; color: #6E685E; line-height: 1.45; margin: 6px 0 0; }
.ag-phase-span { font-size: 12px; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; color: var(--faint); margin: 8px 0 2px; }

/* ---- the same window, typeable (custom plans) --------------------------
   "if this guy is now gonna start later and it's gonna push everybody out, I
   could actually go right here and change a start date and everything else
   changes." An editing control, so it hides on paper exactly like the duration
   slider under it — .ag-phase-span above is what prints. The first phase's
   start and the last phase's end ARE the plan's own dates; they render locked
   rather than missing, so every phase row reads the same. */
.ag-phase-dates { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; margin: 8px 0 2px; }
.ag-pd-field { display: flex; flex-direction: column; gap: 3px; }
.ag-pd-lbl { font-size: 11px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--faint); }
.ag-phase-date { width: auto; min-width: 9.5em; padding: 8px 10px; font-size: 13.5px; font-variant-numeric: tabular-nums; }
/* Same grammar as every other unavailable control on the page
   (.ag-b-iconbtn:disabled): faded and inert, not recoloured — a tinted box
   reads as active, which is the opposite of what this one is. Still focusable,
   so its title reaches a screen reader. */
.ag-phase-date.is-locked { opacity: 0.55; cursor: default; }
.ag-pd-note { font-size: 11.5px; color: var(--faint); line-height: 1.4; flex: 1 1 12em; min-width: 12em; }
@media (max-width: 480px) { .ag-pd-field { flex: 1 1 45%; } .ag-phase-date { min-width: 0; width: 100%; } }

.ag-ms-list { margin-top: 10px; display: flex; flex-direction: column; }

/* ---- per-phase duration slider (plan view; features.sliders) -----------
   Sits under the phase's date window. Dragging it reweights the phase and the
   whole dated timeline + every due date recompute live. Cedar accent, a 44px
   touch target, one-handed on mobile. */
.ag-phase-adjust { display: flex; align-items: center; gap: 12px; margin: 10px 0 2px; }
.ag-phase-adjust-lbl { font-size: 11px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--faint); flex-shrink: 0; }
.ag-phase-adjust-val { font-size: 12.5px; font-weight: 800; color: var(--cedar-2); flex-shrink: 0; min-width: 54px; text-align: right; font-variant-numeric: tabular-nums; }
.ag-phase-slider { -webkit-appearance: none; appearance: none; flex: 1; min-width: 0; height: 44px; background: transparent; cursor: pointer; margin: 0; }
.ag-phase-slider::-webkit-slider-runnable-track { height: 6px; border-radius: 999px; background: #E7DFCF; }
.ag-phase-slider::-moz-range-track { height: 6px; border-radius: 999px; background: #E7DFCF; }
.ag-phase-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 26px; height: 26px; margin-top: -10px; border-radius: 999px; background: var(--cedar-accent); border: 3px solid var(--card); box-shadow: 0 2px 6px rgba(20,40,30,0.3); transition: transform 0.12s, box-shadow 0.12s; }
.ag-phase-slider::-moz-range-thumb { width: 26px; height: 26px; border-radius: 999px; background: var(--cedar-accent); border: 3px solid var(--card); box-shadow: 0 2px 6px rgba(20,40,30,0.3); transition: transform 0.12s, box-shadow 0.12s; }
.ag-phase-slider:active::-webkit-slider-thumb { transform: scale(1.08); }
.ag-phase-slider:focus-visible { outline: none; }
.ag-phase-slider:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px rgba(180,85,47,0.28); }
.ag-phase-slider:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px rgba(180,85,47,0.28); }
@media (prefers-reduced-motion: reduce) {
  .ag-phase-slider::-webkit-slider-thumb { transition: none; }
  .ag-phase-slider::-moz-range-thumb { transition: none; }
}

.ag-ms { border-top: 1px solid var(--border-soft); }
.ag-ms:first-child { border-top: none; }
.ag-ms-row { display: flex; align-items: flex-start; gap: 13px; padding: 14px 4px; }
.ag-ms-check { width: 23px; height: 23px; margin-top: 1px; cursor: pointer; accent-color: var(--green-2); flex-shrink: 0; }
.ag-ms-main { min-width: 0; flex: 1; cursor: pointer; }
.ag-ms-title { font-weight: 600; font-size: 15px; color: var(--dark-text); line-height: 1.35; display: block; }
.ag-ms.is-done .ag-ms-title { text-decoration: line-through; color: #A59E92; }
.ag-ms-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 5px; }
.ag-ms-toggle { margin-left: auto; align-self: flex-start; background: none; border: none; color: var(--muted-2); cursor: pointer; padding: 2px; display: flex; flex-shrink: 0; transition: transform 0.2s, color 0.15s; }
.ag-ms-toggle:hover { color: var(--forest-green); }
.ag-ms.is-open .ag-ms-toggle { transform: rotate(90deg); }
.ag-ms-detail { padding: 0 4px 16px 49px; }
.ag-ms-detail[hidden] { display: none; }
.ag-ms-detail-text { font-size: 13.5px; color: #5C564C; line-height: 1.55; margin: 0; }

/* Notes on one milestone. Revealed by the row's glyph, never rendered open on
   every row — a 41-step plan with a textarea per row is a wall of empty boxes.
   Both live OUTSIDE .ag-ms-meta by construction: liveWeightUpdate() rewrites
   that element's innerHTML on every slider drag, so anything inside it is
   destroyed (listener included) the first time a phase length is adjusted.
   Indented to the milestone title, so a note reads as belonging to its step. */
.ag-ms-note-btn { align-self: flex-start; background: none; border: none; color: var(--muted-2); cursor: pointer; padding: 2px; display: flex; flex-shrink: 0; transition: color 0.15s; }
.ag-ms-note-btn:hover { color: var(--forest-green); }
.ag-ms-note-btn.is-on { color: var(--cedar-accent); }
.ag-ms-note { padding: 0 4px 14px 49px; }
.ag-ms-note[hidden] { display: none; }
.ag-ms-note-label { display: block; font-size: 11.5px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--cedar-2); margin-bottom: 5px; }
.ag-ms-note .ag-notes-input { min-height: 54px; font-size: 14px; padding: 10px 12px; }
.ag-ms-note-print { margin: 0 4px 14px 49px; }

/* due chips — overdue is a gentle amber, never red */
.ag-due { font-size: 11.5px; font-weight: 700; border-radius: 999px; padding: 2px 9px; white-space: nowrap; }
.ag-due-plan { color: var(--muted); background: #F0EADD; }
.ag-due-soon { color: #8a5a17; background: #FBF3E4; border: 1px solid var(--gold-soft); }
.ag-due-overdue { color: #7c631f; background: #F6EEDA; border: 1px solid #E6D08C; }
.ag-due-done { color: var(--green-mid); background: var(--green-tint); }

/* ---- inline Sierra touch card -----------------------------------------
   Deliberately quieter than the milestone it sits under: a soft parchment
   panel with a small label and one text link, never a dark sales block. The
   standalone .ag-touch-cta pill (used on the dark save panel) is untouched;
   only the link INSIDE .ag-touch becomes a quiet text link. */
.ag-touch { margin-top: 14px; background: #F7F3EA; color: var(--ink-soft); border: 1px solid var(--border); border-radius: 12px; padding: 15px 17px; }
.ag-touch-eyebrow { display: inline-flex; align-items: center; gap: 8px; font-size: 10.5px; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted-2); }
.ag-touch-eyebrow::before { content: ""; width: 16px; height: 1px; background: var(--muted-2); display: inline-block; }
.ag-touch-label { font-family: 'Newsreader', serif; font-weight: 600; font-size: 17px; color: var(--forest-green); margin: 7px 0 5px; line-height: 1.3; }
.ag-touch-body { font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); margin: 0 0 10px; }
.ag-touch-cta { display: inline-flex; align-items: center; gap: 7px; background: var(--cedar-accent); color: var(--cream); border-radius: 999px; padding: 10px 18px; font-size: 13.5px; font-weight: 800; text-decoration: none; transition: background 0.15s, transform 0.15s; }
.ag-touch-cta:hover { background: #9c4526; transform: translateY(-1px); }
.ag-touch .ag-touch-cta { background: transparent; color: var(--green-mid); border-radius: 0; padding: 0; font-size: 14px; font-weight: 700; }
.ag-touch .ag-touch-cta:hover { background: transparent; color: var(--forest-green); transform: none; text-decoration: underline; text-underline-offset: 3px; }

/* ---- save panel + OTP -------------------------------------------------- */
.ag-save { background: radial-gradient(130% 130% at 85% 0%, #1E4636, #163C2E 60%, #102D22); color: #F3EDE0; border-radius: 16px; padding: clamp(20px,3vw,30px); }
.ag-save-eyebrow { font-size: 11.5px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: #EBCB8F; }
.ag-save-h { font-family: 'Newsreader', serif; font-weight: 600; font-size: clamp(20px,2.6vw,26px); color: #FBF7EE; margin: 8px 0 6px; }
.ag-save-p { font-size: 14px; line-height: 1.55; color: #CFD8CF; margin: 0 0 16px; max-width: 52ch; }
.ag-save-row { display: flex; gap: 10px; flex-wrap: wrap; max-width: 480px; }
.ag-save-row input { flex: 1 1 200px; min-width: 0; padding: 13px; border: 1.5px solid rgba(255,255,255,0.2); border-radius: 10px; font-size: 15px; font-family: inherit; background: rgba(255,255,255,0.06); color: #fff; }
.ag-save-row input::placeholder { color: #9FB3A6; }
.ag-save-row input:focus { outline: none; border-color: var(--gold-soft); }
.ag-save-btn { background: var(--cedar-accent); color: var(--cream); border: none; border-radius: 10px; padding: 13px 22px; font-weight: 800; font-size: 14px; cursor: pointer; font-family: inherit; min-height: 48px; transition: background 0.15s; }
.ag-save-btn:hover { background: #9c4526; }
.ag-save-btn:disabled { opacity: 0.6; cursor: default; }
.ag-consent { display: flex; gap: 10px; align-items: flex-start; font-size: 12px; color: #DCE5DC; margin: 12px 0 0; line-height: 1.5; max-width: 480px; }
.ag-consent input { width: 16px; height: 16px; margin-top: 2px; accent-color: var(--gold-soft); flex-shrink: 0; }
.ag-consent a { color: var(--gold-soft); font-weight: 600; }
.ag-save-msg { font-size: 13px; margin-top: 12px; min-height: 16px; color: #DCE5DC; }
.ag-save-msg.error { color: #F0B49A; }
.ag-save-msg.success { color: #B7E0BE; }
.ag-save-back { background: none; border: none; color: var(--gold-soft); font-size: 13px; font-weight: 700; cursor: pointer; padding: 0; text-decoration: underline; font-family: inherit; margin-top: 10px; }
.ag-save[data-state="in"] .ag-save-row,
.ag-save[data-state="in"] .ag-consent,
.ag-save[data-state="code"] .ag-save-row-email,
.ag-save[data-state="code"] .ag-consent,
.ag-save[data-state="out"] .ag-save-row-code { display: none; }

/* ---- header plan switcher ---------------------------------------------- */
.ag-switcher { position: relative; }
.ag-switcher-btn { display: inline-flex; align-items: center; gap: 8px; background: transparent; border: 1.5px solid rgba(20,52,42,0.22); color: var(--green-2); border-radius: 999px; padding: 8px 14px; font-size: 13px; font-weight: 700; cursor: pointer; font-family: inherit; max-width: 220px; }
.ag-switcher-btn:hover { background: rgba(20,52,42,0.06); }
.ag-switcher-btn .lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ag-switcher-menu { position: absolute; top: calc(100% + 6px); right: 0; min-width: 260px; background: var(--card); border: 1px solid var(--border); border-radius: 14px; box-shadow: 0 24px 48px -22px rgba(16,45,34,0.5); padding: 6px; z-index: 90; }
.ag-switcher-menu[hidden] { display: none; }
.ag-switcher-item { display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left; background: none; border: none; border-radius: 10px; padding: 10px 12px; cursor: pointer; font-family: inherit; text-decoration: none; }
.ag-switcher-item:hover { background: var(--green-tint); }
.ag-switcher-item.is-active { background: var(--green-tint); }
.ag-switcher-item .t { font-size: 13.5px; font-weight: 700; color: var(--forest-green); }
.ag-switcher-item .m { font-size: 11.5px; color: var(--muted); }
.ag-switcher-sep { height: 1px; background: var(--border-soft); margin: 6px 4px; }
.ag-switcher-new { color: var(--cedar-accent); font-weight: 800; }

/* ==========================================================================
   Custom builder (agents-plan.html, ?edit=1) — manual "build your own" editor
   ========================================================================== */
.ag-builder { display: flex; flex-direction: column; gap: 18px; }
.ag-builder-head { background: var(--card); border: 1px solid var(--border); border-left: 5px solid var(--cedar-accent); border-radius: 16px; box-shadow: var(--shadow-card); padding: clamp(18px,2.4vw,26px); }
.ag-b-name { display: block; width: 100%; font-family: 'Newsreader', serif; font-weight: 600; font-size: clamp(22px,3vw,30px); color: var(--forest-green); margin: 8px 0 0; padding: 4px 10px; border: 1.5px dashed var(--border-2); border-radius: 10px; background: transparent; }
.ag-b-name:focus { outline: none; border-style: solid; border-color: var(--green-2); background: #fff; }
.ag-b-name::placeholder { color: var(--faint); }
.ag-b-help { font-size: 13.5px; color: var(--ink-soft); line-height: 1.55; margin: 12px 0 0; max-width: 60ch; }
.ag-b-fields { display: flex; flex-wrap: wrap; gap: 14px; }
.ag-b-field { flex: 1 1 200px; min-width: 0; }

.ag-b-phases { display: flex; flex-direction: column; gap: 16px; }
.ag-b-phase { background: var(--card); border: 1px solid var(--border); border-left: 5px solid var(--green-mid); border-radius: 16px; box-shadow: var(--shadow-card); padding: clamp(16px,2.2vw,22px); }
.ag-b-phase-head { display: flex; align-items: center; gap: 10px; }
.ag-b-phase-num { font-family: 'Newsreader', serif; font-size: 15px; font-weight: 700; color: var(--cedar-accent); flex-shrink: 0; }
.ag-b-phase-title { flex: 1; min-width: 0; font-family: 'Newsreader', serif; font-weight: 600; font-size: clamp(16px,2vw,19px); color: var(--forest-green); padding: 8px 11px; border: 1.5px solid var(--border-2); border-radius: 10px; background: #fff; }
.ag-b-phase-title:focus { outline: none; border-color: var(--green-2); }
.ag-b-textarea { width: 100%; margin-top: 10px; padding: 10px 12px; border: 1.5px solid var(--border-2); border-radius: 10px; font-family: inherit; font-size: 13.5px; color: var(--dark-text); background: #fff; resize: vertical; line-height: 1.5; }
.ag-b-textarea:focus { outline: none; border-color: var(--green-2); }
.ag-b-textarea::placeholder { color: var(--faint); }

.ag-b-mslist { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.ag-b-msrow { border-top: 1px solid var(--border-soft); padding-top: 10px; }
.ag-b-msrow:first-child { border-top: none; padding-top: 0; }
.ag-b-msrow-top { display: flex; align-items: center; gap: 10px; }
.ag-b-msdot { width: 8px; height: 8px; border-radius: 50%; background: var(--green-tint-border); flex-shrink: 0; }
.ag-b-mstitle { flex: 1; min-width: 0; padding: 9px 11px; border: 1.5px solid var(--border-2); border-radius: 9px; font-family: inherit; font-size: 14.5px; font-weight: 600; color: var(--dark-text); background: #fff; }
.ag-b-mstitle:focus { outline: none; border-color: var(--green-2); }
.ag-b-mstitle::placeholder { color: var(--faint); font-weight: 400; }
.ag-b-msdetail { width: 100%; margin: 8px 0 2px 18px; padding: 9px 11px; border: 1.5px solid var(--border-2); border-radius: 9px; font-family: inherit; font-size: 13px; color: #5C564C; background: #FBF8F1; resize: vertical; line-height: 1.5; }
.ag-b-msdetail:focus { outline: none; border-color: var(--green-2); }

.ag-b-reorder { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
.ag-b-iconbtn { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; background: #F6F1E6; border: 1px solid var(--border-2); border-radius: 8px; color: var(--green-2); font-size: 14px; font-weight: 700; cursor: pointer; font-family: inherit; transition: background 0.12s, color 0.12s, border-color 0.12s; }
.ag-b-iconbtn:hover:not(:disabled) { background: var(--green-tint); border-color: var(--green-tint-border); }
.ag-b-iconbtn:disabled { opacity: 0.35; cursor: default; }
.ag-b-iconbtn.ag-b-del { color: #9c4526; }
.ag-b-iconbtn.ag-b-del:hover:not(:disabled) { background: #F6E7DF; border-color: #E4C4B4; }

.ag-b-addms { align-self: flex-start; margin-top: 12px; background: transparent; border: 1.5px dashed var(--border-2); border-radius: 9px; padding: 8px 14px; font-size: 13px; font-weight: 700; color: var(--green-mid); cursor: pointer; font-family: inherit; }
.ag-b-addms:hover:not(:disabled) { background: var(--green-tint); border-color: var(--green-tint-border); }
.ag-b-addms:disabled { opacity: 0.4; cursor: default; }
.ag-b-addphase { align-self: flex-start; background: var(--forest-green); color: var(--cream); border: none; border-radius: 999px; padding: 12px 22px; font-size: 14px; font-weight: 800; cursor: pointer; font-family: inherit; }
.ag-b-addphase:hover:not(:disabled) { background: #11402F; }
.ag-b-addphase:disabled { opacity: 0.5; cursor: default; }

.ag-b-weights { background: var(--card); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow-card); padding: 6px clamp(14px,2vw,20px); }
.ag-b-weights-toggle { width: 100%; text-align: left; background: none; border: none; padding: 14px 2px; font-size: 14px; font-weight: 800; color: var(--forest-green); cursor: pointer; font-family: inherit; }
.ag-b-weights-body { padding: 0 2px 14px; }
.ag-b-weights-help { font-size: 12.5px; color: var(--muted); line-height: 1.5; margin: 0 0 12px; }
.ag-b-weight-row { display: flex; align-items: center; gap: 12px; padding: 7px 0; border-top: 1px solid var(--border-soft); }
.ag-b-weight-name { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600; color: var(--dark-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ag-b-weight-ctrl { display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0; }
.ag-b-weight-input { width: 68px; padding: 8px 10px; border: 1.5px solid var(--border-2); border-radius: 9px; font-family: inherit; font-size: 14px; text-align: right; background: #fff; color: var(--dark-text); }
.ag-b-weight-input:focus { outline: none; border-color: var(--green-2); }
.ag-b-weight-pct { font-size: 13px; font-weight: 700; color: var(--muted); }
.ag-b-weights-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 12px; }
.ag-b-sum { font-size: 13px; font-weight: 800; color: var(--green-mid); }
.ag-b-sum.is-bad { color: #9c4526; }
.ag-b-reset { background: none; border: 1px solid var(--border-2); border-radius: 9px; padding: 8px 14px; font-size: 12.5px; font-weight: 700; color: var(--ink-soft); cursor: pointer; font-family: inherit; }
.ag-b-reset:hover { background: #EFE9DB; }

.ag-b-preview { margin: 0; }
.ag-b-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.ag-b-note { font-size: 13px; font-weight: 600; color: #9c4526; margin: 0; }

.ag-edit-structure-bar { margin-top: 14px; }

/* ==========================================================================
   Dashboard (plans.html)
   ========================================================================== */
.ag-dash-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px; }
.ag-dash-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 18px; margin-top: 24px; }
.ag-plan-card { background: var(--card); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow-card); padding: 20px; display: flex; flex-direction: column; gap: 12px; }
.ag-plan-card-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.ag-plan-card-name { font-family: 'Newsreader', serif; font-weight: 600; font-size: 19px; color: var(--forest-green); margin: 0; line-height: 1.25; }
.ag-plan-card-tname { font-size: 12.5px; color: var(--muted); margin: 0; }
.ag-plan-card-prog { display: flex; align-items: center; gap: 12px; }
.ag-plan-card-meta { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--muted); flex-wrap: wrap; }
.ag-plan-card-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: auto; padding-top: 6px; }
.ag-mini-btn { border-radius: 999px; padding: 8px 14px; font-size: 12.5px; font-weight: 700; cursor: pointer; font-family: inherit; text-decoration: none; display: inline-flex; align-items: center; gap: 5px; border: 1px solid transparent; }
.ag-mini-primary { background: #1E4636; color: #F3EDE0; }
.ag-mini-primary:hover { background: var(--forest-green); }
.ag-mini-ghost { background: transparent; border-color: var(--border-2); color: var(--ink-soft); }
.ag-mini-ghost:hover { background: #EFE9DB; }
.ag-mini-quarter { background: #FBF3E4; color: #8a5a17; border-color: var(--gold-soft); }
.ag-mini-quarter:hover { background: #F5E9CE; }
/* The one irreversible control on the page. Reads as a warning rather than as
   another neutral action, and only ever appears inside the trash. */
.ag-mini-danger { background: transparent; border-color: #E3C3BB; color: #A3341F; }
.ag-mini-danger:hover { background: #F7E9E5; }
.ag-mini-btn:disabled { opacity: 0.55; cursor: default; }
.ag-empty { text-align: center; padding: 60px 20px; color: var(--muted); }

/* ---- trash ------------------------------------------------------------
   Collapsed by default and below the plans: it is a safety net, not part of
   the working list. It renders only when it has something in it. */
.ag-trash { margin-top: 40px; border-top: 1px solid var(--border); padding-top: 18px; }
.ag-trash-toggle { display: inline-flex; align-items: center; gap: 8px; background: none; border: none; padding: 6px 0; font-family: inherit; font-size: 13.5px; font-weight: 700; color: var(--muted-2); cursor: pointer; }
.ag-trash-toggle:hover { color: var(--forest-green); }
.ag-trash-toggle svg { transition: transform 0.2s; }
.ag-trash.is-open .ag-trash-toggle svg { transform: rotate(180deg); }
.ag-trash-note { margin: 6px 0 0; font-size: 13px; line-height: 1.55; color: var(--muted); max-width: 60ch; }
.ag-trash-body .ag-dash-grid { margin-top: 16px; }
/* Muted so a deleted plan never reads as a live one at a glance. */
.ag-plan-card-trashed { background: #FBF8F2; box-shadow: none; }
.ag-plan-card-trashed .ag-plan-card-name { color: var(--muted-2); }
.ag-savechip-trashed { color: #8a5a17; background: #F6F1E6; border: 1px solid var(--border-2); }
.ag-empty .ag-btn-gold { margin-top: 18px; }

.ag-quarter-flag { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: 0.03em; color: #8a5a17; }

/* generic helpers */
.ag-spinner { text-align: center; padding: 50px 20px; color: var(--muted); font-size: 14px; }
[hidden] { display: none !important; }

/* ==========================================================================
   PHOTOS + DOCUMENTS (plan attachments)

   The SHARED component, in the shared tokens — one block per phase plus one
   for anything that belongs to the whole plan. planner/fire.css re-tints it
   for warm paper (softer edges, no hard rules) rather than restating it, the
   same way it treats .ag-phase and .ag-card. Nothing here is fire- or
   realtor-specific.

   It is deliberately quiet when empty: a title, two small buttons, one hairline
   above it. A phase with nothing attached must not look like a phase with
   something missing.
   ========================================================================== */
.ag-atts { margin-top: 14px; padding-top: 13px; border-top: 1px dashed var(--border-2); }
.ag-atts-general { background: var(--card); border: 1px solid var(--border); border-radius: 16px; box-shadow: var(--shadow-card); padding: 18px 20px; margin-top: 18px; }
.ag-atts-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.ag-atts-title { font-size: 12px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); margin: 0; margin-right: auto; }
.ag-atts-btns { display: flex; flex-wrap: wrap; gap: 8px; }
.ag-att-add { min-height: 36px; }
/* The real <input type="file">. Kept in the layout (not `display:none`) so a
   programmatic .click() is honoured everywhere, and reachable by nothing —
   the visible button in front of it carries the label. */
.ag-att-input { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.ag-atts-empty { font-size: 13px; color: var(--muted-2); margin: 9px 0 0; line-height: 1.55; max-width: 62ch; text-wrap: pretty; }
.ag-atts-error { font-size: 13.5px; font-weight: 600; color: #9c2a1a; background: #FBEDE8; border: 1px solid #F0C9BE; border-radius: 10px; padding: 10px 12px; margin: 10px 0 0; }

.ag-atts-list { list-style: none; margin: 11px 0 0; padding: 0; display: grid; gap: 8px; }
.ag-att { display: flex; flex-wrap: wrap; align-items: center; gap: 11px; background: var(--card-2); border: 1px solid var(--border); border-radius: 12px; padding: 10px 12px; }
.ag-att.is-included { border-color: var(--gold-soft); background: #FDF8EE; }
.ag-att-thumb { width: 46px; height: 46px; flex: none; object-fit: cover; border-radius: 8px; border: 1px solid var(--border-2); background: #EFE9DB; }
/* The thumbnail is a button so the picture itself opens it — the gesture
   everybody tries first. Stripped back to nothing so the image keeps its own
   size and border; line-height:0 stops the inline-image baseline gap. */
.ag-att-thumb-btn { flex: none; padding: 0; border: 0; background: none; line-height: 0; border-radius: 8px; cursor: zoom-in; }
.ag-att-thumb-btn:focus-visible { outline: 2px solid var(--green-2); outline-offset: 3px; }
.ag-att-ico { width: 46px; height: 46px; flex: none; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px; background: #EFE9DB; border: 1px solid var(--border-2); font-size: 10.5px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.ag-att-main { min-width: 0; flex: 1 1 180px; display: flex; flex-direction: column; gap: 3px; }
.ag-att-name { font-size: 14px; font-weight: 600; color: var(--dark-text); line-height: 1.35; overflow-wrap: anywhere; }
.ag-att-meta { font-size: 12px; color: var(--muted-2); }
.ag-att-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-left: auto; }
.ag-att-inc { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; color: var(--muted); cursor: pointer; }
.ag-att-inc input { width: 15px; height: 15px; accent-color: var(--green-mid); cursor: pointer; }
.ag-att-dl { min-height: 34px; }
.ag-att-remove { background: transparent; border: 1px solid transparent; border-radius: 999px; padding: 7px 11px; font-family: inherit; font-size: 12.5px; font-weight: 700; color: var(--muted-2); cursor: pointer; }
.ag-att-remove:hover { color: var(--cedar-accent); background: #F6EDE7; }
.ag-att-remove:focus-visible,
.ag-att-inc input:focus-visible,
.ag-att-add:focus-visible { outline: 2px solid var(--green-2); outline-offset: 2px; }

/* The two-step remove. It takes over the row rather than opening a dialog, so
   the thing being removed stays visible while the question is being answered. */
.ag-att-confirm { flex: 1 1 100%; display: flex; flex-direction: column; gap: 9px; border-top: 1px dashed var(--border-2); padding-top: 10px; }
.ag-att-confirm-p { font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); margin: 0; max-width: 62ch; text-wrap: pretty; }
.ag-att-confirm-btns { display: flex; flex-wrap: wrap; gap: 8px; }
.ag-att-yes { border-color: #E4BFB2; color: #9c4526; }
.ag-att-yes:hover { background: #F6EDE7; }

/* In-flight and held files. Same row shape as a stored one, so a file does not
   jump when it lands. */
.ag-atts-queue { margin-top: 8px; }
.ag-att-q { background: var(--card); border-style: dashed; }
.ag-att-q.is-failed { border-color: #F0C9BE; background: #FDF3F0; border-style: solid; }
.ag-att-q.is-failed .ag-att-meta { color: #9c2a1a; font-weight: 600; }
.ag-att-q.is-held { border-color: var(--gold-soft); background: #FDF8EE; }
.ag-att-bar { display: block; height: 5px; border-radius: 999px; background: #E4DCCA; overflow: hidden; margin-top: 5px; }
.ag-att-fill { display: block; height: 100%; border-radius: 999px; background: var(--green-mid); transition: width 0.2s ease; }

/* The guest prompt. Never a modal, never a blocker: the file is already held,
   and this only explains why an account is what keeps it. */
.ag-att-signin { margin-top: 10px; background: #FDF8EE; border: 1px solid var(--gold-soft); border-radius: 12px; padding: 13px 15px; display: flex; flex-direction: column; align-items: flex-start; gap: 9px; }
.ag-att-signin-p { font-size: 13.5px; line-height: 1.6; color: var(--ink-soft); margin: 0; max-width: 62ch; text-wrap: pretty; }
.ag-att-signin-files { font-size: 12.5px; font-weight: 700; color: var(--muted); margin: 0; overflow-wrap: anywhere; }

@media (max-width: 560px) {
  .ag-att-actions { margin-left: 0; flex: 1 1 100%; }
}

/* ==========================================================================
   Report / print mode (?report=1) — flat, ink-friendly, no chrome
   ========================================================================== */
body.ag-report .site-header,
body.ag-report .beta-bar,
body.ag-report .ag-save,
body.ag-report .ag-report-toolbar,
body.ag-report .ag-ms-toggle,
body.ag-report .ag-phase-adjust,
/* the typeable phase window; .ag-phase-span above it is the printed form */
body.ag-report .ag-phase-dates,
/* belt and braces: timeModeToggleHtml emits nothing in report mode either */
body.ag-report .ag-timemode,
/* Attachments are an editing control. The PDF carries the ones marked
   "include" as an appendix, resolved server-side — belt and braces, since the
   renderer emits no attachment blocks in report mode either. */
body.ag-report .ag-atts,
/* the editable notes box; the note itself prints via .ag-plan-notes-print */
/* The save chip is a live status indicator; on a frozen PDF or a shared
   read-only link it rendered as "On this device", which is about the reader's
   device and is meaningless — and wrong — on a printed artifact. */
body.ag-report .ag-report-date,
body.ag-report .ag-savechip,
body.ag-report .ag-plan-notes,
body.ag-report .ag-phase-notes,
/* the per-milestone editor + its reveal glyph; the note itself prints via
   .ag-ms-note-print, which carries .ag-plan-notes-print for the swap */
body.ag-report .ag-ms-note,
body.ag-report .ag-ms-note-btn,
body.ag-report .ag-plan-label-input:hover { display: none !important; }
body.ag-report .ag-ms-detail { display: block !important; }
body.ag-report .ag-touch { background: none; color: var(--dark-text); border: 1px solid var(--border-2); }
body.ag-report .ag-touch-eyebrow { color: var(--cedar-2); }
body.ag-report .ag-touch-eyebrow::before { background: var(--cedar-2); }
body.ag-report .ag-touch-label { color: var(--forest-green); }
body.ag-report .ag-touch-body { color: #5C564C; }
body.ag-report .ag-touch-cta { background: none; color: var(--cedar-accent); padding: 0; font-weight: 700; }

@media print {
  .site-header, .beta-bar, .ag-save, .ag-report-toolbar, .ag-ms-toggle, .ag-phase-adjust,
  .ag-atts, .ag-plan-notes, .ag-phase-notes, .ag-savechip, .ag-report-date,
  /* the typeable phase window; .ag-phase-span is the printed form */
  .ag-phase-dates,
  /* the hourly/daily switch is a control; the times it chooses print in the
     span line, the snapshot and every due chip */
  .ag-timemode,
  .ag-ms-note, .ag-ms-note-btn,
  /* the builder handoff is an editing control, not part of the plan */
  .ag-edit-structure-bar { display: none !important; }
  /* ...and the prose form takes their place on paper. */
  .ag-plan-notes-print, .ag-report-stamp { display: block !important; }
  .ag-ms-detail { display: block !important; }
  .ag-phase, .ag-card, .ag-planhead { break-inside: avoid; box-shadow: none; }
  .ag-touch { background: none !important; color: var(--dark-text) !important; border: 1px solid var(--border-2); }
  .ag-touch-label { color: var(--forest-green) !important; }
  .ag-touch-body { color: #5C564C !important; }
}

/* report toolbar (matches plan.html's report-toolbar spirit) */
.ag-report-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; background: var(--forest-green); color: #F3EDE0; padding: 10px clamp(16px,4vw,32px); font-size: 13px; }
.ag-report-toolbar .t { font-weight: 700; margin-right: auto; }
.ag-rt-btn { display: inline-flex; align-items: center; gap: 7px; background: rgba(255,255,255,0.1); border: 1px solid rgba(255,255,255,0.2); color: #F3EDE0; border-radius: 999px; padding: 8px 15px; font-size: 12.5px; font-weight: 700; cursor: pointer; font-family: inherit; }
.ag-rt-btn:hover { background: rgba(255,255,255,0.2); }
.ag-report-toolbar[hidden] { display: none; }
/* In-flow variant: the toolbar sits at the top of the plan now (first child of
   .agents-main) rather than as a full-bleed band above the site header, so it
   needs a card's corners and a gap beneath it. */
.agents-main > .ag-report-toolbar { border-radius: 14px; margin-bottom: clamp(16px,3vw,24px); }
/* Phone: the title takes its own line and the buttons share the width as
   full-height targets. 8px 15px on a 12.5px font is a ~33px control, under the
   44px floor this codebase holds elsewhere (.shm-link is 46px). */
@media (max-width: 560px) {
  .agents-main > .ag-report-toolbar { padding: 12px; gap: 8px; }
  .agents-main > .ag-report-toolbar .t { width: 100%; margin-right: 0; }
  .agents-main > .ag-report-toolbar .ag-rt-btn { flex: 1 1 auto; justify-content: center; min-height: 44px; }
}

/* ============================================================================
   AI plan generation (Phase 2). The "Generate with AI" CTA on the custom card,
   the prompt modal, and the quota card — in the refreshed realtor tokens. Only
   rendered when window.SLT_AI_ENABLED is on.
   ========================================================================== */
.ag-btn-gold:disabled { opacity: 0.55; cursor: not-allowed; box-shadow: none; }
.ag-btn-gold:disabled:hover { background: var(--cedar-accent); transform: none; }
.ag-btn-gold.is-loading { opacity: 0.8; cursor: progress; }

/* the second CTA on the "Build your own" card */
.ag-btn-ai { display: inline-flex; align-items: center; gap: 8px; background: var(--card); color: var(--forest-green); border: 1.5px solid var(--gold-soft); border-radius: 999px; padding: 10px 18px; font-family: inherit; font-size: 14px; font-weight: 800; cursor: pointer; transition: background 0.15s, border-color 0.15s, transform 0.15s; }
.ag-btn-ai:hover { background: #FBF3E4; border-color: var(--gold); transform: translateY(-1px); }
.ag-ai-spark { color: var(--gold); font-size: 15px; line-height: 1; }
.ag-ai-free { font-size: 11px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; color: #8a5a17; background: #FBF3E4; border: 1px solid var(--gold-soft); border-radius: 999px; padding: 2px 8px; }

/* prompt modal */
.ag-ai-modal-card { max-width: 580px; }
.ag-ai-eyebrow { display: inline-flex; align-items: center; gap: 6px; color: #8a5a17; }
.ag-ai-textarea { resize: vertical; min-height: 96px; line-height: 1.5; }
.ag-ai-counter { margin-top: 6px; text-align: right; font-size: 12px; font-weight: 700; color: var(--muted-2); }
.ag-ai-fineprint { margin: 16px 0 0; font-size: 12px; line-height: 1.55; color: var(--muted); background: var(--card-2); border: 1px solid var(--border); border-radius: 12px; padding: 12px 14px; }
.ag-ai-error { margin: 14px 0 0; font-size: 13.5px; font-weight: 600; color: #9c2a1a; background: #FBEDE8; border: 1px solid #F0C9BE; border-radius: 10px; padding: 11px 14px; }
.ag-ai-error[hidden] { display: none; }

/* quota card (shown on a 402) */
.ag-ai-quota-actions { display: flex; flex-direction: column; gap: 12px; margin-top: 20px; }
.ag-ai-quota-contact { display: inline-flex; align-items: center; gap: 6px; color: var(--cedar-accent); font-size: 14px; font-weight: 800; text-decoration: none; }
.ag-ai-quota-contact:hover { text-decoration: underline; }
.ag-ai-pro-note { margin: 16px 0 0; font-size: 12.5px; color: var(--muted-2); font-style: italic; }


/* Report mode (the rendered PDF and shared read-only links) shows the prose
   form too — same swap as @media print, driven by the body class instead. */
body.ag-report .ag-plan-notes-print { display: block; }


/* ==========================================================================
   Printed appendix — the files ticked "Include in my PDF".
   Only ever rendered in report mode, so it needs no screen-side hiding; the
   rules below are about paper. Each phase group avoids breaking across a page
   where it can, and an image is capped so one tall photograph cannot push a
   whole page of white space ahead of it.
   ========================================================================== */
.ag-appendix { margin-top: 28px; padding-top: 20px; border-top: 2px solid var(--forest-green); break-before: page; }
.ag-appendix-title { font-size: 19px; font-weight: 800; color: var(--forest-green); margin: 0 0 14px; }
.ag-appendix-phase { margin-bottom: 20px; break-inside: avoid; }
.ag-appendix-phase-head { font-size: 12px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--cedar-2); margin: 0 0 8px; }
.ag-appendix-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; }
.ag-appendix-fig { margin: 0; break-inside: avoid; }
.ag-appendix-fig img { width: 100%; height: auto; max-height: 320px; object-fit: contain; border: 1px solid var(--border-2); border-radius: 8px; background: #fff; }
.ag-appendix-cap { margin-top: 5px; font-size: 11.5px; line-height: 1.4; color: #5C564C; word-break: break-word; }
.ag-appendix-docs { margin-top: 10px; display: flex; flex-direction: column; gap: 5px; }
.ag-appendix-doc { font-size: 13px; color: var(--dark-text); word-break: break-word; }

body.ag-report .ag-report-stamp { display: block; }


/* ==========================================================================
   Plan summary — the overview above the Gantt.
   Four facts you want when reading a plan with somebody: how far along, which
   phase, what is next, and when it runs. Wraps rather than scrolls, so it
   degrades to a stack on a phone, and prints with the rest of the plan.
   ========================================================================== */
.ag-summary { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 16px; }
.ag-sum-cell { flex: 1 1 150px; min-width: 0; padding: 11px 13px; border: 1px solid var(--border-2); border-radius: 11px; background: #FBF8F2; }
.ag-sum-k { display: block; font-size: 10.5px; font-weight: 800; letter-spacing: 0.07em; text-transform: uppercase; color: var(--cedar-2); }
.ag-sum-v { display: block; margin-top: 3px; font-size: 21px; font-weight: 800; line-height: 1.15; color: var(--forest-green); }
/* Titles and date ranges are words, not figures — they need to wrap, not shrink. */
.ag-sum-v-sm { font-size: 14px; line-height: 1.35; overflow-wrap: anywhere; }
.ag-sum-sub { display: block; margin-top: 3px; font-size: 11.5px; line-height: 1.4; color: #6B655B; overflow-wrap: anywhere; }

@media print {
  .ag-summary { break-inside: avoid; }
  .ag-sum-cell { background: none; }
}


/* ==========================================================================
   Project Snapshot — the whole scope, one row per phase.

   Ported from the log-home report (#printSnapshot / .snapshot-table). It is
   the block people actually read a plan from: share, duration, window and task
   count for every phase at once. The stat cells above answer "where am I
   today"; this answers "what is the shape of the whole thing".

   Deliberately styled for BOTH output paths. Download loads the page with
   ?report=1 (body.ag-report); Print prints the live page through @media print.
   Those two have silently disagreed here before, so each gets explicit rules —
   colour on screen and in the PDF, ink-frugal black and white on paper.
   ========================================================================== */
.ag-snapshot { break-inside: avoid; page-break-inside: avoid; }
.ag-snap-title { font-family: "Newsreader", Georgia, serif; font-weight: 600; font-size: 17px; color: var(--forest-green); margin: 0 0 8px; padding-bottom: 6px; border-bottom: 1px solid var(--gold-soft); }
/* Phase names are the one unbounded column; everything else is a short figure. */
.ag-snap-table { width: 100%; border-collapse: collapse; font-size: 11.5px; }
.ag-snap-table th { background: var(--forest-green); color: #fff; font-weight: 700; text-align: left; padding: 6px 9px; }
.ag-snap-table td { padding: 6px 9px; border-bottom: 1px solid var(--border); }
.ag-snap-table tr:nth-child(even) td { background: var(--card-2); }
/* Figures line up column-wise; names do not. */
.ag-snap-table td:nth-child(2), .ag-snap-table td:nth-child(3), .ag-snap-table td:nth-child(5) { font-variant-numeric: tabular-nums; white-space: nowrap; }
.ag-snap-table td:nth-child(4) { white-space: nowrap; }

/* A five-column table cannot shrink to a phone. Let it scroll inside its own
   box rather than pushing the page sideways — and only on screen, since paper
   and PDF have the width for it. */
@media screen and (max-width: 640px) {
  .ag-snapshot { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .ag-snap-table { min-width: 520px; }
}

@media print {
  .ag-snapshot { overflow: visible; }
  .ag-snap-title { font-size: 15px; border-bottom: 1px solid #999; }
  .ag-snap-table { font-size: 10.5px; }
  /* No fills: a grayscale printer turns a solid header into a smear. */
  .ag-snap-table th { background: none; color: #111; text-transform: uppercase; font-size: 9.5px; font-weight: 800; border-bottom: 2px solid #111; }
  .ag-snap-table td { border-bottom: 1px solid #CCC; }
  .ag-snap-table tr:nth-child(even) td { background: none; }
}


/* ==========================================================================
   Touch targets, phones only.
   The 44px floor applies to anything a finger has to hit. These controls were
   sized for a mouse — the attachment actions (Download / Retry / Discard) at
   about 34px, the add buttons at 36, and the milestone detail chevron at
   roughly 20. Missing "Discard" and hitting "Download" on a claim document is
   a real cost, and it lands on whoever is doing this on a phone.

   Scoped to a pointer that is actually coarse, so desktop density is untouched
   — a 44px pill row on a 1440px screen looks clumsy and buys nothing.
   ========================================================================== */
@media (hover: none) and (pointer: coarse) {
  .ag-mini-btn { min-height: 44px; padding-top: 10px; padding-bottom: 10px; }
  .ag-att-add { min-height: 44px; }
  /* The chevron is a small glyph; grow the hit area with padding rather than
     the mark, so the row's rhythm does not change. */
  .ag-ms-toggle, .ag-ms-note-btn { min-width: 44px; min-height: 44px; padding: 12px; }
  /* The builder's reorder / delete icons sit in a tight column; 40px is the
     most that fits without the rows colliding, and it is a long way better
     than 30. */
  .ag-builder-icon, .ag-phase-move, .ag-phase-del { min-width: 40px; min-height: 40px; }
}


/* ==========================================================================
   Ask AI — the sticky assistant.

   Bottom-right launcher that opens a chat panel able to rewrite the plan. It
   opens with the brief the plan was generated from, because the prompt is the
   first thing you would say to an assistant asked to change this plan.

   Fixed to the viewport and mounted on <body>, not inside the plan: every edit
   re-renders the plan, and a panel living in there would be destroyed
   mid-conversation along with the transcript.

   The bottom-right corner is free on this page — planner.css's fixed
   .save-chip / .signin-nudge / .feedback-fab belong to elements planner.js
   creates, and planner.js does not run here. The audience save chip
   (.ag-savechip) is an inline pill, not fixed.
   ========================================================================== */
/* pointer-events: none on the container, auto on the two things you can
   actually hit. On a phone this becomes a full-width strip, and without this it
   would swallow every tap on the bottom of the plan even while closed. */
.ag-chat { position: fixed; right: 18px; bottom: calc(18px + env(safe-area-inset-bottom)); z-index: 150; display: flex; flex-direction: column; align-items: flex-end; gap: 10px; pointer-events: none; }
.ag-chat-fab, .ag-chat-panel { pointer-events: auto; }

.ag-chat-fab { display: inline-flex; align-items: center; gap: 8px; background: var(--forest-green); color: #fff; border: none; border-radius: 999px; padding: 14px 20px; font-family: inherit; font-size: 14.5px; font-weight: 800; cursor: pointer; box-shadow: 0 14px 30px -12px rgba(16,45,34,0.7); }
.ag-chat-fab:hover { background: var(--green-2); }
.ag-chat-fab:focus-visible { outline: 2px solid var(--cedar-accent); outline-offset: 3px; }
.ag-chat[data-open="true"] .ag-chat-fab { display: none; }

.ag-chat-panel { width: min(400px, calc(100vw - 36px)); max-height: min(620px, calc(100vh - 96px)); display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--border-2); border-radius: 18px; box-shadow: 0 26px 60px -24px rgba(16,45,34,0.65); overflow: hidden; }
.ag-chat-head { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--border-2); }
.ag-chat-title { flex: 1 1 auto; font-size: 14.5px; font-weight: 800; color: var(--forest-green); }
.ag-chat-close { background: none; border: none; font-size: 22px; line-height: 1; color: var(--muted-2); cursor: pointer; padding: 4px 6px; }

/* The brief, shown outright. It is the "why" of the plan and the thing you
   copy to run a better version — behind a disclosure it showed only its own
   heading, which is worse than not being there.

   It scrolls within its own bound so a long prompt cannot push the composer
   off the bottom of the panel. */
.ag-chat-brief { border-bottom: 1px solid var(--border-2); padding: 12px 16px 14px; flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; }
.ag-chat-brief-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.ag-chat-brief-t { font-size: 12px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; color: var(--cedar-2); }
.ag-chat-brief-body { overflow-y: auto; max-height: 190px; min-height: 0; }
.ag-chat-brief .ag-src-obj { margin: 0 0 8px; font-size: 13.5px; }
.ag-chat-brief .ag-src-prompt { margin: 0; font-size: 13.5px; }
.ag-chat-brief .ag-src-qas { margin-top: 11px; padding-top: 10px; }
/* The Copy button must not be squeezed into the heading it sits beside. */
.ag-chat-brief .ag-src-copy { flex: none; padding: 6px 12px; font-size: 12px; }

/* The transcript scrolls; the composer never leaves the bottom. */
.ag-chat-log { flex: 1 1 auto; min-height: 90px; overflow-y: auto; display: flex; flex-direction: column; gap: 9px; padding: 14px 16px; }
.ag-chat-compose { display: flex; gap: 8px; align-items: flex-end; padding: 12px 16px; border-top: 1px solid var(--border-2); }
.ag-chat-input { flex: 1 1 auto; resize: none; min-height: 42px; max-height: 120px; }
.ag-chat-send { flex: none; padding: 11px 18px; }

/* A fixed panel on a phone must not sit on top of the plan behind it — it
   becomes a bottom sheet instead, full width with the corner radius at the top
   only, so it reads as a sheet rather than a floating card that missed. */
@media (max-width: 560px) {
  .ag-chat { right: 0; left: 0; bottom: 0; align-items: stretch; gap: 0; }
  .ag-chat-fab { align-self: flex-end; margin: 0 14px calc(14px + env(safe-area-inset-bottom)); }
  .ag-chat-panel { width: 100%; max-height: 82vh; border-radius: 18px 18px 0 0; border-bottom: none; }
  .ag-chat-compose { padding-bottom: calc(12px + env(safe-area-inset-bottom)); }
}

/* Reuses the transcript bubbles from the inline panel it replaces. */
.ag-aiedit-msg { max-width: 88%; padding: 10px 13px; border-radius: 14px; font-size: 13.5px; line-height: 1.5; overflow-wrap: anywhere; }
.ag-aiedit-you { align-self: flex-end; background: var(--forest-green); color: #fff; border-bottom-right-radius: 5px; }
.ag-aiedit-ai { align-self: flex-start; background: var(--card-2); border: 1px solid var(--border-2); color: var(--ink-soft); border-bottom-left-radius: 5px; }
.ag-aiedit-empty { font-size: 13px; line-height: 1.6; color: var(--muted-2); margin: 0; }
.ag-aiedit-badge { font-size: 10.5px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: #8a5a17; background: #FBF3E4; border: 1px solid var(--gold-soft); border-radius: 999px; padding: 3px 9px; }
.ag-aiedit-error { margin: 0 16px 10px; font-size: 13px; font-weight: 700; color: #A3341F; }

/* A control, not part of the plan: it belongs on neither the paper nor the PDF. */
@media print { .ag-chat { display: none !important; } }
body.ag-report .ag-chat { display: none !important; }


/* ==========================================================================
   "New plan" chooser.

   Every New-plan control used to point at /agents, whose picker only walks the
   realtor templates — so whatever you were working in, New plan started a
   realtor plan. Four doors, each linking to that audience's own front page so
   the fire gate, the custom sign-in gate and each landing's setup flow stay in
   the path rather than being routed around.
   ========================================================================== */
.ag-newplan-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 10px; margin: 16px 0 4px; }
.ag-newplan-door { display: flex; flex-direction: column; gap: 4px; padding: 16px 18px; border: 1.5px solid var(--border-2); border-radius: 14px; background: var(--card-2); text-decoration: none; transition: border-color 0.12s, background 0.12s, transform 0.12s; }
.ag-newplan-door:hover { border-color: var(--green-2); background: #fff; transform: translateY(-1px); }
.ag-newplan-door:focus-visible { outline: 2px solid var(--cedar-accent); outline-offset: 2px; }
.ag-newplan-title { font-size: 15.5px; font-weight: 800; color: var(--forest-green); }
.ag-newplan-sub { font-size: 12.5px; line-height: 1.45; color: var(--muted-2); }

@media (prefers-reduced-motion: reduce) {
  .ag-newplan-door:hover { transform: none; }
}


/* ==========================================================================
   Budget on a phase.

   Per-phase dollars are derived from the plan total and each phase's cost
   share, never stored — so they always add up to the total, and editing the
   total re-budgets everything at once. Absent entirely on a plan with no
   budget, which is every plan that existed before this.
   ========================================================================== */
.ag-phase-money { font-size: 12.5px; font-weight: 800; color: var(--forest-green); background: #FBF3E4; border: 1px solid var(--gold-soft); border-radius: 999px; padding: 3px 10px; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* The snapshot's Budget column and its total row. The total is the proof the
   split is honest: the phases above it add up to the figure the user gave. */
.ag-snap-table td:nth-child(5), .ag-snap-table th:nth-child(5) { font-variant-numeric: tabular-nums; }
.ag-snap-table tfoot td { padding: 7px 9px; font-weight: 800; color: var(--forest-green); border-top: 2px solid var(--forest-green); background: none; }
.ag-snap-table tfoot td:nth-child(2) { font-variant-numeric: tabular-nums; }

@media print {
  .ag-phase-money { background: none; border-color: #999; }
  .ag-snap-table tfoot td { border-top: 2px solid #111; color: #111; }
}


/* ==========================================================================
   The brief a plan was generated from.

   Collapsed on screen because it is reference rather than the plan itself;
   always open in the report, since a collapsed <details> prints as a heading
   and nothing else.
   ========================================================================== */
/* Always rendered so the Print button (which prints the LIVE page) has it, but
   on screen the brief lives in the Ask AI widget — this copy is for output
   only. */
.ag-source { margin-top: 20px; display: none; }
@media print { .ag-source { display: block; } }
body.ag-report .ag-source { display: block; }
.ag-source details > summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.ag-source details > summary::-webkit-details-marker { display: none; }
.ag-src-title { font-family: "Newsreader", Georgia, serif; font-weight: 600; font-size: 17px; color: var(--forest-green); }
.ag-source.is-report .ag-src-title { display: block; margin-bottom: 8px; padding-bottom: 6px; border-bottom: 1px solid var(--gold-soft); }
.ag-src-copy { background: none; border: 1.5px solid var(--border-2); border-radius: 999px; padding: 7px 14px; font-family: inherit; font-size: 12.5px; font-weight: 800; color: var(--forest-green); cursor: pointer; }
.ag-src-copy:hover { border-color: var(--green-2); background: var(--card-2); }
/* The objective sits above the prompt and reads as the headline of the brief:
   it is what the plan is FOR, and the prompt is detail in service of it. Given
   its own label because on its own line it would just look like a short first
   paragraph of the prompt, which is exactly the conflation the separate field
   exists to break. */
.ag-src-obj { margin: 12px 0 0; font-size: 15px; line-height: 1.55; font-weight: 700; color: var(--forest-green); overflow-wrap: anywhere; }
.ag-src-obj-l { display: block; font-size: 12px; font-weight: 800; letter-spacing: 0.03em; text-transform: uppercase; color: var(--cedar-2); margin-bottom: 3px; }
/* With an objective above it the prompt is the supporting half, not the lead. */
.ag-src-obj + .ag-src-prompt { margin-top: 10px; }
/* The prompt is the user's own words — preserve the line breaks they typed. */
.ag-src-prompt { margin: 12px 0 0; font-size: 14.5px; line-height: 1.65; color: var(--ink-soft); white-space: pre-wrap; overflow-wrap: anywhere; }
.ag-src-qas { display: flex; flex-direction: column; gap: 9px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border-2); }
.ag-src-qa { display: flex; flex-direction: column; gap: 2px; }
.ag-src-q { font-size: 12px; font-weight: 800; letter-spacing: 0.03em; text-transform: uppercase; color: var(--cedar-2); }
.ag-src-a { font-size: 14px; line-height: 1.5; color: var(--ink-soft); overflow-wrap: anywhere; }

@media print {
  /* Reference, and it belongs with the plan — but never split across a page. */
  .ag-source { break-inside: avoid; }
  .ag-src-copy { display: none !important; }
  .ag-src-title { border-bottom: 1px solid #999; }
}


/* ==========================================================================
   Pagination: one phase per page.

   Mirrors the log-home report, where `.task-section` starts a fresh page
   (print.css:297). A phase is the unit people actually work from — reading one
   that straddles a fold, or two crammed onto a sheet, is the difference
   between a binder someone uses and one they re-flow by hand.

   Written for BOTH output paths. Download renders ?report=1 (body.ag-report)
   and Print goes through @media print; those two have disagreed in this file
   before, so neither is left to inherit from the other. Both properties are
   set — Chromium honours the modern `break-before`, older engines the legacy
   `page-break-before`.

   EVERY phase breaks, the first included — "each phase should start a page".
   The first was briefly exempt to avoid a half-empty cover, but the Gantt card
   already takes its own sheet immediately before it, so the exemption only had
   the effect of crowding phase one onto the chart's page. Log home breaks
   before every phase too (print.css:298).
   ========================================================================== */
@media print {
  .ag-phase {
    page-break-before: always;
    break-before: page;
  }
  /* The timeline card is a page of its own, as it is on the log-home report —
     a Gantt split across a fold is unreadable. */
  .ag-card:has(#agGantt) {
    page-break-before: always;
    break-before: page;
    page-break-inside: avoid;
    break-inside: avoid;
  }
  /* ...and these must never be broken, whatever else moves around them. */
  .ag-snapshot, .ag-source, .ag-summary { break-inside: avoid; page-break-inside: avoid; }
}

body.ag-report .ag-phase {
  page-break-before: always;
  break-before: page;
}
body.ag-report .ag-card:has(#agGantt) {
  page-break-before: always;
  break-before: page;
  page-break-inside: avoid;
  break-inside: avoid;
}
body.ag-report .ag-snapshot,
body.ag-report .ag-source,
body.ag-report .ag-summary { break-inside: avoid; page-break-inside: avoid; }


/* ==========================================================================
   Reminders & calendar — the one profile.

   Preferences were per-plan before this, which is not how anyone holds them:
   someone running a build, a listing and a fire claim had to opt in three
   times, and two of those did nothing. One panel, reachable from any plan,
   writing one row.
   ========================================================================== */
.ag-set-group { padding: 16px 0; border-top: 1px solid var(--border-2); }
.ag-set-group:first-child { border-top: none; padding-top: 6px; }
.ag-set-h { font-size: 12px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--cedar-2); }
.ag-set-p { margin: 7px 0 12px; font-size: 14px; line-height: 1.6; color: var(--ink-soft); }
.ag-set-note { margin: 8px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--muted-2); }
.ag-set-loading { font-size: 14px; color: var(--muted-2); margin: 12px 0; }

/* The whole row is the target, not just the 13px box. */
.ag-set-check { display: flex; align-items: flex-start; gap: 10px; font-size: 14.5px; line-height: 1.5; color: var(--ink-soft); cursor: pointer; padding: 6px 0; }
.ag-set-check input { flex: none; width: 18px; height: 18px; margin-top: 1px; accent-color: var(--forest-green); cursor: pointer; }

.ag-set-btn { background: none; border: 1.5px solid var(--border-2); border-radius: 999px; padding: 11px 18px; font-family: inherit; font-size: 14px; font-weight: 800; color: var(--forest-green); cursor: pointer; }
.ag-set-btn:hover { border-color: var(--green-2); background: var(--card-2); }
.ag-set-saved { margin: 8px 0 0; font-size: 12.5px; font-weight: 800; color: var(--green-2); }

@media (pointer: coarse) {
  .ag-set-check { min-height: 44px; align-items: center; }
  .ag-set-btn { min-height: 44px; }
}

/* Calendar rows inside the Reminders panel. Three tiers, and they are genuinely
   different promises — Google keeps itself current, a subscription refreshes on
   Google's own schedule, a download goes stale silently — so they do not look
   alike. */
.ag-set-row { margin: 12px 0; }
.ag-set-btn-primary { display: inline-flex; padding: 12px 20px; font-size: 14px; }
.ag-set-connected { margin: 0 0 10px; font-size: 14px; font-weight: 700; color: var(--green-2); }

/* The dashboard head puts Reminders beside New plan; on a phone they stack. */
.ag-dash-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
@media (max-width: 560px) {
  .ag-dash-actions { width: 100%; }
  .ag-dash-actions > * { flex: 1 1 auto; text-align: center; justify-content: center; }
}

/* ======================================================================
   Working on a plan with somebody else.

   Two surfaces: the dashboard's "Shared with you" section (plans you were
   invited onto) and the owner's invite modal. They are visually distinct from
   the plans you own on purpose — a shared plan has no Delete, and a card that
   looked identical would make one button mean two different things.
   ====================================================================== */
.ag-h3 { font-family: 'Newsreader', serif; font-weight: 600; font-size: 21px; color: var(--forest-green); margin: 6px 0 0; line-height: 1.3; }

.ag-shared { margin-top: 34px; }
.ag-shared-head { margin-bottom: 14px; }
.ag-shared-head .ag-lead { margin: 4px 0 0; }
/* A quieter card than one of your own: it is somebody else's plan. */
.ag-plan-card-shared { background: var(--card-2, #FBF7EF); border-style: dashed; }
.ag-role-chip {
  flex: none; font-size: 11px; font-weight: 800; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--cedar-2);
  background: rgba(0,0,0,0.04); border-radius: 999px; padding: 5px 10px; white-space: nowrap;
}

/* The invitation, on the dashboard. Sits above everything because acting on it
   is the only reason this person opened the page. */
.ag-invite-card {
  background: var(--card); border: 1.5px solid var(--gold-soft); border-radius: 16px;
  padding: 20px 22px; margin-bottom: 24px; box-shadow: var(--shadow-card);
}
.ag-invite-plan { font-family: 'Newsreader', serif; font-size: 18px; font-weight: 600; color: var(--forest-green); margin: 10px 0 0; }
.ag-invite-note { font-size: 13px; line-height: 1.55; color: var(--cedar-2); margin: 10px 0 0; }

/* The owner's list of who is on the plan. */
.ag-inv-people { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border-2); }
.ag-inv-list { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ag-inv-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.ag-inv-email { display: block; font-size: 14px; color: var(--ink-soft); overflow-wrap: anywhere; }
.ag-inv-state { display: block; font-size: 12px; color: var(--muted); margin-top: 1px; }

@media print {
  /* None of this belongs on paper. */
  .ag-shared, .ag-invite-card, .ag-inv-people { display: none !important; }
}

/* The no-account "work this plan" link, and the banner the doer lands on. */
.ag-worklink { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--border-2); }
.ag-worklink .ag-lead { margin: 6px 0 12px; font-size: 13px; }
.ag-wl-row { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
.ag-wl-url { flex: 1 1 auto; min-width: 0; font-size: 12.5px; }

/* Says whose plan this is and that it is theirs to work. Deliberately warm and
   deliberately not a warning: "someone set this up as a starting point" is the
   framing that turns a wall of somebody else's work into your own plan. */
.ag-work-banner {
  background: var(--card-2, #FBF7EF); border: 1px solid var(--gold-soft);
  border-radius: 14px; padding: 16px 18px; margin-bottom: 20px;
}
.ag-work-banner .ag-lead { margin: 6px 0 0; font-size: 14px; }

@media print {
  .ag-worklink, .ag-work-banner { display: none !important; }
}

/* ======================================================================
   The step chart.

   A Gantt is "90% construction related", and for a birthday party or a job
   hunt it reads as complexity rather than information. This is the same plan
   as a climb: one step per phase, in order, with where you are marked.

   Deliberately SEQUENCE, not duration — proportional time is what the Gantt
   does well and what overwhelms somebody who is not running a schedule. The
   step heights rise with position, not with weight, so nothing here invites a
   "share of the work" reading.
   ====================================================================== */
.ag-steps {
  list-style: none; margin: 4px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(var(--steps), minmax(0, 1fr));
  align-items: end; gap: 10px; min-height: 210px;
}
.ag-step { display: flex; flex-direction: column; justify-content: flex-end; gap: 8px; min-width: 0; }
.ag-step-block {
  height: var(--h); min-height: 34px; border-radius: 10px 10px 0 0;
  background: var(--card-2, #F1EBDF); border: 1px solid var(--border);
  display: flex; align-items: flex-start; justify-content: center; padding-top: 8px;
}
.ag-step-n { font-size: 12px; font-weight: 800; letter-spacing: 0.04em; color: var(--muted); }
.ag-step.is-done .ag-step-block { background: var(--forest-green); border-color: var(--forest-green); }
.ag-step.is-done .ag-step-n { color: #FCF4EA; }
.ag-step.is-now .ag-step-block { background: var(--gold-soft, #E8D6A8); border-color: var(--cedar-2); }
.ag-step.is-now .ag-step-n { color: var(--forest-green); }
/* Everything after where you are, quieter — the point is that you do not have
   to think about it yet. Not hidden: the map is what makes the plan worth
   having, and the printed page still shows all of it. */
.ag-step.is-later .ag-step-block { opacity: 0.55; }
.ag-step-label { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ag-step-title { font-size: 12.5px; font-weight: 700; color: var(--forest-green); line-height: 1.3; overflow-wrap: anywhere; }
.ag-step-meta { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.ag-step-here { font-size: 11px; font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; color: var(--cedar-2); }

/* Under about 640px a staircase across the screen stops being readable; the
   same information stacks. */
@media (max-width: 640px) {
  .ag-steps { grid-template-columns: 1fr; align-items: stretch; min-height: 0; gap: 12px; }
  .ag-step { flex-direction: row; align-items: center; gap: 12px; }
  .ag-step-block { height: auto; min-height: 0; width: 42px; flex: none; border-radius: 10px; padding: 8px 0; justify-content: center; align-items: center; }
}

/* The override. Not polish: a wrong guess with no way to switch is worse than
   no guess at all. */
.ag-chart-toggle { display: inline-flex; gap: 0; border: 1.5px solid var(--border-2); border-radius: 999px; padding: 3px; margin: 0 0 14px; }
.ag-chart-opt {
  background: none; border: 0; border-radius: 999px; padding: 6px 15px; cursor: pointer;
  font-family: inherit; font-size: 12.5px; font-weight: 700; color: var(--muted);
}
.ag-chart-opt.is-on { background: var(--forest-green); color: #FCF4EA; }
.ag-chart-opt:focus-visible { outline: 2px solid var(--cedar-2); outline-offset: 2px; }

@media print {
  /* The switch is a control, not content. The chart itself prints. */
  .ag-chart-toggle { display: none !important; }
  .ag-steps { break-inside: avoid; page-break-inside: avoid; }
  .ag-step.is-later .ag-step-block { opacity: 1; }
}
body.ag-report .ag-chart-toggle { display: none !important; }
body.ag-report .ag-steps { break-inside: avoid; page-break-inside: avoid; }
body.ag-report .ag-step.is-later .ag-step-block { opacity: 1; }

/* ======================================================================
   The GPS cell.

   "A map shows the whole route and is how you plan; a GPS shows only the next
   move and is how you drive." The chart is the map. This is the GPS, so it
   comes first and is the loudest thing on the summary row — without removing
   anything, because the map is what makes the plan worth having.
   ====================================================================== */
.ag-sum-focus {
  background: var(--card-2, #FBF7EF);
  border: 1.5px solid var(--gold-soft);
  border-radius: 12px;
  padding: 12px 14px;
}
.ag-sum-focus .ag-sum-k { color: var(--cedar-2); }
.ag-sum-jump {
  align-self: flex-start; margin-top: 8px;
  background: var(--forest-green); color: #FCF4EA; border: 0; border-radius: 999px;
  padding: 6px 14px; font-family: inherit; font-size: 12px; font-weight: 700; cursor: pointer;
}
.ag-sum-jump:focus-visible { outline: 2px solid var(--cedar-2); outline-offset: 2px; }

/* Where the jump lands. A smooth scroll into the middle of a long list leaves
   you hunting for what moved. */
.ag-ms.is-focused { background: var(--card-2, #FBF7EF); box-shadow: 0 0 0 2px var(--gold-soft); border-radius: 10px; }
@media (prefers-reduced-motion: reduce) {
  .ag-ms.is-focused { transition: none; }
}

@media print {
  /* A button and a transient highlight are neither of them paper. */
  .ag-sum-jump { display: none !important; }
  .ag-ms.is-focused { background: none; box-shadow: none; }
}
body.ag-report .ag-sum-jump { display: none !important; }

/* ======================================================================
   Budget: the Cost row, and the Add/Remove control.

   "It would have the sliders and everything that the rest of the plan does
   have." The Cost row is the Length row's twin and reuses .ag-phase-adjust so
   the existing report/print hide rules apply to it with no new CSS — a control
   is not paper, and the figures print via the phase chip and the snapshot.
   ====================================================================== */
.ag-phase-cost { margin-top: 6px; }
.ag-cost-slider { flex: 1 1 auto; min-width: 90px; }
.ag-cost-amount {
  flex: 0 0 96px; width: 96px; padding: 4px 8px; font-size: 12.5px;
  border: 1px solid var(--border-2); border-radius: 8px; font-family: inherit;
  color: var(--ink-soft); background: var(--card); font-variant-numeric: tabular-nums;
}
.ag-cost-pct-wrap { display: inline-flex; align-items: center; gap: 2px; font-size: 12px; color: var(--muted); }
.ag-cost-pct {
  width: 52px; padding: 4px 6px; font-size: 12.5px; text-align: right;
  border: 1px solid var(--border-2); border-radius: 8px; font-family: inherit;
  color: var(--ink-soft); background: var(--card); font-variant-numeric: tabular-nums;
}
.ag-cost-amount:focus-visible, .ag-cost-pct:focus-visible, .ag-cost-slider:focus-visible {
  outline: 2px solid var(--cedar-2); outline-offset: 2px;
}
/* The percent beside a snapshot amount is supporting detail, not the figure. */
.ag-snap-pct { color: var(--muted); font-size: 0.92em; }

.ag-budget-ctl {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border-2);
}
.ag-budget-lbl { font-size: 12px; font-weight: 800; letter-spacing: 0.03em; text-transform: uppercase; color: var(--cedar-2); }
.ag-budget-total { flex: 0 0 140px; width: 140px; font-variant-numeric: tabular-nums; }
.ag-budget-ctl .ag-set-note { flex: 1 1 100%; margin: 0; }
/* The what-if slider, beside the box rather than instead of it: the box is for
   exact figures, the thumb is for "what does a bit more do". Lives INSIDE
   .ag-budget-ctl so the two hide rules below already cover it — a control is
   not paper. */
.ag-budget-slider { flex: 1 1 160px; min-width: 120px; }
.ag-budget-slider:focus-visible { outline: 2px solid var(--cedar-2); outline-offset: 2px; }

/* A budget is a number on the plan; the controls that change it are not. */
@media print { .ag-budget-ctl { display: none !important; } }
body.ag-report .ag-budget-ctl { display: none !important; }

/* ==========================================================================
   The budget bar graph, on the snapshot card with the figures it draws.

   "When there is a budget, okay, that a bar graph appears… I would just say a
   simple bar graph, vertical bar graph." Divs with percentage heights, the
   same technique the Gantt's .g2-bar uses — a chart library for a dozen
   rectangles is a dependency to keep alive and a second place for the numbers
   to live.

   Two flex rows of equal-basis children — bars, then phase numbers — so the
   axis lines up with the bars without either row being told how many phases
   there are. The plot height is FIXED: twelve phases must not push the
   snapshot onto a second page, and a bar chart that grows with the phase count
   would do exactly that.

   Unlike the controls above, this one IS paper: it is a figure, not a way to
   change one, so it prints and it goes in the PDF.
   ========================================================================== */
.ag-budget-graph { margin-top: 18px; break-inside: avoid; page-break-inside: avoid; }
.ag-bg-cap { font-size: 11px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--cedar-2); margin: 0 0 10px; }
.ag-bg-plot { display: flex; align-items: flex-end; gap: 6px; height: 132px; border-bottom: 1px solid var(--border-2); }
.ag-bg-col { flex: 1 1 0; min-width: 0; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; }
.ag-bg-amt { font-size: 9.5px; font-weight: 700; line-height: 1.2; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; margin-bottom: 3px; }
/* max-height keeps the tallest bar from shoving its own label off the top. */
.ag-bg-bar { display: block; width: 100%; max-width: 44px; max-height: calc(100% - 16px); border-radius: 4px 4px 0 0; background: linear-gradient(180deg, var(--green-mid), var(--forest-green)); }
.ag-bg-axis { display: flex; gap: 6px; padding-top: 6px; }
.ag-bg-n { flex: 1 1 0; min-width: 0; text-align: center; font-size: 10px; font-weight: 800; color: var(--muted-2); font-variant-numeric: tabular-nums; }

/* Match the table's phone width so the two scroll together inside .ag-snapshot
   and the columns stay wide enough for a dollar figure to fit above them. */
@media screen and (max-width: 640px) {
  .ag-bg-plot, .ag-bg-axis { min-width: 520px; }
}

@media print {
  .ag-bg-cap { color: #111; }
  .ag-bg-plot { height: 108px; border-bottom: 1px solid #111; }
  /* A border, not a fill: the bars survive a printer with backgrounds switched
     off, and a gradient smears on grayscale. */
  .ag-bg-bar { background: #EDEAE2; border: 1px solid #333; border-bottom: none; }
  .ag-bg-amt, .ag-bg-n { color: #333; }
}

/* The AI form's budget field is a primary input, styled to match the objective
   rather than the optional attachments/date fields below it. */
.ag-field-primary .ag-field-label { color: var(--forest-green); }
.ag-field-hint { margin: 6px 0 0; font-size: 12px; line-height: 1.5; color: var(--muted); }

/* ======================================================================
   "Prepared for" — who the plan is for.

   Two forms, and CSS picks. Download renders ?report=1 while the Print button
   prints the LIVE page, so a report-only render would vanish from every
   printed copy — the same trap planNotesHtml already navigates.
   ====================================================================== */
.ag-project-for { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.ag-project-name { flex: 1 1 200px; min-width: 0; }
.ag-project-addr-input { flex: 2 1 260px; min-width: 0; }
.ag-project-for .ag-input { padding: 7px 10px; font-size: 13.5px; }
/* The printed sentence is present in the DOM on screen, but hidden there. */
.ag-project-for-print { display: none; }
.ag-project-for.is-report { margin-top: 8px; font-size: 14.5px; color: var(--ink-soft); }
.ag-project-addr { color: var(--muted); }

@media print {
  .ag-project-name, .ag-project-addr-input { display: none !important; }
  .ag-project-for-print { display: block !important; margin: 6px 0 0; font-size: 14px; color: var(--ink-soft); }
}
body.ag-report .ag-project-name, body.ag-report .ag-project-addr-input { display: none !important; }
body.ag-report .ag-project-for-print { display: block !important; margin: 6px 0 0; }
