/* public.css — the ONE stylesheet for every page a guest or tenant meets:
   tenant portal, entry pay, intake/agreement/lease signing, ID details, the
   stay portal + lookup, the room-condition form, the public inspection report,
   privacy, and the door pages. PLATFORM_AUDIT.md order-of-work 2 (2026-09-04):
   fifteen of these pages still loaded the 2025 style.css (eucalyptus #2F4F4A,
   system-ui) while the portal was already on Estate, so a tenant met two brands
   in one afternoon.

   Born as static/tenant_portal.css (TENANT_PORTAL_BRIEF.md §5). Tokens are the
   estate palette, warmer variant, now under --est-* names; the --tp-* names are
   kept as aliases for one release for any inline style="var(--tp-…)" that
   still exists. Load it after /static/fonts.css (no @import: one request
   fewer on a phone). The backoffice keeps estate.css; this sheet never loads
   there.

   Sizing rules (do not lower): inputs 16px (below that iOS zooms the page on
   focus), buttons/inputs min-height 48px, chips 42px, tab buttons 44px, single
   column at every width. */

:root{
  --est-canvas:#F7F3EA;
  --est-card:#FFFFFF;
  --est-border:#E8E1D2;
  --est-inset:#F2EEE3;
  --est-inset-2:#F7F3EA;
  --est-chip-bg:#EFEADD;
  --est-row-line:#F4F0E6;
  --est-ink:#22291C;
  --est-body:#3A4033;
  --est-muted:#6B6F5E;
  --est-faint:#98937D;
  --est-forest:#1C4635;
  --est-green:#2E7D5B;
  --est-green-hover:#256B4D;
  --est-gold:#C9A86A;
  --est-on-gold:#22331F;      /* text on a gold button */
  --est-rust:#B4552D;
  --est-rust-border:#E8C4B4;
  --est-green-bg:#E3EFE9;  --est-green-ink:#0f6b58;
  --est-gold-bg:#FBF3E1;   --est-gold-ink:#92600a;
  --est-rust-bg:#F6E3DF;
  --est-serif:'Cormorant Garamond',Georgia,serif;
  --est-sans:'Inter',system-ui,sans-serif;
  --est-mono:ui-monospace,Menlo,monospace;
  /* dark surfaces (door pages) — Estate ink, not grey-black */
  --est-dark-canvas:#151A14;
  --est-dark-card:#1F261F;
  --est-dark-line:#2C352C;
  --est-dark-ink:#F7F3E8;
  --est-dark-muted:#A8C2AE;
  --est-dark-faint:#7FA38C;
  /* one-release aliases for the portal's old names */
  --tp-canvas:var(--est-canvas); --tp-card:var(--est-card); --tp-line:var(--est-border);
  --tp-border:var(--est-border); --tp-inset:var(--est-inset); --tp-inset-2:var(--est-inset-2);
  --tp-chip-bg:var(--est-chip-bg); --tp-hair:var(--est-row-line); --tp-ink:var(--est-ink);
  --tp-body:var(--est-body); --tp-muted:var(--est-muted); --tp-faint:var(--est-faint);
  --tp-forest:var(--est-forest); --tp-green:var(--est-green); --tp-green-hover:var(--est-green-hover);
  --tp-gold:var(--est-gold); --tp-gold-ink:var(--est-on-gold); --tp-rust:var(--est-rust);
  --tp-rust-line:var(--est-rust-border); --tp-ok-bg:var(--est-green-bg); --tp-ok-ink:var(--est-green-ink);
  --tp-warn-bg:var(--est-gold-bg); --tp-warn-ink:var(--est-gold-ink);
  --tp-danger-bg:var(--est-rust-bg); --tp-danger-ink:var(--est-rust);
  --tp-serif:var(--est-serif); --tp-sans:var(--est-sans);
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body.tp,body.public{
  margin:0;background:var(--est-canvas);color:var(--est-ink);
  font:400 13.5px/1.55 var(--est-sans);
  -webkit-font-smoothing:antialiased;padding-bottom:40px;
}
/* :not(.tp-btn) is load-bearing. `body.tp a` (0,1,2) beats `.tp-btn` (0,1,0),
   so a green button used as a link (Needs-you Arrival, Sign lease) painted its
   label the same green as the fill — a blank brick. Language pills have the
   same trap. */
body.tp a:not(.tp-btn):not(.tp-lang):not(.tp-tab):not(.tp-peek),body.public a:not(.tp-btn):not(.tp-lang):not(.public-btn):not(.gp-btn){color:var(--est-green);text-decoration:none}
body.tp a:not(.tp-btn):not(.tp-lang):not(.tp-tab):not(.tp-peek):hover,body.public a:not(.tp-btn):not(.tp-lang):not(.public-btn):not(.gp-btn):hover{color:var(--est-forest);text-decoration:underline}

.tp-wrap{max-width:440px;margin:0 auto;padding:0 16px 110px;font-variant-numeric:tabular-nums}

/* ── brand + language pills ─────────────────────────────────────────────── */
.tp-top{display:flex;align-items:center;gap:10px;padding:18px 0 0}
.tp-brand{font:600 19px var(--est-serif);color:var(--est-forest)}
.tp-langs{margin-left:auto;display:flex;gap:2px;background:var(--est-chip-bg);border-radius:999px;padding:3px}
.tp-lang{border:none;background:transparent;color:var(--est-muted);font:500 11px var(--est-sans);
  padding:5px 10px;border-radius:999px;cursor:pointer;min-height:30px;text-decoration:none;
  display:inline-flex;align-items:center}
.tp-lang:hover{text-decoration:none}
.tp-lang.on{background:var(--est-forest);color:#fff;font-weight:600}
.tp-lang.soon{color:#B8B2A0;cursor:default}

/* ── hero ───────────────────────────────────────────────────────────────── */
.tp-hero{padding:22px 0 4px}
.tp-hero h1{font:600 34px/1.08 var(--est-serif);color:var(--est-ink);margin:0}
.tp-hero-sub{display:flex;align-items:center;gap:9px;margin-top:7px;flex-wrap:wrap}
.tp-hero-sub .prop{font-size:13.5px;color:var(--est-muted)}

/* status / state pills (shared) */
.pill{display:inline-block;font:600 10px var(--est-sans);letter-spacing:.02em;
  background:var(--est-inset);color:var(--est-muted);padding:4px 10px;border-radius:999px;
  vertical-align:middle}
.pill-t-green{background:var(--est-green-bg);color:var(--est-green-ink)}
.pill-t-amber{background:var(--est-gold-bg);color:var(--est-gold-ink)}
.pill-t-rust{background:var(--est-rust-bg);color:var(--est-rust)}

/* ── beta banner (gold, replaces the old blue) ──────────────────────────── */
.tp-beta{display:flex;gap:10px;align-items:flex-start;background:var(--est-gold-bg);
  border:1px solid #EEDDB4;color:#6b4e14;border-radius:13px;padding:11px 14px;
  font-size:12.5px;line-height:1.5;margin-top:16px}
.tp-beta-chip{flex:0 0 auto;background:var(--est-gold);color:var(--est-on-gold);
  font:700 9px var(--est-sans);letter-spacing:.07em;border-radius:6px;padding:3px 8px}

/* ── action band ────────────────────────────────────────────────────────── */
.tp-band{display:flex;flex-direction:column;gap:10px;margin-top:18px}
.tp-band-eyebrow{font:600 10px var(--est-sans);letter-spacing:.11em;text-transform:uppercase;
  color:var(--est-faint)}
.tp-todo{background:var(--est-card);border:1px solid var(--est-border);border-left:3px solid var(--est-gold);
  border-radius:16px;padding:15px 17px}
.tp-todo.rust{border-color:var(--est-rust-border);border-left-color:var(--est-rust)}
.tp-todo-tag{display:inline-block;font:700 9px var(--est-sans);letter-spacing:.07em;
  text-transform:uppercase;background:var(--est-gold-bg);color:var(--est-gold-ink);
  padding:3px 8px;border-radius:999px;margin-bottom:5px}
.tp-todo.rust .tp-todo-tag{background:var(--est-rust);color:#fff}
.tp-todo-title{font-size:14.5px;font-weight:600;color:var(--est-ink);line-height:1.4}
.tp-todo-sub{font-size:12.5px;color:var(--est-muted);line-height:1.5;margin:4px 0 12px}

/* ── sticky tab bar ─────────────────────────────────────────────────────── */
.tp-tabs{position:sticky;top:0;z-index:20;background:var(--est-canvas);padding:14px 0 12px;margin-top:8px}
.tp-tabbar{display:flex;gap:3px;background:var(--est-chip-bg);border-radius:14px;padding:4px}
.tp-tab{flex:1;border:none;background:transparent;color:var(--est-muted);
  font:500 12.5px var(--est-sans);padding:10px 6px;border-radius:11px;cursor:pointer;
  min-height:44px;position:relative;transition:background .16s ease}
.tp-tab.on{background:#fff;color:var(--est-ink);font-weight:600;box-shadow:0 1px 3px rgba(31,30,29,.1)}
.tp-tab .dot{position:absolute;top:7px;right:9px;width:6px;height:6px;border-radius:50%;background:var(--est-rust)}

/* Portal v2 — status line, bottom tab bar, money peek, signed-agreement row.
   The cleaning report still uses .tp-tabs at the top. */
.tp-status{display:flex;align-items:flex-start;gap:10px;margin-top:14px;padding:11px 14px;
  background:#fff;border:1px solid var(--est-border);border-radius:14px}
.tp-status .dot{width:8px;height:8px;border-radius:50%;flex:none;margin-top:5px;background:var(--est-green)}
.tp-status.warn .dot{background:var(--est-gold)}
.tp-status.rust .dot{background:var(--est-rust)}
.tp-status .msg{font-size:13px;font-weight:500;color:var(--est-ink);line-height:1.4}
.tp-tabnav{position:sticky;bottom:0;z-index:30;max-width:440px;margin:0 auto;
  background:var(--est-canvas);padding:8px 16px calc(10px + env(safe-area-inset-bottom))}
.tp-tabnav .tp-tabbar{background:#fff;border:1px solid var(--est-border);border-radius:16px;
  box-shadow:0 8px 24px rgba(31,30,29,.08)}
.tp-tabnav .tp-tab{min-height:44px;min-width:40px;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:1px;font-size:10px;line-height:1.1;padding:5px 1px 4px}
.tp-tabnav .tp-tab svg{width:18px;height:18px;display:block;flex:none}
.tp-tabnav .tp-tab .lbl{display:block;max-width:100%;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-size:10px;letter-spacing:0}
.tp-tabnav .tp-tab .dot{top:3px;right:4px}
.tp-peek{display:flex;align-items:center;gap:14px;background:#fff;border:1px solid var(--est-border);
  border-radius:20px;padding:16px 18px;color:inherit;text-decoration:none;min-height:72px}
.tp-peek.rust{border-color:var(--est-rust-border)}
.tp-peek-copy{flex:1;min-width:0;display:flex;flex-direction:column}
.tp-peek-amt{font:600 24px var(--est-sans);color:var(--est-ink);letter-spacing:-.01em;line-height:1.15}
.tp-peek-go{width:8px;height:8px;border-right:1.6px solid var(--est-faint);border-bottom:1.6px solid var(--est-faint);
  transform:rotate(-45deg);flex:none}
.tp-lease-row{display:flex;align-items:center;gap:12px;background:#fff;border:1px solid var(--est-border);
  border-radius:16px;padding:14px 18px}
.tp-lease-row .tp-lease-title{font-size:13.5px;font-weight:600;color:var(--est-ink)}
.tp-lease-row .tp-note{margin:1px 0 0;color:var(--est-green-ink)}
.tp-lease-row .tp-btn{margin-left:auto;min-height:40px}
.tp-lease-alert{background:#fff;border:1px solid var(--est-rust-border);border-left:3px solid var(--est-rust);
  border-radius:16px;padding:16px 18px}
.tp-lease-alert h2{margin-top:4px}
.tp-pin-locked{color:rgba(255,255,255,.22)}
.tp-steps-bar{display:flex;gap:4px;margin:14px 0 4px}
.tp-steps-seg{flex:1;height:4px;border-radius:99px;background:var(--est-border)}
.tp-steps-seg.on{background:var(--est-green)}
.tp-steps{list-style:none;margin:8px 0 0;padding:0}
.tp-step{display:flex;gap:12px;align-items:flex-start;padding:12px 0;border-top:1px solid var(--est-border)}
.tp-step:first-child{border-top:none;padding-top:8px}
.tp-step-dot{width:28px;height:28px;border-radius:50%;flex:none;display:flex;align-items:center;
  justify-content:center;font:600 12px var(--est-sans);background:var(--est-inset);color:var(--est-muted);
  position:relative}
.tp-step.now .tp-step-dot{background:var(--est-ink);color:#fff}
.tp-step-dot.done{background:var(--est-green)}
.tp-step-dot.done::after{content:"";width:5px;height:9px;border-right:2px solid #fff;
  border-bottom:2px solid #fff;transform:rotate(45deg) translate(-1px,-1px)}
.tp-step-title{font-size:14.5px;font-weight:600;color:var(--est-ink);line-height:1.35}
.tp-step.done .tp-step-title{color:var(--est-muted);font-weight:500}
.tp-step-sub{font-size:12.5px;color:var(--est-muted);margin-top:2px}
.tp-step .tp-btn{margin-top:10px;min-height:40px}
.tp-due{display:flex;align-items:center;gap:10px;padding:10px 0;border-top:1px solid var(--est-border)}
.tp-due .swatch{width:8px;height:8px;border-radius:3px;flex:none;background:var(--est-gold)}
.tp-due[data-overdue="1"] .swatch{background:var(--est-rust)}
.tp-due[data-kind="cons"] .swatch{background:var(--est-green)}
.tp-due-copy{flex:1;min-width:0}
.tp-due-label{font-size:13.5px;font-weight:600;color:var(--est-ink)}
.tp-due-when{font-size:11.5px;color:var(--est-muted)}
.tp-due-amt{font-weight:600;font-size:13.5px;color:var(--est-ink)}
.tp-reveal > summary.tp-btn.block{width:100%}
.tp-chart{position:relative;height:132px;display:flex;align-items:flex-end;gap:8px;
  margin-top:16px;padding:0 2px;border-bottom:1px solid var(--est-border)}
.tp-chart-col{flex:1;height:100%;display:flex;flex-direction:column;justify-content:flex-end;min-width:0}
.tp-chart-bar{width:100%}
.tp-chart-over{background:#C9A86A;border-radius:6px 6px 0 0}
.tp-chart-incl{background:#A9C4B3}
.tp-chart-line{position:absolute;left:0;right:0;border-top:1.5px dashed #2E7D5B;pointer-events:none}
.tp-chart-line span{position:absolute;right:0;bottom:2px;font:600 10px var(--est-sans);color:#2E7D5B;
  background:#fff;padding-left:6px;white-space:nowrap}
.tp-chart-labels{display:flex;gap:8px;padding:6px 2px 0}
.tp-chart-labels span{flex:1;text-align:center;font:500 10.5px var(--est-sans);color:var(--est-faint)}
.tp-chart-key{display:flex;gap:14px;margin-top:10px;font-size:11px;color:var(--est-muted)}
.tp-swatch{display:inline-block;width:9px;height:9px;border-radius:3px;margin-right:6px}
.tp-swatch.incl{background:#A9C4B3}
.tp-swatch.over{background:#C9A86A}
.tp-breakdown{margin-top:16px;background:var(--est-inset);border-radius:14px;padding:4px 14px}
.tp-breakdown .row{display:flex;gap:10px;padding:9px 0;font-size:13px;color:var(--est-body)}
.tp-breakdown .row span:last-child{margin-left:auto;font-variant-numeric:tabular-nums}
.tp-breakdown .row.head{font:600 10px var(--est-sans);letter-spacing:.08em;text-transform:uppercase;color:var(--est-faint)}
.tp-breakdown .row.incl{color:var(--est-green-ink)}
.tp-breakdown .row.share{border-top:1px solid var(--est-border);font-size:14px;font-weight:700;color:var(--est-ink)}
.tp-util-foot{display:flex;align-items:center;gap:10px;margin-top:12px;flex-wrap:wrap}
.tp-util-foot .tp-btn{margin-left:auto;min-height:40px}

/* ── panels + cards ─────────────────────────────────────────────────────── */
.tp-panel{display:flex;flex-direction:column;gap:14px;margin-top:14px}
.tp-panel[hidden]{display:none}
.tp-card{background:var(--est-card);border:1px solid var(--est-border);border-radius:18px;padding:18px 20px}
.tp-card h2{font:600 21px var(--est-serif);color:var(--est-ink);margin:0 0 10px}
.tp-card-head{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.tp-card-head h2{margin:0}
.tp-card-head .pill{margin-left:auto}
.tp-note{font-size:12.5px;color:var(--est-muted);line-height:1.55;margin:8px 0 0}
.tp-note.faint{color:var(--est-faint);font-size:12px}
.tp-eyebrow{font:600 10px var(--est-sans);letter-spacing:.11em;text-transform:uppercase;color:var(--est-faint)}

/* inset panel (confirmed states, wifi rows) */
.tp-inset{background:var(--est-inset);border-radius:13px;padding:14px 16px;margin-top:12px}
.tp-inset .tp-when{font:600 15px var(--est-sans);color:var(--est-ink)}
.tp-inset .tp-meta{font-size:12.5px;color:var(--est-muted);margin-top:3px;line-height:1.5}

/* ── dark forest door card ──────────────────────────────────────────────── */
.tp-card-dark{background:var(--est-forest);border:none;border-radius:18px;padding:20px 22px;color:#F7F3E8}
.tp-card-dark .tp-eyebrow{color:var(--est-gold)}
.tp-pinrow{display:flex;align-items:center;gap:14px;margin-top:10px;flex-wrap:wrap}
.tp-pin{font:600 38px ui-monospace,Menlo,monospace;letter-spacing:.16em;color:#fff;line-height:1}
.tp-doorhint{font-size:12px;color:#A8C2AE;line-height:1.5;margin:12px 0 0}

/* ── buttons ────────────────────────────────────────────────────────────── */
body.tp a.tp-btn,body.public a.tp-btn,
.tp-btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;
  background:var(--est-green);color:#fff;border:none;border-radius:12px;padding:13px 18px;
  font:600 13.5px var(--est-sans);cursor:pointer;min-height:48px;text-decoration:none}
body.tp a.tp-btn:hover,body.public a.tp-btn:hover,
.tp-btn:hover{background:var(--est-green-hover);color:#fff;text-decoration:none}
.tp-btn.block{width:100%}
.tp-btn.gold{background:var(--est-gold);color:var(--est-on-gold);font-weight:700}
.tp-btn.gold:hover{background:var(--est-gold);opacity:.9;color:var(--est-on-gold)}
.tp-btn.rust{background:var(--est-rust)}
.tp-btn.rust:hover{background:var(--est-rust);opacity:.9}
.tp-btn.ghost{background:#fff;color:var(--est-body);border:1px solid var(--est-border);
  font-size:12.5px;padding:11px 16px;min-height:44px}
.tp-btn.ghost:hover{background:#fff;border-color:var(--est-green);color:var(--est-green)}
.tp-btn[data-busy]{opacity:.75;pointer-events:none}

/* copy affordance (door code / wifi). Hidden until JS unhides it —
   without JS there is nothing to click, so there is nothing to show. */
.tp-copy{display:inline-flex;align-items:center;gap:6px;background:var(--est-inset);
  border:1px solid var(--est-border);border-radius:10px;padding:9px 13px;
  font:600 11.5px var(--est-sans);color:var(--est-muted);cursor:pointer;min-height:42px}
.tp-copy:hover{border-color:var(--est-gold)}
.tp-copy.did{color:var(--est-green)}
.tp-copy-dark{margin-left:auto;background:rgba(255,255,255,.12);border:none;color:#A8C2AE}
.tp-copy-dark.did{background:rgba(127,163,140,.35);color:#DCE7DF}

/* ── forms ──────────────────────────────────────────────────────────────── */
.tp-label{display:block;font:500 11.5px var(--est-sans);color:var(--est-muted);margin:12px 0 5px}
/* 16px, not the prototype's 15px: Safari on iOS zooms the whole page when a
   focused input is below 16px — the exact bug the redesign is meant to kill. */
.tp-input, .tp-select, .tp-textarea{
  width:100%;border:1px solid var(--est-border);border-radius:11px;padding:13px 14px;
  font:400 16px/1.4 var(--est-sans);color:var(--est-ink);background:#fff;outline:none;min-height:48px}
.tp-textarea{border-radius:13px;line-height:1.55;resize:vertical;min-height:96px}
.tp-input:focus,.tp-select:focus,.tp-textarea:focus{border-color:var(--est-green)}
.tp-form-actions{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap}
.tp-form-actions .tp-btn{flex:1;min-width:150px}

/* category chips — radio inputs styled as chips, so the no-JS path works */
.tp-chips{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:2px}
.tp-chip{position:relative;display:inline-flex;align-items:center;border:1px solid var(--est-border);
  background:#fff;color:var(--est-body);font:500 12.5px var(--est-sans);padding:9px 14px;
  border-radius:999px;cursor:pointer;min-height:42px}
.tp-chip:hover{border-color:var(--est-green)}
.tp-chip input{position:absolute;inset:0;opacity:0;cursor:pointer;margin:0}
.tp-chip:has(input:checked){background:var(--est-forest);border-color:var(--est-forest);color:#fff;font-weight:600}
/* :has() fallback (older engines get a visible focus ring instead) */
.tp-chip:focus-within{outline:2px solid var(--est-green);outline-offset:1px}

/* structured maintenance answers (card_help) — shown only while the Maintenance
   chip is checked. Gated on :has() support so engines without it (and no JS)
   simply show the fields; nothing is ever hidden without a way to reveal it. */
.tp-maint{padding:4px 0 0}
@supports selector(:has(*)){
  .tp-maint{display:none}
  form:has(input[name="category"][value="maintenance"]:checked) .tp-maint{display:block}
}
.tp-file{padding:11px 14px;font-size:14px}
.tp-file::file-selector-button{border:1px solid var(--est-border);background:var(--est-chip-bg);
  color:var(--est-ink);border-radius:999px;padding:6px 12px;margin-right:10px;font:500 12.5px var(--est-sans)}
.tp-req .maint-summary{font-weight:500;color:var(--est-body)}

/* ── key/value rows + info blocks ───────────────────────────────────────── */
.tp-kv{display:flex;gap:14px;align-items:baseline;padding:11px 0;border-bottom:1px solid var(--est-row-line)}
.tp-kv:last-child{border-bottom:0}
.tp-kv .k{flex:0 0 38%;max-width:150px;font:500 12.5px var(--est-sans);color:var(--est-muted);line-height:1.45}
.tp-kv .v{flex:1;font:600 13.5px var(--est-sans);color:var(--est-ink);text-align:right;
  line-height:1.45;word-break:break-word}
.tp-blocks{display:flex;flex-direction:column}
.tp-blocks .tp-kv .v{text-align:left;font-weight:500;font-size:14px}
.tp-blocks .tp-p{margin:8px 0 0;font-size:14px;line-height:1.55;color:var(--est-body)}
.tp-copyrow{align-items:center}
.tp-copyrow .tp-copy{flex:none;min-height:42px;padding:8px 12px}

/* legacy info-block bits kept from the old sheet (portal_format emits these) */
.gp-inline-code{display:inline-block;font-family:ui-monospace,Menlo,monospace;font-weight:600;
  font-size:1.05rem;letter-spacing:.12em;color:var(--est-forest);background:var(--est-green-bg);
  border-radius:8px;padding:2px 10px}
.gp-link{color:var(--est-green);font-weight:600;text-decoration:underline;text-underline-offset:2px}
.gp-link-btn{display:inline-flex;align-items:center;gap:6px;background:var(--est-inset);
  color:var(--est-forest);font-weight:600;font-size:.9rem;text-decoration:none;
  border:1px solid var(--est-border);border-radius:10px;padding:10px 14px;min-height:44px}

/* collapsible cards (house rules; "Change" reveals; extra rent rows) */
.tp-fold{background:var(--est-card);border:1px solid var(--est-border);border-radius:18px;overflow:hidden}
.tp-fold > summary{display:flex;align-items:center;gap:10px;padding:18px 20px;cursor:pointer;
  list-style:none;min-height:56px}
.tp-fold > summary::-webkit-details-marker{display:none}
.tp-fold > summary h2{margin:0}
.tp-fold > summary .cue{margin-left:auto;font:600 12px var(--est-sans);color:var(--est-green)}
.tp-fold > summary .cue .less{display:none}
.tp-fold[open] > summary .cue .more{display:none}
.tp-fold[open] > summary .cue .less{display:inline}
.tp-fold > .tp-fold-body{padding:0 20px 18px}
.tp-reveal > summary{list-style:none;cursor:pointer;display:inline-flex;margin-top:12px}
.tp-reveal > summary::-webkit-details-marker{display:none}
.tp-reveal[open] > summary{display:none}
.tp-morelist > summary{list-style:none;cursor:pointer;margin-top:13px}
.tp-morelist > summary::-webkit-details-marker{display:none}
.tp-morelist > summary .tp-btn{width:100%}
.tp-morelist > summary .less{display:none}
.tp-morelist[open] > summary .more{display:none}
.tp-morelist[open] > summary .less{display:inline}

/* ── money tab ──────────────────────────────────────────────────────────── */
.tp-next{border-radius:18px;padding:19px 21px;border:1px solid #EEDDB4;background:var(--est-gold-bg)}
.tp-next.overdue{background:#FBEDE8;border-color:var(--est-rust-border)}
.tp-next.clear{background:#E9F2EC;border-color:#CBE3D4}
.tp-next .tp-eyebrow{color:var(--est-gold-ink)}
.tp-next.overdue .tp-eyebrow{color:var(--est-rust)}
.tp-next.clear .tp-eyebrow{color:var(--est-green-ink)}
.tp-next-amount{display:flex;align-items:flex-end;gap:12px;margin-top:9px;flex-wrap:wrap}
.tp-next-amount .amt{font:600 32px var(--est-sans);color:var(--est-ink);font-variant-numeric:tabular-nums;line-height:1}
.tp-next-amount .due{font-size:13px;color:var(--est-muted);padding-bottom:4px}
.tp-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px}
.tp-tile{background:var(--est-card);border:1px solid var(--est-border);border-radius:16px;padding:15px 17px}
.tp-tile .v{font:600 24px var(--est-sans);color:var(--est-ink);font-variant-numeric:tabular-nums}
.tp-tile .v.warn{color:var(--est-gold-ink)}
.tp-tile .v.rust{color:var(--est-rust)}
.tp-tile .k{font-size:11.5px;color:var(--est-faint);margin-top:4px;line-height:1.4}
.tp-row{display:flex;align-items:center;gap:13px;padding:12px 0;border-bottom:1px solid var(--est-row-line)}
.tp-row .dot{width:11px;height:11px;border-radius:50%;flex:none;background:var(--est-gold);
  box-shadow:0 0 0 3px rgba(201,168,106,.25)}
.tp-row .dot.paid{background:var(--est-green);box-shadow:none}
.tp-row .dot.late{background:var(--est-rust);box-shadow:0 0 0 3px rgba(180,85,45,.18)}
.tp-row .what{flex:1;min-width:0;line-height:1.35}
.tp-row .what .p{display:block;font:600 13.5px var(--est-sans);color:var(--est-ink)}
.tp-row .what .d{display:block;font:400 11.5px var(--est-sans);color:var(--est-faint);margin-top:2px}
.tp-row .amt{text-align:right;flex:none}
.tp-row .amt .n{display:block;font:600 13.5px var(--est-sans);color:var(--est-ink);font-variant-numeric:tabular-nums}
.tp-row .amt .pill{margin-top:3px}

/* ── requests / messages ────────────────────────────────────────────────── */
.tp-req{border-left:3px solid var(--est-gold);padding:2px 0 2px 14px;margin:12px 0 0}
.tp-req.done{border-left-color:var(--est-green)}
.tp-req .head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:5px}
.tp-req .cat{font:600 10.5px var(--est-sans);color:var(--est-faint);letter-spacing:.03em;text-transform:uppercase}
.tp-req .when{margin-left:auto;font:400 11px var(--est-sans);color:var(--est-faint)}
.tp-req .msg{font-size:13.5px;color:var(--est-body);line-height:1.55}
.tp-reply{margin-top:9px;background:#E9F2EC;border-radius:11px 4px 11px 11px;padding:11px 14px}
.tp-reply .who{font:600 10px var(--est-sans);letter-spacing:.07em;text-transform:uppercase;
  color:var(--est-green);margin-bottom:4px}
.tp-reply .txt{font-size:13px;color:var(--est-on-gold);line-height:1.55}

/* utilities table rows reuse .tp-kv; simple compact table fallback */
.tp-table{width:100%;border-collapse:collapse}
.tp-table th{font:500 11.5px var(--est-sans);color:var(--est-muted);text-align:left;padding:6px 0;
  border-bottom:1px solid var(--est-row-line)}
.tp-table td{font-size:13.5px;padding:10px 0;border-bottom:1px solid var(--est-row-line)}
.tp-table td.num{font-variant-numeric:tabular-nums;font-weight:600}
.tp-table th.num,.tp-table td.num{text-align:right}
.tp-cons-months{min-width:0}
.tp-cons-month,.tp-cons-total{padding:12px 0;border-bottom:1px solid var(--est-row-line);min-width:0}
.tp-cons-total{border-bottom:none}
.tp-cons-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.tp-cons-when{min-width:0}
.tp-cons-when .m{font-weight:600;font-size:14.5px;color:var(--est-ink)}
.tp-cons-share{flex:none;text-align:right}
.tp-cons-share .k{display:block;font:500 10.5px var(--est-sans);color:var(--est-muted)}
.tp-cons-share .n{font-weight:600;font-size:15px;font-variant-numeric:tabular-nums;color:var(--est-ink)}
.tp-cons-grid{display:grid;grid-template-columns:1fr 1fr;gap:4px 12px;margin:8px 0 0}
.tp-cons-grid div{display:flex;align-items:baseline;justify-content:space-between;gap:6px;min-width:0}
.tp-cons-grid dt{font-size:11.5px;font-weight:500;color:var(--est-muted);min-width:0;overflow-wrap:anywhere}
.tp-cons-grid dd{margin:0 0 0 auto;font-size:12.5px;font-weight:600;color:var(--est-body);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.tp-cons-badges{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}
.tp-cons-why{flex:0 1 auto}
.tp-cons-why[open]{flex-basis:100%}
.tp-cons-why summary{display:inline-block;list-style:none;cursor:pointer}
.tp-cons-why summary::-webkit-details-marker{display:none}
.tp-cons-why .tp-note{margin:4px 0 0}
.tp-cons-bills{margin-top:6px}
.tp-see{display:flex;align-items:center;min-height:44px;font-weight:600;font-size:13.5px}
.tp-headlink{margin-left:8px;font-weight:600;font-size:13px;min-height:40px;display:inline-flex;align-items:center}

/* ── footer ─────────────────────────────────────────────────────────────── */
.tp-footer{text-align:center;font-size:11.5px;color:var(--est-faint);line-height:1.6;margin-top:26px}

/* ── toasts (fixed, bottom-centred) ─────────────────────────────────────── */
.tp-toasts{position:fixed;left:16px;right:16px;bottom:18px;display:flex;flex-direction:column;
  gap:8px;z-index:60;pointer-events:none;align-items:center}
.tp-toast{background:var(--est-forest);color:#F7F3E8;border-radius:13px;padding:13px 18px;
  font:500 13px var(--est-sans);box-shadow:0 12px 34px rgba(28,70,53,.32);
  display:flex;align-items:center;gap:10px;max-width:520px;width:100%;
  animation:tpToast .22s ease-out}
.tp-toast .dot{width:8px;height:8px;border-radius:50%;background:#7FA38C;flex:none}
.tp-toast.warn .dot{background:var(--est-gold)}

@keyframes tpToast{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes tpIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

@media (prefers-reduced-motion:reduce){
  .tp-toast,.tp-panel{animation:none}
}

/* What to bring to the check-in, itemised inside the Check-in card (2026-08-24).
   Small and quiet: it sits under a checklist line, not as a section of its own. */
.tp-entry-due{margin:6px 0 2px;border-collapse:collapse;font-size:.92em}
.tp-entry-due caption{text-align:left;font-weight:600;padding:0 0 2px;color:inherit}
.tp-entry-due th{font-weight:400;text-align:left;padding:1px 14px 1px 0}
.tp-entry-due td{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap;padding:1px 0}
.tp-entry-due .tp-entry-total th,.tp-entry-due .tp-entry-total td{font-weight:600;border-top:1px solid var(--est-border);padding-top:3px}

/* ── Check-in hours, beside the arrival time the tenant is choosing ─────── */
.tp-hours { margin-top: 14px; }
.tp-hours-office { margin: 0 0 6px; font-size: .92rem; }
.tp-hours-pick {
  margin: 0 0 8px; padding: 8px 10px; border-radius: 8px;
  background: var(--est-inset, #f4f2ec); font-size: .92rem;
}
.tp-hours-pick[data-level="fee"] { background: #fdf3e3; }
.tp-hours-pick[data-level="confirm"] { background: #fdeaea; }
.tp-hours-block { margin: 10px 0; }
.tp-hours-list, .tp-hours-rules { margin: 4px 0 0; padding-left: 0; list-style: none; }
.tp-hours-list li {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 3px 0; border-bottom: 1px solid rgba(0,0,0,.06);
}
.tp-hours-rules { list-style: disc; padding-left: 18px; font-size: .9rem; }
.tp-hours-rules li { margin: 4px 0; }

/* =====================================================================
   PUBLIC SHELL — intake, agreement, lease, ID details, request-link,
   stay lookup, message pages. Ported from style.css's body.public block
   (2026-09-04) onto the tokens above: the card-in-the-middle layout is
   unchanged, the eucalyptus is not. body.public reads at 15px (forms);
   body.tp keeps the portal's denser 13.5px.
   ===================================================================== */
body.public{font-size:15px;line-height:1.6;padding-bottom:0}
body.public h1,body.public h2{font-family:var(--est-serif);font-weight:600;color:var(--est-ink);letter-spacing:-.01em}
body.public h1{font-size:2rem;line-height:1.15;margin:0 0 10px}
body.public h2{font-size:1.42rem;margin:24px 0 10px}
body.public .muted,body.tp .muted{color:var(--est-muted)}
.public-wrap{max-width:560px;margin:0 auto;padding:40px 18px;min-height:100vh;
  display:flex;align-items:center;justify-content:center}
.public-wrap-wide{max-width:860px}
.public-card{background:var(--est-card);border:1px solid var(--est-border);border-radius:20px;width:100%;
  padding:34px 30px;box-shadow:0 20px 60px rgba(28,70,53,.08)}
.public-card-center{text-align:center}
.public-brand{font-family:var(--est-serif);font-size:1.5rem;font-weight:600;
  color:var(--est-forest);letter-spacing:.01em;margin-bottom:10px}
.public-body{font-size:1.02rem;color:var(--est-body);line-height:1.6}
.public-missing{text-align:left;margin:12px 0 0;padding-left:1.2rem;line-height:1.45}
.public-missing li{margin:4px 0}
.public-actions{margin-top:16px}

.public-form{display:flex;flex-direction:column;gap:16px;margin-top:22px}
.public-form label{display:flex;flex-direction:column;gap:6px;font-size:.9rem;
  font-weight:600;color:var(--est-ink)}
.public-form input[type=text],.public-form input[type=email],
.public-form input[type=tel],.public-form input[type=date],
.public-form input[type=time],.public-form input[type=file],.public-form select,.public-form textarea{
  padding:13px;border:1px solid var(--est-border);border-radius:11px;min-height:48px;
  font-size:16px;font-family:inherit;width:100%;background:#fff;color:var(--est-ink)}  /* 16px: no iOS zoom */
.public-form input:focus,.public-form select:focus,.public-form textarea:focus{outline:none;border-color:var(--est-green);
  box-shadow:0 0 0 3px rgba(46,125,91,.16)}
.public-form fieldset{border:1px solid var(--est-border);border-radius:12px;padding:12px 14px;margin:0 0 4px;
  display:flex;flex-direction:column;gap:14px}
.public-form legend{font-size:.85rem;font-weight:600;padding:0 6px}
.public-form legend .muted{font-weight:400}
.public-form .form-section{font-weight:700;font-size:.95rem;margin:6px 0 -2px;
  border-top:1px solid var(--est-border);padding-top:14px}
.public-form .form-section .muted{font-weight:400;font-size:.85rem}
.public-form .coguest{border:1px solid var(--est-border);border-radius:12px;padding:10px 12px;
  display:flex;flex-direction:column;gap:10px;background:var(--est-inset-2)}
.public-form .row2{display:flex;gap:8px}
.public-form .row2 select{flex:0 0 auto;max-width:48%}
.public-form .row2 input{flex:1 1 auto}
.consent{flex-direction:row!important;align-items:flex-start;gap:10px;
  font-weight:400!important;font-size:.88rem;color:var(--est-muted)}
.consent input{margin-top:2px;flex:0 0 auto;width:20px;height:20px}
.public-btn{display:inline-flex;align-items:center;justify-content:center;margin-top:6px;width:100%;
  padding:14px 18px;min-height:48px;font:600 1.02rem var(--est-sans);border:0;cursor:pointer;
  border-radius:12px;background:var(--est-green);color:#fff;letter-spacing:.01em;text-decoration:none}
.public-btn:hover{background:var(--est-green-hover);color:#fff;text-decoration:none}
.public-btn:disabled{opacity:.6;cursor:default}
.public-note{font-size:.82rem;color:var(--est-muted);line-height:1.5}
.public-flash{border-radius:12px;padding:11px 14px;font-size:.92rem;line-height:1.45;margin:10px 0}
.public-flash.ok{background:var(--est-green-bg);color:var(--est-green-ink)}
.public-flash.warn{background:var(--est-gold-bg);color:var(--est-gold-ink)}
.public-flash.err{background:var(--est-rust-bg);color:var(--est-rust)}
.public-foot{font-size:.82rem;color:var(--est-muted);text-align:center;margin-top:18px}
.public-foot a{color:inherit}
/* language pills — the portal's, reusable on every public page */
.public-langs{display:flex;justify-content:flex-end;margin:0 0 6px}
.public-langs .tp-langs{margin-left:0}
/* minimal .est-btn: the impersonation "Back to me" strip and the push-enable
   buttons render on public pages too; they must not need estate.css */
.est-btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:44px;
  padding:10px 14px;border:1px solid var(--est-border);background:#fff;border-radius:12px;
  font:600 .95rem var(--est-sans);color:var(--est-ink);cursor:pointer;text-decoration:none}
.est-btn.primary{background:var(--est-forest);border-color:var(--est-forest);color:#fff}
.est-btn.sm{min-height:40px;padding:8px 12px;font-size:.85rem}
.pts-push .est-btn + .est-btn{margin-left:8px}

/* contract embed */
.pdf-frame{margin:16px 0;border:1px solid var(--est-border);border-radius:12px;overflow:hidden;
  background:var(--est-inset)}
.pdf-frame iframe{width:100%;height:62vh;min-height:420px;border:0;display:block}

@media (max-width:600px){
  .public-wrap{padding:24px 12px}
  .public-card{padding:24px 18px;border-radius:16px}
  body.public h1{font-size:1.7rem}
  .pdf-frame iframe{height:58vh;min-height:340px}
}

/* Legacy variable names from style.css, resolved onto the tokens above. The
   moved templates still carry a few inline style="…var(--line)…" /
   "var(--muted)" attributes (some without fallbacks); this keeps every one of
   them painting Estate instead of transparent while they are retired page by
   page. Scoped to the public bodies only. */
body.public,body.tp{
  --line:var(--est-border);--line-soft:var(--est-row-line);--card:var(--est-card);--panel:var(--est-card);
  --ink:var(--est-ink);--ink-2:var(--est-body);--muted:var(--est-muted);--muted-2:var(--est-faint);
  --brand:var(--est-green);--brand-2:var(--est-green-hover);--brand-deep:var(--est-forest);
  --gold:var(--est-gold);--err:var(--est-rust);--ok:var(--est-green-ink);
  --warn:var(--est-gold-ink);--warn-bg:var(--est-gold-bg)}

/* =====================================================================
   SIGNATURE PAD + "sign here" panel — tenant lease, guest agreement,
   intake step 2. One definition; the three pages used to carry three
   near-identical <style> blocks in eucalyptus.
   ===================================================================== */
.sign-panel{margin:18px 0 4px;padding:18px 18px 20px;border:2px solid var(--est-green);
  border-radius:16px;background:rgba(46,125,91,.05);box-shadow:0 3px 16px rgba(28,70,53,.08)}
.sign-panel .public-btn{margin-top:6px}
.sign-step{font-family:var(--est-serif);font-size:1.5rem;font-weight:600;color:var(--est-forest);margin:0 0 2px}
.sign-step-sub{font-size:.86rem;color:var(--est-muted);margin:0 0 14px}
.sign-as{font-size:.86rem;margin:0 0 12px;padding:8px 12px;border-radius:10px;background:#fff;border:1px solid var(--est-border)}
.bound-list{margin:0;padding-left:20px;font-size:.9rem}
.bound-list li{margin:3px 0}
.step-crumb{font-size:.8rem;letter-spacing:.04em;text-transform:uppercase;color:var(--est-muted);margin:0 0 2px}
.agree-block{margin:6px 0 4px}
.agree-doc{margin:10px 0 0}
.sig-wrap{position:relative;margin:14px 0 4px}
.sign-panel .sig-wrap{margin:0}
.sig-label{display:block;font-size:.9rem;font-weight:600;margin-bottom:6px}
.sig-canvas{width:100%;height:200px;border:2px dashed var(--est-green);border-radius:12px;
  background:#fff linear-gradient(transparent calc(100% - 48px),#D7CDB8 calc(100% - 48px),
    #D7CDB8 calc(100% - 46px),transparent calc(100% - 46px));
  touch-action:none;cursor:crosshair;display:block}
.sig-canvas.signed{border-style:solid;border-color:var(--est-green)}
.sig-x{position:absolute;left:16px;bottom:50px;font-size:20px;font-weight:700;color:#C9C0AE;pointer-events:none}
.sig-canvas.signed + .sig-x{display:none}
.sig-actions{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:8px}
.sig-clear{background:#fff;border:1px solid var(--est-border);border-radius:10px;min-height:44px;
  padding:8px 16px;font:500 .9rem var(--est-sans);cursor:pointer;color:var(--est-muted)}
.sig-clear:hover{border-color:var(--est-green);color:var(--est-green)}
.sig-hint{font-size:.82rem}

/* =====================================================================
   GUEST STAY PORTAL (/stay/{token}) — the .gp-* rules that lived inline in
   guest/stay_portal.html, on Estate tokens. .gp-inline-code / .gp-link /
   .gp-link-btn are defined once above (portal_format emits them on both
   portals).
   ===================================================================== */
.gp-wrap{display:block;max-width:620px;margin:0 auto;padding:22px 16px 40px}
.gp-wrap .public-brand{text-align:center;margin-bottom:6px}
.gp-wrap h1{text-align:center;margin:0 0 2px}
.gp-sub{text-align:center;margin:0 0 18px;color:var(--est-muted)}
.gp-lang{display:flex;justify-content:center;margin:0 0 14px}
.gp-lang .tp-langs{margin-left:0}
.gp-grid{display:flex;flex-direction:column;gap:16px}
.gp-card{background:var(--est-card);border:1px solid var(--est-border);border-radius:18px;padding:18px 20px}
.gp-card h2{font-family:var(--est-serif);font-size:1.35rem;font-weight:600;margin:0 0 10px;color:var(--est-ink)}
.gp-kv{display:flex;justify-content:space-between;gap:12px;padding:8px 0;border-bottom:1px solid var(--est-row-line);font-size:.92rem}
.gp-kv:last-child{border-bottom:0}
.gp-kv .k{color:var(--est-muted)}
.gp-kv .v{font-weight:600;text-align:right;word-break:break-word}
.gp-kv .v a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.gp-pin{font:600 2.2rem var(--est-mono);letter-spacing:.18em;color:var(--est-forest);text-align:center;margin:8px 0}
.gp-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--est-green);color:#fff;
  text-decoration:none;padding:13px 22px;min-height:48px;border-radius:12px;font:600 .95rem var(--est-sans);border:0;cursor:pointer}
.gp-btn:hover{background:var(--est-green-hover);color:#fff;text-decoration:none}
.gp-btn.ghost{background:#fff;color:var(--est-green);border:1px solid var(--est-green)}
.gp-btn.ghost:hover{background:var(--est-green-bg)}
.gp-btn.block{width:100%}
.gp-note{font-size:.84rem;color:var(--est-muted);line-height:1.5}
.gp-note.center{text-align:center}
.gp-flash{background:var(--est-green-bg);color:var(--est-green-ink);border-radius:12px;padding:11px 14px;font-size:.9rem;margin-bottom:14px}
.gp-flash.warn{background:var(--est-gold-bg);color:var(--est-gold-ink)}
.gp-field{display:block;margin:10px 0}
.gp-field label{display:block;font-size:.8rem;color:var(--est-muted);margin-bottom:4px}
.gp-field select,.gp-field textarea{width:100%;box-sizing:border-box;border:1px solid var(--est-border);border-radius:11px;
  padding:12px;font:inherit;font-size:16px;min-height:48px;background:#fff;color:var(--est-ink)}
.gp-req{border-left:3px solid var(--est-gold);padding:2px 0 2px 12px;margin:10px 0;font-size:.88rem}
.gp-req .meta{color:var(--est-muted);font-size:.78rem}
.gp-pre{white-space:pre-wrap;font-size:.9rem;line-height:1.45;margin:0}
/* Arrival / Wi-Fi freeform text — structured, readable */
.gp-blocks{display:flex;flex-direction:column;gap:12px}
.gp-blocks .gp-kv{align-items:flex-start;padding:8px 0}
.gp-blocks .gp-kv .k{flex:0 0 34%;max-width:9.5rem;font-size:.8rem;font-weight:500;line-height:1.4;padding-top:1px}
.gp-blocks .gp-kv .v{flex:1;font-weight:500;text-align:left;font-size:.95rem;line-height:1.5}
.gp-blocks .gp-p,.gp-p{margin:0;font-size:.95rem;line-height:1.55;color:var(--est-body)}
.gp-missing-head{margin:12px 0 4px;font-size:.84rem;font-weight:600;color:var(--est-gold-ink)}
.gp-missing{margin:0;padding-left:1.2rem;font-size:.92rem;line-height:1.6;color:var(--est-body)}
.gp-pay-amt{font:600 1.6rem var(--est-sans);color:var(--est-forest);text-align:center;margin:8px 0;font-variant-numeric:tabular-nums}
.gp-foot{text-align:center;font-size:.82rem;color:var(--est-muted);margin:22px 0 0}
.public-note.center{text-align:center;margin-top:6px}

/* =====================================================================
   ROOM-CONDITION FORM (/inspect/{token}) — the tenant's move-in/move-out
   walkthrough. Was an inline <style> block on a eucalyptus gradient; now on
   the tokens. Class names are unchanged (the wizard script selects .step,
   .q, .seg, .detail); generic ones are scoped to .wiz-wrap so they cannot
   leak into another page on this sheet. .wiznav is fixed to the viewport
   and sits outside .wiz-wrap.
   ===================================================================== */
.wiz-wrap{max-width:560px;margin:0 auto;padding:14px 14px calc(96px + env(safe-area-inset-bottom))}
.wiz-card{background:var(--est-card);border:1px solid var(--est-border);border-radius:18px;padding:22px 18px;
  box-shadow:0 14px 44px rgba(28,70,53,.08)}
.wiz-brand{font-family:var(--est-serif);font-size:1.15rem;font-weight:600;color:var(--est-forest)}
.wiz-head{position:sticky;top:0;z-index:9;background:rgba(247,243,234,.94);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  padding:10px 2px 8px;margin:0 0 12px}
.wiz-bar{height:6px;background:var(--est-chip-bg);border-radius:99px;overflow:hidden;margin-top:8px}
.wiz-bar i{display:block;height:100%;width:0;background:linear-gradient(90deg,var(--est-forest),var(--est-green));
  border-radius:99px;transition:width .3s ease}
.wiz-stepname{display:flex;justify-content:space-between;align-items:baseline;font-size:.8rem;color:var(--est-muted)}
.wiz-stepname b{color:var(--est-ink);font-size:.92rem}
.wiz-wrap .step{display:none;animation:wizIn .25s ease-out}
.wiz-wrap .step.on{display:block}
@keyframes wizIn{from{opacity:0;transform:translateX(10px)}to{opacity:1;transform:none}}
h1.wiz{font-family:var(--est-serif);font-weight:600;font-size:1.7rem;line-height:1.15;margin:0 0 8px;color:var(--est-ink)}
.wiz-wrap .tip{background:var(--est-inset);border-radius:12px;padding:10px 13px;font-size:.86rem;color:var(--est-body);margin:0 0 16px}
.wiz-wrap .q{padding:16px 0 6px;border-top:1px solid var(--est-row-line)}
.wiz-wrap .q:first-of-type{border-top:none}
.wiz-wrap .q .qlabel{font-weight:600;font-size:1rem;margin-bottom:9px;display:block}
.wiz-wrap .q.err .qlabel{color:var(--est-rust)}
.wiz-wrap .q.err{border-radius:10px;background:var(--est-rust-bg);padding-left:10px;padding-right:10px}
/* The step refused to advance and only tinted the question: on a field already
   on screen the smooth-scroll is invisible and Continue reads as a dead button
   (Pedro, 2026-08-18, stuck on an empty emergency contact). Say it in words. */
.wiz-wrap .q .whyreq{display:none;color:var(--est-rust);font-size:13px;margin-top:4px;font-weight:600}
.wiz-wrap .q.err .whyreq{display:block}
/* Facts we already hold (flat, room, bed count, move-in) are CONFIRMED, not
   asked again — the tenant only opens this when something is wrong. */
.stay-known{background:var(--est-inset);border-radius:12px;padding:12px 14px;margin:4px 0 2px;font-size:.95rem;line-height:1.5}
.stay-known b{font-weight:600}
.stay-edit{margin:0 0 6px}
.stay-edit>summary{cursor:pointer;font-size:.86rem;color:var(--est-green);font-weight:600;padding:8px 0;list-style:none;min-height:44px;display:flex;align-items:center}
.stay-edit>summary::-webkit-details-marker{display:none}
/* segmented answer buttons */
.wiz-wrap .seg{display:flex;flex-wrap:wrap;gap:8px}
.wiz-wrap .seg label{position:relative;cursor:pointer}
.wiz-wrap .seg input{position:absolute;opacity:0;pointer-events:none}
.wiz-wrap .seg span{display:inline-flex;align-items:center;padding:10px 14px;border:1.5px solid var(--est-border);border-radius:12px;
  font-size:.92rem;background:#fff;color:var(--est-body);line-height:1.2;min-height:44px;box-sizing:border-box;
  transition:border-color .12s,background .12s,color .12s}
.wiz-wrap .seg input:checked+span{background:var(--est-green);border-color:var(--est-green);color:#fff;font-weight:600}
.wiz-wrap .seg input:focus-visible+span{outline:2px solid var(--est-gold);outline-offset:1px}
.wiz-wrap .seg.compact span{padding:9px 15px;min-width:44px;justify-content:center}
.wiz-wrap .confirm{background:var(--est-inset);border-radius:12px;padding:12px 14px;margin:0 0 14px;font-size:.95rem}
.wiz-wrap .confirm a{color:var(--est-green);font-weight:600}
/* a value the student confirms but cannot change (flat / room) */
.fixedval{margin:0;padding:11px 14px;border:1.5px solid var(--est-border);border-radius:12px;
  background:var(--est-inset-2);color:var(--est-ink);font-weight:600;font-size:.98rem}
.film-how{margin:0 0 14px;font-size:.86rem;color:var(--est-body)}
.film-how summary{cursor:pointer;font-weight:600;color:var(--est-green);min-height:44px;display:flex;align-items:center}
/* issue detail: photo + note */
.wiz-wrap .detail{display:none;margin:12px 0 4px;padding:12px;border:1.5px dashed #D8CFBB;border-radius:12px;background:var(--est-inset-2)}
.wiz-wrap .detail.show{display:block}
.wiz-wrap .detail small{display:block;color:var(--est-muted);margin:0 0 8px;font-size:.82rem}
.photo-btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;min-height:48px;
  padding:13px;border:1.5px solid var(--est-green);border-radius:12px;background:#fff;color:var(--est-green);
  font-weight:600;font-size:.95rem;cursor:pointer}
.photo-btn.got{border-style:solid;background:var(--est-green-bg)}
.photo-btn input{display:none}
.photo-btn.slim{margin-top:10px;padding:10px;font-size:.88rem;font-weight:500;min-height:44px;
  border-width:1px;border-style:dashed;color:var(--est-forest)}
.photo-btn.slim.got{border-style:solid;background:var(--est-green-bg);font-weight:600;color:var(--est-green)}
.wiz-wrap .thumb{display:none;margin-top:10px;max-height:130px;border-radius:10px;border:1px solid var(--est-border)}
.wiz-wrap .detail input[type=text],.wiz-wrap .q input[type=text],.wiz-wrap .q input[type=email],.wiz-wrap .q input[type=date],
.wiz-wrap .q textarea{
  width:100%;padding:13px;border:1px solid var(--est-border);border-radius:12px;font-size:16px;min-height:48px;
  font-family:inherit;background:#fff;color:var(--est-ink);box-sizing:border-box}
.wiz-wrap .q textarea{resize:vertical}
.wiz-wrap .detail input[type=text]{margin-top:10px}
.wiz-wrap .q input:focus,.wiz-wrap .q textarea:focus{outline:none;border-color:var(--est-green);box-shadow:0 0 0 3px rgba(46,125,91,.14)}
.wiz-wrap .q input.sig{font-family:var(--est-serif);font-size:1.25rem}
/* counts grid */
.cgrid .q{padding:12px 0 8px}
.cgrid .qlabel{font-weight:500;font-size:.95rem;margin-bottom:7px}
/* sticky bottom nav */
.wiznav{position:fixed;left:0;right:0;bottom:0;z-index:10;display:flex;gap:10px;
  padding:12px 14px calc(12px + env(safe-area-inset-bottom));
  background:rgba(247,243,234,.96);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  border-top:1px solid var(--est-border);max-width:560px;margin:0 auto}
@media (min-width:588px){.wiznav{left:50%;transform:translateX(-50%);width:560px;border-radius:16px 16px 0 0;border:1px solid var(--est-border);border-bottom:0}}
.wiznav button{flex:1;padding:15px;min-height:48px;border:0;border-radius:12px;font-family:inherit;font-size:1rem;
  font-weight:600;cursor:pointer;letter-spacing:.01em}
.wiznav .back{flex:0 0 96px;background:var(--est-chip-bg);color:var(--est-body)}
.wiznav .next{background:var(--est-green);color:#fff}
.wiznav .next:hover{background:var(--est-green-hover)}
.wiznav .next:disabled{opacity:.6}
.sign-box{background:var(--est-inset-2);border:1px solid var(--est-border);border-radius:12px;padding:14px;margin-top:12px}
.consent2{display:flex;gap:10px;align-items:flex-start;font-size:.9rem;color:var(--est-body);margin-top:12px}
.consent2 input{width:20px;height:20px;margin-top:1px;flex:0 0 auto}
.done-icon{font-size:2.6rem;text-align:center;margin:6px 0}
.wiz-wrap noscript{display:block;background:var(--est-rust-bg);color:var(--est-rust);padding:12px;border-radius:10px;margin-bottom:12px}
/* the upload did not go through: say so on the page, in words, with the answers kept */
.up-err{background:var(--est-rust-bg);border:1.5px solid var(--est-rust);border-radius:12px;padding:12px 14px;margin:0 0 12px;
  font-size:.92rem;line-height:1.5;color:var(--est-ink)}
.up-err b{display:block;color:var(--est-rust);margin-bottom:4px}
.up-err-keep{margin-top:6px;color:var(--est-body);font-size:.86rem}

/* =====================================================================
   PUBLIC INSPECTION REPORT (/report/{token}) — charge / damage / comparison
   report a tenant receives, with the reply form.
   ===================================================================== */
.rep-wrap{max-width:680px;margin:0 auto;padding:18px 14px 60px}
.rep-card{background:var(--est-card);border:1px solid var(--est-border);border-radius:18px;padding:24px 20px;
  box-shadow:0 14px 44px rgba(28,70,53,.08)}
.rep-title{margin:6px 0 2px}
.rep-dl{display:inline-flex;width:auto;margin-top:0}
.rep-h2{margin:26px 0 12px}
.rep-body{white-space:pre-wrap;line-height:1.55;font-size:.95rem;margin:14px 0 0}
.rep-photo{margin:0 0 18px}
.rep-photo img,.rep-photo video{width:100%;border-radius:12px;border:1px solid var(--est-border);display:block}
.rep-photo figcaption{font-size:.8rem;color:var(--est-muted);margin-top:5px}
.rep-diff{width:100%;border-collapse:collapse;font-size:.84rem}
.rep-diff th{text-align:left;padding:6px 4px;border-bottom:1px solid var(--est-border);font-weight:600;color:var(--est-muted)}
.rep-diff td{padding:6px 4px;border-bottom:1px solid var(--est-row-line);vertical-align:top}
.rep-diff .n{display:block;color:var(--est-muted);font-size:.76rem}
.rep-scroll{overflow-x:auto}
.rep-reply{margin-top:26px}
.rep-reply h2{margin:0 0 6px}
.rep-reply .muted{margin:0 0 12px}
.rep-already{margin:0 0 12px;font-size:.9rem}
.rep-reply .public-form{margin-top:0;gap:10px}
.rep-foot{margin-top:26px;font-size:.78rem}

/* =====================================================================
   PRIVACY POLICY (/privacy) + the acceptance gate in front of a portal
   ===================================================================== */
.pv{max-width:680px;margin:28px auto;padding:0 16px 40px}
.pv .public-brand{text-align:center;margin-bottom:6px}
.pv h1{font-size:1.7rem;margin:0 0 8px}
.pv h2{font-size:1.2rem;margin:22px 0 8px}
.pv p,.pv li{font-size:.95rem;line-height:1.55;color:var(--est-body)}
.pv ul{padding-left:1.2rem}
.pv .ver{color:var(--est-muted);font-size:.82rem;margin:0 0 18px}
.pv .doc{max-height:55vh;overflow:auto;border:1px solid var(--est-border);border-radius:12px;padding:14px 16px;background:#fff;margin:0 0 16px}
.pv .doc p,.pv .doc li{font-size:.9rem;line-height:1.5}
.pv .agree{font-size:.92rem;margin:0 0 12px}

/* =====================================================================
   DOOR PAGES (/door/*, guest.placetostay.pt/{slug}-door) — dark on purpose:
   a guest reads this at a street door at night. Estate ink, not the old
   #0c0c0e grey-black; the primary is the action green, Inter throughout,
   the company name top-left. Copy and the auto-retry script live in the
   templates and are unchanged. Class names are the ones those scripts set
   (.status .trying, #again), scoped to the door bodies.
   ===================================================================== */
body.door,body.doors{background:var(--est-dark-canvas);color:var(--est-dark-ink);
  font:16px/1.5 var(--est-sans);margin:0;min-height:100vh;box-sizing:border-box;
  padding:calc(64px + env(safe-area-inset-top)) 1.5rem 1.5rem;-webkit-font-smoothing:antialiased}
body.door{display:grid;place-items:center}
.door-top{position:absolute;top:0;left:0;right:0;display:flex;align-items:center;
  padding:calc(16px + env(safe-area-inset-top)) 20px 0}
.door-brand{font:600 1.2rem var(--est-serif);letter-spacing:.01em;margin:0;color:var(--est-dark-ink)}
.door-wrap{width:100%;max-width:420px;text-align:center}
.doors-wrap{max-width:480px;margin:0 auto}
.door-what{font-size:.9rem;color:var(--est-dark-muted);margin:0 0 1.1rem;line-height:1.45}
.door-title{font:600 .85rem var(--est-sans);color:var(--est-dark-faint);margin:0 0 1.25rem;
  text-transform:uppercase;letter-spacing:.08em}
.door-open{display:block;box-sizing:border-box;width:100%;font:700 1.4rem var(--est-sans);cursor:pointer;
  padding:30px 20px;min-height:48px;background:var(--est-green);color:#fff;text-decoration:none;
  border:1px solid var(--est-green);border-radius:16px;-webkit-tap-highlight-color:transparent;
  transition:background .15s,transform .05s}
.door-open:hover{background:var(--est-green-hover)}
.door-open:active{transform:scale(.98);background:var(--est-green-hover)}
.door-open[disabled]{opacity:.75;cursor:progress}
.door-note{margin:18px 0 0;padding:14px 16px;background:var(--est-dark-card);border:1px solid var(--est-dark-line);
  border-radius:12px;color:#DCE7DF;font-size:.98rem;line-height:1.5;text-align:left}
/* A "do this first" note above the button — gold accent so it is read before tapping. */
.door-note-before{margin:0 0 18px;background:#2A2614;border-color:#6B551F;color:#E7D7A6;font-weight:500;text-align:center}
.door-foot{margin:22px 0 0;font-size:.82rem;color:var(--est-dark-faint);line-height:1.6}
.door-foot a{color:var(--est-dark-muted)}
.doors-grid{display:grid;gap:12px}
.door-btn{display:block;padding:22px 20px;min-height:48px;background:var(--est-dark-card);color:var(--est-dark-ink);
  text-decoration:none;border:1px solid var(--est-dark-line);border-radius:14px;font-size:1.15rem;font-weight:600;
  -webkit-tap-highlight-color:transparent;transition:background .15s,transform .05s}
.door-btn:hover{border-color:var(--est-dark-faint);color:var(--est-dark-ink);text-decoration:none}
.door-btn:active{transform:scale(.98);background:#28312A}
body.door .status{display:block;box-sizing:border-box;padding:28px 20px;border-radius:16px;font-size:1.3rem;font-weight:700;margin-bottom:16px}
body.door .status.ok{background:#173F2D;border:1px solid var(--est-green);color:#DFF6E6}
body.door .status.err{background:#3A1D18;border:1px solid #7A3A2A;color:#FBE0E0}
body.door .status.trying{background:#2A2614;border:1px solid #6B551F;color:#E7D7A6}
body.door .status.trying::after{content:'';display:inline-block;width:.55em;height:.55em;margin-left:.5em;border-radius:50%;
  border:2px solid currentColor;border-right-color:transparent;animation:doorSpin .9s linear infinite;vertical-align:middle}
@keyframes doorSpin{to{transform:rotate(360deg)}}
body.door .again{display:inline-flex;align-items:center;justify-content:center;min-height:44px;margin-top:12px;
  padding:0 12px;color:var(--est-dark-muted);text-decoration:none;font-size:.95rem}
body.door .again:hover{color:var(--est-dark-ink)}
body.door .err-detail{margin-top:10px;font-size:.85rem;opacity:.7;word-break:break-word}
@media (prefers-reduced-motion:reduce){body.door .status.trying::after{animation:none}}

/* =====================================================================
   guest.placetostay.pt/ — the domain's own front door (anti-phishing page,
   see app/guest_front.py). Was a fourth green (#3f6b52) in -apple-system.
   ===================================================================== */
body.front{min-height:100vh;display:grid;place-items:center;padding:1.5rem;box-sizing:border-box;margin:0}
.front-wrap{max-width:460px;text-align:center}
.front-brand{font:600 2rem var(--est-serif);color:var(--est-forest);margin:0 0 .35rem;letter-spacing:.01em}
.front-sub{color:var(--est-muted);margin:0 0 1.4rem}
.front-card{background:var(--est-card);border:1px solid var(--est-border);border-radius:18px;padding:22px 20px;text-align:left}
.front-card p{margin:0 0 1rem;line-height:1.55}
.front-card p:last-child{margin-bottom:0}
.front-foot{margin-top:20px;font-size:.85rem;color:var(--est-faint)}
.front-foot a{color:var(--est-muted)}

/* ── o formulário do quarto num ecrã grande ──────────────────────────────────
   Pedro, 2026-09-08: "digg deep on the UIX to make it easier, specially on a
   laptop". Medido a 1718px de largura: o cartão ocupava 532px e 69% do ecrã
   estava vazio, com 747 botões de condição e 96 campos de foto empilhados numa
   coluna estreita. Num telemóvel isso é certo; num portátil é o tubo por onde
   o Lasse levou 90 minutos. Duas colunas cortam o scroll a metade sem mexer no
   HTML nem no javascript: a secção passa a grelha e só os .q ocupam uma célula.
   Abaixo de 940px nada disto existe — o telemóvel fica exactamente como está. */
@media (min-width:940px){
  .wiz-wrap{max-width:900px}
  .wiznav{width:900px;max-width:900px}
  .wiz-card{padding:26px 26px}
  .wiz-wrap .step.on{display:grid;grid-template-columns:1fr 1fr;column-gap:30px;align-items:start}
  /* título, dicas, blocos de vídeo/inventário: linha inteira. Só as perguntas
     de condição é que emparelham. */
  .wiz-wrap .step.on > *{grid-column:1 / -1}
  .wiz-wrap .step.on > .q{grid-column:auto}
  /* O video e a primeira coisa a fazer, com o quarto ainda intacto:
     linha inteira, nao meia. */
  .wiz-wrap .step.on > #video360{grid-column:1 / -1}
  /* Em duas colunas o traço de topo do primeiro item de cada coluna fica
     desirmanado; a separação passa a ser por baixo, igual em todas. */
  .wiz-wrap .step.on > .q{border-top:none;border-bottom:1px solid var(--est-row-line);
    padding:12px 0 14px}
  .wiz-wrap .step.on > .q:last-child{border-bottom:none}
  /* Chips mais apertados: com o texto grande, "Perfect condition ... Not present"
     ocupava tres linhas por item, 238px cada, e a coluna voltava a ser um tunel.
     No telemovel o alvo tem de continuar grande — isto so existe a partir dos
     940px, onde se aponta com o rato. */
  .wiz-wrap .step.on .seg{gap:6px}
  .wiz-wrap .step.on .seg span{padding:7px 11px;font-size:.86rem}
  .wiz-wrap .step.on .q .qlabel{margin-bottom:7px}
  .wiz-wrap .step.on .photo-btn{padding:9px 12px;font-size:.88rem}
}

/* Cleaning report inside the tenant shell. Phone is two columns; a wide
   window gets three, then four. The wrap grows only on that page. */
body.tp.tp-clean{overflow-x:hidden}
@media (min-width:1100px){
  .tp-wrap.tp-clean-wrap{max-width:960px}
}
.tp-clean-title{font:600 32px/1.12 var(--est-serif);color:var(--est-ink);margin:0;overflow-wrap:anywhere}
.tp-clean-when{margin:8px 0 0;color:var(--est-muted);font-size:14px}
.tp-clean-team{margin:4px 0 0;color:var(--est-faint);font-size:13px}
.tp-clean-scope{margin:14px 0 0;font-size:14px;color:var(--est-body)}
.tp-clean-list{list-style:none;margin:0;padding:0}
.tp-clean-list li{border-bottom:1px solid var(--est-row-line)}
.tp-clean-list li:last-child{border-bottom:0}
.tp-clean-list a{display:flex;justify-content:space-between;gap:12px;align-items:baseline;
  padding:12px 0;min-height:48px}
.tp-clean-list .what{font:600 14px var(--est-sans);color:var(--est-ink)}
.tp-clean-list .when{font-size:12.5px;color:var(--est-muted);text-align:right}
.tp-clean-maint{list-style:none;margin:0;padding:0}
.tp-clean-maint li{display:flex;justify-content:space-between;gap:10px;align-items:center;flex-wrap:wrap;
  padding:8px 0;border-bottom:1px solid var(--est-row-line);font-size:14px}
.tp-clean-maint li:last-child{border-bottom:0}
.tp-photos{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0 0 18px}
@media (min-width:720px){
  .tp-photos{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (min-width:1100px){
  .tp-photos{grid-template-columns:repeat(4,minmax(0,1fr))}
}
.tp-shot{display:block;width:100%;padding:0;border:0;background:var(--est-inset);
  border-radius:12px;overflow:hidden;cursor:pointer;min-height:48px}
.tp-shot img{display:block;width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;background:var(--est-inset)}
.tp-zoom{border:0;padding:0;margin:auto;background:transparent;max-width:100%;width:min(960px,100%)}
.tp-zoom::backdrop{background:rgba(28,70,53,.9)}
.tp-zoom img{display:block;width:100%;height:auto;max-height:78vh;object-fit:contain;background:#fff}
.tp-zoom-bar{display:flex;gap:8px;margin-top:8px;flex-wrap:wrap}
.tp-zoom-bar .tp-btn{flex:1}
.tp-stop{margin:22px 0 0;text-align:center;font-size:12px}
body.tp.tp-clean p.tp-stop a:not(.tp-btn):not(.tp-lang){color:var(--est-faint);font-size:12px;text-decoration:underline}
.tp-clean a.tp-tab{text-decoration:none;text-align:center}
.tp-clean .tp-tabbar{flex-wrap:wrap}
.tp-clean h2.tp-area{font:600 21px/1.2 var(--est-serif);color:var(--est-forest);margin:18px 0 8px}
.tp-back{margin:12px 0 0;font-size:13px}
.tp-clean .tp-card{margin-top:14px}
.tp-clean .tp-card h2{font:600 21px/1.2 var(--est-serif);margin:0 0 8px}
.tp-clean .tp-card ul{margin:0;padding-left:18px}
.tp-clean .tp-card ul.tp-clean-list,.tp-clean .tp-card ul.tp-clean-maint{list-style:none;padding:0}
.tp-clean .tp-card li{margin:4px 0;font-size:14px}
