/* ---------------------------------------------------------------- the tokens
   Every colour, space, corner, control height, type size and layer in the app is named here, and
   nothing below may invent its own (Steven, 2026-09-16; docs/ui-standards.md, docs/archive/ux-plan.md phase 3).

   The palette was written out twice before, once under prefers-color-scheme and once under
   [data-theme="dark"], and the two had to be kept in step by hand. Each colour now names both of its
   values on one line with light-dark(), and `color-scheme` below decides which one applies. The plain
   value in front of each pair is the fallback for a browser without light-dark(): it keeps the light
   palette rather than losing the colour.

   Silver and gold, after the two games the LLC is named for. The structure is silver: clear, light greys
   and a blue-leaning ink (brightened on 2026-09-30, Steven: the old slate read as gloomy). Gold is the
   accent and nothing else -- the primary button, the lane you are on, a signed approval -- so anything
   gold means "this is the live one". --accent is the gold for text and lines (dark enough to read on
   white); --accent-fill is the bright gold a button or a bar is filled with, under --accent-ink. Note that --warn is an amber
   close to the gold accent; they are told apart by where they appear (a warn is a chip inside a card,
   an accent is something you press) rather than by hue. */
:root{
  color-scheme:light dark;

  --ground:#F2F5F9;     --ground:light-dark(#F2F5F9,#151C26);
  --sheet:#FFFFFF;      --sheet:light-dark(#FFFFFF,#1E2632);
  --sheet-2:#F7F9FC;    --sheet-2:light-dark(#F7F9FC,#253041);
  --ink:#14202E;        --ink:light-dark(#14202E,#EEF2F7);
  --ink-2:#34465B;      --ink-2:light-dark(#34465B,#CAD4E0);
  --muted:#5F6F82;      --muted:light-dark(#5F6F82,#97A5B6);
  --line:#D8E0EA;       --line:light-dark(#D8E0EA,#334153);
  --line-2:#E8EDF3;     --line-2:light-dark(#E8EDF3,#2A3644);
  --accent:#9E6400;     --accent:light-dark(#9E6400,#F5C451);
  --accent-ink:#1C1404; --accent-ink:light-dark(#1C1404,#1A1405);
  --accent-soft:#FDF0D2;--accent-soft:light-dark(#FDF0D2,#433419);
  --accent-fill:#F2B33D; --accent-fill:light-dark(#F2B33D,#F5C451);
  --pass:#1E8449;       --pass:light-dark(#1E8449,#56C98A);
  --pass-soft:#DCF3E4;  --pass-soft:light-dark(#DCF3E4,#1D3A2B);
  --warn:#B4610F;       --warn:light-dark(#B4610F,#F0A44B);
  --warn-soft:#FCEBD6;  --warn-soft:light-dark(#FCEBD6,#42301A);
  --fail:#C0362C;       --fail:light-dark(#C0362C,#FF7B70);
  --fail-soft:#FCE4E1;  --fail-soft:light-dark(#FCE4E1,#48221F);
  --focus:#2563EB;      --focus:light-dark(#2563EB,#7BA6F2);

  /* light-dark() returns a colour, not a whole shadow, so the shadow is built from two of them. */
  --shadow-near:rgba(22,32,43,.06); --shadow-near:light-dark(rgba(22,32,43,.06),rgba(0,0,0,.45));
  --shadow-far:rgba(22,32,43,.10);  --shadow-far:light-dark(rgba(22,32,43,.10),rgba(0,0,0,.38));
  --shadow:0 1px 2px var(--shadow-near),0 8px 24px var(--shadow-far);

  /* Eight categorical hues for the rent bar, in a fixed order. A cost keeps its hue whatever else is on
     screen, so the colour means the cost and never its size. Both sets were checked against their own
     surface for colour-blind separation and contrast, rather than picked by eye. Three of the light hues
     sit under 3:1 on white; that is allowed because the ledger under the bar names and prices every
     segment, so nothing is carried by colour alone. */
  --s1:#2a78d6; --s1:light-dark(#2a78d6,#3987e5);
  --s2:#eb6834; --s2:light-dark(#eb6834,#d95926);
  --s3:#1baf7a; --s3:light-dark(#1baf7a,#199e70);
  --s4:#eda100; --s4:light-dark(#eda100,#c98500);
  --s5:#e87ba4; --s5:light-dark(#e87ba4,#d55181);
  --s6:#008300; --s6:light-dark(#008300,#008300);
  --s7:#4a3aa7; --s7:light-dark(#4a3aa7,#9085e9);
  --s8:#e34948; --s8:light-dark(#e34948,#e66767);

  /* Space. Six steps, 4 to 32. A gap or a padding takes one of these, never a number of its own. */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px; --sp-6:32px;

  /* Corners. Three, and 50% for a circle. Small is anything you type in or press; medium is anything
     that holds other things (a panel, a card, a dialog, a drawer); pill is a chip or a toggle. */
  --r-sm:6px; --r-md:10px; --r-pill:999px;

  /* Control heights, so a button, an input and a select on one row line up. */
  --h-btn:34px; --h-sm:28px;

  /* Type. The body is --fs-2; --fs-1 is a hint or a caption, --fs-3 a heading, --fs-4 a page title. */
  --fs-1:12.5px; --fs-2:14.5px; --fs-3:17px; --fs-4:22px;

  /* Layers, in the order they stack. The header sits above the scrim on purpose, so its buttons keep
     working while a drawer is open; the drawer sits above the header. A native <dialog> is in the
     browser's top layer and needs no number. */
  --z-hits:10; --z-scrim:20; --z-menu:30; --z-lanetabs:40; --z-header:50; --z-drawer:60; --z-toast:70;

  --display:"Bricolage Grotesque","Archivo","Helvetica Neue",Arial,sans-serif;
  --body:"Source Sans 3","Segoe UI",system-ui,sans-serif;
}
/* Site settings picks the theme; with no choice the browser's own setting decides. */
:root[data-theme="light"]{color-scheme:light}
:root[data-theme="dark"]{color-scheme:dark}
*{box-sizing:border-box}
html,body{height:100%}
/* Two families (Steven, 2026-10-21): --display for headings and names, --body for the rest, figures included, with
   tabular digits so columns of numbers line up. */
body{margin:0;background:var(--ground);color:var(--ink);font:14.5px/1.45 var(--body);font-variant-numeric:tabular-nums;-webkit-font-smoothing:antialiased}
h1,h2,h3{margin:0;font-family:var(--display);text-wrap:balance}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer}
a{color:var(--accent)}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.num{font-family:var(--body);font-variant-numeric:tabular-nums}
.label{font-size:11.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.hint{font-size:12.5px;color:var(--muted)}

/* The header sits above the drawer scrim so its buttons keep working while a drawer is
   open. Without this the scrim swallowed the first click on Run screen and merely closed
   the drawer, which read as a dead button. The drawers themselves stay above the header. */
/* The page hides things by setting the `hidden` property, and a dozen of those elements also
   carry a `display:` rule of their own -- the save bar, the banner, the drawers, the screen bar.
   An author `display:flex` outranks the browser's own [hidden]{display:none}, so those elements
   stayed painted no matter what the script said. The save bar sat on screen through three
   rounds of "fixes" while every check reported hidden:true, because the property was right and
   only the pixels were wrong. One rule, once, for all of them. */
[hidden]{display:none!important}
.top{display:flex;align-items:center;justify-content:space-between;gap:12px 16px;flex-wrap:wrap;padding:10px 18px;border-bottom:1px solid var(--line);background:var(--sheet);position:sticky;top:0;z-index:var(--z-header)}
.brand{display:flex;align-items:baseline;gap:12px;min-width:0}

/* Search. Filters the cards already on the board; it never fetches anything. */
.find{position:relative;display:flex;align-items:center;flex:1 1 210px;min-width:150px;max-width:400px}
.find input{width:100%;padding:6px 66px 6px 30px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);font-size:13.5px;-webkit-appearance:none;appearance:none}
.find input:focus{background:var(--sheet)}
.find input::placeholder{color:var(--muted)}
.find input::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
.find .mag{position:absolute;left:9px;width:14px;height:14px;color:var(--muted);pointer-events:none}
.find .n{position:absolute;right:30px;font-size:11.5px;color:var(--muted);font-family:var(--body);pointer-events:none;white-space:nowrap}
.find .x{position:absolute;right:6px;border:0;background:transparent;color:var(--muted);font-size:16px;line-height:1;padding:2px 5px;border-radius:var(--r-sm)}
.find .x:hover{color:var(--ink);background:var(--line-2)}
/* Filter just right of the search box on all three pages (Steven, 2026-09-15). */
.find>.fbeside{position:absolute;left:calc(100% + 8px);top:0;bottom:0;margin:0;box-sizing:border-box;padding:0 12px;
  background:var(--sheet-2);border:1px solid var(--line);border-radius:var(--r-sm);font-size:13.5px;font-weight:400;color:var(--ink-2);line-height:1}  /* looks like the search box beside it */
.find>.fbeside:hover{background:var(--sheet)}
@media (max-width:1439px){ .pagetitle>.find:has(>.fbeside){margin-right:96px} }
.brand h1{font-size:19px;font-weight:700;letter-spacing:-.01em;white-space:nowrap}
.brand .sub{color:var(--muted);font-size:13px;white-space:nowrap}
.top-right{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}
.sync{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted)}
.sync::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--warn)}
.sync.on::before{background:var(--pass)} .sync.off::before{background:var(--fail)} .sync.pub::before{background:var(--focus)}
/* The status shows only when something is wrong (Steven, 2026-09-14): "Partner view" and "Public view"
   are not shown. Connecting, Syncing and a server error still are. */
.sync.on,.sync.pub{display:none!important}
/* The house button goes home (Steven, 2026-09-14). The public view has no home to go to. */
body[data-mode="public"] #btn-home{display:none}
/* Application Inputs and Configure Site show only once the page has reached the service signed in
   (Steven, 2026-09-14): never on the public view, never for a visitor without the login. */
body:not(.signed-in) #btn-rules,body:not(.signed-in) #btn-site{display:none!important}
/* App navigation from nav.js (Steven, 2026-09-14): Home, Pipeline, Planning and Purchasing, the current page marked,
   and the Assistant link. Signed-in pages only. */
.appnav{text-decoration:none}
/* Home, Pipeline and Planning centered in the header on a wide screen (Steven, 2026-09-15). */
.appnavs{display:flex;gap:8px;align-items:center}
/* The links and the pipeline's search box share one center line and one width (Steven, 2026-09-15). */
@media (min-width:1440px){ .appnavs{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)}
  .pagetitle{position:relative} .pagetitle>.find{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:max(var(--appnavs-w,440px),520px);max-width:none;margin:0}
  }
@media (max-width:760px){ .appnavs{display:contents} }
/* The header System menu from nav.js: Inputs and Settings in one place on a wide screen. */
body.nav-settings #btn-rules,body.nav-settings #btn-site{display:none!important}
html:not(.signed-in) body:not(.signed-in) .setmenu{display:none!important}
.setmenu{position:relative}
#nav-settings .caret{margin-left:2px;opacity:.7}
.setpop{position:absolute;right:0;top:calc(100% + 6px);z-index:var(--z-menu);width:300px;background:var(--sheet);border:1px solid var(--line);border-radius:var(--r-md);box-shadow:0 12px 30px rgba(0,0,0,.18);padding:6px}
.setitem{display:flex;gap:12px;align-items:flex-start;width:100%;text-align:left;background:none;border:0;border-radius:var(--r-md);padding:10px;font:inherit;color:var(--ink);cursor:pointer}
.setitem:hover,.setitem:focus-visible{background:var(--sheet-2);outline:none}
.setitem .si{flex:none;width:32px;height:32px;border-radius:var(--r-md);display:grid;place-items:center;background:var(--accent-soft);color:var(--accent)}
.setitem .st b{display:block;font-size:14px;font-weight:600}
.setitem .st small{display:block;font-size:12.5px;color:var(--muted);line-height:1.35;margin-top:1px}
/* The partner menu (nav.js): the select stays for its change event but takes no pointer. */
.who-box.who-menu{cursor:pointer} .who-box.who-menu select{pointer-events:none}
.whopop{width:300px}   /* room for the Theme row's icon, word and switch */
.setitem.on{background:var(--sheet-2)}
.setitem .ck{flex:none;align-self:center;margin-left:auto;color:var(--accent)}
.setitem .si.av{font-weight:700;font-size:14px}
.setitem .si.out{background:var(--sheet-2);color:var(--muted)}
.setitem:has(.si.out){align-items:center}
.setsep{height:1px;background:var(--line);margin:4px 6px}
/* A group heading in a menu: System's Application and Admin (Steven, 2026-09-17). */
/* Header menus (Steven, 2026-09-28): Locations shows the current city; Settings and How it works are icons; the user is
   the initial of whoever is signed in. An open menu names itself. The phone menu keeps the words. */
.setttl{padding:8px 10px 4px;font-size:13.5px;font-weight:700;color:var(--ink)}
#nav-region-name{max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.who-init{display:none} .who-first{display:none}
/* The business beside the first name, when the user belongs to more than one (Steven, 2026-10-21). It shows with the name, on a wide screen only. */
/* The where-you-are bar under the header (Steven, 2026-10-21): business › location, each a menu that opens to the left. */
.ctxbar{position:relative;z-index:calc(var(--z-header) - 1);display:flex;align-items:center;gap:6px;flex-wrap:wrap;padding:6px 18px;border-bottom:1px solid var(--line);background:var(--sheet)}
.ctxbar .ctxbtn{display:inline-flex;align-items:center;gap:7px}   /* the same box as Configure and Help (Steven, 2026-10-21) */
.ctxbar .ctxbtn .caret{opacity:.7}
.ctxbar .ctxsep{color:var(--muted);font-size:17px;line-height:1;padding:0 2px}
.ctxbar .ctxpop{left:0;right:auto;width:290px}
.ctxpop .setitem.on{background:color-mix(in srgb,var(--accent) 12%,transparent)} .ctxpop .setitem.on .si{color:var(--accent)}
body.has-ctxbar .pagetitle .regtag{display:none}
.ctxbar [hidden]{display:none!important}
/* Business and location as data pills, the same shape as the Last screen tag, each with its caret (Steven, 2026-10-21). */
/* Only the icon is amber (Steven, 2026-10-23: no tinted fill); the button fill and the firmer border of the row's buttons
   keep them apart from the row. */
body .ctxbar.intitle .ctxbtn{border:1px solid color-mix(in srgb,var(--ink-2) 28%,var(--line));border-radius:var(--r-pill);background:var(--sheet);color:var(--ink);font-size:12.5px;font-weight:600;line-height:18px;padding:2px 9px;gap:6px}
body .ctxbar.intitle .ctxbtn svg:first-child{width:13px;height:13px;color:var(--accent)}
body .ctxbar.intitle .ctxbtn:hover,body .ctxbar.intitle .ctxbtn[aria-expanded="true"]{border-color:var(--accent);color:var(--ink)}
body .ctxbar.intitle{gap:var(--sp-2)} body .ctxbar.intitle .ctxsep{display:none}   /* the header's and the buttons' 8px (Steven, 2026-10-23) */
/* One control size in the title row (Steven, 2026-10-23: the New buttons looked bigger). The boxes were already equal; the
   outlined buttons' border nearly matched the row, so the filled one read larger. A firmer border shows their full size,
   and on a wide screen the search box and its Filter take the buttons' 28px instead of 34px. */
.pagetitle .btn:not(.primary){border-color:color-mix(in srgb,var(--ink-2) 28%,var(--line))}
.pagetitle .btn:not(.primary):hover{border-color:color-mix(in srgb,var(--ink-2) 45%,var(--line))}
@media (min-width:761px){ .pagetitle .find input{height:28px;box-sizing:border-box;padding-top:0;padding-bottom:0;border-color:color-mix(in srgb,var(--ink-2) 28%,var(--line))} }
/* The title row's buttons never wrap on a wide screen (Steven, 2026-10-21). */
@media (min-width:761px){ body.has-ctxbar .pagetitle .acts{flex-wrap:nowrap} }
/* In the title row: compact, borderless chips right after the page name, a thin divider between; their own line on a phone. */
.ctxbar.intitle{padding:0;border:0;background:none;gap:2px;flex-wrap:nowrap;flex:none;margin-right:auto} .pagetitle h2:has(+.ctxbar.intitle){margin-right:0}
.ctxbar.intitle::before{content:"";width:1px;height:22px;background:var(--line);margin:0 8px 0 2px}   /* 14px each side: the row gap (12px) + 2px before, 8px + the 6px gap after */
/* With business and location in the title row, the search box keeps the narrower-screen layout at every width: in the row, room for its Filter button, and wrapping when the row is full (Steven, 2026-10-21). */
@media (min-width:1440px){ body.has-ctxbar .pagetitle>.find{position:relative;left:auto;top:auto;transform:none;width:auto;max-width:400px;margin:0 auto} body.has-ctxbar .pagetitle>.find:has(>.fbeside){margin-right:96px} }
/* On a phone the page name, the pills and the buttons share one row (Steven, 2026-10-23; the pills had a row of their own):
   the name shows its app word (Track, Plan, Acquire), the business pill its icon, the location pill its name, which shortens
   with an ellipsis when the row is full. A search box in the row still takes the next line. */
@media (max-width:760px){
  .pagetitle:has(.ctxbar){flex-wrap:wrap;column-gap:6px}
  .pagetitle h2[data-short]{font-size:0} .pagetitle h2[data-short]::before{content:attr(data-short);font-size:18px}
  body .ctxbar.intitle{flex:1 1 0;min-width:0;margin:0;gap:4px} .ctxbar.intitle::before{display:none}   /* a zero basis: the pills shrink rather than wrap; 4px, the phone buttons' gap */
  body.signed-in .ctxbar.intitle .setmenu.ctxmenu{min-width:0}
  body .ctxbar.intitle .ctxbtn{max-width:100%;padding:4px 7px;gap:5px}
  .ctxbar.intitle #nav-biz [data-name],.ctxbar.intitle #nav-region>svg:first-child{display:none}
  body .ctxbar.intitle .ctxbtn{height:28px;box-sizing:border-box;vertical-align:top}   /* top, not baseline: the icon-only business pill has no text baseline and sat 0.6px high */ body .ctxbar.intitle #nav-biz{padding-left:6px;padding-right:6px} body .ctxbar.intitle #nav-biz svg:first-child{width:17px;height:17px}   /* alone in its pill, the 13px icon looked lost (Steven, 2026-10-23) */
  .ctxbar.intitle #nav-region [data-name]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* The menus span the screen under the pill; opened from the pill's left edge they ran off the right side. */
  body .ctxbar.intitle .setmenu.ctxmenu .setpop{position:fixed;left:12px;right:12px;top:auto;width:auto;margin-top:6px}
}
/* Instructions, Settings and the user's name show their words on a wide screen again (Steven, 2026-10-22; icons only 2026-10-21 to 10-22). */
html:not(.signed-in) body:not(.signed-in) .ctxbar{display:none}
@media (max-width:760px){ .ctxbar{padding:6px 12px} body.signed-in .ctxbar .setmenu.ctxmenu{display:inline-block!important;width:auto} .ctxbar .setmenu.ctxmenu .setpop{position:absolute;width:min(290px,calc(100vw - 24px));margin-top:0;box-shadow:0 12px 30px rgba(0,0,0,.18)} }
@media (min-width:761px){
  /* Home, Instructions and Settings show their words again (Steven, 2026-10-07; icons only since 2026-09-29). The user's
     name sizes the button itself (2026-10-13): the select is laid over it, so a late font cannot push the name out. */
  .who-box.iconly .who{position:absolute;inset:0;width:100%;height:100%;box-sizing:border-box;max-width:none;padding:0;color:transparent;text-indent:-999px}
  .who-box.iconly .who-first{display:block;position:relative;z-index:1;box-sizing:border-box;border:1px solid transparent;padding:5px 26px 5px 34px;line-height:16px;font-size:13.5px;font-weight:600;color:var(--ink);white-space:nowrap;pointer-events:none}
  .who-box.iconly .who-icon{display:none} .who-box.iconly .who-caret{right:7px}
  .who-box.iconly .who-init{position:absolute;left:6px;top:50%;transform:translateY(-50%);width:22px;height:22px;border-radius:50%;background:var(--accent-fill);color:var(--accent-ink);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;pointer-events:none}
}
.sethead{padding:6px 10px 2px;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.setitem.static{cursor:default} .setitem.static:hover{background:none}
/* Theme lines up with the name and Sign out (Steven, 2026-10-23): its own icon box, the word in their column and size. */
.themerow{display:flex;align-items:center;gap:12px;padding:8px 10px}
.themerow .si{flex:none;width:32px;height:32px;border-radius:var(--r-md);display:grid;place-items:center;background:var(--sheet-2);color:var(--muted)}
.themerow .tl{margin-right:auto;font-size:14px;font-weight:600;color:var(--ink)}
.themeseg button{padding:4px 10px;font-size:12.5px}
@media (max-width:760px){ .setmenu:has(.who-box){display:block!important;width:100%} body.menu-open .top-right .setmenu .who-box{display:flex;width:100%;box-sizing:border-box} .whopop{position:static;width:auto;margin-top:6px;box-shadow:none} }
/* On a phone the System menu opens in place, like the user menu (Steven, 2026-09-14). */
@media (max-width:760px){ body.signed-in .setmenu:not(:has(.who-box)){display:block!important;width:100%} .setmenu:not(:has(.who-box)) .setpop{position:static;width:auto;margin-top:6px;box-shadow:none} }
.appnav.on{border-color:var(--accent);color:var(--accent)}
html:not(.signed-in) body:not(.signed-in) .appnav:not(#btn-home){display:none!important}
#btn-home,#btn-home:hover,#btn-home:focus{text-decoration:none}
/* Partner is one dropdown: the label and two buttons took more of the header than the choice
   is worth. */
.who-box{position:relative;display:inline-flex;align-items:center}
.who-box .who-icon{position:absolute;left:10px;pointer-events:none;color:var(--ink)}
/* Drawn like the header buttons beside it: the same border, ground, weight and size. */
.who{-webkit-appearance:none;appearance:none;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet);color:var(--ink);padding:5px 26px 5px 30px;line-height:16px;font-size:13.5px;font-weight:600;font-family:var(--body);max-width:170px;cursor:pointer;field-sizing:content}
/* The browser's own arrow made it taller than the buttons; this small caret replaces it. */
.who-box .who-caret{position:absolute;right:9px;pointer-events:none;color:var(--muted)}
.who:hover{background:var(--sheet-2)}
.btn{border:1px solid var(--line);background:var(--sheet);border-radius:var(--r-sm);padding:6px 11px;font-size:13.5px;font-weight:600;color:var(--ink);white-space:nowrap}
.btn:hover{background:var(--sheet-2)} .btn:disabled{opacity:.5;cursor:default}
.btn.primary{background:var(--accent-fill);border-color:var(--accent-fill);color:var(--accent-ink)}
.btn.primary:hover{background:var(--accent-fill);filter:brightness(1.05)}
.btn.quiet{border-color:transparent;background:transparent;color:var(--muted)}
.btn.danger{color:var(--fail);border-color:var(--fail)}
/* The confirm button in a dialog is a filled primary. Left as gold with red text it read as a
   warning and an invitation at once; a destructive answer should look destructive. */
.btn.primary.danger{background:var(--fail);border-color:var(--fail);color:#fff}
.btn.primary.danger:hover{filter:brightness(1.08)}
.btn.sm{padding:3px 9px;font-size:12.5px}
/* ---------- banners and empty states (Steven, 2026-09-16; docs/ui-standards.md) ----------
   A banner is one state the whole page is in, and is not dismissible: it goes when the state goes.
   An empty box says why it is empty and offers the one thing that fills it, or says what is stopping
   that. StenWimUI.banner writes the banner; no page keeps a copy. */
.banner{background:var(--warn-soft);color:var(--warn);padding:var(--sp-2) var(--sp-4);font-size:13.5px;border-bottom:1px solid var(--line);display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.banner.bad{background:var(--fail-soft);color:var(--fail)}
.banner:not(.bad):not(.warn){background:var(--sheet-2);color:var(--ink-2)}
.empty-note,.tempty{padding:var(--sp-5) var(--sp-4);text-align:center;border:1px dashed var(--line);border-radius:var(--r-md);background:var(--sheet-2);color:var(--muted);font-size:13.5px}
.tempty h3{display:block;color:var(--ink);font-family:var(--display);font-size:var(--fs-3);margin-bottom:var(--sp-1)}
.tempty p{margin:0 0 var(--sp-4);color:var(--muted)}
.tempty .acts{display:flex;gap:var(--sp-3);justify-content:center;flex-wrap:wrap;align-items:center}

.run-full{display:none}   /* the short line is the desktop line too; the full one is the hover text (review U11) */
/* The screen takes minutes, so the bar reports where it actually is: the phase, the count
   inside that phase, and a width that only ever moves forward. A spinner would be a lie
   about a job whose length is known. */
.screenbar{padding:10px 18px;border-bottom:1px solid var(--line-2);background:var(--sheet-2);font-size:13px}
.screenbar .sb-head{display:flex;align-items:center;gap:10px;margin-bottom:7px}
.screenbar .sb-grow{flex:1}
.screenbar .sb-count,.screenbar .sb-note{color:var(--ink-2)}
.screenbar .sb-pct{font-variant-numeric:tabular-nums;font-weight:600}
.screenbar .sb-note{margin-top:6px;font-size:12.5px;min-height:1em}
.screenbar .x{border:0;background:transparent;color:var(--muted);font-size:16px;line-height:1;padding:2px 6px;border-radius:var(--r-sm);cursor:pointer}
.screenbar .x:hover{color:var(--ink);background:var(--line-2)}
.screenbar .sb-track{height:6px;border-radius:var(--r-pill);background:var(--line-2);overflow:hidden}
.screenbar .sb-fill{height:100%;width:0;border-radius:var(--r-pill);background:var(--accent-fill);transition:width .45s ease}
.screenbar[data-state="failed"] .sb-fill{background:var(--fail)}
.screenbar[data-state="done"] .sb-fill{background:var(--pass)}
/* The icon left of the status (Steven, 2026-09-16): the screen icon turning while it runs, a green check when done,
   a red cross when it failed. */
.screenbar .sb-ic{display:inline-flex;flex:none;color:var(--accent)}
.screenbar .sb-ic svg{display:none}
.screenbar .sb-ic .run{display:block;animation:sb-spin 1.2s linear infinite}
.screenbar[data-state="done"] .sb-ic .run,.screenbar[data-state="failed"] .sb-ic .run{display:none}
.screenbar[data-state="done"] .sb-ic .ok{display:block;color:var(--pass)}
.screenbar[data-state="failed"] .sb-ic .bad{display:block;color:var(--fail)}
@keyframes sb-spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){ .screenbar .sb-ic .run{animation:none} }
body[data-mode="public"] .screenbar{display:none}

/* board */
.board{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(280px,1fr);gap:16px;padding:16px 20px 40px;overflow-x:auto;min-height:calc(100vh - 150px);align-items:start}
.col{background:var(--sheet-2);border:1px solid var(--line-2);border-radius:var(--r-md);display:flex;flex-direction:column;max-height:calc(100vh - 180px)}
.col-h{display:flex;align-items:center;justify-content:space-between;padding:12px 14px 10px;gap:8px}
.col-h h2{font-size:14px;font-weight:700;letter-spacing:.01em}
.col-h .n{font-family:var(--body);font-size:12px;color:var(--muted)}
.col-h .lasttag{margin-left:auto;font-size:11.5px;padding:1px 8px}   /* Screened's last screen date, beside the count (2026-10-23) */
.col-body{overflow:auto;padding:0 10px 12px;display:flex;flex-direction:column;gap:10px}
.card{background:var(--sheet);border:1px solid var(--line);border-radius:var(--r-md);cursor:pointer;display:grid;border-left-width:4px;padding:12px 14px;gap:8px;grid-template-columns:minmax(0,1fr)}
.card:hover{box-shadow:var(--shadow)}
.card.on{outline:2px solid var(--accent);outline-offset:-1px}
.card.owned{border-left-color:var(--accent)} .card.pursue{border-left-color:var(--pass)} .card.watch{border-left-color:var(--warn)} .card.pass{border-left-color:var(--fail)} .card.none{border-left-color:var(--line)}
.card .a{display:flex;justify-content:space-between;align-items:center;gap:10px}
/* The star sits at the start of the address line. Unstarred it is a faint outline that does not
   compete with the address; starred it takes the accent, which is the same colour the board uses
   for "this is the live one" everywhere else. */
.card .star{flex:0 0 auto;border:0;background:none;padding:0 2px 0 0;line-height:1;cursor:pointer;
  font-size:15px;color:var(--line);align-self:center}
.card .star:hover{color:var(--muted)}
.card .star.on{color:var(--accent)}
/* The same star in the sheet header, sized to sit beside the address rather than a card title. */
.sheet-star{border:0;background:none;cursor:pointer;padding:0 8px 0 0;line-height:1;
  font-size:20px;color:var(--line);vertical-align:baseline}
.sheet-star:hover{color:var(--muted)}
.sheet-star.on{color:var(--accent)}
.card .a .addr{flex:1 1 auto;min-width:0}
#btn-filter,#btn-pickfilter,#btn-pfilter,#btn-dfilter{display:inline-flex;align-items:center;gap:5px}
#btn-filter .ficon,#btn-pickfilter .ficon,#btn-pfilter .ficon,#btn-dfilter .ficon{color:var(--muted);display:block}
#btn-filter.on,#btn-pickfilter.on,#btn-pfilter.on,#btn-dfilter.on{border-color:var(--accent);color:var(--accent)}
#btn-filter.on .ficon,#btn-pickfilter.on .ficon{color:var(--accent)}
#btn-filter .fcount:not(:empty),#btn-pickfilter .fcount:not(:empty),#btn-pfilter .fcount:not(:empty),#btn-dfilter .fcount:not(:empty){display:inline-block;min-width:16px;margin-left:2px;padding:0 4px;
  border-radius:var(--r-pill);background:var(--accent-fill);color:var(--accent-ink);font-size:11px;font-weight:700}
.seg.wrap{flex-wrap:wrap}
.card .addr{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card .price{font-family:var(--body);white-space:nowrap;flex:0 0 auto;font-size:14px;font-weight:600;color:var(--ink)}
.card .meta{font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:8px;min-width:0;margin:0}
.card .meta .lbl{text-transform:uppercase;letter-spacing:.04em;font-size:10px}
.card .nums{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding-top:9px;border-top:1px solid var(--line-2)}
.card .nums div{font-family:var(--body);font-variant-numeric:tabular-nums;font-size:15px;font-weight:600;line-height:1.15;min-width:0;text-align:center}
.card .nums small{display:block;font-family:var(--body);color:var(--muted);letter-spacing:.04em;text-transform:uppercase;margin-top:3px;font-size:9.5px;font-weight:500}
.card .chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{display:inline-flex;align-items:center;gap:4px;border-radius:var(--r-pill);padding:1px 8px;font-size:11.5px;font-weight:600;line-height:1.5;white-space:nowrap}
.chip.pass{background:var(--pass-soft);color:var(--pass)} .chip.warn{background:var(--warn-soft);color:var(--warn)} .chip.fail{background:var(--fail-soft);color:var(--fail)}
.chip.mute{background:var(--line-2);color:var(--muted)} .chip.accent{background:var(--accent-soft);color:var(--accent)}
.empty{padding:18px 12px;color:var(--muted);font-size:13px}
/* An empty lane shows a drop area rather than a line of text (Steven, 2026-09-14). */
/* Screened out in the last run, under the Screened cards (index.html passedList). */
.passed{margin-top:4px;border-top:1px dashed var(--line);padding-top:10px;display:flex;flex-direction:column;gap:6px}
.passed-h{display:flex;align-items:baseline;gap:8px;font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);padding:0 2px 2px}
.passed-h .n{font-family:var(--body);letter-spacing:0} .passed-h .hint{margin-left:auto;text-transform:none;letter-spacing:0;font-weight:400}
.prow-out{background:var(--sheet);border:1px solid var(--line);border-left:3px solid var(--fail);border-radius:var(--r-md);padding:8px 10px;display:grid;gap:3px;opacity:.92}
.prow-out .po-a{display:flex;justify-content:space-between;gap:8px;font-size:13.5px}
.prow-out .po-a a{color:var(--ink);text-decoration:none} .prow-out .po-a a:hover{color:var(--accent);text-decoration:underline}
.prow-out .po-p{font-family:var(--body);font-size:13px;white-space:nowrap}
.prow-out .po-m{font-size:12px;color:var(--muted)}
.prow-out .po-w{font-size:12px;color:var(--ink-2);line-height:1.35}
.prow-out .btn{justify-self:start;margin-top:3px}
.col-body>.empty{min-height:120px;display:grid;place-items:center;text-align:center;border:1.5px dashed var(--line);border-radius:var(--r-md)}
/* ---------- the board card, spacing ----------
   Four bands: the address and the facts; the condition and the chips; the three figures; where it
   stands. A hairline sits above the figures and above the progress row. The Property and Condition
   labels share one column width, so their values line up. Sizes follow the lane's own width through
   a container query, so a wide desktop lane, a narrow one and a phone each get a card that fits. */
.col-body{container-type:inline-size}
/* minmax(0,1fr): a grid column is as wide as its widest line by default, so a long address or a
   tour line pushed the price and the button out past the card's right edge in a narrow lane. */
.card .condbar{display:flex;align-items:center;gap:8px;min-width:0;margin:0}
.card .meta .txt{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.card .meta .lbl,.card .condbar .lbl{flex:0 0 64px;margin:0}
.card .condbar .val{margin-left:auto;white-space:nowrap}
.card .chips:empty{display:none}
.card .evalrow{padding-top:9px;border-top:1px solid var(--line-2)}
.card .evalrow .lbl{font-size:9.5px}
.card .cardact:not(:has(.btn)):has(.tour:empty){display:none}
@container (max-width:290px){
  .card{padding:10px 11px;gap:7px}
  .card .meta .lbl,.card .condbar .lbl{flex-basis:auto}
  .card .nums{gap:4px} .card .nums div{font-size:13.5px}
  .card .nums small{font-size:9px;letter-spacing:.02em}
  .card .evalrow .lbl{display:none}
}
@container (min-width:400px){
  .card{padding:14px 16px;gap:10px}
  .card .price{font-size:15px}
  .card .nums div{font-size:17px}
  .card .meta .lbl,.card .condbar .lbl{flex-basis:72px}
}

/* drawers */
.scrim{position:fixed;inset:0;background:rgba(0,0,0,.35);z-index:var(--z-scrim)}
.drawer{position:fixed;top:0;right:0;bottom:0;width:min(640px,100vw);background:var(--sheet);border-left:1px solid var(--line);z-index:var(--z-drawer);overflow:auto;box-shadow:var(--shadow);padding:18px 22px 60px}
/* .drawer.req used to be narrower than the property sheet; one width now (Steven, 2026-09-16). */
/* Screen now and its criteria: a centered panel, not a flyout (Steven, 2026-09-15). */
#reqdrawer.drawer{top:50%;left:50%;right:auto;bottom:auto;transform:translate(-50%,-50%);width:min(720px,94vw);max-height:88vh;border:1px solid var(--line);border-radius:var(--r-md)}
#reqdrawer .scr-acts{display:flex;align-items:center;gap:8px;margin:0 0 6px}
#reqdrawer .scr-acts .btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;box-sizing:border-box;padding:0 12px;line-height:1;font-size:13.5px}  /* one size for the three buttons */
#reqdrawer .critwrap{margin-top:12px;border-top:1px solid var(--line-2);padding-top:10px}
#reqdrawer .critwrap>summary{display:none}
#reqdrawer .critwrap[open]>summary{display:flex;align-items:baseline;gap:10px;font-weight:700;font-size:15px;list-style:none;pointer-events:none}
#reqdrawer .critwrap>summary::-webkit-details-marker{display:none}
#reqdrawer #req-crit.on{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
#reqdrawer .critwrap:not([open]){border-top:0;margin:0;padding:0}
#reqdrawer .critwrap>summary .hint{font-weight:400;font-size:12.5px}
.drawer-close{position:absolute;top:12px;right:14px}
.dh{margin-bottom:12px;padding-right:40px}
.dh h2{font-size:24px;font-weight:700;letter-spacing:-.015em;line-height:1.15}
.dh h2:has(.sheet-price){display:flex;align-items:baseline;gap:4px 12px;flex-wrap:wrap}
.dh h2 .sheet-price{margin-left:auto;font-family:var(--body);font-size:.8em;font-weight:600;white-space:nowrap}
.dh .where{color:var(--muted);margin-top:4px;font-size:13.5px;display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.dh a{text-decoration:none} .dh a:hover{text-decoration:underline}
.verdict{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:8px 0 14px;padding:10px 12px;border-radius:var(--r-md);background:var(--sheet-2);border:1px solid var(--line-2)}
.verdict .big{font-weight:700;font-size:20px}
.verdict.pursue .big{color:var(--pass)} .verdict.watch .big{color:var(--warn)} .verdict.pass .big{color:var(--fail)}
.verdict ul{margin:0;padding-left:18px;font-size:13px;color:var(--ink-2)}
.kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin-bottom:14px}
.kpi{padding:9px 10px;border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--sheet-2)}
.kpi .v{font-weight:700;font-size:21px;letter-spacing:-.01em;line-height:1.1;font-variant-numeric:tabular-nums}
.kpi .k{font-size:11.5px;color:var(--muted);margin-top:2px}
.kpi.hero{background:var(--ink);color:var(--ground);border-color:var(--ink)} .kpi.hero .k{color:var(--ground);opacity:.75}
/* ---------- one row shape on a property sheet (Steven, 2026-09-16) ----------
   Stage, Portfolio and Answers each had their own layout, stacked, which read as clutter. One shape:
   the name on the left, the control on the right, with a hairline between rows. */
.srow{display:grid;grid-template-columns:96px minmax(0,1fr);gap:var(--sp-3);align-items:center;padding:var(--sp-3) 0;border-top:1px solid var(--line-2)}
.srow>.label{margin:0;align-self:center}
.srow+.srow{border-top:1px solid var(--line-2)}
.sec{border-top:1px solid var(--line-2);padding-top:12px;margin-top:14px}
.sec h3{font-size:13.5px;font-weight:700;margin-bottom:8px;display:flex;justify-content:space-between;align-items:center;gap:8px}
.gates{list-style:none;margin:0;padding:0;display:grid;gap:5px}
.gate{display:grid;grid-template-columns:20px minmax(0,1fr) auto;gap:8px;align-items:center;font-size:13.5px}
.gate .dot{width:17px;height:17px;border-radius:50%;display:grid;place-items:center;font-size:10.5px;font-weight:700}
.gate.pass .dot{background:var(--pass-soft);color:var(--pass)} .gate.fail .dot{background:var(--fail-soft);color:var(--fail)}
.gate .why{color:var(--muted);font-size:12.5px;font-family:var(--body)}
/* One table style (Steven, 2026-10-21): every data table on the site takes its type, padding and lines from here.
   A table's own rule sets only alignment and widths. */
:root{--cell-y:6px;--cell-x:8px;--th-fs:11.5px;--td-fs:13px}
table.nums,table.ifr,table.rounds,table.rents,table.sugtbl,.loctbl,table.ledger{width:100%;border-collapse:collapse;font-size:var(--td-fs)}
table.nums th,table.ifr th,table.rounds th,table.rents th,table.sugtbl th,.loctbl th{font-size:var(--th-fs);font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);padding:var(--cell-y) var(--cell-x);border-bottom:1px solid var(--line);white-space:nowrap}
table.nums td,table.ifr td,table.rounds td,table.rents td,table.sugtbl td,.loctbl td{padding:var(--cell-y) var(--cell-x);border-top:0;border-bottom:1px dashed var(--line-2)}
table.ledger td{padding:var(--cell-y) 0;border-bottom:1px dashed var(--line-2)}
table.nums small,table.ifr small,table.rounds small,table.rents small,table.sugtbl small,.loctbl small{display:block;color:var(--muted);font-size:11.5px;font-weight:400;white-space:normal;margin:0}
table.nums th{text-align:left}
table.nums td{vertical-align:middle}
table.nums td.est{font-family:var(--body);font-variant-numeric:tabular-nums;color:var(--ink-2);white-space:nowrap}

table.nums input[type=number]{width:96px;padding:4px 6px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);font-family:var(--body);font-size:12.5px;text-align:right}
table.nums input[type=number]:placeholder-shown{border-style:dashed}
.src{display:inline-block;font-size:10.5px;padding:0 5px;border-radius:var(--r-sm);background:var(--line-2);color:var(--muted);margin-left:4px;vertical-align:middle;font-family:var(--body)}
.src.listing,.src.redfin,.src.photos,.src.county{background:var(--pass-soft);color:var(--pass)} .src.estimate,.src.assumption{background:var(--warn-soft);color:var(--warn)} .src.override,.src.manual{background:var(--accent-soft);color:var(--accent)} .src.evaluated{background:var(--pass-soft);color:var(--pass)}
/* ---------- where the rent goes ----------
   A stacked bar, not a ring: nine costs with long names do not read as slices, and several of
   them sit within a few dollars of each other, which is exactly what a ring cannot show. The
   track is the gross rent, the fills are the costs in a fixed order, and what is left unfilled
   at the end is the cash flow -- so the picture answers "how much of the rent do we keep?"
   without needing a number read off it. */
.sbar{display:flex;gap:2px;height:16px;border-radius:var(--r-sm);overflow:hidden;background:var(--line-2);margin:2px 0 6px}
.sbar span{display:block;min-width:2px}
.sbar .rest{background:transparent}
.sbar .over{background:repeating-linear-gradient(45deg,var(--fail),var(--fail) 3px,transparent 3px,transparent 6px)}
.scap{display:flex;justify-content:space-between;gap:8px;font-size:12px;color:var(--muted);margin-bottom:10px}
.scap b{font-family:var(--body);color:var(--ink)}
.scap b.pass{color:var(--pass)} .scap b.fail{color:var(--fail)}
/* The dot in the ledger is what ties a row to its band in the bar. */
.ledger .dot{display:inline-block;width:8px;height:8px;border-radius:var(--r-sm);margin-right:6px;vertical-align:baseline}
.s1{background:var(--s1)} .s2{background:var(--s2)} .s3{background:var(--s3)} .s4{background:var(--s4)}
.s5{background:var(--s5)} .s6{background:var(--s6)} .s7{background:var(--s7)} .s8{background:var(--s8)}

.ledger td+td{text-align:right;font-family:var(--body);font-variant-numeric:tabular-nums}
.ledger tr.total td{border-bottom:0;font-weight:600} .ledger tr.sub td:first-child{padding-left:14px;color:var(--ink-2)}
.two{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.flags{list-style:none;margin:0;padding:0;display:grid;gap:5px}
.flag{display:grid;grid-template-columns:auto minmax(0,1fr);gap:8px;align-items:start;font-size:13px}
.flag .sev{font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;padding:1px 6px;border-radius:var(--r-sm);margin-top:2px}
.flag.hard .sev{background:var(--fail);color:#fff} .flag.high .sev{background:var(--fail-soft);color:var(--fail)} .flag.med .sev{background:var(--warn-soft);color:var(--warn)} .flag.low .sev{background:var(--line-2);color:var(--muted)}
.flag.up .sev{background:var(--pass-soft);color:var(--pass)}
.facts{display:grid;grid-template-columns:repeat(4,1fr);gap:6px 10px;font-size:13px}
.facts div small{display:block;color:var(--muted);font-size:11px;letter-spacing:.04em;text-transform:uppercase}
.remarks{font-size:13px;color:var(--ink-2);line-height:1.45;margin-top:8px;max-height:140px;overflow:auto;padding:8px 10px;background:var(--sheet-2);border-radius:var(--r-sm);border:1px solid var(--line-2)}
textarea{width:100%;min-height:70px;padding:8px 10px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);resize:vertical;line-height:1.4}
.field{display:grid;grid-template-columns:minmax(0,1fr) 150px;align-items:center;gap:10px;padding:4px 0;border-bottom:1px dashed var(--line-2)}
.field:last-child{border-bottom:0} .field label{font-size:13.5px} .field small{display:block;color:var(--muted);font-size:12px}
.field select{width:100%}
.field input{width:100%;padding:5px 8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);font-family:var(--body);font-size:13px;text-align:right}
.field select,.field input[type=date],.field input[type=text]{font-family:var(--body);text-align:left}
.field input[type=checkbox]{width:17px;height:17px;justify-self:end}
.seg{display:inline-flex;border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.seg button{border:0;background:transparent;padding:3px 9px;font-size:12.5px;color:var(--muted);white-space:nowrap} .seg button+button{border-left:1px solid var(--line)}
/* A selected segment had no style of its own: only the yes/no/unknown variants below were ever
   given one, so choosing a property type or a verdict in the filter looked like nothing had
   happened. Those three are more specific and still win where they apply. */
.seg button.on{background:var(--accent-soft);color:var(--accent);font-weight:600}
.seg button:hover:not(.on){background:var(--line-2);color:var(--ink-2)}
.seg button.on.yes{background:var(--pass-soft);color:var(--pass)} .seg button.on.no{background:var(--fail-soft);color:var(--fail)} .seg button.on.na{background:var(--line-2);color:var(--ink)}

/* The property types are a set, not a choice of one, so they are separate pills rather than a
   joined-up control -- a segmented control reads as "pick one". A tick says it is on and says
   plainly that pressing it again takes it off. */
/* Some controls do not belong in the 150px column a field normally gives them: a set of type
   pills stacks one per line in it, and the Tenants and Verdict segments get their last option
   clipped. `.field.wide` puts the label on its own line and hands the control the full width. */
.field.wide{grid-template-columns:1fr;gap:6px}
.field.wide>label{margin-bottom:2px}
/* A grid cell stretches its child by default, which left the segment's border running on
   past its last option to the edge of the panel. Let it be as wide as its buttons. */
.field.wide .seg{justify-self:start}
/* In a normal field row the control column is 150px wide, and a two- or three-option segment left
   its buttons huddled at one end of it. They share the width evenly instead. */
.field>.seg button{flex:1 1 0;text-align:center}
figure.hero{margin:0 0 12px;border:1px solid var(--line-2);border-radius:var(--r-md);overflow:hidden;background:var(--sheet-2)}
figure.hero img{display:block;width:100%;height:auto;max-height:320px;object-fit:cover}
figure.hero figcaption{padding:6px 10px;font-size:12px;color:var(--muted);border-top:1px solid var(--line-2)}
figure.hero a{color:var(--accent);text-decoration:none} figure.hero a:hover{text-decoration:underline}
.cond{display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:start}
.condscore{width:52px;height:52px;border-radius:var(--r-md);display:grid;place-content:center;text-align:center;line-height:1}
.condscore b{font-size:22px;font-weight:700}
.condscore small{font-size:10px;opacity:.8}
.condscore.good{background:var(--pass-soft);color:var(--pass)} .condscore.ok{background:var(--warn-soft);color:var(--warn)}
.condscore.bad{background:var(--fail-soft);color:var(--fail)} .condscore.none{background:var(--line-2);color:var(--muted)}
.condlabel{font-weight:600;font-size:13.5px;margin-bottom:3px}
.condsum{margin:0;font-size:13px;line-height:1.5;color:var(--ink-2)}
.actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px}
.dsec{margin-top:16px;padding-top:12px;border-top:1px solid var(--line-2)} .dsec h3{font-size:13.5px;margin-bottom:8px}
.rankby{list-style:none;margin:0;padding:0;display:grid;gap:4px}
.rankby li{display:flex;align-items:center;gap:8px;padding:4px 6px 4px 8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet);cursor:grab}
.rankby li.dragging{opacity:.5}
.rankby .grip{color:var(--muted)}
.rankby .rk-l{flex:1 1 auto;font-size:13.5px}
.rankby .rk-w{color:var(--muted);font-size:12px;font-variant-numeric:tabular-nums;min-width:3.5ch;text-align:right}
.rankby .btn{padding:1px 7px}
.rankby.off{opacity:.55}
.rankby.off li{cursor:default}
.rankby.off .btn{visibility:hidden}
.fmr{display:grid;grid-template-columns:repeat(5,1fr);gap:6px}
.fmrlabel{font-size:12.5px;color:var(--ink-2);font-weight:600;margin:8px 0 4px}
.fmrlabel .hint{font-weight:400;margin-left:4px}
.fmr label{font-size:11px;color:var(--muted);display:block} .fmr input{width:100%;padding:5px 8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);font-family:var(--body);font-size:13px;text-align:left}
.toggle{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted);cursor:pointer}

dialog{border:1px solid var(--line);border-radius:var(--r-md);background:var(--sheet);color:var(--ink);padding:0;width:min(480px,94vw);box-shadow:var(--shadow)}
dialog::backdrop{background:rgba(0,0,0,.35)} dialog form{padding:18px 20px} dialog h2{font-size:19px;margin-bottom:12px}
dialog form{position:relative} dialog h2{padding-right:40px}
.dlg-x{position:absolute;top:12px;right:14px;padding:3px 9px;line-height:1.2}
/* ---------- form fields (Steven, 2026-09-16; docs/ui-standards.md) ----------
   Two shapes, and only two. A settings row puts the label on the left (.field). A form row, which is what
   a dialog holds, puts it above (.field.wide, and .dlg-field, which is the same thing under an older name
   still in the markup). Every control in either is the same height and the same corner, so a row of them
   lines up. Numbers are mono and right-aligned wherever they appear. */
.dlg-field,.frow{display:grid;gap:var(--sp-1);margin-bottom:var(--sp-3)}
.dlg-field>.label,.frow label{font-size:11.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.dlg-field select,.frow select{width:100%}
.dlg-field input,.dlg-field textarea,.frow input,.frow textarea{
  width:100%;box-sizing:border-box;min-height:var(--h-btn);padding:7px 9px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2)}
.dlg-row{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3)} .dlg-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:14px}
/* The evaluate sheet asks only what is unknown, so it is short on a well-filled property and long
   on a bare one. Give it room and let it scroll rather than sizing it to the worst case. */
/* The Evaluate popup uses the Inputs drawer's rows (Steven, 2026-09-16): .dsec sections and .field rows, with the
   Accept button and the answered tick in a .withaccept box beside the field. */
#eval-dialog{width:min(640px,94vw)}
/* The first listing photo, top right under the price (Steven, 2026-09-29). It floats beside the header lines and the
   button row, and the Portfolio section clears it, so the photo never crosses the rule under the header. On a phone it
   sits under the title, the full width. */
#eval-dialog .evphoto{float:right;width:168px;height:106px;margin:2px 0 10px 16px;border-radius:var(--r-md);overflow:hidden;border:1px solid var(--line);background:var(--sheet-2)}
#eval-dialog .evphoto img{width:100%;height:100%;object-fit:cover;display:block}
#eval-dialog #eval-pf{clear:right}
@media (max-width:600px){ #eval-dialog .evphoto{float:none;display:block;width:100%;height:160px;margin:8px 0} }
#eval-body{max-height:min(62vh,560px);overflow:auto;padding-right:2px}
#eval-body .dsec:first-child{margin-top:0;padding-top:0;border-top:0}
#eval-body .dsec h3{font-size:14px}
.field.hasacc{grid-template-columns:minmax(0,1fr) 232px}
.withaccept{display:flex;gap:6px;align-items:center;min-width:0}
/* The review layout (inputform.js, Property facts; Steven, 2026-10-21): Fact | Recommended values | Applied values | Apply. */

.ifr-cols{display:grid;grid-template-columns:1fr 1fr;gap:0 32px;align-items:start}
@media (max-width:1200px){.ifr-cols{grid-template-columns:1fr}.ifr-cols>.ifr+.ifr thead{display:none}}
.ifr th{text-align:left}
.ifr th.r{text-align:right}
.ifr td{vertical-align:middle}
.ifr tr.ifr-sec td{border-bottom:0;padding-top:16px;font:700 13px var(--display);color:var(--ink)}
.ifr .ifr-f label{display:block;color:var(--ink)}

.ifr .ifr-rec{text-align:right;white-space:nowrap;color:var(--ink-2)}
.ifr .ifr-rec.none{color:var(--muted)}
.ifr .ifr-app{width:170px}
.ifr .ifr-app[colspan]{width:auto}
.ifr .ifr-in{display:flex;gap:6px;align-items:center}
.ifr .ifr-in input,.ifr .ifr-in select{flex:1 1 auto;min-width:0;width:100%;padding:5px 8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);text-align:right}
.ifr .ifr-in select,.ifr .ifr-app[colspan] input{text-align:left}
.ifr .ifr-in .unit{color:var(--muted);font-size:12px;white-space:nowrap}
.ifr .ifr-act{width:76px}
.ifr .ifr-act .btn{color:var(--accent);font-weight:600}
@media (max-width:640px){.ifr .ifr-f small{display:none}.ifr .ifr-app{width:120px}.ifr .ifr-act{width:auto}}
.withaccept input,.withaccept select{flex:1 1 auto;min-width:0}
.withaccept .btn{flex:0 0 auto;padding:4px 10px;font-size:12px}
.withaccept .ok{flex:0 0 auto;color:var(--pass);font-size:15px;line-height:1;align-self:center;padding:0 6px}
/* The input editor (inputform.js, v3.0): where a value comes from, its unit, and the ✕ that goes back to the inherited
   value. A typed override reads in the accent colour; an inherited one is muted. */
.srcchip{display:inline-block;margin-left:6px;padding:0 6px;border-radius:var(--r-pill);background:var(--line-2);color:var(--muted);font-size:11px;font-weight:600;vertical-align:middle;white-space:nowrap}
.srcchip.typed{background:var(--accent-soft);color:var(--accent)}
.withaccept .unit{flex:0 0 auto;color:var(--muted);font-size:12px;white-space:nowrap}
.withaccept .ovr-clear{padding:2px 7px;line-height:1.1}
/* A multi-choice input as a column of checkboxes (inputform.js), right-aligned like a switch. */
.ckmulti{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex:1 1 auto}
.ckmulti label{display:inline-flex;align-items:center;gap:8px;font-size:13px;cursor:pointer}
.ckmulti input[type=checkbox]{width:17px;height:17px;margin:0}
.withaccept textarea{flex:1 1 auto;min-width:0;padding:5px 8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);font-family:var(--body);font-size:13px;resize:vertical}
.field.ovr input::placeholder{color:var(--muted);opacity:1}
details.ifgroup>summary{display:flex;align-items:baseline;gap:10px;cursor:pointer;list-style:none}
details.ifgroup>summary::-webkit-details-marker{display:none}
details.ifgroup>summary h3{margin:0}
details.ifgroup>summary::before{content:"▸";color:var(--muted);font-size:11px}
details.ifgroup[open]>summary::before{content:"▾"}
details.ifgroup[open]>summary{margin-bottom:8px}
/* A grid of small captioned boxes (inputform.js): the bedroom rents on a location's page. */
.ifgrid .gridrow{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px}
.ifgrid .gcell{display:flex;flex-direction:column;gap:2px;min-width:0}
.ifgrid .gcell>span{font-size:11.5px;color:var(--muted)}
.ifgrid .gcell input{width:100%;padding:5px 6px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);font-family:var(--body);font-size:13px;text-align:right}
.ifgrid .gcell.missing input{border-color:var(--fail);box-shadow:0 0 0 2px color-mix(in srgb,var(--fail) 22%,transparent)}
.ifgrid .gcell.missing .reqmark{color:var(--fail)}
.ifgrid .gridacc{display:flex;justify-content:flex-end;margin-top:6px}
/* The editor's grid layout (inputform.js layout:"grid"; Steven, 2026-10-21): label above a small box, four to a row,
   light section headings; grey is inherited, gold is this plan's own. */
.ifg-sec{border-top:1px solid var(--line-2);padding-top:10px;margin-top:12px}
.ifg-sec:first-child{border-top:0;padding-top:0;margin-top:0}
.ifg-h{font-size:12px;font-weight:700;color:var(--ink-2);text-transform:uppercase;letter-spacing:.04em}
.ifg-sec>.ifg-h{margin-bottom:8px}
details.ifg-sec>summary{display:flex;align-items:baseline;gap:10px;cursor:pointer;list-style:none}
details.ifg-sec>summary::-webkit-details-marker{display:none}
details.ifg-sec>summary::before{content:"▸";color:var(--muted);font-size:11px}
details.ifg-sec[open]>summary::before{content:"▾"}
details.ifg-sec[open]>summary{margin-bottom:8px}
.ifg-grid{display:grid;grid-template-columns:repeat(var(--ifg-cols,4),minmax(0,1fr));gap:12px 16px}
.ifg-cell{min-width:0}
.ifg-cell>label{display:block;font-size:12px;color:var(--muted);margin-bottom:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ifg-in{position:relative}
.ifg-in input,.ifg-in select,.ifg-in textarea{width:100%;box-sizing:border-box;padding:6px 8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);color:var(--ink);font-size:13px}
.ifg-in input[type=number]{font-family:var(--body);text-align:right}
.ifg-in textarea{font-family:var(--body);resize:vertical;min-height:54px}
.ifg-in input::placeholder,.ifg-in textarea::placeholder{color:var(--muted);opacity:1}
.ifg-cell.typed .ifg-in input{border-color:var(--accent);background:var(--accent-soft);padding-right:24px}
.ifg-cell.missing .ifg-in input{border-color:var(--fail)}
.ifg-cell.missing .reqmark{color:var(--fail)}
.ifg-x{position:absolute;right:6px;top:50%;transform:translateY(-50%);border:0;background:transparent;color:var(--accent);font-weight:700;cursor:pointer;padding:0 2px}
.ifg-seg{display:flex;border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.ifg-seg button{flex:1 1 0;border:0;border-left:1px solid var(--line);background:var(--sheet-2);padding:6px 4px;font-size:12.5px;color:var(--muted);cursor:pointer}
.ifg-seg button:first-child{border-left:0}
.ifg-seg button.inh{color:var(--ink);font-weight:600;box-shadow:inset 0 -2px 0 var(--muted)}
.ifg-seg button.on{background:var(--accent-soft);color:var(--accent);font-weight:700;box-shadow:inset 0 -2px 0 var(--accent)}
.ifg-legend{display:inline-flex;gap:14px;font-size:12px;color:var(--muted);align-items:center}
.ifg-legend i{display:inline-block;width:12px;height:12px;border-radius:3px;border:1px solid var(--line);background:var(--sheet-2);vertical-align:-2px;margin-right:4px}
.ifg-legend i.t{border-color:var(--accent);background:var(--accent-soft)}
@media (max-width:760px){ .ifg-grid{grid-template-columns:repeat(2,minmax(0,1fr))} .ifg-cell[style*="span"]{grid-column:1/-1 !important} }
/* The property facts on a phone: the label above its box, as the old Evaluate popup had it. */
#sheet-facts .dsec:first-child{margin-top:0;padding-top:0;border-top:0}
@media (max-width:600px){ #sheet-facts .field.hasacc{grid-template-columns:1fr} }
/* A required input carries a star: red while it is empty, grey once it holds a figure (Steven,
   2026-09-16). The words of a field are never recoloured; only the star and the box's outline say it. */
.reqmark{color:var(--muted);font-weight:700;margin-left:3px}
.field.missing>label .reqmark,.fmr>div.missing>label .reqmark{color:var(--fail)}
.withaccept input::placeholder{color:var(--muted);opacity:1}
.withaccept select.proposed{color:var(--muted)}
.drawer .fmr>div .withaccept .btn{padding:3px 6px;font-size:11px}
/* A figure the screen worked out sits in the placeholder, which the browser draws in the muted
   ink already. Accept writes it into the field, where it turns the colour of something somebody
   decided, and the button gives way to a tick so the row says it has been dealt with. */

#eval-body select{width:100%}
#eval-body textarea{padding:7px 9px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);width:100%;font:inherit;color:inherit}
/* The evaluate row sits above the address, because it is the thing to press rather than something
   to read, and the bar beside it says how much of the property is still guesswork. */
.evalrow{display:flex;align-items:center;gap:7px}
.evalrow .lbl{font-size:10px;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);flex:0 0 auto}
.evalbar{flex:1 1 auto;height:5px;border-radius:var(--r-pill);background:var(--line-2);overflow:hidden}
.evalbar i{display:block;height:100%;background:var(--accent-fill);border-radius:var(--r-pill)}
.evalbar.full i{background:var(--pass)}
.evalrow .n{font-family:var(--body);font-size:11px;color:var(--muted);flex:0 0 auto}
.evalrow.sheet-eval{margin:0} .evalrow.sheet-eval .evalbar{height:6px}
/* The flyout's next step gets a row of its own under the progress bar. Beside the stage buttons it
   jumped to a new line whenever they wrapped on a narrow window. */
.sheet-acts{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin:0 0 var(--sp-4)}
@media (max-width:760px){ .sheet-acts .btn{flex:1 1 auto;justify-content:center;padding:9px 12px;font-size:13.5px} }
/* The action sits at the foot of the card, out of the way of reading it. Full width and a proper
   tap target on a phone, where the row is the only thing a thumb can aim at. */
.cardact{display:flex;justify-content:space-between;align-items:center;gap:8px}
.cardact .cardbtns{display:flex;gap:6px;flex:0 0 auto;margin-left:auto}
.cardact .tour{font-size:12px;color:var(--muted);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The foot line is a .meta row like Property and Condition (Steven, 2026-10-21): the same label and value type. */
.card .cardact .tour.meta{flex:1 1 auto}
.cardact .btn{padding:3px 10px;font-size:12px}
/* Gold is what this page uses for the thing to press. The evaluate button is the only action on a
   card, so it gets the colour without taking the weight of a filled primary button. */
.btn.gold{border-color:var(--accent);color:var(--accent);background:transparent}
.btn.gold:hover{background:var(--accent-soft)}
/* On a phone the button takes the whole row and the tour or offer line sits above it, instead of
   being squeezed to nothing beside a full-width button. */
@media (max-width:760px){ .card .cardact{flex-wrap:wrap;row-gap:8px} .card .cardact .tour{flex:1 1 100%}
  .card .cardact .tour:empty{display:none}
  .card .cardact .btn{width:100%;justify-content:center;padding:9px 12px;font-size:13.5px} }
#toast{position:fixed;left:50%;bottom:22px;transform:translateX(-50%);background:var(--ink);color:var(--ground);padding:8px 14px;border-radius:var(--r-md);font-size:13.5px;box-shadow:var(--shadow);z-index:var(--z-toast);opacity:0;pointer-events:none;transition:opacity .2s}
#toast.show{opacity:1;pointer-events:auto}
/* A toast that names another page carries a link, so no message is a dead end (Steven, 2026-09-16). */
#toast a{color:var(--ground);text-decoration:underline;font-weight:600}

/* ---------- the lifecycle stepper (Steven, 2026-09-16; docs/archive/ux-plan.md phase 2) ----------
   One property, one path, drawn the same on a board card, a property sheet and an offer. StenWimUI.stepper
   writes it; no page may draw a progress bar of its own. */
.lsteps{display:flex;gap:4px}
.lsteps span{flex:1;height:6px;border-radius:var(--r-sm);background:var(--line-2)}
.lsteps span.done{background:var(--pass)}
.lsteps span.cur{background:var(--warn)}
/* Where a property was declined (Steven, 2026-09-16): that step is red, the rest of the run is empty. */
.lsteps span.bad{background:var(--fail)}
.lsteps.declined span{opacity:.55}
.lsteplbl{font-size:12px;color:var(--muted);margin-top:5px}
.lsteplbl b{color:var(--ink);font-weight:600}
.lsteplbl b.bad{color:var(--fail)}

/* Each step's name under its own bar, so it is obvious which bar is which (Steven, 2026-09-16). A board
   card keeps the bars alone and names only the step it is on. */
.lsteps.named{display:grid;grid-template-columns:repeat(var(--n,5),minmax(0,1fr));gap:var(--sp-2) var(--sp-3);align-items:start}
.lstep{display:flex;flex-direction:column;gap:var(--sp-2);min-width:0}
/* A named step is as tall as its bar and name; `.lsteps span` fixed it at the bar's 6px, so the names hung below the row
   and crowded whatever came next (Steven, 2026-09-29). */
.lsteps.named span.lstep{height:auto;background:none;border-radius:0}
.lstep i{height:6px;border-radius:3px;background:var(--line-2)}
.lstep.done i{background:var(--pass)}
.lstep.cur i{background:var(--warn)}
.lstep.bad i{background:var(--fail)}
.lstep b{font-size:11.5px;font-weight:500;color:var(--muted);line-height:1.3;overflow-wrap:anywhere}
.lstep.cur b{color:var(--ink);font-weight:600}
.lstep.bad b{color:var(--fail);font-weight:600}
.lsteps.named+.lsteplbl{margin-top:8px}

/* A section you jumped to says so for a moment (Steven, 2026-09-16). */
@keyframes stenwim-flash{0%{box-shadow:0 0 0 3px var(--accent-soft)}100%{box-shadow:0 0 0 0 transparent}}
.flash{animation:stenwim-flash 1.2s ease-out}

/* The next step under a result in the planner (Steven, 2026-09-16). */
.resnext{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap;margin:0 0 var(--sp-4);padding:var(--sp-3) var(--sp-4);border:1px solid var(--line);border-radius:var(--r-md);background:var(--sheet-2)}
.resnext .hint{color:var(--muted);font-size:13px}
.resnext .hint b{color:var(--ink)}
/* The lifecycle above a property sheet's buttons. */
.lifehead{margin:var(--sp-3) 0 var(--sp-5)}
.srow:first-of-type{border-top:1px solid var(--line-2)}

/* ---------- Next up, the home page queue (Steven, 2026-09-16) ---------- */
.nextup{margin:var(--sp-4) 0}
/* A fixed button column (Steven, 2026-09-17): with auto, each row sized its own and the middle text drifted. */
.nurow{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) 150px;gap:16px;align-items:center;padding:9px 10px;border-radius:var(--r-md);color:inherit;text-decoration:none;border:1px solid transparent}
.nurow+.nurow{margin-top:2px}
.nurow:hover{background:var(--sheet-2);border-color:var(--line)}
.nuaddr{font-weight:600;display:flex;align-items:center;gap:8px;min-width:0}
.nuaddr .chip{font-weight:500}
.nuwhat{color:var(--muted);font-size:13px;min-width:0}
.nugo{white-space:nowrap;justify-self:end}
/* On a phone (Steven, 2026-09-17): the address and its note on the left, the button on the right, the address kept
   to two lines, so each row is about half as tall as the stacked layout. */
@media (max-width:760px){
  .nurow{grid-template-columns:minmax(0,1fr) auto;column-gap:10px;row-gap:1px;padding:8px 4px}
  .nurow+.nurow{margin-top:0;border-top:1px solid var(--line-2);border-radius:0}
  .nuaddr{grid-column:1;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;font-size:14px;line-height:1.3}
  .nuwhat{grid-column:1;font-size:12.5px}
  .nugo{grid-column:2;grid-row:1/span 2;align-self:center;justify-self:end;padding:6px 10px;font-size:12.5px}
}

@media (max-width:900px){ .find{order:3;flex-basis:100%;max-width:none} .board{grid-auto-columns:minmax(260px,85vw)} .kpis{grid-template-columns:repeat(2,1fr)} .two{grid-template-columns:1fr} .facts{grid-template-columns:repeat(2,1fr)} .brand .sub{display:none} }

/* ---------- lane tabs, phones only ----------
   Five columns side by side works with a mouse and a wide window, and not at all in a
   hand. Below the width set further down, the columns become one lane at a time, chosen
   here. The strip sticks to the top of the screen and the header scrolls away with the
   content, so switching lanes never needs a scroll back up. */
.lanetabs{display:none;gap:10px;overflow-x:auto;padding:8px 12px;border-bottom:1px solid var(--line-2);background:var(--sheet);-webkit-overflow-scrolling:touch}
/* The lane tabs as bars with the name below, like STATUS (Steven, 2026-09-29): the lane on show amber, the rest grey. */
.lanetabs button{flex:1 0 84px;display:block;border:0;background:none;border-radius:0;padding:2px 0;font:inherit;font-size:12px;font-weight:500;color:var(--muted);text-align:left;cursor:pointer}
.lanetabs button::before{content:"";display:block;margin-bottom:6px;height:6px;border-radius:3px;background:var(--line-2)}
.lanetabs button.on::before{background:var(--warn)}
.lanetabs button.on{color:var(--ink);font-weight:600}

.lanetabs button .n{font-family:var(--body);font-size:11.5px;opacity:.7;margin-left:5px}

/* ---------- public view ----------
   One page, two audiences. The service decides what a stranger may read, so these rules
   are cosmetic: they hide the controls that would do nothing without the private data. */
#btn-login{display:none}
body[data-mode="public"] #btn-login{display:inline-block}
/* Same height as the icon buttons and the Partner box: 16px of content inside 5px of padding. A phone
   keeps the taller menu buttons. */
@media (min-width:761px){ body[data-mode="public"] #btn-login{padding:5px 11px;line-height:16px} }
body[data-mode="public"] .who-box,
body[data-mode="public"] #btn-settings,
body[data-mode="public"] #btn-mhelp,
body[data-mode="public"] #btn-add,
/* The filter narrows by condition, verdict and stars, none of which a visitor can see, so it
   would be a control over data that is not there. Listed by id rather than as a child of
   .top-right, because on a phone it is moved out into the header. */
body[data-mode="public"] #btn-filter,
/* The run controls, the two "show" tick boxes among them, move into the menu on a phone, out from
   under the run bar that hides them, so they are hidden by id as well. */
body[data-mode="public"] #run-controls,
body[data-mode="public"] #runinfo{display:none}
body[data-mode="public"] .banner{background:var(--sheet-2);color:var(--ink-2);border-bottom:1px solid var(--line-2);display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.locked{border:1px dashed var(--line);border-radius:var(--r-md);padding:16px 14px;background:var(--sheet-2);text-align:center;margin-top:16px}
.locked p{margin:0 0 10px;color:var(--muted);font-size:13.5px}

/* ---------- phones ----------
   The rules above assume a mouse and a wide window. Below this width the board shows one
   lane at a time, the page scrolls instead of each column, tap targets grow, and every
   input is 16px, which is the size at which iOS stops zooming the page when you tap one. */
@media (max-width:760px){
  body{font-size:15px;-webkit-text-size-adjust:100%}
  .top{position:static;padding:8px 12px;gap:8px}
  .brand h1{font-size:17px}
  .brand{width:100%}
  /* The search and the hamburger share a row. The search was flex-basis:100%, which pushed
     the button onto a line of its own and cost a whole row of a phone screen to one icon. */
  /* flex-basis:auto sized the box to its placeholder, leaving no room for the filter icon and
     the hamburger, which then wrapped onto a third row. A basis of 60px lets it give way. */
  .find{order:2;flex:1 1 60px;min-width:0;max-width:none}
  .find input{font-size:16px;padding-top:8px;padding-bottom:8px}
  /* The controls used to be a sideways-scrolling strip here, which hid Settings and Requirements
     off the right edge with nothing to say they were there. Now they are behind the hamburger. */
  /* `.top` makes this three classes against the two that hide it further down the sheet, so
     it wins wherever the two rules happen to sit. Matching on specificity alone left the
     hide rule winning here purely because it came later. */
  .top .btn.burger{display:inline-flex;order:4;flex:0 0 auto;margin-left:0;align-self:stretch}
  /* In the header it is an icon: the word would cost more width than it earns beside a search
     box. The count still shows, because a filter that is on and invisible is a trap. */
  .top>#btn-filter{order:3;flex:0 0 auto;align-self:stretch;padding:8px 10px}
  .top-right{display:none}
  body.menu-open .top-right{
    display:flex;order:4;width:100%;flex-direction:column;align-items:stretch;gap:8px;
    padding:10px;margin-top:2px;background:var(--sheet-2);
    border:1px solid var(--line);border-radius:var(--r-md);box-shadow:var(--shadow)}
  body.menu-open .top-right .btn{width:100%;justify-content:center;padding:11px 12px}
  /* In the menu the Partner row is drawn as a button like the rows above it: the icon and the name
     centered together, and a tap anywhere on the row opens the list. */
  /* Settings looks like the user menu button (Steven, 2026-09-15). */
  /* Location, Help, Settings and the user share one look in the phone menu (Steven, 2026-09-28). */
  body.menu-open .top-right #nav-settings,body.menu-open .top-right #nav-region,body.menu-open .top-right #nav-help{background:var(--sheet-2);border:1px solid var(--line);border-radius:var(--r-sm);color:var(--ink)}
  body.menu-open .top-right .who-box{align-self:stretch;justify-content:center;gap:6px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);padding:3px 12px;cursor:pointer}
  body.menu-open .top-right .who-box .who-icon{position:static;color:var(--ink)}
  body.menu-open .top-right .who-box .who-caret{position:static}
  body.menu-open .top-right .who{width:auto;max-width:none;font-size:16px;font-weight:600;padding:7px 2px;border:0;background:transparent}
  body.menu-open .top-right .sync{justify-content:center;padding:2px 0}
  .sync{font-size:12px}
  .btn{padding:8px 12px} .btn.sm{padding:5px 10px}
  /* The status becomes one short line and the controls move into the menu, so the run bar is a
     thin banner rather than a block that costs a third of the screen before a card is seen. */
  /* A field row is a two-column grid, label then a 150px control. On a phone that column is
     narrower than its contents: the tenants Yes/No/Unknown control measured 138px of buttons in
     114px of space and pushed its last button nine pixels off the screen. Below this width the
     label sits above the control and the control gets the full row. */
  .field{grid-template-columns:1fr;gap:3px;padding:7px 0}
  .field label{font-size:14px}
  .field input{text-align:left;font-size:16px;padding:8px 10px}
  select:not([multiple]):not([size]):not(.who){font-size:16px;height:40px}
  .field input[type=checkbox]{justify-self:start;width:20px;height:20px}
  .field .seg{width:100%}
  .field .seg button{flex:1;padding:8px 6px;font-size:13px}
  /* The agent's telephone and the email box get the row to themselves too. */
  .agent-row{gap:6px}
  .agent-row .btn{flex:1 1 auto;justify-content:center}
  .agent-row input{flex:1 1 100%;font-size:16px;padding:8px 10px}
  .dlg-row{grid-template-columns:1fr}
  #runbar{font-size:12px;gap:var(--sp-1) var(--sp-2)}
  /* One line: the title, Screen now, then the pipeline's buttons as icons at the right; the last-screen
     line below (Steven, 2026-09-14). The left group dissolves so its parts can be ordered with the rest. */
  #runbar #btn-screen{padding:7px 10px}
  #runbar #run-controls{gap:var(--sp-1);flex-wrap:nowrap}
  /* On a phone the screen note drops to its own line under the title and the buttons. */
  #runbar #runinfo{order:9;flex:1 1 100%}
  #run-controls .btn{padding:7px 9px}
  #run-controls .btn>span:not(.fcount){display:none}
  /* The home page and the planner: the title and the menu button share the first row. */
  body.plan .top .brand,body.landing .top .brand,.top:not(:has(.find)) .brand{width:auto;flex:1 1 0;min-width:0}
  .top:not(:has(.find)) .brand h1{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  body.plan .top .brand h1,body.landing .top .brand h1{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* Scenario Planner: the title and the buttons as icons on one row, like the pipeline (Steven, 2026-09-14). */
  .pagetitle{flex-wrap:nowrap}
  .pagetitle .acts{margin-left:auto;gap:6px;flex-wrap:nowrap}
  .pagetitle .acts .btn{padding:7px 9px}
  .pagetitle .acts .btn>span{display:none}
  /* With the business and location pills in the row, the buttons give up 3px a side so the location name fits (2026-10-23). */
  body.has-ctxbar .pagetitle .acts{gap:4px}
  body.has-ctxbar .pagetitle .acts .btn,body.has-ctxbar #run-controls .btn,body.has-ctxbar #runbar #btn-screen{padding-left:6px;padding-right:6px}
  /* The progress panel keeps its bar and its one-line head; the long summary underneath is the
     same information the run bar already carries once it finishes. */
  .screenbar{padding:7px 12px}
  .screenbar .sb-head{margin-bottom:5px}
  .screenbar .sb-note{display:none}
  .lanetabs{display:flex;position:sticky;top:0;z-index:var(--z-lanetabs)}
  .board{display:block;padding:10px 12px 56px;min-height:0;overflow:visible}
  .board .col:not([data-lane-on]){display:none}
  .col{max-height:none;background:transparent;border:0;border-radius:0}
  .col-h{display:none}
  .col-body{overflow:visible;padding:0;gap:10px}
    .drawer,.drawer.req{width:100vw;border-left:0;padding:16px 14px calc(56px + env(safe-area-inset-bottom))}
  .drawer-close{top:10px;right:10px;padding:8px 12px}
  .dh{padding-right:56px} .dh h2{font-size:20px}
  .kpi .v{font-size:19px}
  .fmr{grid-template-columns:repeat(3,1fr)} .fmr input{font-size:16px;padding:8px 10px}
  textarea{font-size:16px}
  table.nums input[type=number]{width:86px;font-size:16px}
  figure.hero img{max-height:220px}
  dialog{width:min(480px,96vw)} .dlg-field input{font-size:16px;padding:9px}
  #toast{left:12px;right:12px;transform:none;text-align:center}
}
@media (prefers-reduced-motion: reduce){ *{transition:none!important} }
.btn.icon{display:inline-flex;align-items:center;gap:6px;padding:5px 8px;line-height:1}
.btn.burger{display:none}   /* a hand only; the row fits on a desktop. Two classes, because .btn.icon above is two and would otherwise win. */
.btn.icon svg{display:block}
/* A small button with an icon keeps the small size (the card and flyout actions). */
.btn.sm.icon{padding:3px 9px;gap:5px}
@media (max-width:760px){ .btn.sm.icon{padding:5px 10px} }
.btn.icon .lbl{font-size:12px}
.condbar{display:flex;align-items:center;font-size:11.5px;color:var(--muted)}
.condbar .lbl{text-transform:uppercase;letter-spacing:.04em;font-size:10px;color:var(--muted)}
.condbar .blocks{display:flex;align-items:center;gap:6px}
.condbar .blocks i{width:10px;height:10px;border-radius:50%;border:2px solid var(--line);background:transparent;box-sizing:border-box}
.condbar .blocks .cscore{font-weight:600;font-size:11.5px;color:var(--ink-2);font-family:var(--body)}
.condbar .blocks i.on{background:var(--muted);border-color:var(--muted)}
.condbar.pass .blocks i.on{background:var(--pass);border-color:var(--pass)}
.condbar.warn .blocks i.on{background:var(--warn);border-color:var(--warn)}
.condbar.fail .blocks i.on{background:var(--fail);border-color:var(--fail)}
/* A guess is hollow: the colour still says which way it leans, the fill says how it was arrived at. */
.condbar.guess .blocks i.on{background:transparent}
.condbar.pass .val{color:var(--pass)}
.condbar.warn .val{color:var(--warn)}
.condbar.fail .val{color:var(--fail)}
.condbar.guess .val{font-style:italic}
/* A repair figure someone typed is not the one the photo review produced, so it does not look
   the same either. The title on the bar says which, and what the review had said. */
.condbar .val.over{text-decoration:underline dotted;text-underline-offset:2px}
.addr-find{position:relative}
.addr-hits{position:absolute;left:0;right:0;top:100%;z-index:var(--z-hits);background:var(--sheet);
  border:1px solid var(--line);border-radius:var(--r-md);box-shadow:0 6px 20px rgba(0,0,0,.25);
  max-height:190px;overflow:auto}
.addr-hit{display:block;width:100%;text-align:left;padding:7px 10px;background:none;border:0;
  border-bottom:1px solid var(--line-2);cursor:pointer;color:inherit}
.addr-hit:last-child{border-bottom:0}
.addr-hit:hover,.addr-hit:focus{background:var(--sheet-2)}
.addr-hit b{display:block;font-size:13px}
.addr-hit small{color:var(--muted);font-size:12px}
.condslide{display:flex;align-items:center;gap:12px;margin:2px 0 10px}
.condslide input[type=range]{flex:1 1 160px;max-width:260px}
.condslide output{font-size:13px;color:var(--ink-2)}
.condslide output b{font-size:15px}
.savebar{position:sticky;bottom:0;display:flex;gap:8px;align-items:center;margin-top:14px;
  padding:10px 12px;border-radius:var(--r-md);border:1px solid currentColor;
  background:Canvas;box-shadow:0 -2px 14px rgba(0,0,0,.28)}
.savebar .grow{flex:1}
/* A field keeps clear of the sticky save bar when it is scrolled into view (Steven, 2026-09-29). */
.drawer input,.drawer textarea,.drawer select,.sysdlg input,.sysdlg textarea,.sysdlg select{scroll-margin-bottom:84px}
.shots{display:flex;gap:6px;overflow-x:auto;padding:6px 0 10px;scrollbar-width:thin}
.shots .shot{flex:0 0 auto;width:78px;height:58px;padding:0;border:2px solid transparent;border-radius:var(--r-sm);
  overflow:hidden;background:none;cursor:pointer}
.shots .shot.on{border-color:currentColor}
.shots .shot img{width:100%;height:100%;object-fit:cover;display:block}
.agent-who{font-weight:600;margin-bottom:6px}
.agent-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:6px}
.agent-row input{flex:1 1 220px;min-width:0}
/* The title is a link home to the landing page (added 2026-09-14). Drawn as the title, not as a link. */
.brand h1 a.home{color:inherit;text-decoration:none}
.brand h1 a.home:hover{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:4px}
/* The page's own title under the menu bar: Pipeline, Scenario Planner (Steven, 2026-09-14). The lane
   heights above give up the strip's 44px, so the board still fits the window. */
/* ---------- the one page title bar (Steven, 2026-09-16; docs/ui-standards.md) ----------
   Every page has exactly this: the title, then whatever that page needs to say, then its actions on the
   right with the primary one first. The pipeline had a second bar of its own (.runbar) until 2026-09-16. */
.pagetitle{padding:var(--sp-2) var(--sp-4);min-height:44px;box-sizing:border-box;border-bottom:1px solid var(--line-2);background:var(--sheet-2);display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.pagetitle .ptnote{color:var(--ink-2);font-size:13px;min-width:0}
.pagetitle h2{margin-right:auto}
.pagetitle .acts{display:flex;gap:var(--sp-2);flex-wrap:wrap;align-items:center;margin-left:auto}  /* the same size and spacing as the pipeline's buttons (Steven, 2026-09-15) */
/* The two shared drawers take text-style boxes, as they did on the home page. */
#rules-drawer .field input,#site-drawer .field input{text-align:left;font-family:var(--body)}
.pagetitle h2{font-size:20px;font-weight:700;letter-spacing:-.01em;line-height:1.2;margin-top:0;margin-bottom:0;white-space:nowrap}  /* the same as the pipeline's title (Steven, 2026-09-15) */
@media (max-width:760px){ .pagetitle{padding:8px 12px} .pagetitle h2{font-size:18px} }
/* On a phone the page title and its buttons share one row (Steven, 2026-09-28): the location tag is dropped (the header
   shows the location) and a long title shortens with an ellipsis before the buttons wrap. */
@media (max-width:760px){ .pagetitle h2{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis} .pagetitle h2 .regtag{display:none} .pagetitle .acts{flex:0 0 auto;flex-wrap:nowrap} }
/* On the pipeline the page title sits at the start of the screen status line, not in a strip of its own
   (Steven, 2026-09-14). The public view hides the screen details and keeps the title. */
/* Manual: a property someone added by hand (Steven, 2026-09-14). Blue, apart from the verdict colours. */
.card.manual{border-left-color:var(--focus)}
.verdict.manual .big{color:var(--focus)}
.chip.manual{background:color-mix(in srgb,var(--focus) 16%,transparent);color:var(--focus)}
/* The filter bar: the planner's property filter and the pipeline's Filter (review U3). */
.pfbar{display:flex;flex-wrap:wrap;gap:8px 16px;align-items:center;margin-top:12px;padding:10px 12px;border:1px solid var(--line-2);border-radius:var(--r-md);background:var(--sheet-2)}
.pfbar .pfg{display:flex;align-items:center;gap:6px}
.pfbar .pfl{font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);font-weight:600;white-space:nowrap}
.pfbar .pfnums{display:flex;align-items:center;gap:4px}
.pfbar input[type=number]{width:86px;padding:3px 6px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet);font-family:var(--body);font-size:12.5px}
.pfbar .pfstar{font-size:12.5px;color:var(--ink-2);cursor:pointer}
/* ---------- a filter picker (Steven, 2026-09-16) ----------
   A set of choices with no fixed length: portfolios, and the people an approval waits on. A run of pills
   grew with the data and pushed the rest of the filters off the bar; this stays one button wide. */
.fpick{position:relative;display:inline-flex}
.fpick-btn{display:inline-flex;align-items:center;gap:var(--sp-1);min-height:var(--h-sm);padding:3px 8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet);color:inherit;font-size:12.5px;white-space:nowrap}
.fpick-btn.on{border-color:var(--accent);color:var(--accent);font-weight:600}
.fpick-btn:hover{border-color:var(--accent)}
.fpop{position:absolute;top:calc(100% + 4px);left:0;z-index:var(--z-menu);min-width:220px;max-width:300px;padding:var(--sp-2);border:1px solid var(--line);border-radius:var(--r-md);background:var(--sheet);box-shadow:var(--shadow)}
.fpop-q{width:100%;margin-bottom:var(--sp-2);padding:4px 8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);font:inherit;font-size:12.5px}
.fpop-list{max-height:260px;overflow:auto;display:flex;flex-direction:column;gap:1px}
.fpop-row{display:flex;align-items:center;gap:var(--sp-2);padding:4px 6px;border-radius:var(--r-sm);font-size:13px;cursor:pointer}
.fpop-row:hover{background:var(--sheet-2)}
.fpop-row span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fpop-foot{display:flex;align-items:center;gap:var(--sp-2);margin-top:var(--sp-2);padding-top:var(--sp-2);border-top:1px solid var(--line-2)}
.pfbar input[type=search]{padding:3px 8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet);font:inherit;font-size:12.5px;color:var(--ink);width:240px}
.pfbar .pffoot{flex:1 1 100%;display:flex;align-items:center;gap:8px;border-top:1px dashed var(--line-2);padding-top:8px}
.pfbar .pffoot .hint{margin-right:auto}
.pfbar.fbar{margin:0;border-width:0 0 1px;border-radius:0;padding:10px 18px}
@media (max-width:760px){ .pfbar.fbar{padding:10px 12px} .pfbar input[type=number]{font-size:16px;width:96px} }
/* The search box in the Pipeline bar, centered between the last-screen line and the buttons (Steven, 2026-09-14). */
.pagetitle>.find{flex:0 1 480px;min-width:220px;margin:0 auto}
/* A lane opened from a dashboard link is marked for a moment (Steven, 2026-09-15). */
.col.laneflash{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-md);transition:outline-color .6s}
/* Flyout sections that open and close (Steven, 2026-09-15). */
.sec h3.foldh{cursor:pointer;justify-content:flex-start;user-select:none}
.sec h3.foldh>.hint{margin-left:auto}
.sec h3.foldh:hover{color:var(--accent)}
.sec h3.foldh:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:var(--r-sm)}
.sec h3 .fold{flex:none;color:var(--muted);transition:transform .15s}
.sec.collapsed h3 .fold{transform:rotate(-90deg)}
.sec.collapsed:not(.two)>:not(h3),.sec.two.collapsed>div>:not(h3){display:none!important}
.sec.collapsed h3{margin-bottom:0}
.sec.two.collapsed>div{min-height:0}
.foldall{display:flex;justify-content:flex-end;gap:4px;margin:10px 0 -6px}
.foldall .btn:disabled{opacity:.45}
/* Portfolios (Steven, 2026-09-15). */
.chip.pfchip{border-color:var(--pf);color:var(--pf);background:color-mix(in srgb,var(--pf) 12%,transparent);font-weight:600}
.chip.pfchip .pfic{flex:none;margin-right:1px}
.card .chips .pftag{display:inline-flex;align-items:center;gap:4px}
.pfrow{display:flex;align-items:center;gap:var(--sp-2);margin:0;min-width:0}
.pfrow .label{margin:0}
.pfrow select{flex:1 1 auto;max-width:280px;min-width:0}
.swatches{display:inline-flex;gap:4px;flex-wrap:wrap}
.swatch{width:20px;height:20px;border-radius:50%;border:2px solid transparent;background:var(--pf);padding:0;cursor:pointer;box-shadow:inset 0 0 0 2px var(--sheet)}
.swatch.on{border-color:var(--ink)}
.swatch:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
/* The Assistant link is gold filled (Steven, 2026-09-15), on its own page too. */
#nav-assistant.primary,#nav-assistant.primary.on,#nav-assistant.primary:hover{background:var(--accent-fill);border-color:var(--accent-fill);color:var(--accent-ink)}
#nav-assistant.primary:hover{filter:brightness(1.06)}
/* On the Assistant page it keeps the gold ring the other current-page links have, outside the fill. */
#nav-assistant.primary.on{box-shadow:0 0 0 2px var(--bg,var(--sheet)),0 0 0 3.5px var(--accent)}
/* Configure menus share the Purchasing look (Steven, 2026-09-15): tick boxes for yes or no, gold segments for choices. */
.drawer .field label small a{color:var(--accent)}
/* One dropdown look across the site (Steven, 2026-09-15): no browser chrome, a thin border, the site's colors and one
   caret. The caret is a neutral gray that reads on both themes. */
/* One dropdown (Steven, 2026-09-16): every single-line select is this box, the height of a button beside it.
   A page rule may set only its width and flex. The small one (.sm, and the filter bar) is the height of a .btn.sm.
   The partner picker (.who) is drawn as a header button with its own icon and caret, so it is left out. */
select:not([multiple]):not([size]):not(.who){-webkit-appearance:none;appearance:none;box-sizing:border-box;height:var(--h-btn);padding:0 28px 0 10px;border:1px solid var(--line);border-radius:var(--r-sm);background-color:var(--sheet-2);font-family:var(--body);font-size:13.5px;line-height:1.2;text-align:left;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238b99a8' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center;background-size:12px;padding-right:28px!important;color:var(--ink);cursor:pointer}
select:not([multiple]):not([size]):focus-visible{outline:2px solid var(--focus);outline-offset:1px}
select option{background:var(--sheet);color:var(--ink)}
select.sm:not([multiple]):not([size]),.pfbar select:not([multiple]):not([size]){height:var(--h-sm);font-size:var(--fs-1);padding-left:8px}
.field select{text-align:left}
.card .a .pftag{flex:0 1 auto;max-width:40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px;padding:1px 7px;margin:0}
/* The address shrinks with the column before it is cut (Steven, 2026-09-16), and the portfolio tag gives way first. */
.col-body .card .addr{font-size:clamp(13px,5.4cqi,14.5px)}
.card .chips .pftag{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* AI summary box at the top of a record (Steven, 2026-09-15). */
.aibtn{display:inline-flex;align-items:center;justify-content:center;gap:6px}
.aibtn svg{color:var(--accent);width:14px;height:14px;margin:-3px 0;flex:none}
.aibtn.sm svg{width:13px;height:13px}
.aibrief{margin:10px 0 12px;border:1px solid color-mix(in srgb,var(--accent) 45%,var(--line));background:color-mix(in srgb,var(--accent) 6%,var(--sheet));border-radius:var(--r-md);padding:10px 14px;font-size:13.5px;line-height:1.5}
.aibrief .aib-h{display:flex;align-items:center;gap:8px;color:var(--ink);margin-bottom:4px}
.aibrief .aib-h svg{color:var(--accent);flex:none}
.aibrief .aib-h .grow{flex:1}
.aibrief .aib-at{font-size:12px;color:var(--muted)}
.aibrief .aib-t ul{margin:4px 0;padding-left:20px} .aibrief .aib-t li{margin:2px 0} .aibrief .aib-t p{margin:4px 0}
.aibrief .aib-t.err{color:var(--fail)}
.aibrief .aib-t a{color:var(--accent)}
.aibrief .aib-f{margin-top:6px;font-size:13px} .aibrief .aib-f a{color:var(--accent);font-weight:600;text-decoration:none} .aibrief .aib-f a:hover{text-decoration:underline}
.aibrief .aib-wait{color:var(--muted)} .aibrief .aib-wait i{display:inline-block;width:5px;height:5px;margin-left:3px;border-radius:50%;background:var(--muted);animation:aibdot 1s infinite}
.aibrief .aib-wait i:nth-child(2){animation-delay:.15s} .aibrief .aib-wait i:nth-child(3){animation-delay:.3s}
@keyframes aibdot{50%{opacity:.25}}
/* Regions (Steven, 2026-09-15; docs/archive/regions-plan.md): the header picker, the region tag beside a page title, the
   readiness banner, suggested-value marks in Inputs and the Manage regions dialog. */
.regtag,.lasttag{display:inline-block;margin-left:10px;padding:2px 9px;border-radius:var(--r-pill);border:1px solid var(--line);background:var(--sheet-2);color:var(--muted);font-size:12.5px;font-weight:600;letter-spacing:0;vertical-align:middle;white-space:nowrap}
.regtag.muted,.lasttag{font-weight:500}
/* No room on a phone (Steven, 2026-09-17): the title row ran off the screen. The date stays on the dashboard. */
@media (max-width:760px){ .lasttag{display:none} }
.ready-banner{display:flex;align-items:center;gap:12px;flex-wrap:wrap} .ready-banner span{flex:1 1 320px;line-height:1.4}
.ready-off{opacity:.55;cursor:not-allowed!important;filter:grayscale(.3)}
.drawer .grp{margin-bottom:14px} .drawer .grph{display:flex;align-items:center;gap:8px;font-size:15px;margin:12px 0 4px;padding-bottom:6px;border-bottom:1px solid var(--line)}
.drawer .field.missing input{border-color:var(--fail);box-shadow:0 0 0 2px color-mix(in srgb,var(--fail) 22%,transparent)}
.drawer .fmr>div.missing input{border-color:var(--fail)}
.sugg{display:inline-block;margin-left:6px;padding:1px 6px;border-radius:var(--r-pill);background:var(--warn-soft);color:var(--warn);font-size:11px;font-weight:700;vertical-align:middle;cursor:help}
.drawer .field label [data-rev]{margin-left:6px;vertical-align:middle}
.drawer .fmr>div .sugg{margin-left:3px;padding:0 5px}
dialog.regions{width:min(720px,96vw)}
.reglist{display:flex;flex-direction:column;gap:8px;margin:8px 0}
.regrow{display:grid;grid-template-columns:1fr auto;gap:6px 12px;align-items:center;padding:10px 12px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--sheet-2)}
.regrow.cur{border-color:var(--accent)}
.regrow .rn small{display:block;color:var(--muted);font-size:12.5px;margin-top:2px}
/* Manage businesses (Steven, 2026-10-21) is drawn like Manage locations: its .regrow, .dsec, .field, .loc-acts and buttons. */
#business-dialog .bizp-n{display:flex;align-items:center;gap:10px;min-width:0;cursor:pointer}
#business-dialog .bizp-n input{width:17px;height:17px;flex:none;margin:0}
#business-dialog .bizp-n span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#business-dialog .bizp input[type=number]:disabled{opacity:.5}
#business-dialog h3.bizp-head{display:grid;grid-template-columns:minmax(0,1fr) 150px;gap:10px}
#business-dialog .bizerr{margin:12px 0 0;padding:8px 10px;border:1px solid var(--fail);border-radius:var(--r-sm);background:var(--fail-soft);color:var(--fail);font-size:13px}
#sources-dialog .taxin{width:90px;text-align:right;padding:4px 8px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);font-family:var(--body)}
#sources-dialog td.missing .taxin{border-color:var(--fail)}

#sources-dialog .loctbl th{text-align:left}

#sources-dialog .loctbl .r{text-align:right}
/* Sources list (Steven, 2026-09-28): tabs for Every location and Local, a Find box, one table row a source. */
#sources-dialog .srctabs{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:0 0 6px}
#sources-dialog .srctabs .seg button{padding:5px 14px;font-size:13px}
#sources-dialog .srctabs .srcq{flex:1 1 180px;width:auto;margin:0}
#sources-dialog .srctbl{table-layout:fixed}
#sources-dialog .srctbl td{vertical-align:top;overflow-wrap:anywhere}
#sources-dialog .srctbl .c-type{width:120px} #sources-dialog .srctbl .c-act{width:140px}

#sources-dialog .srctbl .nw{white-space:nowrap}
#sources-dialog .recq{width:100%;box-sizing:border-box;margin:0 0 var(--sp-2);padding:6px 10px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2)}
/* Roles (Steven, 2026-09-16). Until the role is known the owner-only controls stay hidden, which is the safe side. */
body:not([data-role="owner"]) .setmenu:has(#nav-settings){display:none!important}
body:not([data-role="owner"]) .regpop [data-manage],body:not([data-role="owner"]) .regpop .setsep{display:none!important}
body:not([data-role="owner"]) #ev-pf option[value="__new"]{display:none}
/* Generative AI off (Settings > Site, Steven 2026-09-17): no Assistant, Summarize, Suggest or Best offer anywhere. */
html[data-ai="off"] :is(#nav-assistant,.tile-ai,#best-status,.aibtn,.aibrief,#eval-suggest,[data-suggest]){display:none!important}
body[data-role="viewer"] #btn-add,body[data-role="viewer"] #btn-screen,body[data-role="viewer"] #btn-new,body[data-role="viewer"] #btn-build,
body[data-role="viewer"] #btn-propose,body[data-role="viewer"] #btn-run,body[data-role="viewer"] #btn-saverun,body[data-role="viewer"] .cardact .cardbtns{display:none!important}
.viewonly{padding:8px 18px;border-bottom:1px solid var(--line-2);background:var(--sheet-2);color:var(--ink-2);font-size:13px}
.autonote{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);margin:0 0 var(--sp-3);padding:var(--sp-2) var(--sp-3);border:1px solid var(--accent);border-radius:var(--r-md);background:var(--accent-soft);font-size:13px}
.regrow .rs{justify-self:end} .regrow .ra{grid-column:1/-1;display:flex;gap:6px;flex-wrap:wrap}
.sugtbl th,.sugtbl td{text-align:left;vertical-align:top}
.sugtbl td.num{font-variant-numeric:tabular-nums;white-space:nowrap} 
/* One tag on every page (Steven, 2026-09-16): it lived only in purchasing.html, so dialogs elsewhere drew bare text. */
.tag{display:inline-block;font-size:12px;line-height:1.4;border-radius:var(--r-pill);padding:2px 9px;white-space:nowrap;border:1px solid var(--line);color:var(--ink-2)}
.tag.ok{background:var(--pass-soft,var(--sheet-2));color:var(--pass);border-color:transparent} .tag.warn{background:var(--warn-soft);color:var(--warn);border-color:transparent}
.others h3{margin:16px 0 6px;font-size:15px} .others .drow{cursor:pointer}
/* The region menu in the header, drawn like the System menu (Steven, 2026-09-16). */
.regmenu .regpop{width:260px} .regpop .setitem.on{background:color-mix(in srgb,var(--accent) 12%,transparent)} .regpop .setitem.on .si{color:var(--accent)}
/* The user menu's Business section and the New business dialog (Steven, 2026-10-21). */
.whopop .setitem.on{background:color-mix(in srgb,var(--accent) 12%,transparent)} .whopop .setitem.on .si{color:var(--accent)}
/* A region's settings page in the Regions dialog (Steven, 2026-09-16): the Inputs drawer's rows and sections. */
dialog.regions .dsec.first{margin-top:0;padding-top:0;border-top:0}
/* A location's page (Steven, 2026-10-27, mockup B): two tabs, the Plan inputs grid five to a row, the review table of
   suggested values above it, and the Fill buttons on their section headings. */
dialog.regions.wide{width:min(920px,96vw)}
.loc-tabs{display:flex;align-items:center;gap:8px;margin:2px 0 14px} .loc-tabs .grow{flex:1 1 auto}
.loc-tabs .rtabs button .n{font-size:11.5px;opacity:.75;margin-left:6px}
.ifg-h.loc-hrow{display:flex;align-items:center;gap:8px} .loc-hrow .grow{flex:1 1 auto} .loc-hrow .btn{text-transform:none;letter-spacing:0}
.loc-rev{border:1px solid var(--line);border-radius:var(--r-sm);padding:8px 12px 12px;margin:0 0 14px;background:var(--accent-soft)}
.loc-revh{display:flex;align-items:center;gap:8px;margin-bottom:6px} .loc-revh .grow{flex:1 1 auto}
.ifg-grid .ckmulti{flex-direction:row;flex-wrap:wrap;align-items:center;gap:6px 22px;margin-top:4px} .ifg-grid .ckmulti label{flex-direction:row-reverse}
dialog.regions .grp{margin-top:14px} dialog.regions .grph{display:flex;align-items:center;gap:8px;font-size:15px;margin:12px 0 4px;padding-bottom:6px;border-bottom:1px solid var(--line)} dialog.regions .grph .grow{flex:1 1 auto}
dialog.regions .field.missing input,dialog.regions .fmr>div.missing input{border-color:var(--fail);box-shadow:0 0 0 2px color-mix(in srgb,var(--fail) 22%,transparent)}
dialog.regions .field.wide input,dialog.regions .field.wide select{font-family:var(--body);text-align:left}
dialog.regions .dlg-row .field.wide{margin:0}
/* Manage locations reads like Adjust criteria (Steven, 2026-09-16): label left, box right, dashed rules between rows,
   a plain section heading. A text box is wider than a number box; a row with an Accept button is wider still. */
dialog.regions .loc-acts{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin:14px 0 0;padding-top:12px;border-top:1px solid var(--line-2)}
dialog.regions .loc-acts .btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;box-sizing:border-box;padding:0 12px;line-height:1;font-size:13.5px}
dialog.regions .loc-acts [data-inputs].on{background:var(--accent-soft)}
#pf-dialog .regrow .rn b{display:inline-flex;align-items:center;gap:8px}
#pf-dialog .regrow .pfdot{display:inline-flex}
#pf-dialog .regrow .pfdot svg{width:15px;height:15px}
#pf-dialog .field .swatches{display:flex;flex-wrap:wrap;gap:6px}
#pf-dialog .field.text{grid-template-columns:minmax(0,1fr) auto}
#pf-dialog .field.text input{width:240px}
dialog.askdlg{width:min(440px,92vw)}
/* A row whose control is a button: one column width, the button filling it, so a stack of them lines up (Steven, 2026-09-16). */
dialog.regions .field.act{grid-template-columns:minmax(0,1fr) 170px}
dialog.regions .field.act .btn{width:100%;justify-content:center}
dialog.regions .field.text{grid-template-columns:minmax(0,1fr) 240px}
dialog.regions .field.text input{font-family:var(--body);text-align:left}
dialog.regions .field.hasacc{grid-template-columns:minmax(0,1fr) 150px}
dialog.regions .field.hasacc.sugged{grid-template-columns:minmax(0,1fr) 232px}
dialog.regions .grph{font-size:15px;font-weight:700;border-bottom:0;padding-bottom:0;margin:18px 0 0;padding-top:14px;border-top:1px solid var(--line-2)}
dialog.regions .grph .hint{font-size:12.5px;font-weight:400}
dialog.regions .fmr input{font-family:var(--body);text-align:right}
@media (max-width:760px){ dialog.regions .field.text,dialog.regions .field.hasacc,dialog.regions .field.hasacc.sugged{grid-template-columns:1fr} }
.sugbox{margin:6px 0 10px;padding:10px 12px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--sheet-2)}
/* Reports scope toggle (Steven, 2026-09-16). */
#dash-scope{margin-right:4px} #dash-scope button{display:inline-flex;align-items:center;gap:5px}

/* System > Activity (Steven, 2026-09-17): the dashboard's feed and chips, inside the popup. */
#act-dialog .act-top{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin:0 0 10px}
#act-dialog .chips{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 12px}
#act-dialog .chip{gap:6px;font:inherit;font-size:12.5px;font-weight:400;line-height:1;padding:5px 9px;border:1px solid var(--line);background:var(--sheet-2);color:var(--ink-2);cursor:pointer}
#act-dialog .chip b{font-family:var(--body);font-weight:600;color:var(--ink)}
#act-dialog .chip:hover,#act-dialog .chip.on{border-color:var(--accent);color:var(--accent)}
#act-dialog .feed{list-style:none;margin:0;padding:0;max-height:52vh;overflow-y:auto}
#act-dialog .feed li{display:grid;grid-template-columns:24px minmax(0,1fr) auto;gap:10px;align-items:start;padding:7px 0;border-top:1px solid var(--line)}
#act-dialog .feed li:first-child{border-top:0;padding-top:0}
#act-dialog .feed .av{width:24px;height:24px;border-radius:50%;display:grid;place-items:center;font-size:11px;font-weight:700;background:var(--accent-soft);color:var(--accent)}
#act-dialog .feed .av.sys{background:var(--sheet-2);color:var(--muted)}
#act-dialog .feed .tx{font-size:13px;line-height:1.45;color:var(--ink-2);overflow-wrap:anywhere}
#act-dialog .feed .tx b{color:var(--ink);font-weight:600}
#act-dialog .feed .tx a{color:inherit;text-decoration:none;border-bottom:1px dotted var(--muted)}
#act-dialog .feed .tx a:hover{color:var(--accent);border-color:var(--accent)}
#act-dialog .feed time{font-size:12px;color:var(--muted);white-space:nowrap;padding-top:2px}
#act-dialog .feed-empty{font-size:13.5px;color:var(--muted)}
#act-dialog .feed-more{margin-top:10px}
#act-dialog .act-clear{display:grid;grid-template-columns:1fr 1fr;gap:10px}
#act-dialog .act-clear .field{margin:0}
@media (max-width:560px){ #act-dialog .act-clear{grid-template-columns:1fr} }
/* Financials and Settings as pop-up windows like System's other items (Steven, 2026-09-17); they were drawers. */
dialog.sysdlg{max-height:90vh;overflow:auto}
dialog.sysdlg>.dlgbody{position:relative;padding:18px 20px 0}
dialog.sysdlg .loc-acts{position:sticky;bottom:0;z-index:1;background:var(--sheet);padding-bottom:14px}
dialog.sysdlg .field label small a{color:var(--accent)}

/* The proposal view (Steven, 2026-09-17): the Properties table, the inputs a proposal was priced on, and the Summary
   charts, drawn by proposalview.js on a proposal in Planning and on an offer in Purchasing. Moved here from plan.html. */
.rvin summary{cursor:pointer;font-weight:600;font-size:13.5px}
.rvin .rvin-acts{display:flex;justify-content:flex-end;margin:8px 0 0}
.rvin .kv{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:2px 16px;font-size:12.5px;margin:10px 0}
.rvin .kv span{display:flex;justify-content:space-between;gap:8px;border-bottom:1px dotted var(--line-2);padding:2px 0}
.rvin .kv b{font-family:var(--body);font-weight:500}
.tablewrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:0 -6px;padding:0 6px}
table.nums.res{min-width:640px}
table.nums.res th{white-space:nowrap}
table.nums.res th.r,table.nums.res td.r{text-align:right;font-family:var(--body);font-variant-numeric:tabular-nums;white-space:nowrap}
table.nums.res tr.total td{font-weight:600;border-top:2px solid var(--line)}
table.nums.res td.bad{color:var(--fail);font-weight:600}
table.nums.res td.neg{color:var(--fail)}
table.nums.res td.pos{color:var(--pass)}
table.nums.res td.none{color:var(--muted)}
.foot{font-size:12px;color:var(--muted);margin-top:8px;line-height:1.5}
.foot .est{font-weight:600}
/* Results: one panel, a toggle between the rent levels, two tables. */
.rhead{display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px}
.rhead h2{margin:0}
.rhead a.btn{text-decoration:none} /* View scenario on Acquire looks like the buttons beside it (v2.8) */
.rhead .seg button{padding:6px 12px;font-size:13px}
.rhead .seg .mark{color:var(--accent);font-weight:700}
.runtabs{margin:14px 0}   /* 14px above and below the tabs, like every other step on a record page (Steven, 2026-09-29) */
.runtabs .seg button{padding:7px 16px}
.charts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-top:4px}
.charts .ch{border:1px solid var(--line-2);border-radius:10px;background:var(--sheet-2);padding:12px 14px;min-width:0}
.charts .ch.wide{grid-column:1/-1}
.charts h3{margin:0 0 10px;font-size:12px;letter-spacing:.05em;text-transform:uppercase;color:var(--muted);font-weight:700}
.meter{margin:0 0 12px}
.meter .mh{display:flex;justify-content:space-between;gap:8px;font-size:13px;margin-bottom:4px}
.meter .mh b{font-family:var(--body)}
.meter .track{position:relative;height:12px;border-radius:6px;background:var(--line-2);overflow:visible}
.meter .fill{position:absolute;left:0;top:0;bottom:0;border-radius:6px}
.meter .fill.good{background:var(--pass)} .meter .fill.bad{background:var(--fail)} .meter .fill.mid{background:var(--warn)}
.meter .fill.eq{background:var(--s4)}
.meter .mark{position:absolute;top:-4px;bottom:-4px;width:2px;background:var(--ink);border-radius:1px}
.meter .mnote{font-size:11.5px;color:var(--muted);margin-top:3px}
.fb{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.fb li{display:flex;gap:8px;align-items:flex-start;font-size:13px;line-height:1.35}
.fb li .ic{flex:none;width:18px;height:18px;border-radius:50%;display:grid;place-items:center;font-size:11px;font-weight:700}
.fb li.ok .ic{background:var(--pass-soft);color:var(--pass)} .fb li.no .ic{background:var(--fail-soft);color:var(--fail)} .fb li.info .ic{background:var(--accent-soft);color:var(--accent)}
.stack{display:flex;height:22px;border-radius:6px;overflow:hidden;background:var(--line-2);gap:2px}
.stack span{display:block;min-width:2px}
.stack .over{background:repeating-linear-gradient(45deg,var(--fail),var(--fail) 3px,transparent 3px,transparent 6px)}
.legend{display:flex;flex-wrap:wrap;gap:4px 14px;margin-top:8px;font-size:12px;color:var(--ink-2)}
.legend i{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:5px;vertical-align:0}
.legend b{font-family:var(--body);font-weight:600;margin-left:4px}
.hbars{display:grid;gap:7px}
.hbar{display:grid;grid-template-columns:minmax(90px,150px) minmax(0,1fr) 78px;gap:8px;align-items:center;font-size:12.5px}
.hbar .nm{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hbar .v{font-family:var(--body);text-align:right;white-space:nowrap}
.hbar .area{position:relative;height:14px}
.hbar .area .zero{position:absolute;top:-3px;bottom:-3px;width:1px;background:var(--muted)}
.hbar .area .tgt{position:absolute;top:-4px;bottom:-4px;width:2px;background:var(--ink)}
.hbar .area .b{position:absolute;top:0;bottom:0;border-radius:3px}
.hbar .area .b.pos{background:var(--pass)} .hbar .area .b.neg{background:var(--fail)}
.hbar .area .stk{position:absolute;left:0;top:0;bottom:0;display:flex;gap:1px;border-radius:3px;overflow:hidden}
.hbar .area .stk span{display:block}
.hbar .area .lp{position:absolute;left:0;top:3px;bottom:3px;border-radius:3px;background:var(--line)}
.hbar .area .pin{position:absolute;top:-3px;bottom:-3px;width:3px;border-radius:2px}
.hbar .area .pin.off{background:var(--accent-fill)} .hbar .area .pin.tp{background:var(--pass)}
@media (max-width:760px){ .charts{grid-template-columns:1fr} .hbar{grid-template-columns:90px minmax(0,1fr) 66px} }
/* Inputs when saved, wherever it shows (the Properties table, a proposal opened in its plan): room above it, and a line
   under its heading when open (Steven, 2026-09-17). */
.rvin{margin-top:18px}
.rvin[open]>summary{padding-bottom:8px;margin-bottom:4px;border-bottom:1px solid var(--line-2)}
.res .pv-link{color:inherit;text-decoration:underline;text-decoration-color:var(--muted);text-underline-offset:3px}
.res .pv-link:hover{color:var(--accent);text-decoration-color:var(--accent)}
/* The money in the Proposal overview: three columns of label and figure (Steven, 2026-09-17). */
.ofigs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}
.ofigs h3{margin:0 0 6px}
.ofig{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 12px;margin:0;font-size:13px}
.ofig dt{color:var(--ink-2)} .ofig dd{margin:0;text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.ofig dd.neg{color:var(--fail)} .ofig dd.pos{color:var(--pass)}
@media (max-width:760px){ .ofigs{grid-template-columns:1fr} }
/* What record a detail page shows, above its name: Plan, Proposal, Offer (Steven, 2026-09-17). */
.shead .name .rectype{display:block;margin:0 0 -2px 8px;font-size:14px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--accent)}
/* The way back to the list, on the record type's line (Steven, 2026-09-29): "← All plans / PLAN", so no bar above the record. */
.shead .name .crumb{display:flex;align-items:center;gap:8px;margin:0 0 -2px 8px}
.shead .name .crumb .rectype{margin:0}
.shead .name .crumb{margin-bottom:6px;gap:12px}
/* An ordinary button, like every other one on the page (Steven, 2026-09-29). */
.shead .name .crumb .back{margin:0}
/* A source's page: each location's settings for the source, inline under its name (Steven, 2026-09-28). */
#sources-dialog .srcsets{display:flex;flex-wrap:wrap;gap:6px 14px;margin-top:6px}
#sources-dialog .srcset{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted)}
#sources-dialog .srcset input,#sources-dialog .srcset select{padding:3px 7px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);color:var(--ink);font-size:12.5px;max-width:170px}
#sources-dialog [data-addloc]{padding:5px 9px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--sheet-2);color:var(--ink)}
.fmrlabel .btn{margin-left:8px;font-weight:500}
/* A small first photo beside each property's name in a scenario's and an acquisition's Properties table (Steven, 2026-09-29). */
.pview td.pv-prop{white-space:nowrap}
.pview .pv-thumb{display:inline-block;width:64px;height:44px;margin-right:10px;vertical-align:middle;border-radius:var(--r-sm);overflow:hidden;background:var(--sheet-2);border:1px solid var(--line)}
.pview .pv-thumb img{width:100%;height:100%;object-fit:cover;display:block}
/* Track's property as a page, like a plan or an acquisition (Steven, 2026-09-29): the lanes and their tabs step aside and
   the record sits in the page under the title bar. */
html.recview #board,html.recview #lanetabs,html.recview #filterbar{display:none!important}
#drawer.page{position:static;inset:auto;width:auto;max-width:none;margin:0;border:0;box-shadow:none;background:transparent;overflow:visible;z-index:auto;padding:14px 22px 60px}
#drawer.page .dh{padding-right:0}
/* The property page's header, laid out like a plan's and an acquisition's: the way back and PROPERTY, the address and
   price, and the buttons on the right (Steven, 2026-09-29). */
#drawer .shead{display:flex;align-items:flex-start;gap:12px;flex-wrap:wrap;margin-bottom:2px}
#drawer .shead .name{flex:1 1 320px;min-width:0}
#drawer .shead .name .crumb{margin-left:0}
#drawer .shead .acts{display:flex;gap:6px;flex-wrap:wrap;align-items:center;margin:0}
/* One size for every button in a record's header, in Track, Plan and Acquire alike (Steven, 2026-09-29): an icon
   button, a plain one and Summarize all 32px tall. It was Plan's own rule. */
.shead .acts .btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:32px;box-sizing:border-box;padding:0 12px;line-height:1;font-size:13.5px}
#drawer .shead h2.recname{display:flex;align-items:baseline;gap:4px 10px;flex-wrap:wrap;margin:0;font-family:var(--display);font-size:24px;font-weight:700;letter-spacing:-.015em;line-height:1.2}
#drawer .shead h2.recname .sheet-price{font-family:var(--body);font-size:.75em;font-weight:600;color:var(--ink-2);white-space:nowrap}
#drawer .shead+.dh{margin-bottom:6px}
@media (max-width:760px){ #drawer.page{padding:12px 12px 60px} }
/* Every text box opens as tall as its text, so notes never need dragging open again (Steven, 2026-09-29). Browsers
   without field-sizing get the same from ui.js. A very long one stops at 60% of the screen and scrolls. */
textarea{field-sizing:content;min-height:3.2em;max-height:60vh}
/* Status and Portfolio on a property page (Steven, 2026-09-29): the lower band of the header panel, two halves split by
   a thin line, each label beside its value (one 84px label width) and the value centered, at most 440px wide. On a
   phone the halves stack; below 560px each label sits above its value and the six stages go three across. */
#drawer.page .srows{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));margin:0 -18px;border-top:1px solid var(--line-2)}
#drawer.page .srows .srow{display:flex;align-items:center;gap:16px;padding:12px 18px;border:0}
#drawer.page .srows .srow+.srow{border-left:1px solid var(--line-2)}
#drawer.page .srows .srow>.label{align-self:center;flex:0 0 84px}
#drawer.page .srows .pfrow{flex:1 1 auto;display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:10px;min-width:0;min-height:34px}
#drawer.page .srows select{flex:1 1 auto;min-width:0;max-width:440px;height:34px;box-sizing:border-box;font-size:13.5px}
#drawer.page .srows .stagebars{flex:1 1 auto;max-width:440px;min-width:0}
@media (max-width:760px){
  #drawer.page .srows{grid-template-columns:minmax(0,1fr)}
  #drawer.page .srows .srow+.srow{border-left:0;border-top:1px solid var(--line-2)}
}
@media (max-width:560px){
  #drawer.page .srows .srow{flex-direction:column;align-items:stretch;gap:10px}
  #drawer.page .srows .srow>.label{align-self:flex-start;flex:none}
  #drawer.page .srows .pfrow{justify-content:flex-start}
  #drawer.page .srows .stagebars{max-width:none;grid-template-columns:repeat(3,minmax(0,1fr));row-gap:12px}
  #drawer.page .srows select{max-width:none}
}
/* A property page's tabs and panels (Steven, 2026-09-29): the scenario page's tab row, then each section as a panel like
   Plan's, two across on a wide screen. The Summary tab and the wide sections (photos, key numbers, verdict, a table,
   two-part sections) take the full width. */
#drawer.page .proptabs{margin:0 0 14px}   /* one 14px step between the header, notes, tabs and panels (Steven, 2026-09-29) */
#drawer.page .ptpane{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-items:stretch}
#drawer.page .ptpane>.wide{grid-column:1/-1}
#drawer.page .ptpane>*{margin:0;min-width:0}
#drawer.page textarea.recnotes{display:block;width:100%;box-sizing:border-box;min-height:44px;margin:0 0 14px}
#drawer.page .ptpane>.sec{background:var(--sheet);border:1px solid var(--line);border-radius:10px;padding:14px 16px}
#drawer.page .ptpane>.sec h3{font-size:15px;margin-bottom:10px}
@media (max-width:900px){ #drawer.page .ptpane{grid-template-columns:minmax(0,1fr)} }
/* The header panel of a property page (Steven, 2026-09-29): drawn like every other panel on the page, no accent. The
   address line and the lifecycle on top; under a divider, with room below the step names, the stage, portfolio and
   progress in three columns split by thin lines rather than a second box inside the first. */
#drawer.page .rechead{background:var(--sheet);border:1px solid var(--line);border-radius:10px;padding:14px 18px 0;margin:6px 0 14px}
#drawer.page .rechead .dh{margin:0 0 10px;display:flex;align-items:baseline;flex-wrap:wrap}
#drawer.page .rechead .lifehead{margin:0;padding-bottom:16px}
#drawer.page .rechead .lstep b{font-size:12px}
/* The top of a property's Summary tab (Steven, 2026-09-29): photos on the left half, the featured one above a strip of
   the rest that scrolls sideways, and the four key numbers in a 2 by 2 block on the right half, as tall as the photos. */
#drawer.page .sumtop{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px;align-items:stretch}
#drawer.page .sumtop .photos{display:block;margin:0;min-width:0}
#drawer.page .sumtop .photos figure.hero{margin:0;max-width:none}
#drawer.page .sumtop .photos .shots{display:flex;gap:6px;overflow-x:auto;overflow-y:hidden;max-height:none;padding:8px 0 4px}
#drawer.page .sumtop .photos .shots .shot{flex:0 0 auto;width:96px;height:72px;aspect-ratio:auto}
#drawer.page .sumtop .kpis{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:1fr;gap:12px;margin:0}
#drawer.page .sumtop .sumleft{display:flex;flex-direction:column;gap:12px;min-width:0}
#drawer.page .sumtop .sumleft .verdict{margin:0}
#drawer.page .sumtop .sumleft .kpis{flex:1 1 auto}
#drawer.page .sumtop .kpi{display:flex;flex-direction:column;justify-content:center;padding:12px 16px}
#drawer.page .sumtop .kpi .v{font-size:28px}
#drawer.page .sumtop .kpi .k{font-size:12.5px;margin-top:4px}
@media (max-width:900px){ #drawer.page .sumtop{grid-template-columns:minmax(0,1fr)} #drawer.page .sumtop .kpi .v{font-size:24px} }
/* The top line of a property page reads like its card; the place, the links and the last update sit at the foot of the
   header panel, under a divider (Steven, 2026-09-29). */
/* The type, beds, baths and floor area on the title's line (Steven, 2026-09-29), after the price; STATUS names the
   lifecycle below. */
#drawer .shead h2.recname .facts-line{font-family:var(--body);font-size:15px;font-weight:500;letter-spacing:0;color:var(--ink-2);margin-left:6px}
#drawer .shead h2.recname .sheet-state{font-family:var(--body);font-size:12px;font-weight:400;letter-spacing:0;margin-left:6px}
#drawer .shead h2.recname .sheet-state:empty{display:none}
#drawer.page .rechead .dh .label{display:block;margin:0}
#drawer.page .rechead .reclinks{display:flex;align-items:center;flex-wrap:wrap;gap:6px 14px;margin:0 -18px;padding:10px 18px;border-top:1px solid var(--line-2);font-size:13px;color:var(--muted)}
#drawer.page .rechead .reclinks a{color:var(--accent);text-decoration:none;font-weight:600} #drawer.page .rechead .reclinks a:hover{text-decoration:underline}
#drawer.page .rechead .reclinks .upd{margin-left:auto}
/* The public flyout (Steven, 2026-09-29): the four numbers and the verdict follow Listing facts with the same room a
   section gets, instead of sitting right under the listing's remarks. */
#drawer:not(.page) .sec+.kpis{margin-top:16px}
#drawer:not(.page) .kpis+.verdict{margin:12px 0 4px}
/* The page always keeps room for its scrollbar (Steven, 2026-09-29): switching a property's tab between one that fits the
   window and one that scrolls made the scrollbar come and go, and everything at the top shifted sideways by its width. */
html{scrollbar-gutter:stable}
/* The Stage bars: only the current stage lit, in gold (Steven, 2026-09-29). */
.lstep.gold i{background:var(--accent-fill)}
.lstep.gold b{color:var(--accent);font-weight:600}
/* A closed Status (Steven, 2026-09-29): every bar green (bought) or red (declined); only the Closed name is coloured. */
.lsteps.wf-closed .lstep b{color:var(--muted);font-weight:500}
.lsteps.wf-closed .lstep.done:last-child b{color:var(--pass);font-weight:600}
.lsteps.wf-closed .lstep.bad:last-child b{color:var(--fail);font-weight:600}
.lsteplbl b.good{color:var(--pass)}
/* The Stage bars: Purchased lit green, Declined red. */
.lstep.won i{background:var(--pass)}
.lstep.won b{color:var(--pass);font-weight:600}
/* The answer count inside the Evaluate button (Steven, 2026-09-29). */
/* No pill (Steven, 2026-09-29: the pill looked heavy): a thin divider, then the count in the label's own font, a
   same colour and weight as the word (Steven, 2026-09-29). */
.btn .evcount{display:inline-flex;align-items:center;margin-left:4px;padding-left:9px;border-left:1px solid currentColor;
  font:inherit;font-variant-numeric:tabular-nums;line-height:1.1;border-left-color:color-mix(in srgb,currentColor 45%,transparent)}
/* Configure as a centered window in every module (Steven, 2026-09-29; StenWimUI.cfgModal): a fixed header and save bar,
   and between them one scrolling body, one column of sections split by a rule (Steven, 2026-09-30; they were cards in
   two columns). A phone gets the whole screen. */
.drawer.cfgmodal{top:50%;left:50%;right:auto;bottom:auto;transform:translate(-50%,-50%);width:min(640px,94vw);max-height:88vh;
  padding:0;border:1px solid var(--line);border-radius:var(--r-md);display:flex;flex-direction:column;overflow:hidden;box-shadow:var(--shadow-far,var(--shadow))}
.drawer.cfgmodal[hidden]{display:none}
.cfgmodal>.drawer-close{top:14px;right:14px;z-index:2}
.cfgmodal>.dh{flex:none;margin:0;padding:18px 64px 14px 22px;border-bottom:1px solid var(--line)}
.cfgmodal .cfg-body{flex:1 1 auto;min-height:0;overflow:auto;padding:4px 22px 6px}
.cfgmodal .cfg-cols>.dsec{margin:0;padding:16px 0}
.cfgmodal .cfg-cols>.dsec:first-child{border-top:0}
.cfgmodal .cfg-cols>.dsec>h3:first-child{margin-top:0}
.cfgmodal>.savebar{flex:none;position:static;margin:0 22px 16px}
@media (max-width:640px){
  .drawer.cfgmodal{top:0;left:0;transform:none;width:100vw;max-height:none;height:100dvh;border:0;border-radius:0}
  .cfgmodal .cfg-body{padding:2px 14px 4px}
  .cfgmodal>.dh{padding:14px 60px 12px 16px}
  .cfgmodal>.savebar{margin:0 12px 12px}
}
/* Files on a record (Steven, 2026-10-01; files.js): a paperclip first in the record header's buttons, with the count,
   opens the Files window. One row a file: its type, the name (opens it), size, who and when, Download and Delete. */
.fxbtn{display:inline-flex;align-items:center;gap:5px}
.fxbtn .fxn{font-variant-numeric:tabular-nums}
.fxbtn .fxn:empty{display:none}
.fxdlg{width:min(640px,94vw);max-height:84vh;padding:0;border:1px solid var(--line);border-radius:var(--r-md);background:var(--sheet);color:var(--ink);box-shadow:var(--shadow)}
.fxdlg[open]{display:flex;flex-direction:column}
.fxdlg::backdrop{background:rgba(10,16,24,.45)}
.fxdlg-h{display:flex;align-items:flex-start;gap:12px;padding:16px 18px 12px;border-bottom:1px solid var(--line)}
.fxdlg-t{flex:1;min-width:0}
.fxdlg-h h2{margin:0;font-size:var(--fs-3)}
.fxdlg-sub{margin-top:2px;font-size:13px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fxdlg-sub:empty{display:none}
.fxdlg-b{flex:1 1 auto;min-height:120px;overflow:auto;padding:12px 18px 16px}
.fxdlg-b .fx-head h3{display:none}
.fxdlg-b .fx-head{justify-content:flex-end}
.fx .fx-head{display:flex;align-items:center;gap:8px;margin-bottom:6px}
.fx .fx-head h3{flex:1;margin:0;font-size:13.5px;font-weight:700;justify-content:flex-start;gap:6px}
.panel.fx .fx-head h3{font-size:15px}
.fx .fx-head h3 .hint{font-weight:400}
.fx-list{list-style:none;margin:0;padding:0}
.fx-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto auto;align-items:center;column-gap:10px;padding:6px 0;border-top:1px solid var(--line-2)}
.fx-row:first-child{border-top:0}
.fx-type{min-width:34px;padding:3px 6px;border-radius:var(--r-sm);background:var(--accent-soft);color:var(--accent);font-size:10.5px;font-weight:700;letter-spacing:.04em;text-align:center}
.fx-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink);font-weight:600;text-decoration:none}
.fx-name:hover{color:var(--accent);text-decoration:underline}
.fx-meta{font-size:var(--fs-1);color:var(--muted);white-space:nowrap}
.fx-btn{display:inline-flex;align-items:center;justify-content:center;padding:4px 6px;text-decoration:none}
.fx-btn[data-fx-del]:hover{color:var(--fail)}
.fx-empty{font-size:13px;line-height:1.45;color:var(--muted)}
/* Comments on an acquisition (Steven, 2026-10-02; purchasing.html): a bubble with the count in the header opens a thread
   in the Files window's frame, with the box to add one at its foot. */
.cmbtn{display:inline-flex;align-items:center;gap:5px}
.cmbtn .fxn{font-variant-numeric:tabular-nums}
.cmbtn .fxn:empty{display:none}
/* Both buttons carry their name beside the icon (Steven, 2026-10-07); the count follows it, quieter. */
.fxbtn .fxl,.cmbtn .fxl{white-space:nowrap}
.fxbtn .fxn,.cmbtn .fxn{color:var(--muted)}
.cm-thread{list-style:none;margin:0;padding:0}
.cm{padding:8px 0;border-top:1px solid var(--line-2)}
.cm:first-child{border-top:0}
.cm-h{display:flex;align-items:center;gap:8px;font-size:13px}
.cm-at{font-size:var(--fs-1);color:var(--muted)}
.cm-tools{margin-left:auto;display:inline-flex;gap:2px}
.cm-tools [data-cm-edit]:hover{color:var(--accent)}
.cm-tools [data-cm-del]:hover{color:var(--fail)}
.cm-edit textarea{display:block;box-sizing:border-box;width:100%;min-height:60px;margin-top:4px;resize:vertical}
.cm-edit-a{display:flex;justify-content:flex-end;gap:6px;margin-top:6px}
/* The bubble beside the status on a list row (Steven, 2026-10-02): opens the thread without opening the acquisition. */
.cmchip{display:inline-flex;align-items:center;gap:4px;padding:3px 7px;border-radius:var(--r-sm);color:var(--muted);font-size:12.5px;font-variant-numeric:tabular-nums;cursor:pointer}
.cmchip:hover,.cmchip:focus-visible{color:var(--accent);background:var(--accent-soft)}
.cmchip.has{color:var(--ink-2)}
.cm-t{margin-top:2px;font-size:13.5px;line-height:1.45;white-space:pre-wrap;overflow-wrap:anywhere}
.cm-new{display:flex;align-items:flex-end;gap:8px;padding:12px 18px 16px;border-top:1px solid var(--line)}
.cm-new textarea{flex:1;min-height:44px;resize:vertical}
.fx-status{margin-top:6px;font-size:12.5px;color:var(--muted)}
.fx-status:empty{display:none}
.fx.fx-drop{outline:2px dashed var(--accent);outline-offset:3px}
body[data-role="viewer"] .fx-edit{display:none!important}
@media (max-width:640px){
  .fx-row{grid-template-columns:auto minmax(0,1fr) auto auto;row-gap:2px}
  .fx-type,.fx-btn{grid-row:1/span 2}
  .fx-name{grid-column:2;grid-row:1} .fx-meta{grid-column:2;grid-row:2;white-space:normal}
}
/* Track's screen summary is gone from the title row (Steven, 2026-10-21): Last screen and the screen bar say it. */
#runbar #runinfo{display:none!important}
/* The title row in three parts from 1440px (Steven, 2026-10-21): the left block (page name, business and location, Last
   screen) and the buttons share the spare width equally, so the search box with its Filter sits in the middle. */
.ptleft{display:contents}
@media (min-width:1440px){
  body.has-ctxbar .pagetitle{flex-wrap:nowrap}
  body.has-ctxbar .pagetitle>.ptleft{display:flex;align-items:center;gap:var(--sp-3);flex:1 1 0;min-width:max-content}
  body.has-ctxbar .pagetitle>.acts{flex:1 1 0;justify-content:flex-end;min-width:max-content;margin-left:0}
  body.has-ctxbar .pagetitle>.find{position:relative;left:auto;top:auto;transform:none;flex:0 1 420px;min-width:200px;max-width:420px;margin:0 12px}
  body.has-ctxbar .pagetitle>.find:has(>.fbeside){margin:0 108px 0 12px}
}

/* ---------- one control size (Steven, 2026-10-23) ----------
   Every button and every tab on a wide screen is the title row's 28px with 13.5px words: the page's actions, a card's
   buttons, a drawer's buttons, the section tabs and the back buttons. They were 22, 26, 28, 32 and 34px. Quiet icon
   buttons (close, move, edit, delete), the stars and the photo strip are not counted. A choice inside a form (a .seg in a
   .field) keeps the 34px of the boxes beside it. Phones keep their larger tap targets. */
@media (min-width:761px){
  .btn:not(.quiet):not(.dlg-x):not(.burger),.seg:not(.field .seg)>button{height:28px!important;min-height:0!important;box-sizing:border-box;padding-top:0!important;padding-bottom:0!important;font-size:13.5px!important;line-height:26px}
  .seg:not(.field .seg)>button{padding-left:12px;padding-right:12px}
  body .ctxbar.intitle .btn.ctxbtn{font-size:12.5px!important}   /* the data pills: the row's height, their own smaller words */
}

/* ---------- the title row from 761 to 1439px (Steven, 2026-10-27) ----------
   Two rows, not three: the page name, business, location and buttons share the first; the search box and its Filter
   take the second at full width. Below 1100px the outlined buttons show only their icon (the words stay as the
   tooltip). The primary button keeps its words. */
@media (min-width:761px) and (max-width:1439px){
  body.has-ctxbar .pagetitle>.acts{flex-wrap:nowrap}
  body.has-ctxbar .pagetitle>.find{order:5;flex:1 1 100%;max-width:none;margin:0 96px 0 0}
  body.has-ctxbar .pagetitle>.find:not(:has(>.fbeside)){margin-right:0}
}
@media (min-width:761px) and (max-width:1099px){
  body.has-ctxbar .pagetitle .acts .btn:not(.primary):has(>svg)>span{display:none}
  body.has-ctxbar .pagetitle .acts .btn:not(.primary):has(>svg){padding-left:7px;padding-right:7px}
}
/* The header from 761 to 1439px (Steven, 2026-10-27): the site name and the app links share one row where they fit.
   The subtitle gives way (it needed about 1200px), and below 1100px the links sit a little closer and the name is the phone size (17px). The links keep their
   words (2026-10-22). Narrower than about 930px the links still take a row of their own. */
@media (min-width:761px) and (max-width:1439px){
  .top .brand .sub{display:none}
}
@media (min-width:761px) and (max-width:1099px){
  .top{column-gap:12px}
  .top-right,.top-right .appnavs{gap:6px}
  .top-right .btn{padding-left:7px;padding-right:7px}
  .top .brand h1{font-size:17px}
}
