/* CutPile app shell. Dark walnut sidebar, light paper workspace.
   Metronic demo1 layout patterns in the CutPile brand system. */
:root{
  --walnut:#2b211a; --walnut-2:#241c15; --walnut-3:#352a21;
  --paper:#f7f4ee; --surface:#ffffff; --line:#e7e0d4; --line-2:#efe9df;
  /* --card was used in eight places and defined in none, so every one of them had NO background at
     all. Most sit on a pale page and nobody noticed. The call menu opens over the dark brown profile
     header, where a missing background means you read the header straight through the menu. */
  --card:#ffffff;
  /* THE READABILITY FLOOR, measured rather than judged. Small uppercase mono labels are the thing
     people scan a page by, they are set at 9 to 11px, and at that size they need MORE contrast than
     body text, not less. --faint was #9a8a76: 3.35:1 on white, which fails AA for small text, and it
     was carrying every card header, every table header and every field label. Quiet text that cannot
     be read is not quiet, it is absent. All three are now above the line, and the gaps between them
     are wide enough to still read as a hierarchy: 16.8 / 6.5 / 4.9. */
  --ink:#241c15; --muted:#6b5c49; --faint:#7f6f5c;
  /* The smallest type in the app, so the strongest of the greys: 7.7:1. Uppercase mono labels only. */
  --label:#5f513f;
  --oak:#c9a87c; --oak-dim:#a4917b;
  /* The highlight: where you are, what is primary, what to press. It marks the same thing a
     chalk line does on a subfloor, but Jon wanted it warm - a saturated chocolate brown that
     pops off the dark walnut sidebar and still sits inside the walnut/paper/oak family instead
     of the old blue that stood outside it. --chalk-2 is the brighter press/hover; --chalk-soft
     is the pale warm wash for focus glows. (Kept the token name so nothing downstream has to move.) */
  --chalk:#8f4c23; --chalk-2:#ad5f2d; --chalk-soft:#f3e7db;
  --ok:#3f8f43; --ok-soft:#e6f2e6; --warn:#b7791f; --warn-soft:#fbf0da; --lost:#a24a3c; --lost-soft:#f6e6e2;
  /* The four segments of the sample fan in the CutPile mark, sampled from the logo. The standing rule
     is that the spectrum classifies DATA and never becomes chrome, and that still holds: these only
     ever appear as the 2px rule beside a section header, saying what KIND of thing the box holds.
     The header text itself stays --label in every variant, so no accent can push a label below the
     readability floor - two of these four would, on white. Color marks the section; it never carries
     the words. */
  --cat-orange:#f7972a; --cat-red:#ef4c2d; --cat-cyan:#32b2e1; --cat-blue:#296eb2;
}
*{margin:0;padding:0;box-sizing:border-box}
/* The hidden attribute always wins. A class with `display:...` (e.g. .bell-count{display:flex})
   would otherwise beat [hidden] and pin the element visible — that is what showed a "0" bell badge
   and, before this, kept the voice overlay open. One line, whole family of bugs. */
[hidden]{display:none !important}
body{font-family:'Instrument Sans',system-ui,sans-serif;color:var(--ink);background:var(--paper);-webkit-font-smoothing:antialiased;line-height:1.5}
/* Lock the canvas: nothing may push the page wider than the screen, so mobile can't be
   slid sideways. Long tokens (URLs, SKUs) wrap instead of stretching the layout. */
/* overflow-x:clip, not hidden. hidden on html and body makes the body the scroll container, and a
   position:sticky sidebar then sticks to a box that never scrolls while the page scrolls out from
   under it - which is how the version and sign-out footer vanished on every long page. clip stops
   sideways overflow without creating a scroll container, so sticky keeps working. */
html,body{max-width:100%;overflow-x:clip;overscroll-behavior-x:none}
.tl-body,.notif-m,.notif-ctx,.jc-body,.bubble,.ai-bubble{overflow-wrap:anywhere;word-break:break-word}
/* Call-recording player */
.rec{display:flex;align-items:center;gap:.6rem;margin:.4rem 0;max-width:100%}
.rec audio{height:36px;flex:1;min-width:0;max-width:100%}
.rec-dur{font-family:'IBM Plex Mono',monospace;font-size:.72rem;color:var(--faint);flex:none}
/* Scannable activity data: prices, SKUs, dates, phones, codes get a quiet, distinct mark. */
.hl{font-weight:600;border-radius:3px;padding:.02em .2em;white-space:nowrap;background:transparent}
.hl-money{color:#357a39;background:rgba(63,143,67,.12)}
.hl-sku,.hl-code{font-family:'IBM Plex Mono',monospace;font-weight:500;font-size:.94em}
.hl-sku{color:#9a6a1f;background:rgba(201,168,124,.2)}
.hl-code{color:var(--muted);background:var(--line-2)}
.hl-phone{color:var(--ink);background:rgba(122,106,86,.14)}
.hl-date,.hl-time{color:#96631a;background:rgba(183,121,31,.13)}
.hl-dim,.hl-pct{color:var(--ink);background:var(--line-2)}
.tl-title .hl{font-weight:700}
.mono{font-family:'IBM Plex Mono',monospace}
a{color:inherit;text-decoration:none}
.ic{width:20px;height:20px;flex:none}
:focus-visible{outline:2px solid var(--chalk-2);outline-offset:2px;border-radius:3px}

/* ---------- layout ---------- */
.app{display:grid;grid-template-columns:15rem 1fr;min-height:100vh}
.side{background:var(--walnut);color:#e8ddcf;display:flex;flex-direction:column;position:sticky;top:0;height:100vh}
.brand{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.3rem;letter-spacing:-.02em;padding:1.3rem 1.4rem .8rem}
.brand b{color:var(--oak)}
.side nav{flex:1;overflow-y:auto;padding:.4rem .7rem}
.nav-sec{margin-bottom:1.1rem}
.nav-h{display:block;font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.14em;text-transform:uppercase;color:#7d6b57;padding:.4rem .7rem}
.nav-i{display:flex;align-items:center;gap:.7rem;padding:.55rem .7rem;border-radius:7px;color:#cbbba6;font-size:.93rem;font-weight:500}
.nav-i:hover{background:var(--walnut-3);color:var(--paper)}
.nav-i.on{background:var(--chalk);color:#fff}
.nav-i.on .ic{color:#fff}
.nav-i .ic{width:18px;height:18px;color:var(--oak-dim)}
.nav-i.on .ic,.nav-i:hover .ic{color:currentColor}
.side-foot{display:flex;align-items:center;justify-content:space-between;padding:.9rem 1.3rem;border-top:1px solid #3c2f24;color:#7d6b57;font-size:.72rem}
.side-foot a{color:#7d6b57;display:flex}.side-foot a:hover{color:var(--oak)}

.main{min-width:0;display:flex;flex-direction:column}
.top{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:1.05rem clamp(1.1rem,3vw,2.2rem);background:var(--surface);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:10}
.top h1{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.55rem;letter-spacing:-.02em;color:var(--ink)}
.topsearch{display:flex;align-items:center;gap:.5rem;background:var(--paper);border:1px solid var(--line);border-radius:8px;padding:.5rem .8rem;color:var(--muted);min-width:min(20rem,42vw)}
.topsearch .ic{width:17px;height:17px}
.topsearch input{border:0;background:transparent;font:inherit;font-size:.9rem;color:var(--ink);width:100%;outline:none}
.content{padding:clamp(1.1rem,3vw,2.2rem);max-width:80rem;width:100%}
.content-wide{max-width:100%}

/* ---------- topbar right cluster ---------- */
.topright{display:flex;align-items:center;gap:.9rem}
.bell{position:relative;color:var(--muted);display:flex;padding:.35rem;border-radius:8px}
.bell:hover{background:var(--paper);color:var(--ink)}
.bell .ic{width:20px;height:20px}
.bell-count{position:absolute;top:-2px;right:-2px;background:var(--lost);color:#fff;font-size:.6rem;font-weight:700;min-width:15px;height:15px;border-radius:999px;display:flex;align-items:center;justify-content:center;padding:0 3px;font-family:'IBM Plex Mono',monospace}
.topuser .av.sm{width:32px;height:32px;font-size:.72rem}
/* universal search */
.usearch{position:relative;display:flex;align-items:center;gap:.5rem;background:var(--paper);border:1px solid var(--line);border-radius:8px;padding:.5rem .8rem;color:var(--muted);min-width:min(24rem,44vw)}
.usearch .ic{width:17px;height:17px}
.usearch input{border:0;background:transparent;font:inherit;font-size:.9rem;color:var(--ink);width:100%;outline:none}
.usearch-drop{position:absolute;top:calc(100% + .4rem);left:auto;right:0;min-width:min(32rem,94vw);
  max-width:96vw;background:var(--surface);border:1px solid var(--line);border-radius:12px;
  box-shadow:0 18px 44px rgba(0,0,0,.16);overflow:hidden;z-index:60;max-height:70vh;overflow-y:auto;
  padding-bottom:.35rem}

/* ------------------------------------------------- omnisearch: a card per answer
 *
 * Rows became cards because the three kinds of answer were competing on one flat list and nothing
 * told them apart until you had read them. Each kind now has a colour, and they are the colours this
 * system already uses rather than a new scheme invented for the dropdown: staff blue for a person,
 * chalk for a floor, oak for an account.
 *
 * A job is deliberately the exception. It keeps its own STATUS colour on the spine, because that is
 * real information the search worked to put there, and painting every job one shade to make the
 * dropdown tidier would throw it away to win a stripe.
 *
 * The tint is kept very low - a wash, not a fill - so the text on it stays as readable as text on
 * white. A colour-coded list that costs you contrast has made a bad trade.
 */
.ux-group{font-family:'IBM Plex Mono',monospace;font-size:.62rem;font-weight:600;letter-spacing:.13em;
  text-transform:uppercase;color:var(--label);padding:.7rem .8rem .32rem;display:flex;align-items:center;gap:.4rem}
.ux-group::before{content:'';width:4px;height:.95em;border-radius:2px;background:var(--k,var(--line))}
.ux-g-who{--k:#2f5d8a} .ux-g-job{--k:var(--chalk)} .ux-g-acct{--k:var(--oak)}
.ux-g-place{--k:var(--cat-cyan)} .ux-g-prod{--k:var(--chalk-2)} .ux-g-said{--k:var(--line)}

.ux-cards{display:flex;flex-direction:column;gap:.3rem;padding:0 .55rem}
.ux-item{
  display:flex;flex-direction:row;align-items:center;gap:.6rem;
  padding:.5rem .7rem;color:var(--ink);border-radius:9px;
  /* The pinstripe: a hairline all the way round in the kind's colour, and a heavier one down the
     left edge. Both are the same hue, so the card reads as one object rather than a box with a tag
     stuck on it. */
  border:1px solid color-mix(in srgb, var(--k, var(--line)) 26%, transparent);
  border-left:3px solid var(--k, var(--line));
  background:color-mix(in srgb, var(--k, var(--line)) 4.5%, var(--surface));
  transition:background .12s ease, border-color .12s ease, transform .12s ease;
}
.ux-item.ux-k-who{--k:#2f5d8a} .ux-item.ux-k-acct{--k:var(--oak)}
.ux-item.ux-k-place{--k:var(--cat-cyan)} .ux-item.ux-k-prod{--k:var(--chalk-2)}
.ux-item.ux-k-said{--k:var(--line-2)}
.ux-item.ux-k-said .ux-t{font-weight:500}
/* ux-k-job takes its --k from the inline status colour, and falls back if a status has none. */
.ux-item.ux-k-job{--k:var(--chalk)}
.ux-item:hover,.ux-item.on{
  background:color-mix(in srgb, var(--k, var(--line)) 13%, var(--surface));
  border-color:color-mix(in srgb, var(--k, var(--line)) 55%, transparent);
}
.ux-item.on{transform:translateX(1px)}
.ux-t{font-size:.9rem;font-weight:600;letter-spacing:-.005em}
.ux-tx{display:flex;flex-direction:column;gap:.06rem;min-width:0;flex:1 1 auto}
.ux-t,.ux-s{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ux-sw{width:32px;height:32px;flex:0 0 auto;border-radius:6px;object-fit:cover;background:var(--line);
  border:1px solid color-mix(in srgb, var(--k, var(--line)) 30%, transparent)}
.ux-s{font-size:.755rem;color:var(--faint)}
/* The status word the spine cannot say. Right-aligned, quiet, and the first thing to go when the
   card runs out of room - the name and the address matter more. */
.ux-k{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-family:'IBM Plex Mono',monospace;font-size:.58rem;letter-spacing:.09em;text-transform:uppercase;
  color:color-mix(in srgb, var(--k, var(--muted)) 72%, var(--ink));
  background:color-mix(in srgb, var(--k, var(--line)) 15%, transparent);
  border-radius:999px;padding:.16rem .42rem}
@media (max-width:640px){ .ux-k{display:none} }
.ux-ask{margin:.4rem .55rem 0;border-radius:9px;border:1px dashed var(--line);
  background:var(--paper);flex-direction:column;align-items:flex-start;gap:.05rem}
.ux-ask .ux-t{color:var(--chalk);font-weight:600}
@media (max-width:640px){.usearch{min-width:0;width:2.4rem;padding:.5rem}.usearch input{display:none}}

/* voice: talk to CutPile */
.voicebtn{display:flex;align-items:center;gap:1rem;width:100%;max-width:44rem;border:0;cursor:pointer;text-align:left;
  background:linear-gradient(120deg,var(--walnut),var(--walnut-3));color:#f1e7d8;border-radius:14px;padding:1.1rem 1.3rem;margin-bottom:1.5rem;
  box-shadow:0 16px 40px rgba(0,0,0,.28)}
.voicebtn:hover{filter:brightness(1.08)}
.voicebtn.setup{opacity:.9}
.voice-mic{width:48px;height:48px;border-radius:50%;background:var(--chalk);display:flex;align-items:center;justify-content:center;flex:none;position:relative}
.voice-mic .ic{width:24px;height:24px;color:#fff}
.voicebtn:not(.setup) .voice-mic::after{content:"";position:absolute;inset:-5px;border-radius:50%;border:2px solid var(--chalk-2);opacity:.6;animation:voicepulse 1.8s ease-out infinite}
@keyframes voicepulse{0%{transform:scale(1);opacity:.6}100%{transform:scale(1.35);opacity:0}}
@media (prefers-reduced-motion:reduce){.voicebtn .voice-mic::after{animation:none}}
.voice-lead{display:block;font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.2rem;letter-spacing:-.01em;color:#fff}
.voice-sub{display:block;font-size:.85rem;color:var(--oak-dim);margin-top:.15rem}
/* Live-session states for Talk to CutPile. */
.voicebtn[data-state=connecting] .voice-mic{background:var(--warn)}
.voicebtn[data-state=live] .voice-mic{background:var(--ok)}
.voicebtn[data-state=live] .voice-mic::after{border-color:var(--ok);opacity:.7}
.voicelive{max-width:44rem;margin:-.6rem 0 1.5rem;border:1px solid var(--line);border-radius:12px;padding:.9rem 1.1rem;background:var(--surface)}
.voicelive-transcript{font-size:.95rem;line-height:1.5;color:var(--ink);white-space:pre-wrap;max-height:12rem;overflow-y:auto;min-height:1.5rem}
.voicelive-transcript:empty::before{content:"…";color:var(--faint)}
.voicelive-hint{font-size:.72rem;color:var(--muted);margin-top:.5rem}

/* assistant / chat */
.chat{max-width:44rem}
.chat-msg{display:flex;gap:.7rem;margin-bottom:1.1rem;align-items:flex-start}
.chat-msg.you{flex-direction:row-reverse}
.chat-av{width:30px;height:30px;border-radius:8px;background:var(--chalk);color:#fff;display:flex;align-items:center;justify-content:center;flex:none}
.chat-av .ic{width:17px;height:17px}
.bubble{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:.75rem 1rem;font-size:.94rem;max-width:80%}
.chat-msg.you .bubble{background:var(--chalk);color:#fff;border-color:var(--chalk)}
.ai-bubble strong{display:block;margin-bottom:.3rem}
.ai-bubble p{color:var(--muted);font-size:.9rem}
.ai-bubble a{color:var(--chalk);font-weight:600}
.chat-compose{display:flex;gap:.5rem;margin-top:1.5rem;position:sticky;bottom:1rem}
.chat-compose input{flex:1;border:1px solid var(--line);border-radius:10px;padding:.7rem .9rem;font:inherit;font-size:.95rem;background:var(--surface)}
.chat-compose input:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
.chat-compose button{background:var(--chalk);color:#fff;border:0;border-radius:10px;padding:0 1rem;cursor:pointer;display:flex;align-items:center}
.chat-compose button .ic{width:18px;height:18px}
.av.sm{width:28px;height:28px;border-radius:50%;background:var(--walnut);color:var(--oak);display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:.66rem;font-family:'Bricolage Grotesque',sans-serif}
.has-photo{background-size:cover!important;background-position:center;color:transparent!important}
@media (max-width:640px){.topsearch{display:none}}

/* ---------- general feed ---------- */
/* Wraps. It used to be nowrap with an ellipsis, which was fine when the hint was three words;
   now it is a sentence, and a nowrap sentence sets a min-content width that no grid track can
   shrink below - which pushed the whole job page wider than a phone screen. */
.composer-hint{font-family:'IBM Plex Mono',monospace;font-size:.72rem;color:var(--faint);white-space:normal;line-height:1.45}
.tl-author{font-weight:700;font-size:.95rem;font-family:'Bricolage Grotesque',sans-serif}
.tl-dot .av.sm{width:34px;height:34px;font-size:.72rem}
.mention{color:var(--chalk);font-weight:600;background:var(--chalk-soft);padding:.02rem .3rem;border-radius:5px}
.tl-tags{display:flex;align-items:center;gap:.35rem;margin-top:.5rem;font-size:.75rem;color:var(--muted);font-family:'IBM Plex Mono',monospace}
.tl-tags .ic{width:13px;height:13px;color:var(--oak-dim)}

/* ---------- per-job chat ---------- */
.jobchat{margin-bottom:1rem}
.jc-thread{display:flex;flex-direction:column;gap:.7rem;max-height:22rem;overflow-y:auto;margin-bottom:.8rem}
.jc-msg{display:flex;flex-direction:column;gap:.15rem;background:var(--paper);border:1px solid var(--line-2);border-radius:10px;padding:.55rem .8rem}
.jc-msg.ai{background:var(--chalk-soft);border-color:var(--chalk-soft)}
.jc-who{font-family:'IBM Plex Mono',monospace;font-size:.64rem;letter-spacing:.08em;text-transform:uppercase;color:var(--chalk)}
.jc-msg.ai .jc-who{color:var(--chalk)}
.jc-body{font-size:.92rem;color:var(--ink)}
.jc-time{font-size:.72rem;color:var(--faint)}
.jc-compose{display:flex;gap:.5rem}
/* The composer is a textarea now (see the note in modules/jobs/view.php). It has to keep looking
   like the single-line box it was: no resize grip, no scrollbar until it has really grown. The
   mention wrapper sits between the form and the field, so it takes the flex sizing. */
.jc-compose input,.jc-compose textarea,.jc-compose .mention-wrap{flex:1;min-width:0;
  border:1px solid var(--line);border-radius:9px;padding:.6rem .8rem;font:inherit;font-size:.92rem;
  background:var(--paper)}
.jc-compose .mention-wrap{padding:0;border:0;background:none}
.jc-compose textarea{display:block;width:100%;resize:none;overflow-y:auto;max-height:140px;
  line-height:1.45}
.jc-compose input:focus,.jc-compose textarea:focus{outline:none;border-color:var(--chalk-2);
  box-shadow:0 0 0 3px var(--chalk-soft)}
.jc-compose button{align-self:flex-end;height:38px}
.jc-compose button{background:var(--chalk);color:#fff;border:0;border-radius:9px;padding:0 .9rem;cursor:pointer;display:flex;align-items:center}
.jc-compose button .ic{width:17px;height:17px}
.jc-note{margin-top:.6rem;font-size:.8rem;color:var(--faint)}
.jc-note a{color:var(--chalk);font-weight:600}

/* account -> jobs list */
.acctjob{display:flex;align-items:center;gap:.7rem;padding:.6rem 0;border-bottom:1px solid var(--line-2)}
.acctjob:last-child{border-bottom:0}
.acctjob:hover{background:var(--paper)}
.acctjob-b{flex:1;display:flex;flex-direction:column;min-width:0}
.acctjob-n{font-weight:600;font-size:.92rem}
.acctjob-s{font-size:.8rem;color:var(--faint)}

/* ---------- notifications ---------- */
.notif{display:flex;align-items:flex-start;gap:.7rem;padding:.75rem .2rem;border-bottom:1px solid var(--line-2)}
.notif:last-child{border-bottom:0}
.notif:hover{background:var(--paper)}
.notif-dot{width:8px;height:8px;border-radius:50%;background:transparent;margin-top:.45rem;flex:none}
.notif.fresh .notif-dot{background:var(--chalk)}
.notif-body{flex:1;display:flex;flex-direction:column;gap:.15rem}
.notif-msg{font-weight:600;font-size:.92rem}
.notif.fresh .notif-msg{color:var(--ink)}
.notif-ctx{font-size:.84rem;color:var(--muted)}
.notif-time{font-size:.78rem;color:var(--faint);white-space:nowrap}

/* ---------- identity picker ---------- */
/* The picker needs a wider card than the passphrase form it borrows its styling from. That card is
   24rem, which is right for one password field and wrong for two columns of people: after the avatar,
   the gap and the room kept for the arrow, about 55 pixels were left for a name. Every name of two
   words wrapped onto a second line, every card grew a line taller, and the whole thing looked stretched
   because it was. */
/* Named login-who, not who: .who is already the avatar-and-name row in the jobs list, and a card
   wearing that class inherits its display:flex and lays itself out sideways. */
/* Two classes deep on purpose: .login sets a 24rem width some 700 lines further down this file, and at
   equal specificity the later rule wins. A single .login-who was being overruled by it and the card
   never actually widened, so the names simply truncated instead of wrapping. */
.login.login-who{width:min(33rem,94vw)}
/* minmax(0,1fr), not 1fr. Holding the names to one line made each card's min-content as wide as its
   longest name, and a plain 1fr is really minmax(auto,1fr), which refuses to go below that: the columns
   pushed straight out through the side of the card. The zero lets them shrink so the ellipsis can do
   the job it was added for. The forms are the grid items, so they need to be allowed to shrink too. */
.who-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:.65rem;margin-top:1.4rem}
.who-grid > form{min-width:0}
/* One column while the card is narrow enough that two would crush the names again. */
@media (max-width:30rem){.login.login-who{width:min(22rem,94vw)} .who-grid{grid-template-columns:minmax(0,1fr)}}
/* scoped past .login button so these get their own deliberate style, not the CTA fill */
.who-grid .who-pick{
  position:relative;display:flex;align-items:center;gap:.75rem;width:100%;
  background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:13px;
  padding:.68rem 1.55rem .68rem .75rem;cursor:pointer;font:inherit;text-align:left;
  transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease;
}
.who-grid .who-pick:hover,.who-grid .who-pick:focus-visible{
  transform:translateY(-3px);border-color:var(--chalk-2);
  box-shadow:0 12px 26px rgba(43,33,26,.15);outline:none;
}
.who-grid .who-pick .av{width:42px;height:42px;flex:0 0 42px;font-size:.86rem;transition:box-shadow .16s ease}
.who-grid .who-pick:hover .av,.who-grid .who-pick:focus-visible .av{box-shadow:0 0 0 3px var(--chalk-soft)}
.who-id{display:flex;flex-direction:column;min-width:0;gap:.05rem}
/* Never wrap. A name that does not fit is trimmed instead, so every card is exactly the same height
   and the grid reads as a row of people rather than a stack of different-sized boxes. */
.who-name{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:.98rem;letter-spacing:-.01em;
  line-height:1.2;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.who-handle{font-family:'IBM Plex Mono',monospace;font-size:.71rem;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.who-grid .who-pick::after{content:"\2192";position:absolute;right:.85rem;top:50%;transform:translateY(-50%) translateX(-4px);color:var(--chalk);font-size:1.05rem;opacity:0;transition:opacity .16s ease,transform .16s ease}
.who-grid .who-pick:hover::after,.who-grid .who-pick:focus-visible::after{opacity:1;transform:translateY(-50%) translateX(0)}

/* ---------- product catalog ---------- */
.prod-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(13rem,1fr));gap:.9rem}
.prod{background:var(--surface);border:1px solid var(--line);border-radius:11px;overflow:hidden;display:flex;flex-direction:column}
/* Hover is warm, focus is chalk. They were both --chalk-2, which meant hovering a
   card looked identical to focusing it and the focus ring lost its only job. */
.prod:hover{border-color:var(--oak)}
.prod.disc{opacity:.55}
.prod-img{aspect-ratio:4/3;background:var(--plank);overflow:hidden}
.prod-img img{width:100%;height:100%;object-fit:cover;display:block}
.prod-body{padding:.7rem .8rem}
.prod-name{font-weight:600;font-size:.92rem;line-height:1.2}
.prod-meta{color:var(--faint);font-size:.76rem;margin-top:.25rem}
.color-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(6.5rem,1fr));gap:.7rem}
.color{border:1px solid var(--line);border-radius:9px;overflow:hidden;background:var(--surface)}
.color.dropped{opacity:.5}
.color img{width:100%;aspect-ratio:1;object-fit:cover;display:block}
.color-noimg{width:100%;aspect-ratio:1;background:var(--plank)}
.color-name{padding:.4rem .5rem;font-size:.76rem;font-weight:500}
/* coordinating trim tiles reuse the color grid; the trim image sits on paper (moldings are shot on white) */
.prod-trim-lead{margin:.1rem 0 .7rem;font-size:.82rem;color:var(--muted);line-height:1.45}
.color.trim img,.color.trim .color-noimg{object-fit:contain;background:var(--paper)}
.trim-dims{display:block;font-size:.62rem;color:var(--muted);font-weight:400;margin-top:.1rem}
.trim-colors{display:block;font-size:.58rem;color:var(--faint);font-weight:400}

/* ---------- knowledge graph ---------- */
.gtype{display:flex;align-items:center;gap:.7rem;background:var(--surface);border:1px solid var(--line);border-radius:11px;padding:1rem 1.1rem}
.gtype:hover{border-color:var(--oak);background:var(--paper)}
.gtype .ic{width:20px;height:20px;color:var(--oak-dim)}
.gtype-n{font-weight:600;font-size:.95rem}
.gtype-c{margin-left:auto;font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:1.15rem;color:var(--muted)}
.gcard{display:flex;flex-direction:column;gap:.2rem;background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:.85rem 1rem}
.gcard:hover{border-color:var(--oak);background:var(--paper)}
.gcard-name{font-weight:600;font-size:.95rem}
.gcard-hint{font-size:.8rem;color:var(--faint)}
.gnode-head{display:flex;align-items:center;gap:.8rem;flex-wrap:wrap;margin-bottom:1.2rem}
.gnode-head h2{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.7rem;letter-spacing:-.02em}
.gback{margin-left:auto;font-size:.85rem;color:var(--chalk);font-weight:600}
.grel + .grel{margin-top:1rem;padding-top:1rem;border-top:1px solid var(--line-2)}
.grel-label{font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-bottom:.5rem}
.grel-nodes{display:flex;flex-wrap:wrap;gap:.5rem}
.gchip{display:inline-flex;align-items:center;gap:.45rem;background:var(--paper);border:1px solid var(--line);border-radius:8px;padding:.4rem .7rem;font-size:.88rem;font-weight:500}
.gchip:hover{border-color:var(--oak);background:var(--surface)}
.gchip-t{font-family:'IBM Plex Mono',monospace;font-size:.6rem;letter-spacing:.06em;text-transform:uppercase;color:var(--oak-dim)}

/* ---------- SOPs ---------- */
.sop-form-row{display:flex;gap:.6rem;margin-bottom:.6rem}
.sop-form-row input{flex:1;min-width:0;border:1px solid var(--line);border-radius:8px;padding:.6rem .7rem;font:inherit;font-size:.92rem;background:var(--paper)}
.sop-form textarea{width:100%;border:1px solid var(--line);border-radius:8px;padding:.7rem .8rem;font:inherit;font-size:.95rem;resize:vertical;min-height:4rem;background:var(--paper)}
.sop-form input:focus,.sop-form textarea:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
.sop-form-actions{margin-top:.6rem;display:flex;justify-content:flex-end}
.sop-cat{font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.13em;text-transform:uppercase;color:var(--faint);margin:1.4rem 0 .6rem}
.card.sop{padding:1rem 1.2rem}
.sop-head{display:flex;align-items:center;gap:.6rem;margin-bottom:.35rem}
.sop-title{font-family:'Bricolage Grotesque',sans-serif;font-weight:600;font-size:1.05rem}
.sop-body{color:var(--ink);font-size:.93rem;white-space:pre-wrap}
.sop-meta{margin-top:.5rem;font-family:'IBM Plex Mono',monospace;font-size:.7rem;color:var(--faint)}

/* ---------- 1-Click panel ---------- */
.app{grid-template-columns:15rem 1fr auto}
.pn{width:20rem;background:var(--surface);border-left:1px solid var(--line);height:100vh;position:sticky;top:0;display:flex;flex-direction:column;overflow:hidden}
body.pn-collapsed .pn{display:none}
.pn-top{display:flex;align-items:center;justify-content:space-between;padding:.9rem 1rem;border-bottom:1px solid var(--line)}
.pn-title{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:.95rem;letter-spacing:-.01em}
.pn-who{font-family:'IBM Plex Mono',monospace;font-size:.7rem;color:var(--faint)}
.pn-acts{display:flex;gap:.25rem;align-items:center}
.pn-btn{background:none;border:0;cursor:pointer;color:var(--faint);padding:.3rem;border-radius:6px;display:flex;font-size:1rem;line-height:1}
.pn-btn:hover{background:var(--paper);color:var(--ink)}
.pn-btn .ic{width:16px;height:16px}
.pn-body{flex:1;overflow-y:auto;padding:.8rem;display:flex;flex-direction:column;gap:.6rem}
.pn-open{display:none;position:fixed;right:0;top:50%;transform:translateY(-50%);z-index:30;background:var(--walnut);color:var(--oak);border:0;border-radius:8px 0 0 8px;padding:.7rem .4rem;cursor:pointer;font-size:1rem}
body.pn-collapsed .pn-open{display:block}
.pn-box{border:1px solid var(--line);border-radius:11px;overflow:hidden}
.pn-h{display:flex;align-items:center;gap:.45rem;padding:.5rem .7rem;background:var(--paper);font-family:'IBM Plex Mono',monospace;font-size:.64rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.pn-h .ic{width:14px;height:14px;color:var(--oak-dim)}
.pn-count{margin-left:auto;background:var(--chalk);color:#fff;border-radius:999px;padding:0 .35rem;font-size:.6rem}
.pn-row{display:flex;align-items:center;gap:.5rem;padding:.45rem .7rem;border-top:1px solid var(--line-2)}
.pn-row:hover{background:var(--paper)}
.pn-row.sent{background:var(--chalk-soft)}
.pn-row-t{font-size:.85rem;font-weight:500;display:flex;flex-direction:column;min-width:0}
.pn-row-s{font-size:.72rem;color:var(--faint);font-weight:400}
.pn-none{padding:.55rem .7rem;font-size:.8rem;color:var(--faint)}
.pn-tile{display:flex;align-items:center;gap:.6rem;border:1px solid var(--line);border-radius:11px;padding:.6rem .7rem;background:var(--surface)}
.pn-tile:hover{border-color:var(--oak);background:var(--paper)}
.pn-tile.sent{background:var(--chalk-soft);border-color:var(--chalk)}
.pn-tile-i{width:34px;height:34px;border-radius:9px;background:var(--walnut);color:var(--oak);display:flex;align-items:center;justify-content:center;flex:none}
.pn-tile.dial .pn-tile-i{background:var(--ok-soft);color:var(--ok)}
.pn-tile-i .ic{width:17px;height:17px}
.pn-tile-t{font-size:.88rem;font-weight:600;display:flex;flex-direction:column;min-width:0}
.pn-tile-s{font-size:.72rem;color:var(--faint);font-weight:400}
.pn-empty{font-size:.85rem;color:var(--faint);padding:.5rem}
.pn-empty a{color:var(--chalk);font-weight:600}
@media (max-width:1200px){.pn{display:none}.pn-open{display:none!important}}

/* pop-out remote */
.pn-popbody{background:var(--walnut);padding:.7rem}
.pn-pop{background:var(--surface);border-radius:14px;overflow:hidden;min-height:calc(100vh - 1.4rem);display:flex;flex-direction:column}
.pn-linked{font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.06em;color:var(--ok);background:var(--ok-soft);padding:.4rem .8rem;text-align:center}
.pn-linked.warn{color:var(--lost);background:var(--lost-soft)}

/* panel manager in settings */
.pl-row{display:flex;align-items:center;gap:.7rem;padding:.55rem 0;border-bottom:1px solid var(--line-2)}
.pl-row.off{opacity:.5}
.pl-type{font-family:'IBM Plex Mono',monospace;font-size:.6rem;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);width:5.5rem;flex:none}
.pl-label{flex:1;font-weight:600;font-size:.9rem;display:flex;flex-direction:column;min-width:0}
.pl-cfg{font-family:'IBM Plex Mono',monospace;font-size:.7rem;color:var(--faint);font-weight:400;overflow:hidden;text-overflow:ellipsis}
.pl-acts{display:flex;gap:.3rem;align-items:center}
.pl-acts form{display:flex}
.pl-add{display:flex;gap:.5rem;margin-top:1rem;flex-wrap:wrap;align-items:center}
.pl-add select,.pl-add input[type=text]{border:1px solid var(--line);border-radius:7px;padding:.5rem .7rem;font:inherit;font-size:.88rem;background:var(--paper)}
.pl-add input[type=text]{flex:1;min-width:9rem}
.pl-ext{display:flex;align-items:center;gap:.3rem;font-size:.8rem;color:var(--muted);text-transform:none;letter-spacing:0;font-family:inherit;margin:0}
.jc-note code{font-family:'IBM Plex Mono',monospace;font-size:.72rem;background:var(--paper);padding:.05rem .3rem;border-radius:4px}

/* ---------- generic cards ---------- */
.card{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:1.3rem 1.4rem}
.card + .card{margin-top:1rem}
/* A SECTION HEADER SHOULD CAP ITS SECTION. This was 11px of pale grey floating above a box, which
   told you a heading existed without telling you where its contents ended. It now has three jobs:
   a short accent rule that says what kind of box this is, a label dark enough to read at a glance,
   and a hairline that closes the header off from the content under it. Jon: the monotone palette
   makes it hard to find things when scanning. */
.card-h{display:flex;align-items:center;gap:.55rem;font-family:'IBM Plex Mono',monospace;
  font-size:.7rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--label);
  margin-bottom:.9rem;padding-bottom:.55rem;border-bottom:1px solid var(--line-2)}
/* The snapped chalk line, the same mark the breadcrumb rule uses: a floor layer snaps one to say
   where the first row goes. Here it says where a section starts. */
.card-h::before{content:'';flex:none;width:4px;height:1.1em;border-radius:2px;background:var(--chalk)}
/* What KIND of box, in one rule of color. Money, time, trouble, reference, people. Anything
   unlabelled stays chalk, so nothing has to be classified before it can be shown. */
.card-h.money::before{background:var(--ok)}
.card-h.time::before{background:var(--warn)}
.card-h.risk::before{background:var(--lost)}
.card-h.data::before{background:var(--cat-cyan)}
.card-h.people::before{background:var(--cat-blue)}
.card-h.stock::before{background:var(--cat-orange)}
/* A count or a state belongs on the header line, pushed to the end, in the same mono. */
.card-h .card-h-n{margin-left:auto;font-weight:500;letter-spacing:.06em;color:var(--faint)}
.stub{color:var(--muted);max-width:60ch}
.stub h2{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:1.4rem;color:var(--ink);margin-bottom:.5rem}

/* ---------- status chips ---------- */
.chip{display:inline-flex;align-items:center;gap:.4rem;font-size:.74rem;font-weight:600;padding:.22rem .6rem;border-radius:999px;white-space:nowrap}
.chip.gray{background:var(--line-2);color:var(--muted)}
.chip.ok{background:var(--ok-soft);color:var(--ok)}
.chip.warn{background:var(--warn-soft);color:var(--warn)}
.chip.lost{background:var(--lost-soft);color:var(--lost)}
.chip.chalk{background:var(--chalk-soft);color:var(--chalk)}
/* Status chips wear the job's own color (the V1 palette, which is the Google Calendar palette), passed
   inline as --sc. Solid pill + white text so status reads at a glance and works in both light and dark. */
.chip.st{background:var(--sc,#6B7280);color:#fff;text-shadow:0 1px 1px rgba(0,0,0,.16)}
.st-dot{display:inline-block;width:.5rem;height:.5rem;border-radius:50%;margin-right:.4rem;vertical-align:-1px;flex:none}

/* ---------- customers table ---------- */
.toolbar{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:1rem;flex-wrap:wrap}
.toolbar .count{color:var(--muted);font-size:.9rem;
  /* The count must never be what decides whether this row fits. A long search term used to be able to
     wrap the buttons onto a second line, which moved the whole table down the page. It gets a share of
     the space and an ellipsis instead. */
  /* No min-width: the dots are anchored to the right by margin-left:auto, so they do not move with this
     text anyway, and a floor here would override the mobile rule that keeps this row inside the
     viewport. */
  flex:0 1 auto;max-width:24rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.filters{display:flex;gap:.5rem;flex-wrap:wrap;align-items:center}
.listsel{font:inherit;font-size:.8rem;font-weight:600;padding:.4rem .6rem;border-radius:8px;border:1px solid var(--line);
  background:var(--surface);color:var(--ink);cursor:pointer;max-width:14rem}
.listsel:hover{border-color:var(--oak)}
.filt{font-size:.82rem;font-weight:600;padding:.4rem .8rem;border-radius:8px;border:1px solid var(--line);color:var(--muted);background:var(--surface)}
.filt.on{background:var(--chalk);color:#fff;border-color:var(--chalk)}
.table-wrap{background:var(--surface);border:1px solid var(--line);border-radius:12px;overflow:hidden}
table.cust{width:100%;border-collapse:collapse;font-size:.92rem}
/* The header row of a table is the single thing a person scans a list by, so it reads as a header:
   darker, heavier, and sitting on a rule twice the weight of the row lines beneath it. */
table.cust th{text-align:left;font-family:'IBM Plex Mono',monospace;font-size:.68rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--label);font-weight:600;padding:.8rem 1rem;
  border-bottom:2px solid var(--line);background:var(--paper)}
table.cust td{padding:.75rem 1rem;border-bottom:1px solid var(--line-2);vertical-align:middle}
/* A phone number broken across three lines is not a phone number. The data columns hold their line;
   the name column is the one allowed to wrap, because it is the one with room. */
table.cust td.num{white-space:nowrap}
table.cust tr:last-child td{border-bottom:0}
table.cust tbody tr:hover,table.cust tr.row:hover{background:var(--paper)}
.who{display:flex;align-items:center;gap:.7rem}
.av{width:36px;height:36px;border-radius:50%;background:var(--walnut);color:var(--oak);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.8rem;flex:none;font-family:'Bricolage Grotesque',sans-serif}
.who .nm{font-weight:600}
.who .sub{color:var(--faint);font-size:.8rem}
.num{font-variant-numeric:tabular-nums;color:var(--muted)}
.pager{display:flex;gap:.4rem;justify-content:center;margin-top:1.2rem}
.pager a,.pager span{padding:.4rem .7rem;border-radius:7px;font-size:.85rem;border:1px solid var(--line);color:var(--muted);background:var(--surface)}
.pager .cur{background:var(--chalk);color:#fff;border-color:var(--chalk)}

/* ---------- customer profile ---------- */
.prof-cover{background:linear-gradient(120deg,var(--walnut),var(--walnut-3));border-radius:14px;padding:1.5rem 1.6rem;color:#e8ddcf;position:relative}
.prof-top{display:flex;gap:1.2rem;align-items:flex-start}
.av-lg{width:74px;height:74px;border-radius:50%;background:#1e1712;color:var(--oak);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:1.5rem;flex:none;font-family:'Bricolage Grotesque',sans-serif;border:2px solid rgba(201,168,124,.35)}
/* The left column owns its own vertical space now: identity at the top, actions at
   the bottom, and the room between them is breathing rather than a pocket of nothing.
   The site panel sets the card's height; the left side has to fill it deliberately or
   it just stops halfway down. */
.prof-main{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:space-between;
  gap:1.1rem;align-self:stretch}
.prof-id{min-width:0}
.prof-main .prof-actions{margin-top:0}
.prof-id h2{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.7rem;letter-spacing:-.02em;color:#fff;display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}
.prof-loc{display:flex;align-items:center;gap:.4rem;color:var(--oak-dim);font-size:.9rem;margin-top:.3rem}
.prof-loc .ic{width:15px;height:15px}
.hot{position:relative;background:none;border:0;cursor:pointer;padding:.3rem;color:var(--oak-dim);
  line-height:0;border-radius:10px;-webkit-tap-highlight-color:transparent;touch-action:manipulation;
  transition:transform .12s cubic-bezier(.34,1.56,.64,1),color .25s}
.hot:hover{color:var(--oak)}
/* tactile: it gives under the thumb and springs back past its own size */
.hot:active{transform:scale(.86)}
.hot .ic{width:26px;height:26px;position:relative;z-index:2;overflow:visible}
.hot-ic{display:block;position:relative;z-index:2}
.hot .fl-out,.hot .fl-core{transition:fill .45s ease, stroke .45s ease}
.hot .fl-out{fill:transparent}
.hot .fl-core{fill:transparent;opacity:0;transition:opacity .3s ease .1s, fill .45s}

/* lit: the flame fills, the core glows, and it never sits perfectly still */
.hot.on{color:#ff7a18}
.hot.on .fl-out{fill:url(#flameGrad);stroke:#ff8c2a}
.hot.on .fl-core{fill:#ffd76a;opacity:1;animation:coreFlicker 1.9s ease-in-out infinite}
.hot.on .hot-ic{animation:flameLive 2.6s ease-in-out infinite;transform-origin:50% 85%}
.hot.on{filter:drop-shadow(0 0 7px rgba(255,110,20,.55))}

/* a real flame is never symmetrical twice: skew and scale on different periods so
   the loop never lines up with itself */
@keyframes flameLive{
  0%,100%{transform:scale(1) skewX(0deg)}
  22%{transform:scale(1.05,1.09) skewX(-2.2deg)}
  47%{transform:scale(.97,1.03) skewX(1.6deg)}
  71%{transform:scale(1.04,1.06) skewX(-1deg)}
}
@keyframes coreFlicker{
  0%,100%{opacity:1;transform:translateY(0)}
  30%{opacity:.72;transform:translateY(.4px)}
  60%{opacity:1;transform:translateY(-.3px)}
  80%{opacity:.85}
}

/* the strike: a punch, then it settles */
.hot.lighting .hot-ic{animation:strike .9s cubic-bezier(.2,.9,.25,1)}
@keyframes strike{
  0%{transform:scale(.55) rotate(-9deg)}
  18%{transform:scale(1.5) rotate(4deg)}
  34%{transform:scale(.92) rotate(-2deg)}
  52%{transform:scale(1.16) rotate(1deg)}
  72%{transform:scale(.98)}
  100%{transform:scale(1) rotate(0)}
}
/* the flash of ignition, gone almost before you see it */
.hot-flash{position:absolute;inset:-6px;border-radius:50%;pointer-events:none;z-index:1;opacity:0;
  background:radial-gradient(circle,rgba(255,225,150,.95) 0%,rgba(255,120,20,.5) 42%,rgba(255,80,0,0) 72%)}
.hot.lighting .hot-flash{animation:flash .62s ease-out}
@keyframes flash{
  0%{opacity:0;transform:scale(.3)}
  12%{opacity:1;transform:scale(1.05)}
  100%{opacity:0;transform:scale(2.1)}
}
/* blown out: it gutters, leans away, and dies */
.hot.dousing .hot-ic{animation:gutter .52s ease-in}
@keyframes gutter{
  0%{transform:scale(1) skewX(0)}
  30%{transform:scale(1.1,.86) skewX(11deg)}
  60%{transform:scale(.7,1.15) skewX(-7deg);opacity:.65}
  100%{transform:scale(.9) skewX(0);opacity:1}
}
/* The embers need somewhere to GO. Sized to the button, they left a 35px box in
   about ten frames and the whole burst was a 150ms twitch: measured 147 lit pixels
   at frame 2, 54 by frame 10, and zero by frame 25 while all 46 were still alive.
   They were not dying, they were escaping. So the canvas reaches well above the
   icon and the button does not clip it. */
/* Explicit width/height, not left+right. A <canvas> is a REPLACED element: with
   left and right both set and width auto it does not stretch, it keeps its intrinsic
   300x150 and quietly drops `right`. The box was landing 300px wide with the embers
   spawning a hundred pixels away from the flame they were supposed to be coming out
   of. Centerd on the button, reaching 58px above it. */
.hot-embers{position:absolute;width:96px;height:104px;left:50%;margin-left:-48px;
  top:-58px;pointer-events:none;z-index:3}
.hot{overflow:visible}
.prof-top{overflow:visible}

/* the quality floor: if the machine says no motion, it is a color change */
@media (prefers-reduced-motion:reduce){
  .hot,.hot .hot-ic,.hot.on .hot-ic,.hot.on .fl-core{animation:none!important;transition:color .2s!important}
  .hot:active{transform:none}
  .hot-flash{display:none}
}
/* bigger target on a phone, where this is a thumb and not a mouse */
@media (max-width:640px){ .hot{padding:.55rem} .hot .ic{width:30px;height:30px} }
.hot.on{color:var(--oak)}.hot.on .ic{fill:var(--oak)}
/* The action buttons live on their own full-width row below the header now (below the weather), so
   they get the whole box width and stop wrapping into the person column. */
.prof-actions{display:flex;gap:.6rem;flex-wrap:wrap;margin-top:1.2rem;padding-top:1.1rem;border-top:1px solid rgba(201,168,124,.18)}
/* min-height, not padding alone: an <a> and a <button> with the same padding still
   disagree by a pixel or two, and a row of buttons that nearly line up looks worse
   than one that obviously does not. */
.pa{display:inline-flex;align-items:center;justify-content:center;gap:.45rem;font-size:.85rem;font-weight:600;padding:.5rem .72rem;border-radius:8px;background:rgba(255,255,255,.1);color:#f1e7d8;border:1px solid rgba(201,168,124,.25);min-height:2.375rem;min-width:8.5rem;box-sizing:border-box;white-space:nowrap}
.prof-actions .menuwrap{display:inline-flex}
.prof-actions .menuwrap > .pa{width:100%}
/* the dropdown section: a divider, then the triangle Bootstrap draws */
.pa-caret{display:flex;align-items:center;align-self:stretch;margin-left:.2rem;padding-left:.55rem;
  border-left:1px solid rgba(201,168,124,.3)}
.pa-caret::after{content:"";display:block;border-top:.3em solid;border-right:.3em solid transparent;
  border-left:.3em solid transparent;opacity:.85}
.pa.primary .pa-caret{border-left-color:rgba(255,255,255,.35)}
.pa:hover{background:rgba(255,255,255,.18)}
.pa.primary{background:var(--chalk);border-color:var(--chalk);color:#fff}
.pa.primary:hover{background:var(--chalk-2)}
.pa .ic{width:16px;height:16px}

.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(8rem,1fr));gap:.7rem;margin:1rem 0}
.stat{background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:.8rem 1rem}
.stat .k{font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.stat .v{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:1.25rem;margin-top:.2rem}
.stat .v.sm{font-size:.98rem;font-weight:600}

.prof-grid{display:grid;grid-template-columns:20rem 1fr;gap:1rem;align-items:start;margin-top:1rem}
@media (max-width:900px){.app{grid-template-columns:1fr}.side{display:none}}
.kv{display:flex;flex-direction:column;gap:.6rem}
.kv .row{display:flex;flex-direction:column;gap:.1rem}
.kv .k{font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.kv .val{font-size:.92rem}
.kv a.val{color:var(--chalk);font-weight:500}
.ai{font-size:.92rem;color:var(--ink)}
.ai b,.ai i{color:var(--ink)}

/* ---------- the wall (composer + timeline) ---------- */
.composer{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:1rem 1.1rem;margin-bottom:1rem}
.composer textarea{width:100%;border:1px solid var(--line);border-radius:9px;padding:.7rem .8rem;font:inherit;font-size:.95rem;resize:vertical;min-height:3.6rem;color:var(--ink);background:var(--paper)}
.composer textarea:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
.composer-row{display:flex;align-items:center;gap:.6rem;margin-top:.7rem;flex-wrap:wrap}
.composer select{font:inherit;font-size:.85rem;padding:.45rem .6rem;border:1px solid var(--line);border-radius:8px;background:var(--surface);color:var(--ink)}
/* Scope the primary style to the submit button only. As a bare `.composer button` it also caught the
   attach clip (a type selector out-specificities the .composer-clip class), painting it solid blue. */
.composer button[type="submit"]{margin-left:auto;background:var(--chalk);color:#fff;border:0;border-radius:8px;font:inherit;font-weight:600;font-size:.9rem;padding:.55rem 1.2rem;cursor:pointer}
.composer button[type="submit"]:hover{background:var(--chalk-2)}
.composer-hint{font-size:.75rem;color:var(--faint)}

/* ---- @mention: live tagging in any textarea ------------------------------- */
/* A backdrop mirrors the text behind a transparent-background textarea and paints a
   soft mark behind each @handle, so a tag reads as tagged right in the box. */
.mention-wrap{position:relative;display:block}
.mention-backdrop{position:absolute;inset:0;overflow:hidden;pointer-events:none;border-radius:inherit}
.mention-backdrop-inner{width:100%;height:100%;box-sizing:border-box;color:transparent;overflow:hidden;
  white-space:pre-wrap;word-wrap:break-word;overflow-wrap:break-word;margin:0}
.mention-wrap > textarea{position:relative;z-index:1}
.mnt{border-radius:3px;padding:.02em 0}
/* pending: you are mid-tag. matched: that is a real teammate. */
.mnt-pending{background:rgba(201,168,124,.14);box-shadow:0 1px 0 0 rgba(201,168,124,.7)}
.mnt-match{background:rgba(201,168,124,.34);box-shadow:0 0 0 1px rgba(201,168,124,.55)}
/* A tagged floor. Chalk rather than oak so a person and a product never read as the same kind of
   thing at a glance: one is who, the other is what. */
.mnt-prod{background:rgba(143,76,35,.16);box-shadow:0 0 0 1px rgba(143,76,35,.42)}
.mention-opt.prod{align-items:flex-start;gap:.55rem;padding:.42rem .55rem}
.mention-sw{flex:none;width:30px;height:30px;border-radius:5px;object-fit:cover;
  background:var(--plank,var(--line-2));border:1px solid var(--line)}
.mention-opt.prod .mention-nm{white-space:normal;display:flex;flex-direction:column;gap:.05rem;line-height:1.25}
.mention-opt.prod .mention-nm small{font-weight:500;font-size:.72rem;color:var(--faint);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* A floor we actually stock, marked without a word: there is no room for one, and the dot is the
   same green the catalog uses for it. */
.mention-carry{display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--ok,#3f8f43);
  margin-left:.35rem;vertical-align:.12em}
.mention-drop:has(.mention-opt.prod){min-width:340px;max-width:440px;max-height:300px}
.mention-drop{max-width:320px}
.mention-opt.prod .mention-nm code{font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.03em;color:var(--oak-dim);background:none;padding:0}
.mention-opt.prod .mention-sw{width:44px;height:44px;border-radius:7px}
.mention-opt.prod{padding:.5rem .6rem;border-bottom:1px solid var(--line-2)}
.mention-opt.prod:last-child{border-bottom:0}

.mention-drop{position:absolute;z-index:50;min-width:200px;max-width:260px;max-height:220px;overflow-y:auto;
  background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:.25rem;
  box-shadow:0 12px 34px rgba(30,23,18,.18)}
.mention-opt{display:flex;align-items:center;gap:.5rem;width:100%;text-align:left;border:0;background:none;
  border-radius:7px;padding:.4rem .5rem;cursor:pointer;font:inherit}
.mention-opt.on,.mention-opt:hover{background:var(--paper)}
.mention-av{flex:none;width:26px;height:26px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;
  background:var(--walnut);color:#e8ddcf;font-size:.66rem;font-weight:700;font-family:'IBM Plex Mono',monospace}
.mention-nm{font-weight:600;font-size:.85rem;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mention-hd{margin-left:auto;font-family:'IBM Plex Mono',monospace;font-size:.72rem;color:var(--oak)}
/* inline SMS composer + message direction */
.sms-compose{border:1px solid var(--oak);border-radius:12px;padding:.85rem 1rem;margin-bottom:1rem;background:linear-gradient(120deg,rgba(201,168,124,.1),transparent)}
.sms-compose-h{display:flex;align-items:center;gap:.4rem;font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-bottom:.5rem}
.sms-compose-h .ic{width:15px;height:15px;color:var(--oak)}
.sms-compose textarea{width:100%;border:1px solid var(--line);border-radius:8px;padding:.5rem .65rem;font:inherit;font-size:.9rem;background:var(--surface);resize:vertical}
.sms-compose-row{display:flex;align-items:center;gap:.7rem;margin-top:.5rem}
.sms-status{font-size:.78rem;color:var(--muted);margin-right:auto}
.sms-status.err{color:var(--lost)}
/* email composer: same language as the SMS one, with a subject line */
.mail-compose{border:1px solid var(--oak);border-radius:12px;padding:.85rem 1rem;margin-bottom:1rem;background:linear-gradient(120deg,rgba(201,168,124,.1),transparent)}
.mail-compose-h{display:flex;align-items:center;gap:.4rem;font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-bottom:.5rem}
.mail-compose-h .ic{width:15px;height:15px;color:var(--oak)}
.mail-subject{width:100%;border:1px solid var(--line);border-radius:8px;padding:.5rem .65rem;font:inherit;font-size:.92rem;font-weight:600;background:var(--surface);margin-bottom:.5rem}
.mail-compose textarea{width:100%;border:1px solid var(--line);border-radius:8px;padding:.5rem .65rem;font:inherit;font-size:.9rem;background:var(--surface);resize:vertical}
.mail-subject:focus,.mail-compose textarea:focus{outline:none;border-color:var(--oak)}
.mail-compose-row{display:flex;align-items:center;gap:.7rem;margin-top:.5rem;flex-wrap:wrap}
.mail-alt{font-size:.72rem;color:var(--muted);margin-right:auto}
.mail-alt a,.linklike{color:var(--oak);text-decoration:none;background:none;border:0;padding:0;font:inherit;font-size:inherit;cursor:pointer}
.mail-alt a:hover,.linklike:hover{text-decoration:underline}
/* CutPile-drafted follow-ups, queued for a one-click send */
.drafts{border:1px solid var(--oak);border-radius:12px;background:linear-gradient(120deg,rgba(201,168,124,.12),transparent);
  padding:.85rem 1rem;margin-bottom:1rem}
.drafts-h{display:flex;align-items:center;gap:.4rem;font-family:'IBM Plex Mono',monospace;font-size:.66rem;
  letter-spacing:.05em;text-transform:uppercase;color:var(--oak);margin-bottom:.7rem}
.drafts-h .ic{width:15px;height:15px}
.draft{background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:.7rem .75rem;margin-bottom:.6rem;transition:opacity .2s ease}
.draft:last-child{margin-bottom:0}
.draft-sent{opacity:.5}
.draft-top{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-bottom:.5rem;font-size:.78rem}
.draft-to{font-weight:600;color:var(--ink)}
.draft-reason{color:var(--muted)}
.draft-status{margin-left:auto;font-size:.74rem;color:var(--muted)}
.draft-status.err{color:var(--lost)}
.draft-subject{width:100%;border:1px solid var(--line);border-radius:8px;padding:.45rem .6rem;font:inherit;font-size:.88rem;
  font-weight:600;background:var(--paper);margin-bottom:.45rem}
.draft-body{width:100%;border:1px solid var(--line);border-radius:8px;padding:.5rem .6rem;font:inherit;font-size:.86rem;
  line-height:1.5;background:var(--paper);resize:vertical}
.draft-subject:focus,.draft-body:focus{outline:none;border-color:var(--oak)}
.draft-actions{display:flex;gap:.5rem;justify-content:flex-end;margin-top:.5rem}
.btn.ghost{background:transparent;color:var(--muted);border:1px solid var(--line)}
.btn.ghost:hover{color:var(--ink);border-color:var(--oak)}
/* The direction badge was never colored, and not because nobody chose a color: the markup writes
   `tl-dir tl-out` and these two rules asked for `.out`. Every sent and received badge in the app has
   been rendering as plain grey text since it was written. Both spellings are matched now so it
   cannot silently come apart again. */
.tl-dir{font-family:'IBM Plex Mono',monospace;font-size:.62rem;font-weight:500;letter-spacing:.06em;
  text-transform:uppercase;padding:.1rem .4rem;border-radius:4px}
.tl-dir.out,.tl-dir.tl-out{color:#2f6b33;background:rgba(63,143,67,.16)}
.tl-dir.in,.tl-dir.tl-in{color:#835716;background:rgba(183,121,31,.18)}
/* a job activity names its customer and links back to the job */
a.tl-author{color:var(--ink);text-decoration:none}
a.tl-author:hover{color:var(--oak)}
/* the channel a message came through, alongside its direction */
/* Which road a message came down. An outline at 9px reads as a smudge, so each one now carries a
   wash of its own color: the channel is the fastest thing to pick out when scanning a day. */
.tl-chan{font-family:'IBM Plex Mono',monospace;font-size:.62rem;font-weight:500;letter-spacing:.06em;
  text-transform:uppercase;padding:.1rem .4rem;border-radius:4px;border:1px solid var(--line);color:var(--label)}
.tl-chan-call{color:#255780;border-color:rgba(47,107,163,.35);background:rgba(47,107,163,.1)}
.tl-chan-sms{color:#2f6b33;border-color:rgba(63,143,67,.35);background:rgba(63,143,67,.1)}
.tl-chan-email{color:#6f4780;border-color:rgba(138,90,158,.35);background:rgba(138,90,158,.1)}

/* ---- Daily Activity: day navigation, then search / filter / sort ---------- */
.day-nav{display:flex;align-items:center;gap:.7rem;margin-bottom:.9rem}
.day-arrow{width:34px;height:34px;flex:none;display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:9px;background:var(--surface);color:var(--ink);
  font-size:1.25rem;line-height:1;text-decoration:none}
.day-arrow:hover{border-color:var(--oak);color:var(--oak)}
.day-arrow.off{opacity:.35;cursor:default}
.day-when{display:flex;flex-direction:column;line-height:1.15;min-width:0}
.day-label{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.15rem;letter-spacing:-.01em;color:var(--ink)}
.day-sub{font-size:.72rem;color:var(--muted);font-family:'IBM Plex Mono',monospace;letter-spacing:.02em}
.day-pick{font:inherit;font-size:.8rem;padding:.35rem .5rem;border:1px solid var(--line);border-radius:8px;
  background:var(--surface);color:var(--ink);cursor:pointer;margin-left:auto}
.day-today{font-size:.78rem;font-weight:600;color:var(--oak);text-decoration:none;white-space:nowrap}
.day-today:hover{text-decoration:underline}

.da-bar{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem;margin-bottom:.7rem}
.da-search{position:relative;display:flex;align-items:center;flex:1 1 220px;min-width:180px}
.da-search-ic{position:absolute;left:.6rem;width:16px;height:16px;color:var(--muted);pointer-events:none}
.da-search input{width:100%;font:inherit;font-size:.85rem;padding:.5rem .6rem .5rem 2rem;
  border:1px solid var(--line);border-radius:9px;background:var(--surface);color:var(--ink)}
.da-search input:focus{outline:none;border-color:var(--oak)}
.da-clear{position:absolute;right:.55rem;color:var(--muted);text-decoration:none;font-size:1.1rem;line-height:1}
.da-clear:hover{color:var(--ink)}
.da-filters{display:flex;gap:.4rem;flex-wrap:wrap;align-items:center}
.da-count{font-size:.78rem;color:var(--muted);margin-bottom:.8rem;font-family:'IBM Plex Mono',monospace;letter-spacing:.02em}
.da-pager{display:flex;align-items:center;justify-content:center;gap:1rem;margin-top:1rem}
.da-pageno{font-size:.76rem;color:var(--muted);font-family:'IBM Plex Mono',monospace}
/* composer attach clip + preview chips */
.composer-clip{flex:none;width:34px;height:34px;padding:0;border:1px solid var(--line);background:transparent;border-radius:9px;
  color:var(--muted);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;line-height:0;
  transition:background .14s ease,border-color .14s ease,color .14s ease}
.composer-clip:hover{color:var(--oak);border-color:var(--oak);background:var(--paper)}
.composer-clip svg{width:18px;height:18px;display:block}
/* new feed/chat items slide in at the top instead of the page jumping */
@keyframes item-in{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.tl-item.just-in,.jc-msg.just-in{animation:item-in .3s ease}
@media (prefers-reduced-motion:reduce){.tl-item.just-in,.jc-msg.just-in{animation:none}}
.composer-atts{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.7rem}
.att-chip{position:relative;display:flex;align-items:center;gap:.4rem;border:1px solid var(--line);border-radius:8px;
  padding:.3rem .5rem;background:var(--paper);font-size:.78rem;color:var(--ink);max-width:14rem;overflow:hidden}
.att-chip img{width:44px;height:44px;object-fit:cover;border-radius:6px;display:block}
.att-chip.loading{opacity:.6}
.att-chip-n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.att-chip-s{color:var(--faint)} .att-chip-s.err{color:var(--lost)}
.att-chip-x{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;border:0;background:var(--walnut);
  color:#fff;font-size:.8rem;line-height:1;cursor:pointer;display:grid;place-items:center}
/* feed: image gallery + file chips */
.att-gallery{display:flex;flex-wrap:wrap;gap:.4rem;margin:.5rem 0}
.att-thumb{border:1px solid var(--line);border-radius:8px;padding:0;overflow:hidden;cursor:zoom-in;background:var(--paper);line-height:0}
.att-thumb img{width:88px;height:88px;object-fit:cover;display:block;transition:transform .18s}
.att-thumb:hover img{transform:scale(1.05)}
/* Job Attachments gallery: a captioned grid, newest first, images and documents together. */
.jga.att-gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:.9rem;margin:.4rem 0 0}
.jga-cell{margin:0;display:flex;flex-direction:column;gap:.35rem}
.jga .jga-thumb{width:100%}
.jga .jga-thumb img{width:100%;height:130px}
.jga-file{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.35rem;height:130px;border:1px solid var(--line);border-radius:8px;background:var(--paper);color:var(--ink);text-decoration:none;padding:.6rem;text-align:center}
.jga-file:hover{border-color:var(--oak);background:var(--chalk-soft)}
.jga-file-ic svg{width:30px;height:30px;color:var(--chalk)}
.jga-file-name{font-size:.76rem;font-weight:600;line-height:1.25;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;word-break:break-word}
.jga-file-sz{font-size:.68rem;color:var(--faint)}
.jga-cap{font-size:.7rem;color:var(--muted);line-height:1.3}
.jga-empty{color:var(--muted);font-size:.9rem;padding:1.4rem 0}
.att-files{display:flex;flex-direction:column;gap:.35rem;margin:.5rem 0}
.att-file{display:flex;align-items:center;gap:.55rem;border:1px solid var(--line);border-radius:8px;padding:.45rem .6rem;background:var(--paper);max-width:22rem}
.att-file:hover{border-color:var(--oak)}
.att-ic{flex:none;width:30px;height:30px;display:grid;place-items:center;color:var(--oak);background:rgba(201,168,124,.14);border-radius:7px}
.att-ic svg{width:17px;height:17px}
.att-meta{display:flex;flex-direction:column;min-width:0}
.att-name{font-size:.84rem;font-weight:600;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.att-sz{font-family:'IBM Plex Mono',monospace;font-size:.66rem;color:var(--faint)}
/* Previewable documents (PDFs): a first-page thumbnail that opens the file; falls back to the type icon. */
.att-docs{display:flex;flex-wrap:wrap;gap:.5rem;margin:.5rem 0}
.att-doc{display:flex;flex-direction:column;width:110px;border:1px solid var(--line);border-radius:8px;overflow:hidden;background:var(--paper);text-decoration:none;color:var(--ink)}
.att-doc:hover{border-color:var(--oak)}
.att-doc-thumb{display:block;height:120px;background:#fff;line-height:0}
.att-doc-thumb img{width:100%;height:120px;object-fit:cover;object-position:top;display:block}
.att-doc-ic{display:none;height:120px;align-items:center;justify-content:center;color:var(--oak);background:rgba(201,168,124,.14)}
.att-doc-ic svg{width:34px;height:34px}
.att-doc.noprev .att-doc-thumb{display:none}
.att-doc.noprev .att-doc-ic{display:flex}
.att-doc-name{font-size:.72rem;font-weight:600;padding:.35rem .45rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border-top:1px solid var(--line)}
/* Same PDF preview inside the job Attachments gallery cell (fills the grid cell). */
.jga .jga-doc{width:100%}
.jga .jga-doc .att-doc-thumb,.jga .jga-doc .att-doc-thumb img,.jga .jga-doc .att-doc-ic{height:130px}
.jga .jga-doc .att-doc-name{display:none}
/* lightbox */
.lb{position:fixed;inset:0;z-index:200;background:rgba(20,15,10,.92);display:flex;align-items:center;justify-content:center;
  padding:2.5rem 1rem;animation:lb-in .18s ease}

/* ---- Talk to CutPile: the in-place voice overlay --------------------------- */
/* Default HIDDEN. A class selector would otherwise beat the [hidden] attribute and pin the
   overlay open over the whole app — it only shows when JS clears `hidden`. */
.talk-overlay{position:fixed;inset:0;z-index:300;display:none;align-items:center;justify-content:center;padding:1.2rem}
.talk-overlay:not([hidden]){display:flex}
body.talk-open{overflow:hidden}
.talk-scrim{position:absolute;inset:0;background:rgba(20,15,10,.55);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:lb-in .18s ease}
.talk-card{position:relative;z-index:1;width:min(92vw,380px);background:linear-gradient(160deg,var(--walnut),var(--walnut-3));
  color:#efe6d8;border:1px solid rgba(201,168,124,.3);border-radius:20px;padding:2rem 1.5rem 1.4rem;
  display:flex;flex-direction:column;align-items:center;gap:.9rem;box-shadow:0 30px 80px rgba(20,15,10,.5);animation:talk-in .24s cubic-bezier(.2,.8,.2,1)}
@keyframes talk-in{from{opacity:0;transform:translateY(14px) scale(.97)}to{opacity:1;transform:none}}
.talk-x{position:absolute;top:.7rem;right:.85rem;width:30px;height:30px;border:0;background:rgba(255,255,255,.1);
  color:#efe6d8;border-radius:50%;font-size:1.2rem;line-height:1;cursor:pointer}
.talk-x:hover{background:rgba(255,255,255,.2)}
.talk-orb{width:96px;height:96px;border-radius:50%;display:grid;place-items:center;
  background:radial-gradient(circle at 35% 30%,#e6c79a,var(--oak) 60%,#9c7b4f);color:#3a2c1c;
  box-shadow:0 0 0 0 rgba(201,168,124,.5);transition:transform .2s ease}
.talk-orb .ic,.talk-orb-mic .ic{width:34px;height:34px}
.talk-orb.connecting{animation:talk-fade 1.1s ease-in-out infinite}
.talk-orb.live{animation:talk-breathe 3.4s ease-in-out infinite}
.talk-orb.speaking{animation:talk-ring 1s ease-out infinite}
.talk-orb.error{background:radial-gradient(circle at 35% 30%,#e6a89a,#b4543f 60%);}
@keyframes talk-breathe{0%,100%{transform:scale(1)}50%{transform:scale(1.05)}}
@keyframes talk-fade{0%,100%{opacity:.55}50%{opacity:1}}
@keyframes talk-ring{0%{box-shadow:0 0 0 0 rgba(201,168,124,.55)}100%{box-shadow:0 0 0 26px rgba(201,168,124,0)}}
.talk-status{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:1.02rem;text-align:center;color:#fff}
.talk-transcript{width:100%;max-height:9rem;overflow-y:auto;font-size:.82rem;line-height:1.5;color:#d8cbb8;
  white-space:pre-wrap;text-align:center;padding:0 .3rem}
.talk-transcript:empty{display:none}
.talk-end{margin-top:.2rem;background:rgba(255,255,255,.12);color:#efe6d8;border:1px solid rgba(201,168,124,.35);
  border-radius:10px;font:inherit;font-weight:600;font-size:.9rem;padding:.5rem 1.4rem;cursor:pointer}
.talk-end:hover{background:rgba(255,255,255,.2)}
@media (prefers-reduced-motion:reduce){.talk-orb.connecting,.talk-orb.live,.talk-orb.speaking{animation:none}}
@keyframes lb-in{from{opacity:0}to{opacity:1}}
.lb-fig{margin:0;display:flex;flex-direction:column;align-items:center;gap:.6rem;max-width:92vw;max-height:88vh}
.lb-fig img{max-width:92vw;max-height:80vh;object-fit:contain;border-radius:6px;box-shadow:0 20px 60px rgba(0,0,0,.5)}
.lb-fig figcaption{color:#e8ddcf;font-size:.82rem;font-family:'IBM Plex Mono',monospace}
.lb-x{position:absolute;top:1rem;right:1.1rem;width:40px;height:40px;border:0;background:rgba(255,255,255,.12);color:#fff;
  border-radius:50%;font-size:1.5rem;line-height:1;cursor:pointer}
.lb-x:hover{background:rgba(255,255,255,.22)}
.lb-nav{position:absolute;top:50%;transform:translateY(-50%);width:46px;height:46px;border:0;border-radius:50%;
  background:rgba(255,255,255,.12);color:#fff;font-size:2rem;line-height:1;cursor:pointer}
.lb-nav:hover{background:rgba(255,255,255,.22)}
.lb-prev{left:1rem} .lb-next{right:1rem}
@media (prefers-reduced-motion:reduce){.lb{animation:none}}
/* Voice-note button while recording. */
.pa.rec{background:var(--lost);border-color:var(--lost);color:#fff;animation:vnpulse 1.5s ease-in-out infinite}
.pa.rec .ic{color:#fff}
/* Call in browser: the Call button becomes a live status while connected (size stays static, per Jon). */
.pa.pa-connecting{opacity:.75;pointer-events:none}
.menubtn.pa.pa-oncall{background:var(--live,#3f9d55);border-color:var(--live,#3f9d55);color:#fff;cursor:pointer;animation:vnpulse 1.6s ease-in-out infinite;gap:.5rem}
.menubtn.pa.pa-oncall .pa-dot{width:8px;height:8px;border-radius:50%;background:#fff;flex:none;box-shadow:0 0 0 0 rgba(255,255,255,.6);animation:cibdot 1.4s ease-out infinite}
.menubtn.pa.pa-oncall .pa-cib-t{font-variant-numeric:tabular-nums}
@keyframes cibdot{0%{box-shadow:0 0 0 0 rgba(255,255,255,.55)}100%{box-shadow:0 0 0 7px rgba(255,255,255,0)}}
@keyframes vnpulse{0%,100%{box-shadow:0 0 0 0 rgba(162,74,60,.5)}50%{box-shadow:0 0 0 6px rgba(162,74,60,0)}}

/* Full transcript accordion: feeds show the summary; the wall of words waits behind a click. */
.tl-tr{margin:.4rem 0 0}
.tl-tr>summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:.35rem;font-size:.74rem;font-weight:600;color:var(--muted)}
.tl-tr>summary::-webkit-details-marker{display:none}
.tl-tr>summary::before{content:"\25B8";font-size:.7rem;transition:transform .15s}
.tl-tr[open]>summary::before{transform:rotate(90deg)}
.tl-tr>summary:hover{color:var(--oak)}
.tl-tr-body{margin-top:.4rem;padding:.6rem .75rem;border:1px solid var(--line);border-radius:8px;background:var(--paper);font-size:.82rem;line-height:1.55;color:var(--muted);max-height:20rem;overflow-y:auto}

.timeline{position:relative}
.tl-item{display:grid;grid-template-columns:2.4rem 1fr;gap:.7rem;padding-bottom:1rem}
.tl-mark{display:flex;flex-direction:column;align-items:center}
.tl-dot{width:34px;height:34px;border-radius:50%;background:var(--surface);border:1px solid var(--line);display:flex;align-items:center;justify-content:center;color:var(--muted);flex:none}
.tl-dot .ic{width:16px;height:16px}
.tl-dot.call{color:var(--ok);border-color:var(--ok-soft);background:var(--ok-soft)}
.tl-dot.text{color:var(--chalk);border-color:var(--chalk-soft);background:var(--chalk-soft)}
.tl-dot.mail{color:var(--warn);border-color:var(--warn-soft);background:var(--warn-soft)}
.tl-line{flex:1;width:2px;background:var(--line-2);margin-top:.3rem}
.tl-item:last-child .tl-line{display:none}
.tl-card{background:var(--surface);border:1px solid var(--line);border-radius:11px;padding:.8rem 1rem}
.tl-head{display:flex;align-items:baseline;gap:.6rem;flex-wrap:wrap;margin-bottom:.25rem}
.tl-type{font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.tl-time{font-size:.78rem;color:var(--faint);margin-left:auto}
.tl-hl{font-weight:600;font-size:.95rem}
.tl-body{font-size:.9rem;color:var(--muted);margin-top:.2rem;white-space:pre-wrap}
.tl-badge{font-size:.6rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;padding:.1rem .35rem;border-radius:4px;background:var(--lost-soft);color:var(--lost)}
/* The placeholder card, on screen for the moment between hitting enter and the server answering.
   It shows the raw text with its line breaks; the real card replaces it formatted. */
.tl-body.typed{white-space:pre-wrap}
/* On screen before the server has answered. It is real text in a real card, just not filed yet. */
.tl-item.pending .tl-card{opacity:.72}
.tl-item.pending .tl-dot{background:var(--line);border-color:var(--line)}
.tl-pendatt{font-size:.75rem;color:var(--faint);margin-top:.3rem}
.tl-item.failed .tl-card{opacity:1;border-color:var(--lost)}
.tl-item.failed .tl-type{color:var(--lost)}
.tl-retry{display:block;margin-top:.5rem;font:inherit;font-size:.78rem;padding:.3rem .6rem;border:1px solid var(--lost);border-radius:7px;background:var(--lost-soft);color:var(--lost);cursor:pointer}
.empty{color:var(--faint);text-align:center;padding:2rem;font-size:.92rem}

/* ---------- settings ---------- */
.flash{border-radius:9px;padding:.75rem 1rem;font-size:.92rem;margin-bottom:1rem}
.flash.ok{background:var(--ok-soft);color:var(--ok)}
.flash.err{background:var(--lost-soft);color:var(--lost)}
.keygroup{font-family:'IBM Plex Mono',monospace;font-size:.64rem;letter-spacing:.12em;text-transform:uppercase;color:var(--faint);margin:1.3rem 0 .5rem}
.keygroup:first-of-type{margin-top:.3rem}
/* The key rack. One grid for every row so nothing staggers: a status edge, the
   identity, a fixed-width field, a fixed-width action slot. Empty, stored, live and
   failing rows all use the same three columns, so Save/Test/Remove line up down the
   page whether or not a given row has a Test button. */
.keyrack{overflow:hidden}
.keyrow{display:grid;grid-template-columns:3px 1fr 19rem 9.5rem;gap:0 1rem;align-items:center;
  padding:.85rem .2rem .85rem .6rem;border-bottom:1px solid var(--line-2);position:relative}
.keyrow:last-child{border-bottom:0}
/* the signature: a status-colored edge turns the list into a rack you read at a glance */
.key-edge{grid-column:1;align-self:stretch;border-radius:3px;background:var(--line)}
.s-live .key-edge{background:#3f8a5f}
.s-stored .key-edge{background:var(--oak)}
.s-fail .key-edge{background:var(--lost)}
.s-empty .key-edge{background:var(--line-2)}
.key-id{grid-column:2;min-width:0}
.key-top{display:flex;align-items:center;gap:.55rem}
.key-label{font-weight:600;font-size:.94rem;color:var(--ink)}
.s-empty .key-label{color:var(--muted)}
.key-chip{font-size:.58rem}
.key-mask{font-size:.78rem;color:var(--muted);margin:.12rem 0 .2rem;letter-spacing:.04em}
.s-empty .key-mask{color:var(--faint)}
.key-help{font-size:.78rem;color:var(--muted);line-height:1.4;max-width:46ch}
.key-get{color:var(--oak);font-weight:600;white-space:nowrap}
.key-get:hover{color:var(--ink);text-decoration:underline}
.key-field{grid-column:3;display:flex;gap:.4rem}
.key-field input{flex:1;min-width:0;border:1px solid var(--line);border-radius:7px;padding:.5rem .7rem;font:inherit;font-size:.84rem;background:var(--paper)}
.key-field input:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
.key-acts{grid-column:4;display:flex;gap:.4rem;justify-content:flex-end}
.key-acts form{margin:0}
.key-notest{font-family:'IBM Plex Mono',monospace;font-size:.62rem;color:var(--faint);align-self:center;
  padding:.3rem .5rem;border:1px dashed var(--line);border-radius:6px;white-space:nowrap}
/* the callout: what is blocking a finished feature, built from the vault so it can't drift */
/* Pricing rates form */
.pricecfg{display:flex;flex-wrap:wrap;gap:1rem;align-items:flex-end;margin:.3rem 0 .2rem}
.pricecfg label{display:flex;flex-direction:column;gap:.35rem;font-size:.78rem;color:var(--muted)}
/* email sending config */
.smtpcfg{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:.8rem 1rem;align-items:end;margin:.3rem 0 .2rem}
.smtpcfg label{display:flex;flex-direction:column;gap:.3rem;font-size:.76rem;color:var(--muted)}
.smtpcfg input,.smtpcfg select{font:inherit;font-size:.88rem;padding:.5rem .6rem;border:1px solid var(--line);
  border-radius:8px;background:var(--surface);color:var(--ink)}
.smtpcfg input:focus,.smtpcfg select:focus{outline:none;border-color:var(--oak)}
.smtpcfg .btn{grid-column:1/-1;justify-self:start}
.smtp-badge{margin-left:auto;font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.05em;
  text-transform:uppercase;padding:.15rem .5rem;border-radius:999px}
.smtp-badge.on{color:#357a39;background:rgba(63,143,67,.14)}
.smtp-badge.off{color:var(--muted);background:var(--paper);border:1px solid var(--line)}
.pricecfg-in{display:flex;align-items:center;gap:.25rem;border:1px solid var(--line);border-radius:8px;
  padding:.4rem .55rem;background:var(--surface);color:var(--ink);font-weight:700}
.pricecfg-in input{border:0;outline:none;width:4.5rem;font:inherit;font-size:.98rem;background:transparent;color:var(--ink)}
.pricecfg-u{font-family:'IBM Plex Mono',monospace;font-size:.62rem;color:var(--faint);letter-spacing:.04em}
.pricecfg .btn{align-self:flex-end}

/* AI cost dashboard */
.aic-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(7rem,1fr));gap:.6rem;margin:.4rem 0 .3rem}
.aic-tile{border:1px solid var(--line);border-radius:10px;padding:.7rem .8rem;background:var(--paper)}
.aic-tile.bad{border-color:var(--lost);background:var(--lost-soft)}
.aic-n{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.5rem;color:var(--ink);line-height:1}
.aic-l{font-family:'IBM Plex Mono',monospace;font-size:.6rem;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);margin-top:.3rem}
.aic-since{font-size:.75rem;color:var(--muted);margin:.2rem 0 .9rem}
.aic-since .mono{font-family:'IBM Plex Mono',monospace;font-size:.72rem}
.aic-insights{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1rem}
.aic-ins{border-left:3px solid var(--line);border-radius:0 8px 8px 0;padding:.5rem .75rem;background:var(--paper)}
.aic-ins.good{border-left-color:var(--ok);background:var(--ok-soft)}
.aic-ins.watch{border-left-color:var(--warn);background:var(--warn-soft)}
.aic-ins.act{border-left-color:var(--lost);background:var(--lost-soft)}
.aic-ins-t{display:block;font-weight:700;font-size:.85rem;color:var(--ink)}
.aic-ins-b{display:block;font-size:.8rem;color:var(--muted);line-height:1.45;margin-top:.15rem}
.aic-break{margin-bottom:.9rem}
.aic-break-h{font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-bottom:.4rem}
.aic-row{display:grid;grid-template-columns:8rem 1fr 4.5rem;grid-template-areas:'k track v' 'c c c';gap:.1rem .6rem;align-items:center;padding:.25rem 0}
.aic-k{grid-area:k;font-size:.82rem;color:var(--ink);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.aic-track{grid-area:track;height:8px;background:var(--line-2);border-radius:5px;overflow:hidden}
.aic-fill{display:block;height:100%;border-radius:5px;background:var(--oak)}
.aic-fill.t-light{background:var(--ok)}
.aic-fill.t-mid{background:var(--oak)}
.aic-fill.t-frontier{background:var(--lost)}
.aic-v{grid-area:v;font-family:'IBM Plex Mono',monospace;font-size:.85rem;color:var(--ink);text-align:right}
.aic-c{grid-area:c;font-size:.68rem;color:var(--faint);font-family:'IBM Plex Mono',monospace}
.aic-detail{margin-top:.5rem}
.aic-detail summary{cursor:pointer;font-size:.8rem;color:var(--oak);font-weight:600}
.aic-table{margin-top:.6rem;overflow-x:auto}
.aic-tr{display:grid;grid-template-columns:6rem 4rem 9rem 3rem 4rem 3.5rem 4.5rem;gap:.5rem;padding:.35rem 0;border-bottom:1px solid var(--line-2);font-size:.78rem;align-items:center;min-width:34rem}
.aic-th{font-family:'IBM Plex Mono',monospace;font-size:.6rem;letter-spacing:.06em;text-transform:uppercase;color:var(--faint);font-weight:600}
.aic-tier{font-family:'IBM Plex Mono',monospace;font-size:.55rem;text-transform:uppercase;letter-spacing:.05em;padding:.02rem .25rem;border-radius:3px;color:#fff}
.aic-tier.t-light{background:var(--ok)}
.aic-tier.t-mid{background:var(--oak)}
.aic-tier.t-frontier{background:var(--lost)}
.aic-tier.t-unknown{background:var(--faint)}

.needs{border:1px solid var(--oak);background:linear-gradient(180deg,rgba(201,168,124,.09),transparent)}
.needs-h{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:1rem;color:var(--ink);
  display:flex;align-items:center;gap:.5rem;margin-bottom:.6rem}
.needs-h .ic{width:18px;height:18px;color:var(--oak)}
.needs-row{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;padding:.5rem 0;border-top:1px solid var(--line-2)}
.needs-what{font-size:.88rem;color:var(--ink)}
.needs-powers{color:var(--muted);display:block;font-size:.8rem;margin-top:.1rem}
.needs-get{color:var(--oak);font-weight:700;white-space:nowrap;font-size:.84rem}
.needs-get:hover{color:var(--ink)}
.v1sync{display:flex;align-items:flex-start;justify-content:space-between;gap:1.2rem;flex-wrap:wrap}
.v1sync-state{flex:1 1 20rem;min-width:0}
.v1sync-note{display:block;color:var(--muted);font-size:.84rem;margin-top:.35rem;line-height:1.45}
.v1sync-note code{font-family:'IBM Plex Mono',monospace;font-size:.78rem;color:var(--ink)}
.v1sync form{flex:0 0 auto}
@media (max-width:720px){
  .keyrow{grid-template-columns:3px 1fr;gap:.5rem .8rem}
  .key-field,.key-acts{grid-column:2}
  .key-field{margin-top:.5rem}
}
.btn{border:0;border-radius:7px;font:inherit;font-weight:600;font-size:.85rem;padding:.5rem .9rem;cursor:pointer;background:var(--chalk);color:#fff;white-space:nowrap}
.btn:hover{background:var(--chalk-2)}
.btn.ghost{background:var(--surface);color:var(--muted);border:1px solid var(--line)}
.btn.ghost:hover{background:var(--paper);color:var(--ink)}
.btn.danger{background:var(--surface);color:var(--lost);border:1px solid var(--lost-soft)}
.btn.danger:hover{background:var(--lost-soft)}
@media (max-width:760px){.keyrow{grid-template-columns:1fr}}
.modlist{display:flex;flex-direction:column}
.modrow{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.75rem 0;border-bottom:1px solid var(--line-2)}
.modrow:last-child{border-bottom:0}
.modname{font-weight:600;font-size:.95rem}
.modsum{color:var(--faint);font-size:.85rem;margin-left:.6rem}
@media (max-width:600px){.modsum{display:none}}
.toggle{width:42px;height:24px;border-radius:999px;border:0;background:var(--line);cursor:pointer;position:relative;flex:none;transition:background .15s}
.toggle.on{background:var(--chalk)}
.toggle .knob{position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:#fff;transition:transform .15s}
.toggle.on .knob{transform:translateX(18px)}

/* ---------- brand lockup with emblem ---------- */
.brand-emblem{display:flex;align-items:center;gap:.55rem;padding:1.2rem 1.3rem .8rem}
.brand-emblem img{width:26px;height:26px;flex:none}
.brand-emblem .wm{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.25rem;letter-spacing:-.02em;color:#e8ddcf}
.brand-emblem .wm b{color:var(--oak)}
.login .brand-lock{display:flex;align-items:center;gap:.6rem;margin-bottom:.2rem}
.login .brand-lock img{width:40px;height:40px}

/* ---------- login ---------- */
.login-body{display:flex;align-items:center;justify-content:center;min-height:100vh;background:linear-gradient(120deg,var(--walnut),var(--walnut-2))}
.login{background:var(--surface);border-radius:14px;padding:2.2rem 2rem;width:min(24rem,92vw);box-shadow:0 30px 70px rgba(0,0,0,.4)}
.brand-lg{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:2rem;letter-spacing:-.02em}
.brand-lg b{color:var(--oak)}
.login-sub{color:var(--muted);font-size:.92rem;margin:.3rem 0 1.3rem}
.login-err{background:var(--lost-soft);color:var(--lost);border-radius:8px;padding:.6rem .8rem;font-size:.88rem;margin-bottom:1rem}
.login label{display:block;font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-bottom:.4rem}
.login input[type=password]{width:100%;border:1px solid var(--line);border-radius:8px;padding:.7rem .8rem;font:inherit;font-size:1rem;margin-bottom:1rem}
.login input[type=password]:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
.login .remember{display:flex;align-items:center;gap:.5rem;text-transform:none;letter-spacing:0;font-family:inherit;font-size:.85rem;color:var(--muted);margin-bottom:1.2rem}
.login button{width:100%;background:var(--chalk);color:#fff;border:0;border-radius:8px;font:inherit;font-weight:600;font-size:1rem;padding:.8rem;cursor:pointer}
.login button:hover{background:var(--chalk-2)}

/* ============================================================
   MOBILE: app-like chrome. Bottom bar, sheets, touch sizing.
   Desktop never sees any of this.
   ============================================================ */
.mbar,.msheet{display:none}

@media (max-width:900px){
  /* the bottom bar: thumb-reachable, safe-area aware */
  .mbar{display:grid;grid-template-columns:repeat(5,1fr);position:fixed;left:0;right:0;bottom:0;z-index:80;
    background:var(--walnut);border-top:1px solid #3c2f24;
    padding-bottom:env(safe-area-inset-bottom,0)}
  .mb-tab{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.15rem;
    min-height:56px;background:none;border:0;cursor:pointer;position:relative;
    color:#9a8871;font-size:.62rem;font-weight:600;font-family:'IBM Plex Mono',monospace;letter-spacing:.03em;text-decoration:none}
  .mb-tab .ic{width:21px;height:21px}
  .mb-tab.on,.mb-tab:active{color:var(--oak)}
  .mb-tab.on .ic{color:var(--oak)}
  .mb-badge{position:absolute;top:6px;right:calc(50% - 18px);background:var(--lost);color:#fff;
    font-size:.55rem;min-width:14px;height:14px;border-radius:999px;display:flex;align-items:center;justify-content:center;padding:0 3px}
  /* keep content clear of the bar */
  body{padding-bottom:calc(56px + env(safe-area-inset-bottom,0))}
  body.msheet-open{overflow:hidden}

  /* sheets slide up from the bar */
  .msheet:not([hidden]){display:block;position:fixed;inset:0;z-index:90;background:rgba(30,23,18,.5)}
  .msheet-card{position:absolute;left:0;right:0;bottom:0;max-height:82vh;display:flex;flex-direction:column;
    background:var(--surface);border-radius:18px 18px 0 0;padding-bottom:env(safe-area-inset-bottom,0);
    animation:msheet-up .18s ease-out}
  @keyframes msheet-up{from{transform:translateY(14px);opacity:.6}to{transform:none;opacity:1}}
  .msheet-grab{width:38px;height:4px;border-radius:999px;background:var(--line);margin:.6rem auto .2rem}
  .msheet-head{display:flex;align-items:center;justify-content:space-between;padding:.6rem 1.1rem .7rem;
    border-bottom:1px solid var(--line);font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.05rem}
  .msheet-link{font-family:'Instrument Sans',sans-serif;font-size:.82rem;font-weight:600;color:var(--chalk)}
  .msheet-body{overflow-y:auto;padding:.8rem 1rem 1.2rem;display:flex;flex-direction:column;gap:.5rem}
  .msheet-sec{font-family:'IBM Plex Mono',monospace;font-size:.6rem;letter-spacing:.12em;text-transform:uppercase;
    color:var(--faint);margin:.6rem 0 .1rem}
  .msheet-row{display:flex;align-items:center;gap:.7rem;min-height:48px;padding:0 .3rem;font-size:.95rem;font-weight:500}
  .msheet-row .ic{width:19px;height:19px;color:var(--oak-dim)}
  .msheet-row .chip{margin-left:auto}

  /* the panel lives in the sheet on a phone, never squeezed into the page */
  .pn,.pn-open{display:none!important}

  /* dense tables: drop the columns a phone cannot use, grow the tap target */
  table.cust th:nth-child(3),table.cust td:nth-child(3),
  table.cust th:nth-child(4),table.cust td:nth-child(4),
  table.cust th:nth-child(5),table.cust td:nth-child(5){display:none}
  table.cust td{padding:.85rem .8rem}
  table.cust tr.row{cursor:pointer}
  .toolbar{gap:.6rem}
  .filters{overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:.2rem}
  .filt{white-space:nowrap}

  /* profile + grids breathe */
  .prof-grid{grid-template-columns:1fr}
  .prod-grid{grid-template-columns:repeat(auto-fill,minmax(9rem,1fr))}
  .stats{grid-template-columns:1fr 1fr}
  .pa{min-height:44px;min-width:0;flex:1 1 auto}
  .content{padding-bottom:1rem}
}

/* honor reduced motion for the sheet */
@media (prefers-reduced-motion:reduce){.msheet-card{animation:none}}

/* CutPile Voice chooser (ElevenLabs) */
.voice-form{display:flex;flex-direction:column;gap:.9rem;margin-top:.8rem}
.vf-label{font-weight:600;color:var(--ink);font-size:.9rem;margin-top:.4rem}
.vf-label .cc-hint{font-weight:400}
.voice-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(15rem,1fr));gap:.6rem}
.voice-opt{display:flex;align-items:center;gap:.6rem;text-align:left;border:1px solid var(--line);border-radius:10px;
  background:var(--surface);padding:.6rem .7rem;cursor:pointer;transition:.12s;color:var(--ink)}
.voice-opt:hover{border-color:var(--oak)}
.voice-opt.on{border-color:var(--chalk);background:var(--chalk-soft,rgba(201,168,124,.12))}
.vo-play{flex:none;width:26px;height:26px;border-radius:50%;display:grid;place-items:center;font-size:.62rem;
  background:rgba(201,168,124,.18);color:var(--oak)}
.voice-opt.on .vo-play{background:var(--chalk);color:#fff}
.vo-main{flex:1;min-width:0;display:flex;flex-direction:column}
.vo-name{font-weight:600;font-size:.92rem}
.vo-desc{font-size:.74rem;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:capitalize}
.vo-check{flex:none;color:var(--chalk);opacity:0;font-weight:700}
.voice-opt.on .vo-check{opacity:1}
.voice-sliders{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:.7rem 1.2rem}
.vslide{display:grid;grid-template-columns:1fr auto;align-items:center;gap:.2rem .6rem;font-size:.86rem;font-weight:600;color:var(--ink)}
.vslide .cc-hint{grid-column:1;font-weight:400;font-size:.72rem}
.vslide input[type=range]{grid-column:1;width:100%;accent-color:var(--chalk)}
.vslide output{grid-column:2;grid-row:2;font-family:'IBM Plex Mono',monospace;font-size:.78rem;color:var(--muted);min-width:2.4rem;text-align:right}
.voice-pickrow{display:flex;gap:.5rem;align-items:stretch}
.voice-pickrow select{flex:1;min-width:0}
.btn.sm{padding:.4rem .7rem;font-size:.82rem;white-space:nowrap}
.voice-test{border:1px solid var(--line);border-radius:10px;background:var(--paper);padding:.7rem;display:flex;flex-direction:column;gap:.55rem}
.voice-test textarea{width:100%;box-sizing:border-box;border:1px solid var(--line);border-radius:8px;padding:.55rem .7rem;font:inherit;font-size:.9rem;line-height:1.45;background:var(--surface);color:var(--ink);resize:vertical;min-height:3rem}
.voice-test textarea:focus{outline:none;border-color:var(--oak)}
.voice-test-row{display:flex;align-items:center;gap:.8rem;flex-wrap:wrap}
.voice-dirty{font-size:.82rem;color:#9a6a1f;background:rgba(201,168,124,.14);border:1px solid rgba(201,168,124,.3);border-radius:8px;padding:.4rem .6rem}
.voice-dirty b{font-weight:700}
.voice-status{display:flex;flex-direction:column;gap:.35rem;margin:.4rem 0 .2rem}
.voice-status .vs-row{display:flex;justify-content:space-between;gap:1rem;font-size:.86rem;padding:.32rem 0;border-bottom:1px solid var(--line)}
.voice-status .vs-row:last-child{border-bottom:none}
.voice-status .vs-k{color:var(--cream-dim,#8a7a63)}
.voice-status .vs-v{color:var(--ink);font-weight:600;text-align:right}

/* Whispers: the suggestion queue */
.wh-wrap{max-width:56rem;margin:0 auto;padding:clamp(1rem,2.5vw,1.8rem) 0}
.wh-head h1{display:flex;align-items:center;gap:.5rem;font-size:1.6rem;margin:0 0 .25rem}
.wh-head h1 .ic{width:22px;height:22px;color:var(--oak)}
.wh-head p{color:var(--muted);margin:0 0 1.2rem;font-size:.92rem;max-width:46rem}
.wh-empty{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.6rem;color:var(--muted);
  border:1px dashed var(--line);border-radius:14px;padding:2.4rem 1.5rem;background:var(--surface)}
.wh-empty .ic{width:30px;height:30px;color:var(--oak);opacity:.7}
.wh-empty p{max-width:34rem;font-size:.92rem}
.wh-list{display:flex;flex-direction:column;gap:.8rem}
.wh-card{border:1px solid var(--line);border-radius:14px;background:var(--surface);padding:1rem 1.1rem;
  border-left:3px solid var(--oak)}
.wh-top{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin-bottom:.5rem}
.wh-chip{font-family:'IBM Plex Mono',monospace;font-size:.6rem;letter-spacing:.08em;text-transform:uppercase;
  padding:.15rem .5rem;border-radius:5px;background:rgba(201,168,124,.16);color:var(--oak);border:1px solid rgba(201,168,124,.3)}
.wh-chip.wh-price{background:rgba(122,90,31,.14);color:#9a6a1f;border-color:rgba(122,90,31,.3)}
.wh-chip.wh-contact{background:rgba(47,95,138,.14);color:#3a6ea0;border-color:rgba(47,95,138,.3)}
.wh-chip.wh-product{background:rgba(53,106,58,.14);color:#3a7a41;border-color:rgba(53,106,58,.3)}
.wh-meta{font-size:.78rem;color:var(--muted)} .wh-meta a{color:var(--chalk);font-weight:600}
.wh-title{font-weight:700;color:var(--ink);font-size:1.02rem;line-height:1.35}
.wh-detail{color:var(--muted);font-size:.9rem;margin-top:.3rem;line-height:1.5}
.wh-actions{display:flex;gap:.5rem;justify-content:flex-end;margin-top:.8rem}
.wh-actions form{margin:0}
.wh-btn{display:inline-flex;align-items:center;gap:.35rem;font:inherit;font-size:.85rem;font-weight:600;cursor:pointer;
  border-radius:9px;padding:.45rem .9rem;border:1px solid var(--line)}
.wh-btn .ic{width:15px;height:15px}
.wh-btn.ghost{background:var(--paper);color:var(--muted)}
.wh-btn.ghost:hover{color:var(--ink);border-color:var(--line-2,var(--oak))}
.wh-btn.go{background:var(--chalk);color:#fff;border-color:var(--chalk)}
.wh-btn.go:hover{background:var(--chalk-2)}
.wh-recent-h{font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.14em;text-transform:uppercase;color:var(--faint);margin:2rem 0 .7rem}
.wh-recent{display:flex;flex-direction:column;gap:.15rem}
.wh-rrow{display:flex;align-items:center;gap:.7rem;padding:.5rem .2rem;border-bottom:1px solid var(--line-2,var(--line));font-size:.86rem}
.wh-rstate{font-family:'IBM Plex Mono',monospace;font-size:.58rem;letter-spacing:.06em;text-transform:uppercase;padding:.12rem .45rem;border-radius:4px;flex:none}
.wh-rstate.wh-on{background:rgba(63,157,85,.14);color:#3f9d55}
.wh-rstate.wh-off{background:var(--line-2,var(--line));color:var(--muted)}
.wh-rtitle{color:var(--ink);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.wh-rmeta{color:var(--faint);font-size:.72rem;flex:none}

@media (max-width:900px){
  /* nav lives in the More sheet on a phone; the rail would only steal the screen */
  .side{display:none!important}
  .app{grid-template-columns:1fr!important}
  .top{padding:.8rem 1rem;position:sticky;top:0}
  .top h1{font-size:1.15rem}
  .content{padding:1rem}
}

@media (max-width:900px){
  /* the job/customer table must fit the phone, not be clipped by the wrapper */
  .table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  table.cust{width:100%}
  .who .sub{display:none}            /* the email does not earn its width on a phone */
  .who{gap:.5rem}
  .who .nm{font-size:.9rem;line-height:1.25}
  table.cust .chip{font-size:.62rem;padding:.18rem .4rem;white-space:normal}
  table.cust td:last-child{font-size:.74rem;white-space:nowrap}
  table.cust td{padding:.75rem .5rem}
  table.cust th{padding:.6rem .5rem}
}

/* ---------- color detail: gallery + carton calculator ---------- */
.cl-dot{width:22px;height:22px;border-radius:6px;border:1px solid var(--line);flex:none}
.cl-hero{background:var(--plank);aspect-ratio:4/3;display:flex;align-items:center;justify-content:center;overflow:hidden}
.cl-hero img,.cl-hero video{width:100%;height:100%;object-fit:cover;display:block}
.cl-thumbs{display:flex;gap:.4rem;padding:.6rem;overflow-x:auto;background:var(--surface);border-top:1px solid var(--line-2)}
.cl-thumb{width:58px;height:58px;flex:none;border-radius:8px;overflow:hidden;border:2px solid transparent;background:var(--plank);cursor:pointer;padding:0;position:relative}
.cl-thumb.on{border-color:var(--chalk)}
.cl-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.cl-play{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:var(--walnut);color:var(--oak)}
.cl-play .ic{width:20px;height:20px}
.cl-sample{display:flex;align-items:center;justify-content:space-between;gap:.6rem;padding:.45rem 0;border-bottom:1px solid var(--line-2);font-size:.86rem}
.cl-sample:last-child{border-bottom:0}
.cl-sample-p{font-size:.74rem;color:var(--faint)}
a.color{display:block;color:inherit}
a.color:hover{border-color:var(--oak)}

.calc-sf{display:flex;align-items:baseline;gap:.4rem;background:var(--paper);border:1px solid var(--line);border-radius:10px;padding:.7rem .9rem;margin-bottom:.9rem}
.calc-sf-n{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.5rem}
.calc-sf-l{font-size:.8rem;color:var(--muted)}
.calc-row{display:flex;align-items:center;justify-content:space-between;gap:.8rem;margin-bottom:.7rem}
.calc-row label{font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.calc-input{display:flex;align-items:center;gap:.4rem;border:1px solid var(--line);border-radius:8px;padding:.45rem .6rem;background:var(--surface)}
.calc-input input{border:0;outline:none;font:inherit;font-size:1rem;width:6.5rem;text-align:right;background:transparent}
.calc-input span{font-size:.78rem;color:var(--faint)}
.calc select{border:1px solid var(--line);border-radius:8px;padding:.45rem .6rem;font:inherit;font-size:.9rem;background:var(--surface)}
.calc-out{border-top:1px solid var(--line-2);padding-top:.8rem;margin-top:.2rem}
.calc-line{display:flex;align-items:baseline;justify-content:space-between;padding:.3rem 0;font-size:.88rem;color:var(--muted)}
.calc-line b{color:var(--ink);font-weight:600}
.calc-line.big{border-top:1px solid var(--line-2);border-bottom:1px solid var(--line-2);margin:.3rem 0;padding:.6rem 0}
.calc-line.big b{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.6rem;color:var(--chalk)}

/* Total cost block under the calculator. Money is oak, matching the pricing card,
   so it reads as price rather than as another carton count. */
.calc-cost{border-top:1px solid var(--line);margin-top:1rem;padding-top:.85rem}
.calc-cost-h{display:flex;justify-content:space-between;align-items:baseline;gap:.6rem;
  font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-bottom:.35rem}
.calc-cost-h span{text-transform:none;letter-spacing:0;font-family:inherit;font-size:.74rem;color:var(--muted)}
.calc-cost .calc-line.big b{font-family:'IBM Plex Mono',monospace;font-weight:700;font-size:1.35rem;color:var(--oak)}
.calc-cost .calc-line.install b{color:var(--oak)}
.calc-cost-note{font-size:.72rem;color:var(--muted);line-height:1.45;margin-top:.55rem}
.calc-min{font-family:'IBM Plex Mono',monospace;font-weight:500;font-size:.66rem;color:var(--oak);margin-left:.15rem}

/* Pricing sits full width at the top of a product and each color, above the rest,
   with the price ladder laid out as a ROW of cells to use the width. It collapses to
   fewer columns, then to a stack, as the screen narrows. */
.price-band{margin:1rem 0 0}
.price-band .pricing{margin-bottom:0}
.price-band .pl{display:grid;grid-template-columns:repeat(auto-fit,minmax(8.5rem,1fr));gap:0;
  border:1px solid var(--line-2);border-radius:10px;overflow:visible;margin-bottom:.7rem}
/* Supplied & installed — the headline price, its own box above the ladder. */
.pl-hero{display:flex;flex-direction:column;gap:.15rem;padding:.7rem .9rem;margin-bottom:.6rem;
  border:1px solid var(--oak);border-radius:12px;background:linear-gradient(120deg,rgba(201,168,124,.16),transparent)}
.plh-k{font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);display:flex;align-items:center;gap:.35rem}
.plh-v{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.75rem;color:var(--oak);line-height:1}
.plh-v small{font-size:.78rem;color:var(--muted);font-weight:600;margin-left:.15rem}
.plh-n{font-size:.76rem;color:var(--muted)}
.pl-floor{font-family:'IBM Plex Mono',monospace;font-size:.5rem;letter-spacing:.05em;text-transform:uppercase;
  padding:.05rem .3rem;border-radius:4px;background:var(--oak);color:#fff;margin-left:.3rem;vertical-align:middle}
/* Merchandising price-group tag: color + name (never color alone). */
.pband{display:inline-flex;align-items:center;gap:.3rem;margin-left:.4rem;font-family:'IBM Plex Mono',monospace;
  font-size:.56rem;letter-spacing:.06em;text-transform:uppercase;font-weight:600;padding:.12rem .45rem .12rem .35rem;
  border-radius:20px;border:1px solid var(--pb);color:var(--pb)}
.pband-dot{width:9px;height:9px;border-radius:50%;background:var(--pb)}
.pband-lg{font-size:.62rem;padding:.2rem .55rem .2rem .45rem}
.pband-lg .pband-dot{width:11px;height:11px}
/* Reusable circled-? tooltip (View\hint). */
.hintq{display:inline-grid;place-items:center;width:15px;height:15px;border-radius:50%;border:1px solid var(--line);
  color:var(--faint);font-family:'IBM Plex Mono',monospace;font-size:.6rem;cursor:help;position:relative;vertical-align:middle;flex:none}
.hintq:hover,.hintq:focus-visible{color:var(--ink);border-color:var(--oak);outline:none}
.hintq-tip{position:absolute;bottom:150%;left:50%;transform:translateX(-50%) translateY(4px);width:210px;
  background:var(--walnut);color:#e8ddcf;font-family:'Instrument Sans',system-ui,sans-serif;font-weight:400;
  font-size:.75rem;line-height:1.42;text-align:left;letter-spacing:0;text-transform:none;padding:.55rem .65rem;
  border-radius:9px;box-shadow:0 12px 32px rgba(0,0,0,.3);opacity:0;visibility:hidden;transition:opacity .14s,transform .14s;z-index:30;pointer-events:none}
.hintq:hover .hintq-tip,.hintq:focus-visible .hintq-tip{opacity:1;visibility:visible;transform:translateX(-50%)}
.price-band .pl-row{grid-template-columns:none;display:flex;flex-direction:column;gap:.2rem;
  padding:.6rem .8rem;border-bottom:0;border-right:1px solid var(--line-2)}
.price-band .pl-row:last-child{border-right:0}
.price-band .pl-n{grid-column:auto}
@media (max-width:560px){
  .price-band .pl-row{border-right:0;border-bottom:1px solid var(--line-2)}
  .price-band .pl-row:last-child{border-bottom:0}
}

/* ---------- rendered markdown ---------- */
.md p{margin:0 0 .55rem}
.md p:last-child{margin-bottom:0}
.md strong,.md b{font-weight:700;color:var(--ink)}
.md em,.md i{font-style:italic}
.md a{color:var(--chalk);font-weight:500;word-break:break-word}
.md a:hover{text-decoration:underline}
.md code{font-family:'IBM Plex Mono',monospace;font-size:.85em;background:var(--paper);padding:.05rem .3rem;border-radius:4px}
.md ul,.md ol{margin:.3rem 0 .6rem 1.1rem}
.md li{margin:.15rem 0}
.tl-body.md,.jc-body.md{white-space:normal}

/* ======================================================================
   SPLIT VIEW
   Two panes, never three. The split icon on a nav row opens that page on
   the right; the left carries on as the main window.
   ====================================================================== */

/* the split icon, revealed on hover of its nav row */
.nav-row{position:relative;display:flex;align-items:center}
.nav-row .nav-i{flex:1;min-width:0}
.nav-split{position:absolute;right:.3rem;top:50%;transform:translateY(-50%);
  display:flex;align-items:center;justify-content:center;
  width:1.6rem;height:1.6rem;padding:0;border:0;border-radius:5px;
  background:transparent;color:var(--chalk);cursor:pointer;
  opacity:0;transition:opacity .12s ease,background .12s ease}
.nav-split .ic{width:15px;height:15px}
.nav-row:hover .nav-split,.nav-split:focus-visible{opacity:.75}
.nav-split:hover{opacity:1;background:rgba(255,255,255,.1)}
/* on a touch screen there is no hover, so never hide it behind one */
@media (hover:none){.nav-split{opacity:.5}}
/* the icon would sit on top of the label text in a narrow rail */
@media (max-width:900px){.nav-split{display:none}}

/* the two panes */
.split-wrap{display:block}
.split-wrap.on{display:grid;grid-template-columns:1fr 1fr;gap:0;
  align-items:stretch;height:calc(100vh - 3.9rem)}
.split-wrap.on > .content{overflow-y:auto;min-width:0}

.splitpane{display:flex;flex-direction:column;min-width:0;
  border-left:1px solid var(--line);background:var(--paper)}
.sp-bar{display:flex;align-items:center;gap:.4rem;flex:0 0 auto;
  padding:.45rem .6rem;border-bottom:1px solid var(--line);background:var(--card)}
.sp-title{flex:1;min-width:0;font-family:'IBM Plex Mono',monospace;font-size:.68rem;
  font-weight:500;letter-spacing:.03em;text-transform:uppercase;color:var(--chalk);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sp-btn{display:flex;align-items:center;justify-content:center;
  width:1.7rem;height:1.7rem;border:0;border-radius:5px;background:transparent;
  color:var(--chalk);cursor:pointer;text-decoration:none}
.sp-btn:hover{background:var(--paper);color:var(--ink)}
.sp-btn .ic{width:15px;height:15px}
.sp-frame{flex:1;width:100%;border:0;background:var(--paper)}

/* the pane document itself */
body.pane{background:var(--paper)}
body.pane .content.pane-content{padding:1rem;container-type:inline-size;container-name:cp}

/* ----------------------------------------------------------------------
   CONTAINER QUERIES
   This is what makes the panes work at all.

   Everything else in this file is responsive to the VIEWPORT. A half pane
   on a 1440px screen is ~700px wide while the viewport is still 1440px, so
   `@media (max-width:900px)` never fires and the pane would get the desktop
   layout crushed into half the space. These rules ask the container how wide
   IT is, which is the question that actually matters here.

   The grids built on auto-fit/minmax (.stats, .prod-grid, .color-grid) need
   nothing: they already reflow on their own width.
   ---------------------------------------------------------------------- */
.content{container-type:inline-size;container-name:cp}

@container cp (max-width:900px){
  /* the profile's two columns become one: 20rem of specs next to a 380px
     column is not a layout, it is a squeeze */
  .prof-grid{grid-template-columns:1fr}
  .keyrow{grid-template-columns:1fr;gap:.4rem}
  .prof-top{flex-wrap:wrap}
  /* nowrap matters as much as the column does. The base .toolbar is flex-wrap:
     wrap; once the direction is column, wrap means "wrap into more columns", and
     in a multi-line flex container align-items:stretch sizes items to their flex
     LINE, not to the container. The line takes the width of the widest item, so
     both children stretched to the full chip row and burst out of the pane. */
  .toolbar{flex-direction:column;align-items:stretch;gap:.6rem;min-width:0;flex-wrap:nowrap}
  /* min-width:0 is the load-bearing half of this. A flex item defaults to
     min-width:auto, which refuses to shrink below its content, so the row of
     brand chips forces the toolbar wider than the pane and overflow-x never
     gets the chance to scroll. */
  .filters{overflow-x:auto;padding-bottom:.2rem;min-width:0;flex-wrap:nowrap}
  .count{min-width:0}
}

@container cp (max-width:640px){
  .prof-cover{padding:.9rem}
  .av-lg{width:3rem;height:3rem;font-size:1rem}
  .prof-id h2{font-size:1.1rem}
  .prof-actions{flex-wrap:wrap}
  .pa{flex:1 1 auto;justify-content:center}
  .stats{grid-template-columns:1fr 1fr}
  .card{padding:.8rem}
  .card-h{font-size:.68rem}
  /* a table has no business in a 500px pane; let it scroll on its own */
  .tablewrap{overflow-x:auto}
  .jc-row{flex-direction:column;align-items:flex-start;gap:.2rem}
  .cl-hero img{max-height:14rem}
}

/* a pane is a reading surface: the composer and calculator still work, but
   nothing should demand a wide window to be usable */
@container cp (max-width:520px){
  .prod-grid{grid-template-columns:repeat(auto-fill,minmax(9rem,1fr))}
  .color-grid{grid-template-columns:repeat(auto-fill,minmax(5rem,1fr))}
  .calc-row{flex-direction:column;align-items:stretch;gap:.3rem}
}

/* on a phone the window is already one narrow column; a second one would
   leave two useless slivers. The pane stacks under the content instead. */
@media (max-width:900px){
  .split-wrap.on{grid-template-columns:1fr;height:auto}
  .splitpane{border-left:0;border-top:2px solid var(--oak);height:70vh}
}

/* ---------------------------------------------------------------- pricing card
   Internal only. Cost and margin are hidden until asked for, so they are not on
   screen while a customer is standing next to you. */
.pricing .pr-note{display:block;font-size:.68rem;color:var(--muted);font-weight:400;margin-top:.05rem}
.pricing .pr-empty{color:var(--muted);font-style:italic;font-size:.85rem}
/* A missing price, wearing a number. Reads as a defect at a glance rather than as money: the
   figure is struck through and the label under it says what it really is. */
.pricing .pr-none{display:inline-flex;flex-direction:column;align-items:flex-end;line-height:1.05}
.pricing .pr-none{font:600 .95rem/1.05 var(--mono,ui-monospace,monospace);color:var(--danger,#b3261e);
  text-decoration:line-through;text-decoration-thickness:1.5px}
.pricing .pr-none span{margin-top:.15rem;font:500 .62rem/1 var(--mono,ui-monospace,monospace);
  letter-spacing:.06em;text-transform:uppercase;text-decoration:none;color:var(--danger,#b3261e);opacity:.8}
.pr-hint.warn{color:var(--danger,#b3261e)}
/* Outbox. The words themselves lead, because what you are approving is the wording. */
.ob-draft .ob-body{font-size:1rem;line-height:1.5;padding:.55rem .1rem;white-space:pre-wrap}
.ob-draft .ob-subj{font-weight:650;padding-top:.4rem}
.ob-why{display:flex;gap:.4rem;align-items:flex-start;font-size:.82rem;color:var(--chalk);
  border-top:1px solid var(--line);padding-top:.5rem;margin-top:.35rem}
.ob-why.err{color:var(--danger,#b3261e)}
.ob-why svg{width:14px;height:14px;flex:0 0 auto;margin-top:.1rem}
.ob-act{display:flex;gap:.5rem;margin-top:.7rem}
.ob-act form{margin:0}
.ob-when{margin-left:auto;font-size:.78rem;color:var(--chalk);font-weight:400}
/* A floor we do not sell, wherever it can still be searched for. Findable, never mistakable. */
.jps-no,.ac-no{font-style:normal;font-weight:600;color:var(--danger,#b3261e);
  letter-spacing:.02em;text-transform:uppercase;font-size:.9em}
.prod.disc .prod-t::after{content:''}
/* When the card is holding a placeholder its one explanatory line carries the warning. */
.pricing.ph .pr-why{color:var(--danger,#b3261e)}
.pr-reveal,.pr-edit{display:inline-flex;align-items:center;gap:.3rem;
  padding:.2rem .5rem;border:1px solid var(--line);border-radius:6px;
  background:var(--surface);color:var(--muted);cursor:pointer;
  font-family:'IBM Plex Mono',monospace;font-size:.72rem;font-weight:500}
.pr-reveal .ic{width:12px;height:12px}
.pr-reveal:hover,.pr-edit:hover{border-color:var(--chalk);color:var(--ink)}
.pr-reveal.on{background:var(--walnut);color:#fff;border-color:var(--walnut)}
.pr-edit{margin-left:.35rem}

.pr-form{margin:.7rem 0 0;padding:.7rem;border:1px dashed var(--line);border-radius:8px;background:var(--paper)}
.pr-form label{display:block;font-size:.72rem;font-weight:600;color:var(--muted);margin-bottom:.35rem}
.pr-inline{display:flex;align-items:center;gap:.35rem}
.pr-dollar{color:var(--muted);font-weight:600}
.pr-form input[type=number]{flex:1;min-width:0;padding:.4rem .5rem;border:1px solid var(--line);border-radius:6px;
  font-family:'IBM Plex Mono',monospace;font-size:.9rem;background:var(--card);color:var(--ink)}
.pr-form input[type=text]{width:100%;margin-top:.4rem;padding:.35rem .5rem;border:1px solid var(--line);
  border-radius:6px;font-size:.78rem;background:var(--card);color:var(--ink)}
.pr-form button{padding:.4rem .8rem;border:0;border-radius:6px;background:var(--walnut);color:#fff;
  font-weight:600;font-size:.8rem;cursor:pointer}

.pr-out{margin-top:.8rem;padding-top:.7rem;border-top:1px solid var(--line-2)}
.pr-out.empty-out{border-top:0;padding-top:0}
.pr-line{display:flex;align-items:baseline;justify-content:space-between;gap:.6rem;padding:.25rem 0;font-size:.85rem}
.pr-line span{color:var(--muted)}
.pr-line b{font-family:'IBM Plex Mono',monospace;font-weight:600;color:var(--ink);white-space:nowrap}
.pr-line b small{font-size:.68rem;color:var(--muted);font-weight:400;margin-left:.1rem}
.pr-line.big{padding:.45rem 0;border-top:1px solid var(--line-2);border-bottom:1px solid var(--line-2);margin:.3rem 0}
.pr-line.big span{color:var(--ink);font-weight:600}
.pr-line.big b{font-size:1.35rem;color:var(--oak)}
.pr-line.sub b{color:var(--muted);font-size:.78rem}
/* anything derived from cost stays blurred until you reveal cost */
.pr-hide{filter:blur(5px);opacity:.55;transition:filter .12s ease,opacity .12s ease;user-select:none}
.pr-hide.shown{filter:none;opacity:1;user-select:auto}
.pr-why{font-size:.78rem;color:var(--muted);line-height:1.45;margin-top:.4rem}
.pr-hint{font-size:.78rem;color:var(--chalk);margin-top:.3rem}
.pr-rule{margin-top:.6rem;padding-top:.5rem;border-top:1px dashed var(--line-2);
  font-size:.7rem;color:var(--muted);line-height:1.5}
.pr-rule a{color:var(--chalk);font-weight:600}

/* ------------------------------------------------------- job feed: two views
   The timeline and the chat are one job's story. Tabs, not two boxes. */
/* The card cannot clip its own contents. It used to say overflow:hidden, purely so the tab strip -
   which is flush against the top edge and has its own background - was cut to the card's rounded
   corners. That one line also cut off the product autocomplete inside the Products tab at the card's
   bottom edge, leaving one visible suggestion out of twenty-three, which is a search box that cannot
   be searched with.
   
   So the clipping moves to the thing that actually needed it: the tab strip rounds its own top
   corners, and the card is free to let a dropdown hang past its edge. */
.jobfeed{padding:0;overflow:visible}
.jf-tabs{display:flex;align-items:center;gap:.2rem;padding:.4rem .5rem 0;
  border-bottom:1px solid var(--line);background:var(--paper);
  border-radius:12px 12px 0 0}
.jf-tab{display:inline-flex;align-items:center;gap:.35rem;
  padding:.5rem .9rem;border:0;border-bottom:2px solid transparent;
  background:none;cursor:pointer;color:var(--muted);
  font-family:'Instrument Sans',sans-serif;font-size:.85rem;font-weight:600;
  border-radius:6px 6px 0 0;margin-bottom:-1px}
.jf-tab:hover{color:var(--ink);background:var(--surface)}
.jf-tab.on{color:var(--ink);border-bottom-color:var(--oak);background:var(--card)}
.jf-n{display:inline-flex;align-items:center;justify-content:center;min-width:1.15rem;
  padding:0 .25rem;border-radius:999px;background:var(--line-2);color:var(--muted);
  font-family:'IBM Plex Mono',monospace;font-size:.62rem;font-weight:600}
.jf-tab.on .jf-n{background:var(--oak);color:#fff}
.jf-panel{padding:.9rem}
.jf-panel[hidden]{display:none}
.jf-panel .composer{margin-top:0}
.jf-panel .jc-thread{max-height:26rem;overflow-y:auto}
@container cp (max-width:640px){
  .jf-tab{padding:.45rem .6rem;font-size:.8rem}
  .jf-panel{padding:.7rem}
}

/* ---- Most Important Facts: in the header (on the walnut cover) and the Job Facts tab ---- */
.prof-rule{border:0;border-top:1px solid rgba(201,168,124,.22);margin:.9rem 0 .75rem}
.pf-head{display:flex;align-items:baseline;gap:.6rem;margin-bottom:.55rem}
.pf-title{font-family:'IBM Plex Mono',monospace;font-size:.72rem;letter-spacing:.09em;text-transform:uppercase;color:var(--oak)}
.pf-more{margin-left:auto;font-size:.8rem;color:var(--oak-dim);border-bottom:1px dotted transparent;cursor:pointer;white-space:nowrap}
.pf-more:hover{color:#fff;border-bottom-color:var(--oak)}
.pf-list{display:flex;flex-direction:column}
.pf-row{display:flex;align-items:flex-start;gap:.55rem}

/* the accordion: closed by default, the single top fact (in full) plus a triangle; opening reveals
   the rest. The first fact is top-aligned, right under the divider. */
.pf-first{position:relative;display:flex;align-items:flex-start;gap:.55rem;cursor:pointer;border-radius:8px;outline-offset:3px}
.pf-first .pf-row{flex:1;min-width:0}
.pf-tri{flex:0 0 auto;align-self:flex-start;width:14px;height:14px;position:relative;color:var(--oak-dim);margin-top:.35rem;transition:transform .32s cubic-bezier(.4,0,.2,1),color .2s}
.pf-tri::before{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-42%);border-left:5px solid transparent;border-right:5px solid transparent;border-top:6px solid currentColor}
.pf-first:hover .pf-tri,.pf-first:focus-visible .pf-tri{color:#fff}
.prof-facts.pf-open .pf-tri{transform:rotate(180deg);color:var(--oak)}
.pf-rest{display:grid;grid-template-rows:0fr;transition:grid-template-rows .4s cubic-bezier(.4,0,.2,1)}
.prof-facts.pf-open .pf-rest{grid-template-rows:1fr}
.pf-rest-in{overflow:hidden;min-height:0;display:flex;flex-direction:column;gap:.45rem;padding-top:.45rem}
@media (prefers-reduced-motion:reduce){.pf-tri,.pf-rest{transition:none}}
.pf-score{flex:0 0 auto;min-width:2.1rem;height:1.5rem;padding:0 .32rem;border-radius:6px;display:inline-flex;align-items:center;justify-content:center;font-family:'IBM Plex Mono',monospace;font-weight:600;font-size:.82rem;font-variant-numeric:tabular-nums;line-height:1}
.pf-score.pf-hi{background:var(--oak);color:#241c15}
.pf-score.pf-mid{background:rgba(201,168,124,.28);color:#f1e7d8}
.pf-score.pf-lo{background:rgba(201,168,124,.13);color:var(--oak-dim)}
.pf-body{min-width:0;padding-top:.06rem}
.pf-fact{display:block;color:#f4ece0;font-size:.94rem;font-weight:500;line-height:1.35}
/* category on its own line, and beside it the source moment: absolute date/time, then time-ago */
.pf-meta{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap;margin-top:.24rem}
.pf-cat{font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.06em;text-transform:uppercase;color:var(--oak-dim);border:1px solid rgba(201,168,124,.3);border-radius:4px;padding:.06rem .3rem}
.pf-when{font-size:.72rem;color:var(--oak-dim);font-variant-numeric:tabular-nums}
.pf-ago{color:var(--oak)}
.pf-detail{color:var(--oak-dim);font-size:.85rem;margin-top:.2rem;line-height:1.4}
.pf-rank{display:none}
.pf-empty{color:var(--oak-dim);font-size:.88rem;line-height:1.45}

.jf-facts-lede{color:var(--muted);font-size:.9rem;margin-bottom:.9rem;max-width:44rem;line-height:1.5}
.jf-facts{display:flex;flex-direction:column;gap:.6rem}
.jf-facts .pf-row{align-items:flex-start;gap:.7rem;padding:.6rem .7rem;background:var(--surface);border:1px solid var(--line);border-radius:10px}
.jf-facts .pf-rank{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.4rem;height:1.5rem;font-family:'IBM Plex Mono',monospace;font-size:.8rem;color:var(--faint);font-variant-numeric:tabular-nums}
.jf-facts .pf-score.pf-mid{background:rgba(201,168,124,.24);color:var(--ink)}
.jf-facts .pf-score.pf-lo{background:var(--line-2);color:var(--muted)}
.jf-facts .pf-fact{color:var(--ink);font-size:.98rem}
.jf-facts .pf-cat{color:var(--muted);border-color:var(--line)}
.jf-facts .pf-when{color:var(--faint)}
.jf-facts .pf-ago{color:var(--oak-dim)}
.jf-facts .pf-detail{color:var(--muted)}
.jf-facts .pf-empty{color:var(--muted)}

/* ---- Assistant: full-width typed chat, the same mind and tools as Talk to CutPile ---- */
.assistant{display:flex;flex-direction:column;height:calc(100vh - 8rem);min-height:30rem;width:100%;max-width:58rem;margin-inline:auto}
.asst-stream{flex:1;overflow-y:auto;display:flex;flex-direction:column;gap:1rem;padding:.4rem .2rem 1rem}
.asst-msg{display:flex;gap:.7rem;max-width:100%;align-items:flex-start}
.asst-msg.me{flex-direction:row-reverse}
.asst-av{flex:0 0 auto;width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:.7rem;font-weight:700}
.asst-av.ai{background:var(--walnut);color:var(--oak)}
.asst-av.me{background:var(--chalk);color:#fff;text-transform:uppercase}
.asst-bubble{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:.75rem 1rem;font-size:.95rem;line-height:1.55;max-width:100%;min-width:0;overflow-wrap:anywhere}
.asst-msg.me .asst-bubble{background:var(--chalk);color:#fff;border-color:var(--chalk);max-width:min(36rem,85%)}
.asst-bubble p{margin:0 0 .5rem}.asst-bubble p:last-child{margin-bottom:0}
.asst-bubble ul{margin:.2rem 0 .5rem;padding-left:1.1rem}.asst-bubble li{margin:.15rem 0}
.asst-bubble a{color:var(--chalk);font-weight:600}
.asst-msg.me .asst-bubble a{color:#fff;text-decoration:underline}
.asst-media{display:flex;flex-wrap:wrap;gap:.4rem;margin-bottom:.4rem}
.asst-media img{max-width:150px;max-height:150px;border-radius:8px;object-fit:cover}
.asst-err{color:#b4462f}
.asst-composer{flex:0 0 auto;border:1px solid var(--line);border-radius:14px;background:var(--surface);padding:.5rem .5rem .35rem}
.asst-atts{display:flex;gap:.4rem;flex-wrap:wrap;padding:.3rem .3rem .1rem}
.asst-chip{position:relative;display:inline-flex}
.asst-chip img{width:44px;height:44px;border-radius:6px;object-fit:cover;border:1px solid var(--line)}
.asst-chip button{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;border:0;background:var(--ink);color:#fff;font-size:12px;line-height:1;cursor:pointer}
.asst-inputrow{display:flex;align-items:flex-end;gap:.4rem}
.asst-inputrow textarea{flex:1;border:0;background:transparent;font:inherit;font-size:.98rem;line-height:1.5;color:var(--ink);resize:none;max-height:200px;padding:.5rem .3rem;outline:none}
.asst-tool{flex:0 0 auto;width:38px;height:38px;border-radius:9px;border:0;background:transparent;color:var(--muted);cursor:pointer;display:flex;align-items:center;justify-content:center}
.asst-tool:hover{background:var(--paper);color:var(--ink)}
.asst-send{flex:0 0 auto;width:38px;height:38px;border-radius:9px;border:0;background:var(--chalk);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center}
.asst-send:hover{background:var(--chalk-2)}
.asst-send:disabled{opacity:.5;cursor:default}
.asst-tool .ic,.asst-send .ic{width:18px;height:18px}
.asst-foot{font-size:.72rem;color:var(--faint);padding:.35rem .5rem 0;text-align:center}
.asst-setup{margin-top:1rem;padding:1rem;border:1px solid var(--line);border-radius:12px;background:var(--surface);font-size:.95rem}
.asst-setup p{margin:.3rem 0 0;color:var(--muted)}
.asst-dots{display:inline-flex;gap:.25rem;padding:.15rem 0}
.asst-dots span{width:7px;height:7px;border-radius:50%;background:var(--oak-dim);animation:asstdot 1.2s infinite ease-in-out}
.asst-dots span:nth-child(2){animation-delay:.15s}.asst-dots span:nth-child(3){animation-delay:.3s}
@keyframes asstdot{0%,60%,100%{opacity:.25;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}
@media (prefers-reduced-motion:reduce){.asst-dots span{animation:none}}

/* ---- Email Templates: the admin management app ---- */
.et-head{margin-bottom:1.2rem}
.et-head h1{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.5rem;letter-spacing:-.02em;color:var(--ink)}
.et-lede{color:var(--muted);font-size:.95rem;margin-top:.3rem;max-width:46rem;line-height:1.5}
.et-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:1.2rem;align-items:start}
@media (max-width:900px){.et-grid{grid-template-columns:1fr}}
.et-list{padding:0;overflow:hidden}
.et-count{margin-left:.4rem;font-size:.75rem;color:var(--faint);font-weight:400}
.et-empty,.et-note{color:var(--muted);padding:1.1rem;font-size:.92rem;line-height:1.5}
.et-row{display:flex;align-items:center;gap:.6rem;padding:.7rem .9rem;border-top:1px solid var(--line-2)}
.et-row:hover{background:var(--paper)}
.et-row.on{background:var(--chalk-soft)}
.et-row-main{flex:1;min-width:0}
.et-name{font-weight:600;color:var(--ink)}
.et-name:hover{color:var(--chalk)}
.et-sub{font-size:.82rem;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.et-row-actions{display:flex;align-items:center;gap:.4rem;flex:none}
.et-inline{display:inline-flex}
.et-pill{font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.05em;text-transform:uppercase;padding:.28rem .55rem;border-radius:20px;border:1px solid var(--line);background:var(--surface);color:var(--faint);cursor:pointer}
.et-pill.on{background:var(--chalk);color:#fff;border-color:var(--chalk)}
.et-edit,.et-del{width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border-radius:7px;border:1px solid var(--line);background:var(--surface);color:var(--muted);cursor:pointer}
.et-edit:hover{color:var(--chalk);border-color:var(--chalk)}
.et-del:hover{color:var(--lost);border-color:var(--lost)}
.et-edit .ic,.et-del .ic{width:15px;height:15px}
.et-form{padding:1.1rem 1.2rem}
.et-label{display:block;font-size:.8rem;font-weight:600;color:var(--ink);margin:.9rem 0 .3rem}
.et-label:first-of-type{margin-top:.2rem}
.et-label span{font-weight:400;color:var(--faint);font-size:.75rem;margin-left:.3rem}
.et-input{width:100%;border:1px solid var(--line);border-radius:9px;padding:.6rem .7rem;font:inherit;font-size:.92rem;color:var(--ink);background:var(--paper)}
.et-input:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
.et-body{font-family:'IBM Plex Mono',monospace;font-size:.85rem;line-height:1.55;resize:vertical}
.et-optrow{display:flex;align-items:center;gap:1.4rem;margin-top:.9rem;flex-wrap:wrap}
.et-check{display:inline-flex;align-items:center;gap:.45rem;font-size:.88rem;color:var(--ink)}
.et-sort input{width:4.5rem;margin-left:.4rem;border:1px solid var(--line);border-radius:6px;padding:.3rem .45rem;font:inherit;background:var(--paper)}
.et-actions{display:flex;align-items:center;gap:1rem;margin-top:1.1rem}
.et-save{background:var(--chalk);color:#fff;border:0;border-radius:8px;font:inherit;font-weight:600;padding:.6rem 1.3rem;cursor:pointer}
.et-save:hover{background:var(--chalk-2)}
.et-cancel{color:var(--muted);font-size:.9rem}
.et-cancel:hover{color:var(--ink)}
.et-vars{margin-top:1.5rem;border-top:1px solid var(--line-2);padding-top:1rem}
.et-vars-h{font-size:.8rem;font-weight:600;color:var(--ink);margin-bottom:.6rem}
.et-vars-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(11rem,1fr));gap:.4rem}
.et-var{text-align:left;border:1px solid var(--line);border-radius:8px;background:var(--surface);padding:.4rem .6rem;cursor:pointer;font-family:'IBM Plex Mono',monospace;font-size:.76rem;color:var(--chalk);display:flex;flex-direction:column;gap:.1rem}
.et-var span{font-family:'Instrument Sans',sans-serif;color:var(--muted);font-size:.72rem}
.et-var:hover{border-color:var(--chalk);background:var(--chalk-soft)}
.et-vars-note{font-size:.75rem;color:var(--faint);margin-top:.7rem;line-height:1.45}
.et-preview{border:1px solid var(--line);border-radius:9px;background:var(--paper);padding:.75rem .85rem;min-height:4.5rem}
.et-preview-subj{font-weight:700;color:var(--ink);font-size:.95rem;padding-bottom:.4rem;margin-bottom:.5rem;border-bottom:1px solid var(--line-2)}
.et-preview-subj:empty{display:none}
.et-preview-body{font-size:.9rem;line-height:1.55;color:var(--ink)}
.et-sig-form{display:flex;flex-direction:column;gap:.6rem;align-items:flex-start}
.et-sig-form textarea{width:100%;font-family:'IBM Plex Mono',monospace;font-size:.85rem;line-height:1.5}

/* ---- Avatar menu (top-right): personal settings + control center + sign out ---- */
.usermenu{display:flex}
.topuser{border:0;background:transparent;padding:0;cursor:pointer;display:flex;align-items:center;border-radius:50%}
.topuser:hover .av.sm,.topuser:focus-visible .av.sm{box-shadow:0 0 0 3px var(--chalk-soft)}
.um-pop{right:0;left:auto;min-width:16rem}
.um-head{display:flex;align-items:center;gap:.6rem;padding:.7rem .9rem;border-bottom:1px solid var(--line-2)}
.um-id{display:flex;flex-direction:column;min-width:0}
.um-name{font-weight:600;color:var(--ink)}
.um-role{font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.06em;text-transform:uppercase;color:var(--oak-dim)}

/* ---- Control Center ---- */
.cc-tabs{display:flex;flex-wrap:wrap;gap:.15rem;border-bottom:1px solid var(--line);margin-bottom:1.3rem}
.cc-tab{border:0;background:transparent;font:inherit;font-size:.9rem;font-weight:600;color:var(--muted);padding:.6rem .85rem;border-bottom:2px solid transparent;margin-bottom:-1px;cursor:pointer;border-radius:6px 6px 0 0}
.cc-tab:hover{color:var(--ink);background:var(--surface)}
.cc-tab.on{color:var(--ink);border-bottom-color:var(--chalk)}
.cc-panel[hidden]{display:none}
.cc-panel>.card{margin-bottom:1.1rem}
.cc-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(8rem,1fr));gap:.7rem;margin-bottom:1.1rem}
.cc-tile{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:.85rem 1rem;display:flex;flex-direction:column;gap:.15rem}
.cc-k{font-family:'IBM Plex Mono',monospace;font-size:.64rem;letter-spacing:.07em;text-transform:uppercase;color:var(--faint)}
.cc-v{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.5rem;color:var(--ink);line-height:1}
.cc-form{display:flex;flex-direction:column;gap:.7rem;max-width:44rem}
.cc-field{display:flex;flex-direction:column;gap:.3rem}
.cc-label{font-size:.82rem;font-weight:600;color:var(--ink)}
.cc-hint{font-weight:400;color:var(--faint);font-size:.74rem}
.cc-form input[type=text],.cc-form input[type=email],.cc-form input[type=tel]{border:1px solid var(--line);border-radius:9px;padding:.55rem .7rem;font:inherit;font-size:.92rem;color:var(--ink);background:var(--paper)}
.cc-form input:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
/* Textareas were never given a rule here, only inputs were, so every one of them on this page was a raw
   browser box sitting next to properly dressed fields. These are for writing sentences that get spoken
   out loud, so they get room to hold one. */
.cc-form textarea{width:100%;box-sizing:border-box;border:1px solid var(--line);border-radius:9px;
  padding:.6rem .75rem;font:inherit;font-size:.92rem;line-height:1.5;color:var(--ink);
  background:var(--paper);resize:vertical;min-height:5rem}
.cc-form textarea:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
.cc-form select{border:1px solid var(--line);border-radius:9px;padding:.55rem .7rem;font:inherit;
  font-size:.92rem;color:var(--ink);background:var(--paper)}
.cc-form select:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
.cc-form .btn{align-self:flex-start}

/* The variables you can drop into a spoken line. Click one and it lands at the cursor, because copying
   bracket syntax by hand from a paragraph of help text is a small misery nobody should have to repeat. */
.vars{display:flex;flex-wrap:wrap;gap:.32rem;margin:.1rem 0 .15rem}
.vars-t{font-family:var(--mono);font-size:.63rem;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-4);align-self:center;margin-right:.15rem}
.var-chip{font-family:var(--mono);font-size:.68rem;padding:.2rem .45rem;border-radius:6px;cursor:pointer;
  border:1px solid var(--line);background:var(--surface);color:var(--ink-3);transition:all .13s ease}
.var-chip:hover{border-color:var(--chalk-2);background:var(--chalk-soft);color:var(--ink)}
.var-chip b{font-weight:600}
.var-chip i{font-style:normal;color:var(--ink-4);margin-left:.3rem}
.var-chip:hover i{color:var(--ink-3)}
.cc-links{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:.7rem}
.cc-link{display:flex;align-items:center;gap:.7rem;padding:.8rem .9rem;border:1px solid var(--line);border-radius:10px;color:var(--ink)}
.cc-link:hover{border-color:var(--chalk);background:var(--paper)}
.cc-link .ic{width:20px;height:20px;color:var(--oak-dim);flex:none}
.cc-link span{display:flex;flex-direction:column}
.cc-link em{font-style:normal;color:var(--muted);font-size:.8rem}
.cc-roadmap p{color:var(--muted);font-size:.92rem;line-height:1.55;margin-top:.2rem}
.cc-roadmap code,.cc-plain code{font-family:'IBM Plex Mono',monospace;font-size:.85em;background:var(--line-2);padding:.05rem .3rem;border-radius:4px}
.cc-plain{color:var(--muted);font-size:.92rem;line-height:1.55}
.cc-btnrow{display:flex;gap:.6rem;flex-wrap:wrap;align-items:center;margin-top:.3rem}
.cc-manual{margin-top:1rem;border-top:1px solid var(--line-2);padding-top:.8rem}
.cc-manual>summary{cursor:pointer;font-weight:600;font-size:.9rem;color:var(--chalk);list-style:none}
.cc-manual>summary::-webkit-details-marker{display:none}
.cc-manual>summary::before{content:"\25B8 ";color:var(--oak-dim)}
.cc-manual[open]>summary::before{content:"\25BE "}
.cc-manual .cc-form{margin-top:.8rem}
.cc-allgood{display:flex;align-items:center;gap:.5rem;color:#357a39;font-size:.95rem}
.cc-allgood .ic{width:18px;height:18px}
.cc-jump{display:flex;flex-wrap:wrap;gap:.4rem}
.cc-jump .chip{cursor:pointer;border:1px solid var(--line)}
.cc-jump .chip:hover{border-color:var(--chalk);color:var(--chalk)}
.cc-bars{display:flex;flex-direction:column;gap:.5rem}
.cc-bar-row{display:flex;align-items:center;gap:.7rem}
.cc-bar-label{flex:0 0 11rem;font-size:.82rem;color:var(--ink);text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cc-bar-track{flex:1;height:.8rem;background:var(--line-2);border-radius:6px;overflow:hidden}
.cc-bar-fill{display:block;height:100%;background:var(--oak);border-radius:6px}
.cc-bar-n{flex:0 0 2rem;font-variant-numeric:tabular-nums;font-size:.82rem;color:var(--muted);text-align:right}
.cc-spark{display:flex;align-items:flex-end;gap:3px;height:5rem}
.cc-spark-bar{flex:1;background:var(--chalk);border-radius:3px 3px 0 0;min-height:4px;opacity:.85}
.cc-spark-bar:hover{opacity:1}

/* ---- My Settings (personal) ---- */
.av.lg{width:52px;height:52px;font-size:1.1rem}
.me-head{display:flex;align-items:center;gap:.9rem;margin-bottom:1.3rem}
.me-sub{color:var(--muted);font-size:.88rem;margin-top:.15rem}
.me-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr));gap:1.1rem;align-items:start}
.me-form{display:flex;flex-direction:column;gap:.7rem}
.me-form label{display:flex;flex-direction:column;gap:.3rem;font-size:.82rem;font-weight:600;color:var(--ink)}
.me-form input[type=text],.me-form input[type=tel],.me-form input[type=date]{border:1px solid var(--line);border-radius:9px;padding:.55rem .7rem;font:inherit;font-weight:400;font-size:.92rem;color:var(--ink);background:var(--paper)}
.me-form input:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
.me-check{flex-direction:row!important;align-items:center;gap:.45rem!important;font-weight:400!important}
.me-hint{font-weight:400;color:var(--faint);font-size:.74rem}
.me-form .btn{align-self:flex-start}

/* ---- money-owed switch: header chip, action button, set panel ---- */
.owes-chip{font-family:'IBM Plex Mono',monospace;font-size:.64rem;letter-spacing:.05em;text-transform:uppercase;padding:.22rem .5rem;border-radius:20px;background:rgba(162,74,60,.18);color:#eab6aa;border:1px solid rgba(162,74,60,.45)}
.owes-chip.blocking{background:var(--lost);color:#fff;border-color:var(--lost)}
.pa.owes{color:#eab6aa}
.money-compose{background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:.9rem 1rem;margin-bottom:.8rem}
.money-toggle{display:flex;gap:1.3rem;margin:.5rem 0 .7rem}
.money-radio{display:inline-flex;align-items:center;gap:.4rem;font-size:.9rem;color:var(--ink);cursor:pointer}
.money-detail{display:flex;flex-wrap:wrap;align-items:center;gap:.9rem;transition:opacity .2s}
.money-detail label{display:inline-flex;align-items:center;gap:.4rem;font-size:.85rem;color:var(--ink)}
.money-detail select{border:1px solid var(--line);border-radius:7px;padding:.35rem .5rem;font:inherit;background:var(--paper);color:var(--ink)}
.money-detail input[type=text]{flex:1;min-width:14rem;border:1px solid var(--line);border-radius:7px;padding:.45rem .6rem;font:inherit;font-size:.88rem;background:var(--paper);color:var(--ink)}
.money-actions{margin-top:.8rem}
.cal-add-form{display:inline}
.chip-btn{cursor:pointer;border:1px solid var(--line);background:var(--surface);font:inherit;font-family:'IBM Plex Mono',monospace}
.chip-btn:hover{border-color:var(--oak);color:var(--oak)}

/* ---- Financials tab (QuickBooks) ---- */
.fin{display:flex;flex-direction:column;gap:1.1rem}
.fin-note,.fin-empty{color:var(--muted);font-size:.92rem;padding:.4rem 0;line-height:1.5}
.fin-note a{color:var(--chalk);font-weight:600}
.fin-status{display:flex;align-items:baseline;gap:.7rem;padding:.85rem 1.1rem;background:var(--surface);border:1px solid var(--line);border-radius:10px}
.fin-status-k{font-family:'IBM Plex Mono',monospace;font-size:.64rem;letter-spacing:.07em;text-transform:uppercase;color:var(--faint)}
.fin-status-v{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.6rem;line-height:1}
.fin-status-v.owed{color:var(--lost)}
.fin-status-v.clear{color:#357a39}
.fin-sec-h{font-family:'IBM Plex Mono',monospace;font-size:.64rem;letter-spacing:.07em;text-transform:uppercase;color:var(--faint);margin-bottom:.45rem}
.fin-tbl-wrap{overflow-x:auto}
.fin-tbl{width:100%;border-collapse:collapse;font-size:.88rem}
.fin-tbl th{text-align:left;font-family:'IBM Plex Mono',monospace;font-size:.6rem;letter-spacing:.05em;text-transform:uppercase;color:var(--faint);padding:.3rem .55rem;border-bottom:1px solid var(--line);white-space:nowrap}
.fin-tbl td{padding:.42rem .55rem;border-bottom:1px solid var(--line-2);color:var(--ink);white-space:nowrap}
.fin-tbl .num{text-align:right;font-variant-numeric:tabular-nums}
.fin-tbl td.owed{color:var(--lost);font-weight:600}

/* ---- QuickBooks customer linking card ---- */
.qbo-search-row{display:flex;gap:.4rem;margin-bottom:.5rem}
.qbo-search-row input{flex:1;min-width:0;border:1px solid var(--line);border-radius:8px;padding:.5rem .6rem;font:inherit;font-size:.9rem;background:var(--paper);color:var(--ink)}
.qbo-search-row input:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
.qbo-results{display:flex;flex-direction:column;gap:.4rem}
.qbo-res{display:flex;align-items:center;gap:.6rem;padding:.5rem .6rem;border:1px solid var(--line);border-radius:8px}
.qbo-res-b{flex:1;min-width:0;display:flex;flex-direction:column}
.qbo-res-n{font-weight:600;color:var(--ink);font-size:.9rem}
.qbo-res-s{font-size:.78rem;color:var(--muted)}
.qbo-pick{flex:none}
.qbo-or{text-align:center;color:var(--faint);font-size:.72rem;text-transform:uppercase;letter-spacing:.08em;margin:.7rem 0;position:relative}
.qbo-or span{background:var(--surface);padding:0 .5rem;position:relative;z-index:1}
.qbo-or::before{content:"";position:absolute;left:0;right:0;top:50%;height:1px;background:var(--line-2)}
.qbo-linked{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
.qbo-id{font-family:'IBM Plex Mono',monospace;font-size:.82rem;color:var(--ink)}
.qbo-muted{color:var(--muted);font-size:.85rem;padding:.3rem 0}
.qbo-err{color:#b4462f;font-size:.85rem;padding:.3rem 0}
.qbo-status{font-size:.85rem;color:var(--muted);margin-top:.4rem}

/* the soft arrival flash the smooth-scroll leaves on what it lands on */
@keyframes cpflash{0%{box-shadow:0 0 0 0 rgba(201,168,124,0)}18%{box-shadow:0 0 0 3px rgba(201,168,124,.55)}100%{box-shadow:0 0 0 0 rgba(201,168,124,0)}}
.cp-flash{animation:cpflash 1.5s ease-out;border-radius:12px}
@media (prefers-reduced-motion:reduce){.cp-flash{animation:none}}

/* ------------------------------------------------------------- people list
   One row per human. The chips are the roles they hold, which is the whole
   point of the model: a person can carry several without being duplicated. */
.ppl{display:flex;flex-direction:column}
.person{display:flex;align-items:center;gap:.7rem;padding:.6rem 0;border-bottom:1px solid var(--line-2)}
.person:last-child{border-bottom:0}
.person-main{flex:1;min-width:0}
.person-nm{font-weight:600;color:var(--ink);display:flex;align-items:baseline;gap:.4rem;flex-wrap:wrap}
.person-nm .person-title{font-weight:500;font-size:.8rem;color:var(--oak)}
.person-nick{font-weight:400;font-size:.8rem;color:var(--muted)}
.person-sub{font-size:.8rem;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.person-sub a{color:var(--chalk)}
.person-gap{font-style:italic;opacity:.75}
.person-roles{display:flex;gap:.3rem;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end}
.ppl-note{margin-top:.8rem;padding-top:.6rem;border-top:1px dashed var(--line-2);
  font-size:.72rem;color:var(--muted);line-height:1.5}
.ppl-note a{color:var(--chalk);font-weight:600}
@container cp (max-width:520px){
  .person{flex-wrap:wrap}
  .person-roles{width:100%;justify-content:flex-start;padding-left:2.6rem}
}
.pr-note.pr-live{color:var(--oak);font-weight:600}
.pr-flag{margin-top:.6rem;padding:.5rem .6rem;border-radius:6px;background:#fdf6e7;border:1px solid #e8d9b0;
  font-size:.76rem;color:#7a5c1e;line-height:1.5}
.pr-ask{margin-top:.5rem;padding:.5rem .6rem;border-radius:6px;background:var(--paper);border:1px dashed var(--chalk);
  font-size:.76rem;color:var(--ink);line-height:1.5}
.pr-ask b{color:var(--chalk)}
.pr-ask a,.pr-flag a{color:var(--chalk);font-weight:600}
.person-title{font-size:.78rem;color:var(--chalk);font-weight:600;margin-top:.05rem}
.person-does{font-size:.72rem;color:var(--muted);margin-top:.15rem;line-height:1.4}

/* ------------------------------------------------------------------- brain */
.brain-lead{font-size:.78rem;color:var(--muted);line-height:1.55;margin:0 0 .8rem}
/* What CutPile can do: the feature nodes, grouped by state */
.cap-sub{font-weight:400;color:var(--muted);font-size:.82rem}
.cap-group{margin-top:.9rem}
.cap-gh{display:flex;align-items:center;gap:.45rem;font-family:'IBM Plex Mono',monospace;font-size:.66rem;
  letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin-bottom:.5rem}
.cap-n{background:var(--paper);border:1px solid var(--line);border-radius:999px;padding:0 .4rem;font-size:.62rem}
.cap-dot{width:8px;height:8px;border-radius:50%;flex:none}
.cap-dot-live{background:#3f8f43}
.cap-dot-building{background:var(--oak)}
.cap-dot-planned{background:var(--muted)}
.cap-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:.6rem}
.cap-item{border:1px solid var(--line);border-radius:10px;padding:.6rem .7rem;background:var(--surface)}
.cap-top{display:flex;align-items:baseline;gap:.5rem;margin-bottom:.25rem}
.cap-name{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:.9rem;color:var(--ink);letter-spacing:-.01em}
.cap-ver{margin-left:auto;font-family:'IBM Plex Mono',monospace;font-size:.62rem;color:var(--faint)}
.cap-sum{font-size:.76rem;line-height:1.5;color:var(--muted)}
.cap-status{margin-top:.4rem;font-family:'IBM Plex Mono',monospace;font-size:.64rem;color:var(--oak);
  border-top:1px dashed var(--line);padding-top:.35rem}
.brain-brief{font-family:'IBM Plex Mono',monospace;font-size:.74rem;line-height:1.6;
  white-space:pre-wrap;word-break:break-word;color:var(--ink);margin:0;
  background:var(--paper);padding:.8rem;border-radius:8px;overflow-x:auto}
.gap{padding:.6rem 0;border-bottom:1px solid var(--line-2)}
.gap:last-of-type{border-bottom:0}
.gap-q{font-size:.88rem;color:var(--ink);line-height:1.45}
.gap.p1 .gap-q{font-weight:600}
.gap-m{display:flex;align-items:center;gap:.45rem;margin-top:.35rem;flex-wrap:wrap}
.gap-about{font-family:'IBM Plex Mono',monospace;font-size:.66rem;color:var(--chalk)}
.gap-by{font-size:.68rem;color:var(--muted)}
.gap-ans{margin-left:auto;padding:.15rem .5rem;border:1px solid var(--line);border-radius:5px;
  background:var(--surface);color:var(--muted);font-size:.7rem;font-weight:600;cursor:pointer}
.gap-ans:hover{border-color:var(--chalk);color:var(--ink)}
.gap-form{display:flex;gap:.35rem;margin-top:.45rem}
.gap-form input{flex:1;min-width:0;padding:.35rem .5rem;border:1px solid var(--line);border-radius:6px;
  font-size:.8rem;background:var(--card);color:var(--ink)}
.gap-form button{padding:.35rem .7rem;border:0;border-radius:6px;background:var(--walnut);color:#fff;
  font-size:.75rem;font-weight:600;cursor:pointer}
.blog{display:flex;flex-direction:column}
.blog-row{display:flex;align-items:baseline;gap:.45rem;padding:.35rem 0;border-bottom:1px solid var(--line-2);font-size:.76rem}
.blog-row:last-child{border-bottom:0}
.blog-s{flex:1;min-width:0;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.blog-t{font-size:.66rem;color:var(--muted);white-space:nowrap;font-family:'IBM Plex Mono',monospace}
.brain-gapnote{margin-top:.6rem;padding:.5rem .6rem;border-radius:6px;background:var(--paper);
  border:1px dashed var(--line);font-size:.74rem;color:var(--muted);line-height:1.5}
.brain-gapnote b{color:var(--ink)}
@container cp (max-width:640px){ .blog-row{flex-wrap:wrap} .blog-s{white-space:normal} }

/* ------------------------------------------------- the price ladder
   Five prices, cheapest first. The one we are actually charging is marked. */
.pl{display:flex;flex-direction:column;margin-bottom:.7rem}
.pl-row{display:grid;grid-template-columns:4.2rem 1fr;gap:.2rem .6rem;align-items:baseline;
  padding:.4rem 0;border-bottom:1px solid var(--line-2)}
.pl-row:last-child{border-bottom:0}
.pl-k{font-family:'IBM Plex Mono',monospace;font-size:.66rem;font-weight:600;letter-spacing:.04em;
  text-transform:uppercase;color:var(--muted)}
.pl-v{font-family:'IBM Plex Mono',monospace;font-size:.95rem;color:var(--ink);display:flex;align-items:center;gap:.3rem}
.pl-v.strong{font-size:1.15rem;font-weight:600}
.pl-n{grid-column:2;font-size:.68rem;color:var(--muted);line-height:1.4}
.pl-row.regular.is-live .pl-v,.pl-row.sale .pl-v{color:var(--oak)}
.pl-row.regular.is-live{background:linear-gradient(90deg,rgba(180,120,60,.06),transparent);
  margin:0 -.4rem;padding-left:.4rem;padding-right:.4rem;border-radius:5px}
.pl-row.map .pl-v,.pl-row.retail .pl-v{color:var(--muted)}
.pr-ecom{margin-top:.6rem;padding:.55rem .65rem;border-radius:6px;background:var(--paper);
  border:1px solid var(--line);font-size:.76rem;color:var(--ink);line-height:1.55}
.pr-ecom b{color:var(--chalk)}

/* ---------------------------------------------------------- price history
   Two points make a trend. One makes a number. Nothing shows until there is
   something real to show. A rising cost is bad news, so it is red. */
.ph{margin-top:.7rem;padding-top:.6rem;border-top:1px solid var(--line-2)}
.ph-h{font-family:'IBM Plex Mono',monospace;font-size:.64rem;font-weight:600;letter-spacing:.05em;
  text-transform:uppercase;color:var(--muted);margin-bottom:.4rem}
.ph-row{display:grid;grid-template-columns:3.2rem auto 1fr;gap:.2rem .5rem;align-items:center;padding:.25rem 0}
.ph-k{font-family:'IBM Plex Mono',monospace;font-size:.64rem;font-weight:600;text-transform:uppercase;color:var(--muted)}
.ph .spark{display:block}
.ph-v{font-family:'IBM Plex Mono',monospace;font-size:.76rem;color:var(--ink);white-space:nowrap}
.ph-v b{margin-left:.3rem;font-weight:600}
.ph-v b.up{color:var(--lost)}
.ph-v b.down{color:var(--ok)}
.ph-n{grid-column:3;font-size:.64rem;color:var(--muted)}
.ph-note{margin-top:.45rem;font-size:.66rem;color:var(--muted);line-height:1.45;font-style:italic}
@container cp (max-width:520px){ .ph-row{grid-template-columns:3.2rem 1fr} .ph .spark{grid-column:2} .ph-n{grid-column:1/-1} }

/* ------------------------------------------------- gallery labels
   The 360 spin has worked all along, behind an unlabeled icon, so nobody knew it
   was there. Media that is not named is media that is not used. */
.cl-thumb{position:relative}
.cl-lbl{position:absolute;left:0;right:0;bottom:0;padding:.12rem .2rem;
  background:linear-gradient(0deg,rgba(0,0,0,.82),rgba(0,0,0,0));
  color:#fff;font-family:'IBM Plex Mono',monospace;font-size:.52rem;font-weight:600;
  letter-spacing:.03em;text-transform:uppercase;text-align:center;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none}
.cl-thumb.is-vid{background:var(--walnut);display:flex;align-items:center;justify-content:center}
.cl-thumb.is-vid .cl-play{color:#fff;font-size:1.1rem;line-height:1}
.cl-thumb.on{outline:2px solid var(--oak);outline-offset:1px}

/* ------------------------------------------------- text for estimate
   Paste-ready. The words come from the server, the numbers from the calculator. */
.est{margin-top:.9rem;padding-top:.8rem;border-top:1px solid var(--line-2)}
.est label{display:block;font-family:'IBM Plex Mono',monospace;font-size:.64rem;font-weight:600;
  letter-spacing:.05em;text-transform:uppercase;color:var(--muted);margin-bottom:.35rem}
.est textarea{width:100%;padding:.55rem .65rem;border:1px solid var(--line);border-radius:8px;
  background:var(--paper);color:var(--ink);font-size:.82rem;line-height:1.5;resize:vertical;
  font-family:'Instrument Sans',sans-serif}
.est textarea:focus{outline:2px solid var(--chalk);outline-offset:-1px}
.est button{margin-top:.45rem;padding:.4rem .9rem;border:0;border-radius:6px;
  background:var(--walnut);color:#fff;font-weight:600;font-size:.8rem;cursor:pointer}
.est button:disabled{background:var(--line);color:var(--muted);cursor:default}
.est button.ok{background:var(--ok)}


/* -------------------------------------------------------------- breadcrumbs
   There were none: every page invented its own "Back to customers" link, so the
   only way to know where you were was to remember. A trail says where you are AND
   how you got there, and it gives the split pane something to be a link to.

   The hairline under it is a snapped chalk line. A breadcrumb marks your position;
   a chalk line marks where the floor starts. Same job, and it is the one place the
   accent's name becomes a thing you can see. */
.crumbs{display:flex;align-items:center;flex-wrap:wrap;gap:.3rem;
  font-family:'IBM Plex Mono',monospace;font-size:.68rem;letter-spacing:.02em;
  padding:0 0 .5rem;margin-bottom:1rem;
  border-bottom:1px solid var(--chalk-soft);position:relative}
.crumbs::after{content:'';position:absolute;left:0;bottom:-1px;width:2.5rem;height:1px;background:var(--chalk)}
.crumbs a{color:var(--muted);text-decoration:none;white-space:nowrap}
.crumbs a:hover{color:var(--chalk)}
.crumbs .sep{color:var(--faint);user-select:none}
.crumbs .here{color:var(--ink);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:32ch}
.crumbs .crumb-split{margin-left:auto;display:flex;align-items:center;gap:.3rem;
  color:var(--muted);background:none;border:1px solid var(--line);border-radius:5px;
  padding:.12rem .4rem;cursor:pointer;font-family:inherit;font-size:.62rem;font-weight:600}
.crumbs .crumb-split:hover{border-color:var(--chalk);color:var(--chalk)}
.crumbs .crumb-split .ic{width:11px;height:11px}
@container cp (max-width:520px){ .crumbs .here{max-width:18ch} .crumbs .crumb-split{display:none} }

/* ------------------------------------------------- products on a job
   The chip is the point: a sample that is out is a liability with a date on it,
   a favorite is their signal, a suggestion is ours. Same card, different meaning. */
.jp-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:.8rem;margin-bottom:1rem}
.jp{position:relative;display:flex;gap:.6rem;padding:.55rem;border:1px solid var(--line);
  border-radius:10px;background:var(--card)}
.jp-late{border-color:var(--lost);background:var(--lost-soft)}
.jp-img{flex:none;width:62px;height:62px;border-radius:7px;overflow:hidden;background:var(--line);display:block}
.jp-img img{width:100%;height:100%;object-fit:cover}
.jp-b{min-width:0;flex:1}
.jp-n{font-weight:600;font-size:.84rem;margin:.2rem 0 .05rem;line-height:1.25}
.jp-c{font-size:.76rem;color:var(--oak);font-weight:500}
.jp-m{font-size:.68rem;color:var(--muted);margin-top:.1rem;line-height:1.4}
.jp-due{font-size:.68rem;color:var(--warn);font-weight:600;margin-top:.15rem}
.jp-due.late{color:var(--lost)}
.jp-x{position:absolute;top:.25rem;right:.3rem}
.jp-x button{border:0;background:none;color:var(--faint);font-size:1rem;line-height:1;cursor:pointer;padding:.1rem .2rem}
.jp-x button:hover{color:var(--lost)}
.jp-add{padding:.7rem;border:1px dashed var(--line);border-radius:10px;background:var(--paper)}
.jp-add-row{display:flex;gap:.4rem;margin-bottom:.4rem;flex-wrap:wrap}
.jp-add-row:last-child{margin-bottom:0}
.jp-add input,.jp-add select{flex:1;min-width:7rem;padding:.4rem .5rem;border:1px solid var(--line);
  border-radius:6px;font-size:.82rem;background:var(--card);color:var(--ink);font-family:inherit}
.jp-add button{padding:.4rem 1rem;border:0;border-radius:6px;background:var(--walnut);color:#fff;
  font-weight:600;font-size:.82rem;cursor:pointer;flex:none}
.jp-add button:hover{background:var(--oak)}
@container cp (max-width:640px){ .jp-grid{grid-template-columns:1fr} .jp-add-row{flex-direction:column} }

/* ------------------------------------------------- the call menu
   One click opens, a second click dials. You cannot un-ring a phone, and this was
   the only irreversible thing in the app that never asked. */
.callwrap{position:relative;display:inline-block}
.callbtn{cursor:pointer;font:inherit}
.callbtn .caret{margin-left:.3rem;font-size:.6rem;opacity:.7}
.callmenu{position:absolute;top:calc(100% + .35rem);left:0;z-index:400;min-width:16rem;
  background:var(--card);border:1px solid var(--line);border-radius:10px;
  box-shadow:0 14px 40px rgba(36,28,21,.18);overflow:hidden;padding:.25rem}
.callmenu[hidden]{display:none}
.callopt{display:block;width:100%;text-align:left;padding:.5rem .6rem;border:0;border-radius:7px;
  background:none;cursor:pointer;font-family:inherit;text-decoration:none;color:var(--ink)}
.callopt:hover{background:var(--paper)}
.callopt.primary .callopt-t{color:var(--chalk)}
.callopt.off{cursor:default;opacity:.6}
.callopt.off:hover{background:none}
.callopt-t{display:block;font-weight:600;font-size:.86rem}
.callopt-s{display:block;font-size:.7rem;color:var(--muted);line-height:1.4;margin-top:.1rem}
@container cp (max-width:520px){ .callmenu,.menupop{left:auto;right:0} }

/* lookup panels + copy. The icon copies, the text opens a panel: one rule, and the
   affordance has to read at a glance or nobody discovers either half. */
.menuwrap{position:relative;display:inline-block;max-width:100%}
.menupop{position:absolute;top:calc(100% + .35rem);left:0;z-index:60;min-width:17rem;max-width:min(22rem,92vw);
  background:var(--surface);border:1px solid var(--line);border-radius:10px;
  box-shadow:0 18px 44px rgba(0,0,0,.16);padding:.3rem}
.menupop[hidden]{display:none}
.menusep{font-family:'IBM Plex Mono',monospace;font-size:.58rem;letter-spacing:.11em;text-transform:uppercase;
  color:var(--faint);padding:.5rem .6rem .25rem;border-top:1px solid var(--line);margin-top:.25rem}
/* The reset is for TEXT triggers (a name, an address). A trigger that is already a
   button keeps its skin: this rule used to strip .pa's background, border and padding
   back off, so Call and Email rendered as bare text beside three real buttons. */
.menubtn{font:inherit;cursor:pointer;text-align:left;max-width:100%}
.menubtn:not(.pa){background:none;border:0;color:inherit;padding:0}
/* the text triggers: underline on hover only, so the profile does not look like a
   1996 link farm at rest but every one of them still announces itself */
.linkish{border-bottom:1px dashed transparent;transition:border-color .12s,color .12s}
.menubtn:hover .linkish,.linkish:hover{border-bottom-color:var(--oak);color:var(--ink)}
/* On the dark profile cover the same links must BRIGHTEN, not go to near-black ink,
   or they vanish against the walnut. */
.prof-cover .menubtn:hover .linkish,.prof-cover .linkish:hover{color:#fff;border-bottom-color:var(--oak)}
.idname{font:inherit;color:inherit}
.idname:hover{color:var(--oak)}
.unver{display:inline-block;margin-left:.3rem;font-size:.6rem;font-weight:700;color:var(--faint);
  border:1px solid var(--line);border-radius:50%;width:1rem;height:1rem;line-height:.9rem;text-align:center}
/* the copy buttons */
.cpy{background:none;border:0;padding:.15rem;margin:0;cursor:pointer;color:var(--muted);
  border-radius:5px;display:inline-flex;align-items:center;position:relative;flex:0 0 auto}
.cpy:hover{color:var(--ink);background:var(--paper)}
.cpy .cpy-ok{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:var(--surface);color:var(--oak);border-radius:5px;opacity:0;transform:scale(.6);
  transition:opacity .12s,transform .12s;pointer-events:none}
.cpy.copied .cpy-ok{opacity:1;transform:scale(1)}
.cpy.copied{color:var(--oak)}
.cpy.copyfail{color:#b4442e}
.cpy.copyfail .cpy-ok{opacity:0}
/* Copy confirmation toast: shown when a menu item is copied and the menu is dismissed,
   so the in-place flash would never be seen. Walnut ground, oak tick of the palette. */
.cp-toast{position:fixed;left:50%;bottom:1.8rem;transform:translateX(-50%) translateY(.5rem);
  background:var(--walnut);color:var(--paper);padding:.55rem .95rem;border-radius:.6rem;
  font-size:.85rem;font-weight:600;letter-spacing:.01em;box-shadow:0 10px 30px rgba(43,33,26,.28);
  opacity:0;pointer-events:none;z-index:9999;transition:opacity .18s ease,transform .18s ease;
  display:flex;align-items:center;gap:.45rem}
.cp-toast::before{content:"";width:.7rem;height:.7rem;border-radius:50%;background:var(--oak)}
.cp-toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
@media (prefers-reduced-motion:reduce){.cp-toast{transition:opacity .18s ease}}
/* Overlay modal (send-a-text, and reusable): a dimmed backdrop plus a centered card, so a temporary
   surface reads as temporary. Dismissed by Send, Cancel, the backdrop, or Escape. */
.cp-modal{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:1.2rem}
.cp-modal[hidden]{display:none}
.cp-modal-back{position:absolute;inset:0;background:rgba(36,28,21,.5);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
.cp-modal-card{position:relative;z-index:1;width:min(30rem,100%);background:var(--surface);
  border:1px solid var(--line);border-radius:.8rem;box-shadow:0 24px 60px rgba(36,28,21,.32);
  padding:1.1rem 1.15rem 1rem;animation:cpModalIn .16s ease}
@keyframes cpModalIn{from{opacity:0;transform:translateY(.5rem) scale(.98)}to{opacity:1;transform:none}}
.cp-modal-h{display:flex;align-items:center;justify-content:space-between;gap:.6rem}
.cp-modal-t{display:flex;align-items:center;gap:.45rem;font-weight:700;color:var(--ink);font-size:1rem}
.cp-modal-t svg{width:18px;height:18px;color:var(--chalk)}
.cp-modal-x{border:0;background:transparent;font-size:1.5rem;line-height:1;color:var(--muted);cursor:pointer;padding:0 .2rem}
.cp-modal-x:hover{color:var(--ink)}
.cp-modal-sub{color:var(--muted);font-size:.83rem;margin:.35rem 0 .7rem}
.cp-modal-card textarea{width:100%;border:1px solid var(--line);border-radius:.5rem;padding:.6rem .7rem;
  font:inherit;color:var(--ink);background:var(--paper);resize:vertical;min-height:4.5rem}
.cp-modal-card textarea:focus{outline:none;border-color:var(--chalk-2)}
.cp-modal-row{display:flex;align-items:center;gap:.6rem;margin-top:.8rem}
.cp-modal-row .sms-status{margin-right:auto}
@media (prefers-reduced-motion:reduce){.cp-modal-card{animation:none}}
.btn.sm{padding:.32rem .6rem;font-size:.78rem}
.nav-i{position:relative}
.nav-badge{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);background:var(--chalk);color:#fff;font-size:.64rem;font-weight:700;border-radius:999px;min-width:1.1rem;height:1.1rem;display:flex;align-items:center;justify-content:center;padding:0 .3rem;line-height:1}
.ibx-startjob{margin-top:.5rem}
/* ---------------------------------------------------------------- Unified Inbox */
.ibx-wrap{padding:clamp(1rem,2.5vw,1.8rem);display:flex;flex-direction:column;min-height:0}
.ibx-head{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin-bottom:1rem}
.ibx-title{display:flex;align-items:center;gap:.5rem;font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.5rem;color:var(--ink);margin:0}
.ibx-title svg{width:22px;height:22px;color:var(--chalk)}
.ibx-chips{display:flex;gap:.4rem;flex-wrap:wrap}
.ibx-chip{display:inline-flex;align-items:center;gap:.35rem;padding:.35rem .7rem;border-radius:999px;border:1px solid var(--line);color:var(--muted);font-size:.82rem;font-weight:600;background:var(--surface)}
.ibx-chip:hover{border-color:var(--oak);color:var(--ink)}
.ibx-chip.on{background:var(--chalk);border-color:var(--chalk);color:#fff}
.ibx-chip-n{background:rgba(0,0,0,.12);border-radius:999px;padding:0 .4rem;font-size:.72rem;line-height:1.4}
.ibx-chip.on .ibx-chip-n{background:rgba(255,255,255,.25)}
.ibx-flash{background:var(--chalk-soft);color:var(--chalk);border:1px solid rgba(143,76,35,.25);border-radius:.5rem;padding:.5rem .8rem;font-size:.85rem;font-weight:600;margin-bottom:.8rem}
.ibx-flash.err{background:#fbe9e5;color:#b4442e;border-color:rgba(180,68,46,.3)}
.ibx-panes{display:grid;grid-template-columns:minmax(300px,360px) 1fr;gap:1rem;align-items:stretch;min-height:0;height:calc(100vh - 12rem)}
.ibx-list{border:1px solid var(--line);border-radius:.7rem;background:var(--surface);overflow-y:auto;display:flex;flex-direction:column}
.ibx-empty-list{padding:1.2rem;color:var(--muted);font-size:.88rem}
.ibx-row{display:flex;align-items:flex-start;gap:.65rem;padding:.7rem .8rem;border-bottom:1px solid var(--line-2);position:relative}
.ibx-row:hover{background:var(--paper)}
.ibx-row.sel{background:var(--chalk-soft)}
.ibx-av .av{flex:none}
.ibx-row-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:.15rem}
.ibx-row-top{display:flex;align-items:baseline;justify-content:space-between;gap:.5rem}
.ibx-row-name{font-weight:600;color:var(--ink);font-size:.9rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ibx-row.unread .ibx-row-name{font-weight:800}
.ibx-row-time{color:var(--faint);font-size:.72rem;white-space:nowrap;flex:none}
.ibx-row-prev{color:var(--muted);font-size:.82rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ibx-row.unread .ibx-row-prev{color:var(--ink)}
.ibx-you{color:var(--faint)}
.ibx-row-tags{display:flex;align-items:center;gap:.35rem;margin-top:.1rem}
.ibx-tag{font-size:.66rem;font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--muted);background:var(--line-2);border-radius:.3rem;padding:.05rem .35rem}
.ibx-tag.warn{color:var(--chalk);background:var(--chalk-soft)}
.ibx-ch{margin-left:auto;color:var(--faint);display:inline-flex}
.ibx-ch svg{width:14px;height:14px}
.ibx-dot{position:absolute;top:.85rem;right:.7rem;width:8px;height:8px;border-radius:50%;background:var(--chalk)}
.ibx-thread{border:1px solid var(--line);border-radius:.7rem;background:var(--surface);display:flex;flex-direction:column;min-height:0}
.ibx-empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;color:var(--faint);gap:.5rem;padding:2rem}
.ibx-empty svg{width:34px;height:34px;opacity:.5}
.ibx-thread-h{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;padding:.9rem 1rem;border-bottom:1px solid var(--line)}
.ibx-thread-name{font-weight:700;color:var(--ink);font-size:1.05rem}
.ibx-thread-sub{font-size:.82rem;color:var(--muted);margin-top:.15rem;display:flex;align-items:center;gap:.4rem}
.ibx-thread-sub a{color:var(--chalk);font-weight:600}
.ibx-thread-actions{display:flex;gap:.4rem;flex:none}
.ibx-thread-actions form{margin:0}
.ibx-attach{padding:.8rem 1rem;border-bottom:1px solid var(--line);background:var(--paper)}
.ibx-attach-h{font-size:.83rem;color:var(--muted);margin-bottom:.5rem}
.ibx-attach-search{display:flex;gap:.4rem;margin-bottom:.5rem}
.ibx-attach-search input{flex:1;border:1px solid var(--line);border-radius:.45rem;padding:.4rem .6rem;font:inherit;font-size:.85rem;background:var(--surface);color:var(--ink)}
.ibx-attach-none{font-size:.82rem;color:var(--faint)}
.ibx-attach-hit{margin:.25rem 0}
.ibx-attach-btn{display:flex;flex-direction:column;align-items:flex-start;width:100%;text-align:left;border:1px solid var(--line);border-radius:.45rem;background:var(--surface);padding:.45rem .6rem;cursor:pointer}
.ibx-attach-btn:hover{border-color:var(--oak);background:var(--chalk-soft)}
.ibx-attach-name{font-weight:600;color:var(--ink);font-size:.87rem}
.ibx-attach-meta{color:var(--muted);font-size:.76rem}
.ibx-msgs{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:.6rem}
.ibx-msg{display:flex;flex-direction:column;max-width:78%}
.ibx-msg.in{align-self:flex-start;align-items:flex-start}
.ibx-msg.out{align-self:flex-end;align-items:flex-end}
.ibx-bubble{padding:.55rem .8rem;border-radius:.9rem;font-size:.9rem;line-height:1.45;white-space:pre-wrap;word-break:break-word}
.ibx-msg.in .ibx-bubble{background:var(--line-2);color:var(--ink);border-bottom-left-radius:.25rem}
.ibx-msg.out .ibx-bubble{background:var(--chalk);color:#fff;border-bottom-right-radius:.25rem}
.ibx-msg-meta{font-size:.7rem;color:var(--faint);margin-top:.2rem}
.ibx-media{margin-top:.35rem}
.ibx-msg.out .ibx-media{align-self:flex-end}
.ibx-media .att-gallery{margin:0}
.ibx-reply{display:flex;gap:.6rem;width:100%;box-sizing:border-box;padding:.85rem 1rem;border-top:1px solid var(--line);align-items:flex-end}
/* The @mention autocomplete wraps the textarea in .mention-wrap, so that wrapper must be the flex child. */
.ibx-reply .mention-wrap{flex:1 1 auto;min-width:0;display:block}
.ibx-reply textarea{width:100%;box-sizing:border-box;flex:1 1 auto;min-width:0;border:1px solid var(--line);border-radius:.6rem;padding:.55rem .8rem;font:inherit;font-size:.9rem;line-height:1.45;color:var(--ink);background:var(--paper);resize:vertical;min-height:2.6rem;max-height:12rem}
.ibx-reply textarea:focus{outline:none;border-color:var(--chalk-2)}
.ibx-reply .btn{flex:none;white-space:nowrap}
@media (max-width:820px){
  .ibx-panes{grid-template-columns:1fr;height:auto}
  .ibx-list{max-height:40vh}
  .ibx-thread{min-height:60vh}
}
/* ------------------------------------------------------ New Estimate intake */
.pn-newest{display:flex;align-items:center;justify-content:center;gap:.4rem;width:100%;margin:0 0 .7rem;padding:.6rem .8rem;border:0;border-radius:.55rem;background:var(--chalk);color:#fff;font:inherit;font-weight:700;font-size:.9rem;cursor:pointer}
.pn-newest:hover{background:var(--chalk-2)}
.pn-newest-i{font-size:1.15rem;line-height:1;font-weight:700}
.nest-card{width:min(38rem,100%);max-height:88vh;overflow-y:auto}
.nest-form{display:flex;flex-direction:column;gap:.7rem;margin-top:.3rem}
.nest-sec{font-weight:700;font-size:.72rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted)}
.nest-services{display:grid;grid-template-columns:1fr 1fr;gap:.25rem .8rem}
.nest-chk{display:flex;align-items:center;gap:.45rem;font-size:.85rem;color:var(--ink);cursor:pointer;padding:.15rem 0}
.nest-chk input{width:16px;height:16px;accent-color:var(--chalk);flex:none}
.nest-grid2{display:grid;grid-template-columns:1fr 1fr;gap:.7rem}
.nest-grid3{display:grid;grid-template-columns:1fr .55fr .7fr;gap:.7rem}
.nest-f{display:flex;flex-direction:column;gap:.25rem;font-size:.76rem;font-weight:600;color:var(--muted)}
.nest-f input,.nest-f textarea{border:1px solid var(--line);border-radius:.45rem;padding:.45rem .6rem;font:inherit;font-size:.9rem;font-weight:400;color:var(--ink);background:var(--paper);width:100%}
.nest-f textarea{resize:vertical}
.nest-f input:focus,.nest-f textarea:focus{outline:none;border-color:var(--chalk-2)}
.nest-toggles{display:flex;gap:1.4rem;flex-wrap:wrap;padding:.2rem 0}
.nest-tog{display:flex;align-items:center;gap:.45rem;font-size:.85rem;color:var(--ink);cursor:pointer}
.nest-tog input{width:16px;height:16px;accent-color:var(--chalk)}
.nest-foot{display:flex;align-items:center;gap:.6rem;margin-top:.3rem;padding-top:.7rem;border-top:1px solid var(--line)}
.nest-status{margin-right:auto;font-size:.82rem;color:var(--muted)}
.nest-status.err{color:#b4442e}
.nest-done{padding:.5rem 0}
.nest-done-h{font-weight:700;color:var(--ink);font-size:1.1rem;margin-bottom:.6rem}
.nest-done-notes{list-style:none;padding:0;margin:0 0 1rem;display:flex;flex-direction:column;gap:.3rem}
.nest-done-notes li{font-size:.85rem;color:var(--muted);padding-left:1.15rem;position:relative}
.nest-done-notes li::before{content:"\2713";position:absolute;left:0;color:var(--oak);font-weight:700}
.nest-done-actions{display:flex;gap:.6rem}
@media (max-width:560px){.nest-services,.nest-grid2,.nest-grid3{grid-template-columns:1fr}}
/* ------------------------------------------------------------------- Referrals */
.refer-card{width:min(40rem,100%)}
.email-card{width:min(40rem,100%)}
.email-card .mail-subject{margin-bottom:.5rem}
.email-card .mail-alt{margin:.55rem 0 0}
/* The AI email composer: a magic button that writes a strategic email for this customer + stage. */
.mail-ai-row{display:flex;align-items:center;gap:.7rem;flex-wrap:wrap;margin:.1rem 0 .6rem}
.btn.ai-compose{display:inline-flex;align-items:center;gap:.4rem;background:linear-gradient(135deg,var(--walnut),#4a3a2c);color:var(--oak-bright,#e3ceac);border:1px solid var(--walnut);border-radius:8px;padding:.45rem .75rem;font-weight:600;cursor:pointer}
.btn.ai-compose:hover{filter:brightness(1.08)}
.btn.ai-compose .ic{width:15px;height:15px}
.btn.ai-compose[disabled]{opacity:.6;cursor:default}
.mail-ai-note{font-size:.75rem;color:var(--muted);flex:1;min-width:10rem}
.mail-ai-note.working{color:var(--oak)}
.mail-ai-note.done{color:var(--ink)}
.mail-ai-note.err{color:#c0492f}
.sms-atts{display:flex;gap:.4rem;flex-wrap:wrap;padding:.3rem 0 0}
.sms-att{position:relative;display:inline-flex}
.sms-att img{width:52px;height:52px;border-radius:6px;object-fit:cover;border:1px solid var(--line)}
.sms-att button{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;border:0;background:var(--ink);color:#fff;font-size:12px;line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center}
#sms-attach{display:inline-flex;align-items:center;gap:.3rem}
#sms-attach svg{width:15px;height:15px}
.refer-card select,.nest-f select{border:1px solid var(--line);border-radius:.45rem;padding:.45rem .6rem;font:inherit;font-size:.9rem;color:var(--ink);background:var(--paper);width:100%}
.refer-preview{background:var(--paper);border:1px solid var(--line);border-radius:.5rem;padding:.7rem .8rem;font-family:'IBM Plex Mono',monospace;font-size:.78rem;line-height:1.5;white-space:pre-wrap;word-break:break-word;max-height:30vh;overflow:auto;margin:.2rem 0 0;color:var(--ink)}
.rfa-cols{display:grid;grid-template-columns:22rem 1fr;gap:1.2rem;align-items:start}
.rfa-form{display:flex;flex-direction:column;gap:.7rem}
.rfa-phone-form{display:flex;gap:.5rem;align-items:flex-end}
.rfa-phone-form .nest-f input{min-width:12rem}
.rfa-cat{font-weight:700;text-transform:uppercase;letter-spacing:.05em;font-size:.72rem;color:var(--muted);margin:1rem 0 .4rem}
.rfa-cat:first-child{margin-top:0}
.rfa-card{display:flex;justify-content:space-between;gap:1rem;background:var(--surface);border:1px solid var(--line);border-radius:.6rem;padding:.7rem .85rem;margin-bottom:.5rem}
.rfa-card.off{opacity:.62}
.rfa-card-co{font-weight:700;color:var(--ink)}
.rfa-card-meta{font-size:.82rem;color:var(--muted);margin-top:.15rem}
.rfa-card-notes{font-size:.8rem;color:var(--faint);margin-top:.3rem}
.rfa-card-actions{display:flex;gap:.35rem;align-items:flex-start;flex:none;flex-wrap:wrap;justify-content:flex-end}
.rfa-card-actions form{margin:0}
.rfa-card-main{flex:1 1 auto;min-width:0}
.rfa-card-logo{flex:none;width:56px;height:56px;border:1px solid var(--line);border-radius:.5rem;background:var(--paper);overflow:hidden;display:flex;align-items:center;justify-content:center}
.rfa-card-logo img{max-width:100%;max-height:100%;object-fit:contain}
.rfa-logo-cur{display:flex;align-items:center;gap:.6rem;margin:.35rem 0}
.rfa-logo-cur img{max-width:120px;max-height:64px;width:auto;height:auto;border:1px solid var(--line);border-radius:.4rem;background:var(--paper);padding:2px}
.rfa-logo-rm{display:flex;align-items:center;gap:.3rem;font-size:.8rem;color:var(--muted)}
.rfa-form .nest-hint{display:block;font-size:.76rem;color:var(--faint);margin-top:.25rem}
@media (max-width:820px){.rfa-cols{grid-template-columns:1fr}}
.cal-loc{display:flex;align-items:center;gap:.4rem;font-size:.85rem;color:var(--muted);background:var(--paper);border:1px solid var(--line);border-radius:.45rem;padding:.45rem .6rem}
.cal-loc svg{width:15px;height:15px;color:var(--chalk);flex:none}
/* Intake address: single Places autocomplete field, with a parsed confirmation and the Google dropdown
   above the modal. */
.nest-parsed{font-size:.78rem;color:var(--muted);background:var(--chalk-soft);border-radius:.4rem;padding:.35rem .55rem}
.pac-container{z-index:10000 !important;border-radius:.5rem;border:1px solid var(--line);box-shadow:0 10px 30px rgba(43,33,26,.22);font-family:inherit}
/* speed dial lives in the header, so it must read as a control at 28px and never
   shove the search box around */
.sd{flex:0 0 auto}
.sdbtn{display:inline-flex;align-items:center;gap:.15rem;padding:.45rem .5rem;border-radius:8px;
  border:1px solid var(--line);background:var(--surface);color:var(--muted)}
.sdbtn:hover{color:var(--ink);border-color:var(--oak)}
.sd .menupop{left:auto;right:0;min-width:19rem}
.pa.on{border-color:var(--oak);color:var(--oak)}

/* the split shell: two iframes, neither able to reload the other */
.split-shell .split-wrap.on{display:grid;grid-template-columns:1fr 1fr;gap:0;height:calc(100vh - 3.9rem)}
.split-shell .sp-left{border:0;width:100%;height:100%;background:var(--paper)}
.split-shell .splitpane{min-width:0}
/* Expanded: the right pane takes the whole shell. The left iframe is only hidden,
   never unloaded, so shrinking back is instant and it has not lost its place. */
.split-shell .split-wrap.on.sp-expanded{grid-template-columns:1fr}
.split-wrap.sp-expanded > .sp-left{display:none}
/* one button, two icons, whichever matches what the click will do */
#sp-full .sp-i-shrink{display:none}
.split-wrap.sp-expanded #sp-full .sp-i-expand{display:none}
.split-wrap.sp-expanded #sp-full .sp-i-shrink{display:flex}
#sp-full{padding:0}
#sp-full > span{display:flex;align-items:center;justify-content:center;width:100%;height:100%}
@media (max-width:900px){
  .split-shell .split-wrap.on{grid-template-columns:1fr;height:auto}
  .split-shell .sp-left{height:70vh}
}


/* ---- the job site: the house, and the sky over it ------------------------- */
/* Same width, stacked, on the right of the brown header, exactly as asked. The width
   is the photo's: 240 wide at Street View's 480x300 is a clean 2x for retina. */
/* 320, not 240. A street view at 240 is a postage stamp of trees, and seven days of
   forecast will not fit in it. This is the half of the card that answers "what am I
   walking into", so it gets the room. */
.prof-site{flex:0 0 auto;width:320px;display:flex;flex-direction:column;gap:.5rem}
.site-photo{position:relative;display:block;width:100%;aspect-ratio:16/10;border-radius:10px;overflow:hidden;
  background:rgba(0,0,0,.25);border:1px solid rgba(201,168,124,.25);cursor:pointer}
.site-photo img{width:100%;height:100%;object-fit:cover;display:block}
.site-photo.none{cursor:default;display:flex;align-items:center;justify-content:center;text-align:center;
  padding:.7rem;font-size:.72rem;line-height:1.45;color:#c3b49f}
.site-photo.none a{color:var(--oak);text-decoration:underline}
/* the hover tools: thin, outlined, glassy. They rise in when the photo is hovered
   or keyboard-focused, and stay put on touch where there is no hover to reveal them. */
.sv-tools{position:absolute;top:.45rem;right:.45rem;display:flex;gap:.3rem;
  opacity:0;transform:translateY(-3px);transition:opacity .16s ease,transform .16s ease;pointer-events:none}
.site-photo:hover .sv-tools,.site-photo:focus-within .sv-tools{opacity:1;transform:none;pointer-events:auto}
.sv-tool{width:29px;height:29px;display:inline-flex;align-items:center;justify-content:center;
  border-radius:8px;border:1px solid rgba(255,255,255,.5);background:rgba(20,15,10,.5);color:#fff;
  cursor:pointer;padding:0;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);
  transition:background .14s ease,border-color .14s ease}
.sv-tool:hover{background:rgba(20,15,10,.82);border-color:#fff}
.sv-tool svg{width:16px;height:16px}
@media (hover:none){.sv-tools{opacity:1;transform:none;pointer-events:auto}}

/* the immersive panorama: it grows to cover the whole brown header, sitting above
   every button and panel inside it. A full-screen control lifts it to a true window. */
.sv-immersive{position:absolute;inset:0;z-index:55;border-radius:14px;overflow:hidden;background:#12100e;
  opacity:0;transform:scale(.985);transition:opacity .24s ease,transform .24s ease}
.sv-immersive.open{opacity:1;transform:none}
.sv-immersive .sv-frame{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
.sv-immersive:fullscreen,.sv-immersive:fullscreen .sv-frame{border-radius:0}
.sv-ctrls{position:absolute;top:.6rem;right:.6rem;display:flex;gap:.4rem;z-index:2}
/* No backdrop-filter. The blur is painted to the element's square bounding box and is not clipped by
   border-radius, so a gray square showed behind each rounded button. A more opaque background gives
   the same legibility over photography with none of the artefact, and background-clip keeps the fill
   inside the border rather than under the translucent edge. */
.sv-ctrl{width:34px;height:34px;display:inline-flex;align-items:center;justify-content:center;
  border-radius:9px;border:1px solid rgba(255,255,255,.55);background:rgba(20,15,10,.78);color:#fff;
  background-clip:padding-box;cursor:pointer;padding:0;
  box-shadow:0 1px 6px rgba(0,0,0,.28);
  transition:background .14s ease,border-color .14s ease}
.sv-ctrl:hover{background:rgba(20,15,10,.92);border-color:#fff}
.sv-ctrl svg{width:18px;height:18px}
@media (prefers-reduced-motion:reduce){
  .sv-tools,.sv-immersive{transition:none}
  .sv-immersive{transform:none}
}
.site-wx{background:rgba(0,0,0,.25);border:1px solid rgba(201,168,124,.25);border-radius:10px;
  padding:.55rem .6rem;color:#e8ddcf}
.site-wx.none{font-size:.72rem;color:#c3b49f;text-align:center}
.wx-now{display:flex;align-items:center;gap:.5rem}
.wx-ic{width:22px;height:22px;flex:0 0 auto;color:var(--oak)}
.wx-temp{font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.35rem;line-height:1;color:#fff}
.wx-meta{display:flex;flex-direction:column;min-width:0;line-height:1.25}
.wx-words{font-size:.72rem;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wx-rh{font-size:.64rem;color:#b3a794;cursor:help}
/* damp enough to matter for wood, or dry enough to matter. Neutral in between: a
   number that is always colored is a number nobody reads. */
.wx-rh.high{color:#7fb3e8}
.wx-rh.low{color:#e0a86a}
.wx-days{display:grid;grid-template-columns:repeat(7,1fr);gap:.1rem;margin-top:.5rem;
  padding-top:.5rem;border-top:1px solid rgba(201,168,124,.18)}
.wx-day{display:flex;flex-direction:column;align-items:center;gap:.12rem;min-width:0}
.wx-day .wx-ic{width:16px;height:16px}
.wx-dow{font-family:'IBM Plex Mono',monospace;font-size:.55rem;letter-spacing:.04em;text-transform:uppercase;color:#b3a794}
.wx-hl{font-size:.66rem;font-weight:700;color:#fff;white-space:nowrap;letter-spacing:-.02em}
.wx-lo{font-weight:500;color:#a89a86}
/* a rain chance only earns color when it would change the plan */
.wx-pop{font-size:.55rem;color:#8fa9c9;min-height:.7rem}
.wx-pop.on{color:#7fb3e8;font-weight:700}
@media (max-width:900px){
  /* Stacked, full width, still. The photo and the weather side by side squeezed
     seven days into half a phone, and a forecast you have to squint at is decoration.
     Vertical space on a phone is the cheapest thing there is. */
  .prof-site{width:100%}
  .prof-site .site-photo{aspect-ratio:16/7}
}


/* ---- the feed: a generated headline, and what it was about ---------------- */
.tl-title{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:.95rem;
  letter-spacing:-.01em;color:var(--ink);margin:.15rem 0 .3rem}
/* the topic is the second axis: a call and an email about the same deposit share it */
.tl-topic{font-family:'IBM Plex Mono',monospace;font-size:.58rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);background:var(--paper);
  border:1px solid var(--line);border-radius:4px;padding:.1rem .35rem}


/* ---- the state cluster: where the job is, and whether it is hot ----------- */
/* Two facts of the same kind, so they sit together. The fire used to float between
   the name and the site column belonging to neither, which is what made it read as
   orphaned. */
.prof-state{display:flex;align-items:center;gap:.5rem;margin-top:.45rem}
.st-wrap{position:relative;display:inline-flex}
/* NOT font:inherit. This button lives inside an h2, so inheriting means inheriting
   1.7rem of Bricolage Grotesque, which blew the chip up to the size of the name it
   was sitting next to. Same trap as .menubtn stripping .pa: a reset that reaches
   further than the thing it was written for. .chip already knows how it should look;
   this only adds the parts that make it a button. */
.stbtn{display:inline-flex;align-items:center;gap:.1rem;cursor:pointer;border:0}
.stbtn .pa-caret{border-left-color:currentColor;opacity:.45;padding-left:.4rem;margin-left:.25rem}
.stbtn:hover{filter:brightness(1.12)}
.st-wrap .menupop{min-width:19rem}
/* where you are: named, not offered. A menu item that does nothing gets clicked twice */
.st-now .callopt-t{display:flex;align-items:center;justify-content:space-between;gap:.5rem}
.st-here{font-family:'IBM Plex Mono',monospace;font-size:.55rem;letter-spacing:.08em;
  text-transform:uppercase;color:var(--oak);font-weight:400}


/* ---- the job chat: people, and one non-person ----------------------------- */
/* CutPile's replies have to be unmistakable at a glance. Same bubble shape as
   everyone else's - it is a participant, not a system banner - but it carries the
   oak the rest of the app uses for "this came from the machine". */
.jc-msg.ai{border-left:2px solid var(--oak);padding-left:.6rem;background:linear-gradient(90deg,rgba(201,168,124,.07),transparent 60%)}
.jc-msg.ai .jc-who{color:var(--oak);font-weight:700}
.jc-msg.ai .jc-who::after{content:'AI';font-family:'IBM Plex Mono',monospace;font-size:.5rem;letter-spacing:.08em;
  margin-left:.3rem;padding:.05rem .22rem;border:1px solid var(--line);border-radius:3px;color:var(--faint);vertical-align:.1em}
/* a tag should look like a tag while you type it */
/* Three kinds of tag, three codes, and they are not decoration: a person, a floor and CutPile itself
   are different sorts of thing and clicking each does something different, so they should not look
   alike. Staff blue is already this system's color for a teammate - it is what the inbox uses to
   separate staff from customers - so a tagged person carries it here too rather than inventing a
   fourth meaning for the same shade of oak. */
.jc-tag{color:var(--muted);font-weight:600}
/* @cutpile is a summons, not a mention. It gets the oak the rest of the app uses for
   "the machine did this"; a person's handle stays quiet. */
.jc-tag.is-ai{color:var(--oak);background:rgba(201,168,124,.12);border-radius:4px;padding:0 .18rem}
.jc-tag.is-who,.jc-tag.is-prod{border-radius:4px;padding:.02em .26em;cursor:pointer;
  text-decoration:none;transition:background .12s ease,box-shadow .12s ease}
.jc-tag.is-who{color:#2f5d8a;background:rgba(47,93,138,.10)}
.jc-tag.is-who:hover,.jc-tag.is-who:focus-visible{background:rgba(47,93,138,.18);
  box-shadow:0 0 0 1px rgba(47,93,138,.35);outline:none}
.jc-tag.is-prod{color:var(--chalk);background:rgba(143,76,35,.11)}
.jc-tag.is-prod:hover,.jc-tag.is-prod:focus-visible{background:rgba(143,76,35,.2);
  box-shadow:0 0 0 1px rgba(143,76,35,.4);outline:none}


/* ==== Impression: the asset studio ======================================== */
.imp-sub{color:var(--muted);font-size:.92rem}
.imp-types{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:.9rem;margin-top:1rem}
.imp-type{margin:0}
.imp-type-btn{display:flex;flex-direction:column;gap:.5rem;width:100%;text-align:left;cursor:pointer;
  background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:.9rem;transition:border-color .15s,transform .1s}
.imp-type-btn:hover{border-color:var(--oak);transform:translateY(-2px)}
.imp-type-ratio{display:flex;align-items:center;justify-content:center;width:100%;max-height:150px;
  background:linear-gradient(135deg,var(--walnut),#20180f);border-radius:8px;color:rgba(255,255,255,.5)}
.imp-type-dim{font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.05em}
.imp-type-name{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:1rem;color:var(--ink)}
.imp-type-blurb{font-size:.76rem;color:var(--muted);line-height:1.4}
.imp-recent{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:.8rem}
.imp-r{display:flex;flex-direction:column;gap:.35rem}
.imp-r-thumb{display:flex;align-items:center;justify-content:center;width:100%;max-height:180px;overflow:hidden;
  background:var(--paper);border:1px solid var(--line);border-radius:8px}
.imp-r-thumb img{width:100%;height:100%;object-fit:cover}
.imp-r-draft{font-family:'IBM Plex Mono',monospace;font-size:.6rem;text-transform:uppercase;letter-spacing:.08em;color:var(--faint)}
.imp-r-t{font-weight:600;font-size:.84rem;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.imp-r-s{font-size:.7rem;color:var(--faint)}

/* the composer: controls left, stage right */
.imp-studio{display:grid;grid-template-columns:360px 1fr;gap:1.2rem;align-items:start}
.imp-panel{display:flex;flex-direction:column;gap:.5rem;position:sticky;top:1rem}
.imp-ph{display:flex;justify-content:space-between;align-items:center}
.imp-dim{font-size:.72rem;color:var(--faint)}
.imp-title{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:1.1rem;border:0;border-bottom:1px solid var(--line);
  padding:.3rem 0;background:none;color:var(--ink);margin-bottom:.3rem}
.imp-title:focus{outline:none;border-bottom-color:var(--oak)}
.imp-l{font-family:'IBM Plex Mono',monospace;font-size:.6rem;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);margin-top:.5rem}
.imp-panel input[type=text],.imp-panel select,.imp-ta,.imp-in{width:100%;border:1px solid var(--line);border-radius:8px;
  padding:.5rem .6rem;font:inherit;font-size:.86rem;background:var(--surface);color:var(--ink)}
.imp-ta{resize:vertical;line-height:1.35}
.imp-panel input:focus,.imp-panel select:focus,.imp-ta:focus{outline:none;border-color:var(--oak)}
.imp-ai{display:flex;gap:.4rem}
.imp-ai input{flex:1}
.imp-ai-go{white-space:nowrap;flex:0 0 auto}
.imp-uploads{display:grid;grid-template-columns:1fr 1fr;gap:.5rem}
.imp-up{display:flex;align-items:center;justify-content:center;text-align:center;border:1px dashed var(--line);
  border-radius:8px;padding:.9rem .5rem;font-size:.78rem;color:var(--muted);cursor:pointer;font-weight:600}
.imp-up:hover{border-color:var(--oak);color:var(--ink)}
.imp-up input{display:none}
.imp-adv{border-top:1px solid var(--line);margin-top:.6rem;padding-top:.3rem}
.imp-adv summary{cursor:pointer;font-weight:600;font-size:.84rem;color:var(--ink);padding:.4rem 0}
.imp-adv[open] summary{color:var(--oak)}
.imp-check{display:flex;align-items:center;gap:.5rem;font-size:.82rem;color:var(--ink);margin-top:.6rem;cursor:pointer}
.imp-check input{width:auto}
.imp-apply{margin-top:.8rem}
.imp-panel input[type=range]{width:100%}
/* the stage */
.imp-stage{display:flex;flex-direction:column;gap:.8rem}
.imp-canvas{width:100%;background:var(--paper) repeating-conic-gradient(#0000 0% 25%,rgba(0,0,0,.03) 0% 50%) 0/28px 28px;
  border:1px solid var(--line);border-radius:12px;overflow:hidden;position:relative;max-height:74vh}
.imp-frame{border:0;transform-origin:top left;position:absolute;top:0;left:0}
.imp-actions{display:flex;align-items:center;gap:.7rem;flex-wrap:wrap}
.imp-note{font-size:.78rem}
.imp-note.ok{color:var(--muted)}
.imp-note.bad{color:#b4442e;max-width:30rem;line-height:1.4}
@media (max-width:820px){ .imp-studio{grid-template-columns:1fr} .imp-panel{position:static} }


/* ==== the notifications bell dropdown ===================================== */
/* the bell became a .menubtn, so re-assert its own look over the reset (which would
   otherwise strip its padding and mute color). Defined last, so equal specificity
   wins on order. */
.notif-wrap{position:relative;display:inline-flex}
.bell.menubtn{padding:.35rem;color:var(--muted);background:none;border:0;border-radius:8px}
.bell.menubtn:hover{background:var(--paper);color:var(--ink)}
.notif-pop{left:auto;right:0;min-width:22rem;max-width:min(24rem,92vw);padding:0;overflow:hidden}
.notif-h{font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.09em;text-transform:uppercase;
  color:var(--faint);padding:.7rem .8rem .5rem;display:flex;align-items:center;gap:.5rem;border-bottom:1px solid var(--line)}
.notif-hn{background:var(--chalk);color:#fff;border-radius:999px;padding:.05rem .4rem;font-size:.58rem;letter-spacing:.04em}
.notif-empty{padding:1.4rem .8rem;color:var(--muted);font-size:.86rem;text-align:center}
.notif-row{display:flex;align-items:flex-start;gap:.55rem;padding:.65rem .8rem;border-bottom:1px solid var(--line-2);color:var(--ink)}
.notif-row:hover{background:var(--paper)}
.notif-dot{width:7px;height:7px;border-radius:50%;background:transparent;margin-top:.4rem;flex:none}
.notif-row.fresh{background:linear-gradient(90deg,rgba(63,98,255,.05),transparent 70%)}
.notif-row.fresh .notif-dot{background:var(--chalk)}
.notif-c{display:flex;flex-direction:column;gap:.15rem;min-width:0}
.notif-m{font-size:.86rem;line-height:1.35;font-weight:500;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.notif-row.fresh .notif-m{font-weight:600}
.notif-t{font-size:.72rem;color:var(--faint)}
.notif-all{display:block;text-align:center;padding:.7rem;font-size:.82rem;font-weight:600;color:var(--oak);
  border-top:1px solid var(--line);background:var(--surface)}
.notif-all:hover{background:var(--paper);color:var(--ink)}

/* ---- pinning notifications ---- */
.notif-pop .notif-list{max-height:min(60vh,26rem);overflow-y:auto}
.notif-row{display:flex;align-items:stretch;gap:0;padding:0;position:relative;border-bottom:1px solid var(--line-2)}
.notif-row.cleared{opacity:.5}
.notif-ctx{display:block;font-size:.78rem;color:var(--faint);line-height:1.35;margin-top:.1rem}
.notif-link{display:flex;align-items:flex-start;gap:.55rem;flex:1;min-width:0;padding:.65rem .3rem .65rem .8rem;color:inherit}
.notif-clearall{margin-left:auto;font-family:'Instrument Sans',system-ui,sans-serif;font-size:.68rem;letter-spacing:.01em;
  text-transform:none;color:var(--oak);background:transparent;border:0;cursor:pointer;padding:.2rem .35rem;border-radius:6px;font-weight:600}
.notif-clearall:hover{background:rgba(201,168,124,.16);color:var(--ink)}
/* the pin toggle: visible, and it snaps in sharp when held */
.notif-pin{flex:none;align-self:center;width:32px;height:32px;margin-right:.45rem;border:0;background:transparent;
  color:var(--oak-dim);border-radius:8px;cursor:pointer;display:grid;place-items:center;opacity:.55;transition:opacity .15s,color .15s,background .15s}
.notif-pin svg{width:17px;height:17px;transform-origin:50% 14%}
.notif-row:hover .notif-pin,.notif-row.pinned .notif-pin{opacity:1}
.notif-pin:hover{color:var(--oak);background:rgba(201,168,124,.18)}
.notif-pin:focus-visible{opacity:1;outline:2px solid var(--oak);outline-offset:1px}
/* the held state: a bold oak rail, a SOLID filled pin, and a flame-quiet sway */
.notif-row.pinned{background:linear-gradient(90deg,rgba(201,168,124,.16),transparent 78%);box-shadow:inset 4px 0 0 var(--oak)}
.notif-row.pinned .notif-pin{color:var(--oak)}
.notif-row.pinned .notif-pin svg{fill:var(--oak);animation:pin-sway 7s ease-in-out infinite alternate}
@keyframes pin-sway{from{transform:rotate(-2deg)}to{transform:rotate(2deg)}}
/* the press: the tack drives in fast, point-first, with a hard impact and a crisp recoil */
.notif-row.just-pinned .notif-pin svg{animation:pin-press .42s cubic-bezier(.3,1.7,.5,1) both}
@keyframes pin-press{
  0%{transform:translateY(-20px) rotate(-38deg) scale(1.5);opacity:0}
  42%{transform:translateY(1px) rotate(3deg) scale(.72);opacity:1}   /* impact */
  64%{transform:translateY(-2px) rotate(-1deg) scale(1.12)}          /* recoil */
  100%{transform:translateY(0) rotate(0) scale(1)}
}
/* the row takes the impact: a quick thunk + a warm flash as it grabs the top spot */
.notif-row.just-pinned{animation:pin-caught 1s ease both}
@keyframes pin-caught{
  0%{transform:translateY(6px) scale(1.008);background:rgba(201,168,124,.4)}
  30%{transform:translateY(1px)}
  44%{transform:translateY(0) scale(1)}
  100%{background:linear-gradient(90deg,rgba(201,168,124,.16),transparent 78%)}
}
/* a sharp ring snaps out from the pinhead at impact */
.notif-ripple{position:absolute;top:50%;right:1.4rem;width:10px;height:10px;border-radius:50%;border:2.5px solid var(--oak);
  transform:translate(50%,-50%) scale(.3);opacity:0;pointer-events:none}
.notif-row.just-pinned .notif-ripple{animation:pin-ripple .5s cubic-bezier(.2,.8,.3,1) .14s both}
@keyframes pin-ripple{from{opacity:.7;transform:translate(50%,-50%) scale(.3)}to{opacity:0;transform:translate(50%,-50%) scale(2.6)}}
/* clearing exit */
.notif-row.clearing{animation:notif-clear .32s ease forwards;overflow:hidden}
@keyframes notif-clear{to{opacity:0;transform:translateX(14px);max-height:0;padding-top:0;padding-bottom:0;border-width:0}}
@media (prefers-reduced-motion:reduce){
  .notif-row.pinned .notif-pin svg,.notif-row.just-pinned .notif-pin svg,.notif-row.just-pinned,
  .notif-row.just-pinned .notif-ripple,.notif-row.clearing{animation:none!important}
}

/* deep-link: land ON the entry. A brief oak wash so the eye catches where it meant to. */
.deeplit{animation:deeplit 2.4s ease-out}
@keyframes deeplit{
  0%{background:rgba(201,168,124,.35);box-shadow:0 0 0 4px rgba(201,168,124,.28)}
  12%{background:rgba(201,168,124,.32)}
  100%{background:transparent;box-shadow:0 0 0 4px transparent}
}
@media (prefers-reduced-motion:reduce){ .deeplit{animation:none;outline:2px solid var(--oak);outline-offset:2px} }


/* settings: platform vs personal eyebrow + info flash */
.set-eyebrow{font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--faint);margin:1.4rem 0 .5rem;display:flex;align-items:center;gap:.5rem}
.set-eyebrow:first-child{margin-top:0}
.set-eyebrow::after{content:'';flex:1;height:1px;background:var(--line)}
.flash.info{background:rgba(201,168,124,.12);border:1px solid var(--oak);color:var(--ink)}


/* ==== Cockpit + the daily briefing ======================================== */
.ckpt{max-width:52rem}
.ckpt-head{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;margin-bottom:1.2rem}
.ckpt-date{font-family:'IBM Plex Mono',monospace;font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.ckpt-refresh button{background:none;border:0;color:var(--faint);font:inherit;font-size:.8rem;cursor:pointer;
  font-family:'IBM Plex Mono',monospace;letter-spacing:.06em;text-transform:uppercase}
.ckpt-refresh button:hover{color:var(--oak)}
.brief-loading{display:flex;align-items:center;gap:.7rem;color:var(--muted);font-size:.95rem;padding:1.4rem 0}
.brief-spin{width:16px;height:16px;border:2px solid var(--line);border-top-color:var(--oak);border-radius:50%;animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){ .brief-spin{animation:none} }
.brief-hello{font-family:'Bricolage Grotesque',sans-serif;font-size:1.5rem;font-weight:700;letter-spacing:-.01em;line-height:1.35;color:var(--ink);margin-bottom:1.6rem;
  padding-bottom:1.3rem;border-bottom:1px solid var(--line)}
.brief-hello p{margin:0}
.brief-sec{margin-bottom:1.5rem}
/* The briefing's section headings were --oak: 2.24:1 on paper, the lowest contrast text in the app,
   on the one screen everybody reads every morning. They also all looked identical, so the eight
   sections of a briefing read as one long list. Now each carries a rule in a color that says what
   KIND of section it is - money, time, trouble, the day's shape - and the words are dark enough to
   read from a standing start with a coffee in the other hand. */
.brief-sec-h{display:flex;align-items:center;gap:.55rem;font-family:'IBM Plex Mono',monospace;
  font-size:.7rem;letter-spacing:.11em;text-transform:uppercase;color:var(--label);
  margin-bottom:.7rem;font-weight:600;padding-bottom:.5rem;border-bottom:1px solid var(--line-2)}
.brief-sec-h::before{content:'';flex:none;width:4px;height:1.15em;border-radius:2px;background:var(--chalk)}
.brief-sec[data-sec=watch] .brief-sec-h::before{background:var(--lost)}
.brief-sec[data-sec=estimates] .brief-sec-h::before,
.brief-sec[data-sec=loops] .brief-sec-h::before{background:var(--warn)}
.brief-sec[data-sec=momentum] .brief-sec-h::before{background:var(--ok)}
.brief-sec[data-sec=orders] .brief-sec-h::before{background:var(--cat-orange)}
.brief-sec[data-sec=calendar] .brief-sec-h::before,
.brief-sec[data-sec=install_today] .brief-sec-h::before,
.brief-sec[data-sec=install_tomorrow] .brief-sec-h::before{background:var(--cat-blue)}
.brief-sec[data-sec=notes] .brief-sec-h::before{background:var(--cat-cyan)}
.brief-item{display:block;padding:.7rem .9rem;border:1px solid var(--line);border-radius:10px;margin-bottom:.5rem;
  background:var(--surface);transition:border-color .12s,transform .1s}
.brief-item:hover{border-color:var(--oak);transform:translateX(2px)}
.brief-item-cust{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap;margin-bottom:.2rem;
  font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:.82rem;color:var(--oak);letter-spacing:.01em}
.brief-item-city{font-family:'IBM Plex Mono',monospace;font-weight:400;font-size:.68rem;color:var(--muted);letter-spacing:.02em}
/* NEED TO SCHEDULE shouts; Need to schedule does not. The renderer already sentence-cases the
   status and text-transform was shouting it back. It also carries the status color now, as a dot,
   so the briefing and the jobs list agree about what a stage looks like. */
.brief-item-stage{display:inline-flex;align-items:center;gap:.35rem;font-family:'IBM Plex Mono',monospace;
  font-weight:500;font-size:.64rem;letter-spacing:.04em;
  color:var(--label);border:1px solid var(--line);border-radius:999px;padding:.1rem .45rem}
.brief-item-h{display:block;font-weight:700;font-size:.95rem;color:var(--ink);margin-bottom:.15rem}
.brief-item-b{display:block;font-size:.88rem;line-height:1.5;color:var(--muted)}
.brief-item-b p{margin:0}
.brief-empty{color:var(--muted);font-size:.95rem;padding:1.4rem 0;line-height:1.5}


/* SOP -> graph: what the graph just learned from a saved SOP */
.sop-learned{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem;line-height:1.6}
.sop-learned-chip{display:inline-flex;align-items:center;background:var(--surface);border:1px solid var(--oak);
  color:var(--ink);border-radius:999px;padding:.15rem .6rem;font-size:.8rem;font-weight:600}
.sop-learned-chip:hover{background:var(--paper)}

/* ---------- who gets notified (settings > communications) ---------- */
.nk-tabs{display:flex;flex-wrap:wrap;gap:.35rem;margin-bottom:.6rem}
.nk-tab{display:inline-flex;align-items:center;gap:.4rem;font-size:.78rem;padding:.3rem .6rem;border:1px solid var(--line);border-radius:999px;background:var(--surface);color:var(--muted);text-decoration:none}
.nk-tab:hover{border-color:var(--oak);color:var(--ink)}
.nk-tab.on{background:var(--oak);border-color:var(--oak);color:#fff}
.nk-n{font-size:.68rem;font-variant-numeric:tabular-nums;opacity:.75}
.nk-what{font-size:.8rem;color:var(--muted);margin:.1rem 0 .8rem}
.nk-grid{border:1px solid var(--line);border-radius:9px;overflow:hidden}
.nk-head,.nk-row{display:grid;grid-template-columns:1fr 11rem 6rem 5rem;align-items:center;gap:.7rem;padding:.5rem .8rem}
.nk-head{font-size:.66rem;text-transform:uppercase;letter-spacing:.05em;color:var(--faint);font-weight:600;background:var(--paper);border-bottom:1px solid var(--line)}
.nk-head span:nth-child(n+3),.nk-row .nk-chk{text-align:center;justify-self:center}
.nk-row+.nk-row{border-top:1px solid var(--line-2)}
.nk-who{font-size:.86rem;color:var(--ink);display:grid;grid-template-columns:auto auto;justify-content:start;align-items:baseline;column-gap:.4rem;row-gap:.2rem;min-width:0}
.nk-last{grid-column:1 / -1;justify-self:start}
.nk-h{font-size:.72rem;color:var(--faint);font-family:'IBM Plex Mono',monospace}
.nk-row input[type=tel]{font:inherit;font-size:.8rem;padding:.3rem .5rem;border:1px solid var(--line);border-radius:7px;background:var(--surface);color:var(--ink);width:100%}
.nk-chk{position:relative;display:inline-flex;cursor:pointer}
.nk-chk input{position:absolute;opacity:0;width:0;height:0}
.nk-chk span{width:34px;height:19px;border-radius:999px;background:var(--line);transition:background .15s;position:relative;display:block}
.nk-chk span::after{content:"";position:absolute;top:2px;left:2px;width:15px;height:15px;border-radius:50%;background:#fff;transition:transform .15s}
.nk-chk input:checked+span{background:var(--ok)}
.nk-chk input:checked+span::after{transform:translateX(15px)}
.nk-chk input:focus-visible+span{outline:2px solid var(--oak);outline-offset:2px}
.nk-nomob{opacity:.4}
.nk-actions{display:flex;gap:.6rem;flex-wrap:wrap;margin:.9rem 0 .5rem}
@media (max-width:680px){.nk-head{display:none}.nk-row{grid-template-columns:1fr 4.5rem 4.5rem;grid-template-areas:"who who who" "mob app sms";gap:.4rem .7rem}
  .nk-who{grid-area:who}.nk-row input[type=tel]{grid-area:mob}}

/* The photo/map toggle shows the icon for where you would go next, not where you are. */
.sv-i{display:inline-flex}
.site-photo[data-view="map"] .sv-i-map,
.site-photo[data-view="pano"] .sv-i-photo{display:none}

/* Entry cards for a full-page admin tool reached from the Control Center. */
.cc-tools{display:grid;grid-template-columns:1fr 1fr;gap:.6rem}
@media (max-width:720px){.cc-tools{grid-template-columns:1fr}}
.cc-tool{display:flex;flex-direction:column;gap:.25rem;padding:.75rem .85rem;border:1px solid var(--line);border-radius:10px;background:var(--surface);text-decoration:none;transition:border-color .12s}
.cc-tool:hover{border-color:var(--oak)}
.cc-tool-n{font-size:.9rem;font-weight:600;color:var(--ink)}
.cc-tool-d{font-size:.78rem;color:var(--muted);line-height:1.5}

/* ---------- shared inbox, color coded by who you are talking to ----------
   Customers keep the system brown: they are most of the traffic, and the default should be
   the calm one. Staff are blue. Reps and distributors are burgundy, in the red family, because
   those threads usually carry a price, a delivery date, or something holding a job up. */
:root{--staff:#2f5d8a;--staff-soft:#e6eef6;--pro:#7d2b3a;--pro-soft:#f7e6e9}
.ibx-row{position:relative;border-left:3px solid transparent}
.ibx-row.pk-customer{border-left-color:var(--oak)}
.ibx-row.pk-staff{border-left-color:var(--staff)}
.ibx-row.pk-pro{border-left-color:var(--pro)}
.ibx-row.pk-unknown{border-left-color:var(--line)}
.ibx-row.pk-staff .av{background:var(--staff-soft);color:var(--staff)}
.ibx-row.pk-pro .av{background:var(--pro-soft);color:var(--pro)}
.ibx-tag.party{background:transparent;border:1px solid var(--line);color:var(--faint)}
.ibx-row.pk-staff .ibx-tag.party{border-color:var(--staff);color:var(--staff);background:var(--staff-soft)}
.ibx-row.pk-pro .ibx-tag.party{border-color:var(--pro);color:var(--pro);background:var(--pro-soft)}
.ibx-row.pk-customer .ibx-tag.party{border-color:var(--oak);color:var(--oak)}
/* What intake does on your behalf, said once, instead of two checkboxes nobody should have to think about. */
.nest-auto{font-size:.8rem;color:var(--muted);line-height:1.55;background:var(--paper);border:1px solid var(--line-2);border-radius:9px;padding:.6rem .75rem;margin:.2rem 0 .4rem}

/* ---------- job action buttons: one shape, and three across on a phone ----------
   Both labels are in the markup and exactly one is displayed, so a screen reader announces one
   word rather than both. min-width is what stopped three fitting on a narrow screen, so on a
   phone the row becomes a real three column grid and the buttons size to it. */
.pa-sm{display:none}
@media (max-width:640px){
  .prof-actions{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.45rem}
  .prof-actions .menuwrap{display:block}
  .pa{min-width:0;width:100%;padding:.5rem .4rem;gap:.3rem;font-size:.8rem}
  .pa .ic{width:15px;height:15px;flex:none}
  .pa-lg{display:none}
  .pa-sm{display:inline}
  .pa-caret{margin-left:.1rem;padding-left:.35rem}
}

/* ---------- mobile: nothing may push the page wider than the screen ----------
   A grid track of `1fr` is really `minmax(auto, 1fr)`, and that `auto` floor is the item's
   min-content width. One long unbreakable line inside a card therefore widens the whole column
   past the viewport, and since the shell clips horizontally the overflow is not even scrollable -
   it is simply gone. `minmax(0, 1fr)` lets the track shrink and the content reflow instead. */
@media (max-width:900px){
  .prof-grid{grid-template-columns:minmax(0,1fr)}
  .prof-grid > *{min-width:0}
}
@media (max-width:640px){
  /* A tab strip is the one thing that should scroll sideways rather than wrap: keeping the tabs on
     one line is what makes them readable as a row. It scrolls within itself, not the page. */
  .jf-tabs{overflow-x:auto;flex-wrap:nowrap;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .jf-tabs::-webkit-scrollbar{display:none}
  .jf-tab{flex:0 0 auto}
  /* Anything that can carry a long unbroken value: an email, a url, a style number. */
  .kv .row,.kv .k,.kv .val{min-width:0;overflow-wrap:anywhere}
  .composer,.card,.jf-panel{min-width:0}
}

/* ---------- job action buttons: ONE font, settled here and nowhere else ----------
   These six buttons were rendering in two different typefaces at two different sizes. `.pa` sets a
   size and weight but no family, so a plain <button> fell back to the browser default (Arial), while
   `.menubtn` uses the `font:inherit` SHORTHAND, which fixes the family but resets size and weight
   back to inherited 16px/400. So the dropdown buttons and the plain ones could never agree.
   This rule sits after both and states all three properties explicitly, so every action button is the
   same regardless of which classes it happens to carry. Longhand, never the `font` shorthand. */
.prof-actions .pa,
.prof-actions .menubtn.pa{font-family:inherit;font-size:.85rem;font-weight:600;line-height:1.2;letter-spacing:0}
.prof-actions .pa .pa-t{font:inherit}

/* ---------- job details: group it, and let the content outrank its labels ----------
   The card read as disjointed because every row had identical spacing and identical emphasis, so
   nothing grouped and nothing led. Two changes fix it. First, proximity: a label and its value are
   pulled tight together into one unit, and the gap BETWEEN units grows, so the eye sees three things
   instead of six. Second, hierarchy: the value is what somebody came here to read, not the word
   "Phone", so the value gets the size and the label recedes. */
.card .kv{gap:1.05rem}
.card .kv .row{gap:.05rem}
/* 9px at 3.35:1 and then knocked back another 15% by opacity. This was the least readable text in
   the app and it is the text that says what every value means. */
.card .kv .k{font-size:.62rem;font-weight:600;letter-spacing:.12em;color:var(--label)}
.card .kv .val{font-size:.97rem;color:var(--ink);line-height:1.45}

/* The work they asked for: the one place in this card with color, and the thing the card is really
   for. Separated by a hairline because it answers a different question from the contact rows. */
.jd-work{margin-top:1.15rem;padding-top:1rem;border-top:1px solid var(--line-2)}
.jd-work-h{font-family:'IBM Plex Mono',monospace;font-size:.58rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--faint);opacity:.85;margin-bottom:.5rem}
.jd-chips{display:flex;flex-wrap:wrap;gap:.35rem}
.jd-chip{font-size:.82rem;line-height:1.25;padding:.3rem .6rem;border-radius:999px;
  background:var(--oak-soft,rgba(201,168,124,.14));color:var(--ink);
  border:1px solid rgba(201,168,124,.42)}

/* ---------- composer row: one line, not three ----------
   The hint used to wrap onto a row of its own beneath the clip, which made the new-post box tall for
   no reason. It now sits beside the clip and wraps within that row, so two lines of hint cost the box
   nothing extra in height and the whole thing stays compact. */
.composer-row{flex-wrap:nowrap;align-items:center}
.composer-row .composer-clip{flex:0 0 auto;align-self:center}
.composer-row .composer-hint{flex:1 1 auto;min-width:0;line-height:1.35;margin:0}
.composer button[type="submit"]{flex:0 0 auto;align-self:center;white-space:nowrap}
@media (max-width:520px){
  /* Too narrow for three abreast: the hint steps down but the controls stay paired. */
  .composer-row{flex-wrap:wrap}
  .composer-row .composer-hint{order:3;flex:1 0 100%}
}

/* ---------- Fast Action Bar: let it be as tall as it needs to be ----------
   It was pinned to exactly one screen with its own inner scrollbar, so a third widget, or a hot list
   with more than a couple of names, simply got cut off - and an inner scrollbar inside a page that
   already scrolls is a thing people rarely find. A job page is long anyway, so the bar now takes its
   natural height and scrolls with the page like everything else.

   The header stays pinned within it, so New Estimate and the panel controls remain reachable however
   far down the feed you are. If the bar ever gets genuinely unwieldy, the next step is collapsible
   widgets rather than putting the clipping back. */
.pn{height:auto;min-height:100vh;overflow:visible;position:static;align-self:stretch}
.pn-body{overflow:visible;flex:0 0 auto}
.pn-top{position:sticky;top:0;z-index:4;background:var(--surface)}
.pn-box{overflow:visible}

/* ---------- the status track ----------
   Eight dots in the order a job actually travels: needs estimate, measurements, estimate out, needs
   scheduling, on the calendar, then done or lost. The hairline behind them is the point - it makes the
   row read as a path rather than a color key, so scanning left to right is scanning the funnel.
   Selecting is one click from rest. Anything deselected fades hard rather than merely dimming, because
   the whole ask was that it be obvious when jobs are being hidden. */
.stk{position:relative;display:inline-flex;align-items:center;gap:.7rem;padding:.35rem .7rem;margin:0 .15rem}
/* The rail has to be visible or the pipeline reading does not land, but it must not compete with
   the dots. A warm hairline that fades at both ends: present, clearly deliberate, not a divider. */
.stk-rail{position:absolute;left:.75rem;right:.75rem;top:50%;height:1px;transform:translateY(-50%);
  background:linear-gradient(90deg,transparent,rgba(201,168,124,.55) 18%,rgba(201,168,124,.55) 82%,transparent)}
/* No paper ring on the resting dot: it was 3px wide on a 8.8px gap, so the rings met in the middle
   and painted over the rail the whole idea depends on. The rail now runs behind the dots like
   stations on a line, which is the reading we want. */
.stk-dot{position:relative;z-index:1;width:12px;height:12px;border-radius:50%;background:var(--sc);flex:none;
  transition:transform .16s cubic-bezier(.2,.9,.3,1.3),box-shadow .16s ease,opacity .16s ease}
.stk-dot:hover{transform:scale(1.35)}
.stk-dot.on{transform:scale(1.3);box-shadow:0 0 0 4px color-mix(in srgb,var(--sc) 38%,transparent)}
.stk-dot.off{opacity:.22;transform:scale(.82)}
.stk-dot.off:hover{opacity:.7;transform:scale(1.1)}
.stk-dot:focus-visible{outline:2px solid var(--oak);outline-offset:4px}
/* the name and count, only while pointing at it: the dots stay wordless so the row stays small */
.stk-tip{position:absolute;left:50%;top:calc(100% + 9px);transform:translateX(-50%) translateY(-3px);
  display:flex;align-items:center;gap:.4rem;white-space:nowrap;pointer-events:none;opacity:0;
  background:var(--ink);color:var(--paper);font-family:'IBM Plex Mono',monospace;font-size:.62rem;
  letter-spacing:.04em;padding:.28rem .5rem;border-radius:6px;z-index:5;
  transition:opacity .14s ease,transform .14s ease}
.stk-tip b{font-weight:700;opacity:.75}
.stk-dot:hover .stk-tip,.stk-dot:focus-visible .stk-tip{opacity:1;transform:translateX(-50%) translateY(0)}
.stk-clear{position:relative;z-index:2;display:inline-flex;align-items:center;justify-content:center;
  width:17px;height:17px;margin-left:.25rem;border-radius:50%;color:var(--faint);
  background:var(--paper);flex:none;transition:color .14s ease,transform .14s ease}
.stk-clear svg{width:11px;height:11px}
.stk-clear:hover{color:var(--lost);transform:rotate(90deg)}
@media (prefers-reduced-motion:reduce){
  .stk-dot,.stk-tip,.stk-clear{transition:none}
  .stk-clear:hover{transform:none}
}
@media (max-width:640px){ .stk{width:100%;justify-content:space-between;gap:.3rem} }

/* ---------- contact profile ----------
   A contact is a person AT a company, so the header names both and the two phone numbers are separate
   actions: you want Greg, and failing that you want Greg's switchboard. Everything else deliberately
   mirrors the job profile, because nobody should have to learn this page twice. */
.ct-cover{background:linear-gradient(160deg,var(--walnut),#2f251c)}
.ct-sub{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-top:.35rem}
.ct-title{color:var(--oak-dim);font-size:.9rem}
.ct-org{color:var(--oak);font-size:.9rem;font-weight:600;text-decoration:none;border-bottom:1px solid transparent}
.ct-org:hover{border-bottom-color:var(--oak)}
.ct-kind{font-family:'IBM Plex Mono',monospace;font-size:.6rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--oak-dim);border:1px solid rgba(201,168,124,.35);border-radius:999px;padding:.1rem .45rem}
/* The portal comes first on purpose: it is the link somebody is hunting for at 7am with an order to place. */

/* The one switch left on the intake form. Reads as a sentence rather than a setting, and says who it
   means by "the team" so nobody has to go and look. */
.nest-tell{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap;cursor:pointer;
  padding:.6rem .75rem;margin-top:.2rem;border:1px solid var(--line);border-radius:10px;background:var(--surface)}
.nest-tell input{margin:0;accent-color:var(--oak);width:15px;height:15px;position:relative;top:2px}
.nest-tell-t{font-size:.86rem;font-weight:600;color:var(--ink-2)}
.nest-tell-w{font-size:.78rem;color:var(--ink-4)}
.nest-tell:has(input:not(:checked)){border-style:dashed;background:transparent}
.nest-tell:has(input:not(:checked)) .nest-tell-t,
.nest-tell:has(input:not(:checked)) .nest-tell-w{color:var(--ink-4)}

/* ---- The assistant's tool list -------------------------------------------------------------------
   A reference you read down, not a table you scan across: the name first because that is what the
   assistant is told, the arguments beside it because that is what it needs, and the description below
   in plain words because that is what decides whether it reaches for the thing. */
.tool-sec{display:flex;align-items:center;gap:.5rem;font-family:var(--mono);font-size:.66rem;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-4);margin:1.2rem 0 .55rem}
.tool-sec:first-of-type{margin-top:.2rem}
.tool-c{background:var(--chalk-soft);color:var(--ink-3);border-radius:20px;padding:.05rem .4rem;font-size:.63rem}
.tool-warn{text-transform:none;letter-spacing:0;font-family:inherit;font-size:.72rem;color:var(--lost)}
.tool-list{display:flex;flex-direction:column;gap:.1rem}
.tool{padding:.5rem .1rem;border-top:1px solid var(--line-2)}
.tool:first-child{border-top:0}
.tool-h{display:flex;align-items:baseline;gap:.55rem;flex-wrap:wrap}
.tool-n{font-family:var(--mono);font-size:.8rem;font-weight:600;color:var(--ink);background:none;padding:0}
.tool-args{display:flex;gap:.28rem;flex-wrap:wrap}
.tool-arg{font-family:var(--mono);font-size:.65rem;color:var(--ink-4);background:var(--surface);
  border:1px solid var(--line-2);border-radius:5px;padding:.02rem .3rem}
/* Required arguments carry weight, because a call without one simply fails. */
.tool-arg.req{color:var(--ink-2);font-weight:600;border-color:var(--line)}
.tool-arg.none{border:0;background:none;font-style:italic}
.tool-d{font-size:.83rem;line-height:1.5;color:var(--ink-3);margin-top:.2rem;max-width:60rem}

.cc-preview{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;margin:-.2rem 0 .2rem}
.cc-preview-n{font-size:.78rem;color:var(--ink-4)}

/* Dates the calendar holds that the record does not. Sits between the briefing and its notes: more
   than a note, less than the morning's work, and one button from being settled. */
.brief-dates{margin-top:1.2rem;padding-top:.9rem;border-top:1px solid var(--line-2)}
.brief-dates-h{font-family:var(--mono);font-size:.66rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-4);margin-bottom:.5rem}
.bd-row{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap;padding:.42rem 0;border-top:1px solid var(--line-2)}
.bd-row:first-of-type{border-top:0}
.bd-who{font-weight:600;font-size:.9rem;color:var(--ink-2);text-decoration:none}
.bd-who:hover{color:var(--oak)}
.bd-tag{font-family:var(--mono);font-size:.63rem;letter-spacing:.03em;color:var(--ink-4);
  border:1px solid var(--line-2);border-radius:5px;padding:.04rem .32rem}
.bd-when{font-size:.83rem;color:var(--ink-3);margin-right:auto}
/* What the record currently thinks, when it disagrees rather than being blank. */
.bd-was{font-size:.72rem;color:var(--lost);margin-left:.4rem}
.bd-go{font-size:.73rem;font-weight:600;padding:.2rem .55rem;border-radius:7px;cursor:pointer;
  border:1px solid var(--line);background:var(--surface);color:var(--ink-3);white-space:nowrap;
  transition:border-color .13s ease,background .13s ease,color .13s ease}
.bd-go:hover:not(:disabled){border-color:var(--chalk-2);background:var(--chalk-soft);color:var(--ink)}
.bd-go:disabled{opacity:.65;cursor:default}
.bd-row.done .bd-who,.bd-row.done .bd-when{color:var(--ink-4)}
.bd-row.done .bd-go{border-color:transparent;background:transparent;color:var(--ok,#0B8043)}

/* The calendar's sticky notes. Deliberately the quietest thing on the page: they are notations on a
   day, not work, and must never compete with the jobs above them. */
.brief-notes{display:flex;align-items:baseline;gap:.4rem;flex-wrap:wrap;margin-top:1.1rem;padding-top:.85rem;
  border-top:1px solid var(--line-2)}
.brief-notes-h{font-family:var(--mono);font-size:.66rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-4);margin-right:.2rem}
.brief-note{font-size:.8rem;color:var(--ink-3);background:var(--surface);border:1px solid var(--line-2);
  border-radius:6px;padding:.12rem .45rem}

/* ---- Financial documents ---------------------------------------------------------------------------
   A row you can open. The whole row is the target, because the document is what you came for. */
.fin-row{cursor:pointer;transition:background .12s ease}
.fin-row:hover{background:var(--chalk-soft)}
.fin-expired td{color:var(--ink-4)}
.fin-flag{display:inline-block;font-size:.72rem;font-weight:600;color:var(--lost);
  background:var(--lost-soft);border-radius:5px;padding:.05rem .35rem;margin-right:.4rem}
.fin-exp{font-size:.72rem;color:var(--ink-4)}
/* The one action that fixes an expired estimate, sitting where the problem is stated. */
.fin-revive{font-size:.7rem;font-weight:600;padding:.15rem .45rem;border-radius:6px;cursor:pointer;
  border:1px solid var(--line);background:var(--surface);color:var(--ink-3);white-space:nowrap;
  transition:border-color .13s ease,color .13s ease,background .13s ease}
.fin-revive:hover:not(:disabled){border-color:var(--chalk-2);background:var(--chalk-soft);color:var(--ink)}
.fin-revive:disabled{opacity:.6;cursor:default}

/* The preview. Tall on purpose: a page of an estimate is portrait and reading it should not mean
   scrolling a letterbox. */
.fin-doc-card{width:min(56rem,94vw)}
.fin-doc-frame{width:100%;height:min(72vh,860px);border:1px solid var(--line);border-radius:10px;
  background:var(--paper);display:block}
.fin-doc-row{align-items:center}
.fin-doc-note{font-size:.76rem;color:var(--ink-4);margin-right:auto;margin-left:.2rem}
@media (max-width:640px){ .fin-doc-frame{height:64vh} .fin-doc-note{display:none} }

/* ---- Contact profile: place, lookups, feed files ---------------------------------------------------
   A rep is a relationship you keep for years, so their page earns the same care a job site gets. */
.ct-place .card-h,.ct-find .card-h{margin-bottom:.6rem}
.ct-map{display:block;width:100%;height:150px;border:1px solid var(--line);border-radius:10px;
  background-size:cover;background-position:center;cursor:pointer;position:relative;padding:0;
  transition:border-color .16s ease, box-shadow .16s ease}
.ct-map:hover{border-color:var(--chalk-2);box-shadow:0 6px 18px rgba(36,28,21,.14)}
.ct-map-open{position:absolute;right:.5rem;bottom:.5rem;font-size:.7rem;font-weight:600;
  background:rgba(255,255,255,.94);color:var(--ink-2);border-radius:6px;padding:.15rem .45rem}
.ct-addr{font-size:.88rem;color:var(--ink-2);margin:.6rem 0 .5rem;line-height:1.45}
.ct-place-acts{display:flex;flex-wrap:wrap;gap:.35rem}
.ct-chip{font-size:.75rem;font-weight:600;color:var(--ink);background:var(--surface);
  border:1px solid var(--line);border-radius:7px;padding:.22rem .5rem;text-decoration:none;
  transition:border-color .13s ease,background .13s ease,color .13s ease}
.ct-chip:hover{border-color:var(--chalk-2);background:var(--chalk-soft);color:var(--ink)}
.ct-map-card{width:min(52rem,94vw)}
.ct-map-frame{width:100%;height:min(66vh,620px);border:1px solid var(--line);border-radius:10px;display:block}

/* Files on the way into a note. */
.composer-clip{border:0;background:none;cursor:pointer;color:var(--ink-4);padding:.2rem;line-height:0;
  border-radius:7px;transition:color .13s ease,background .13s ease}
.composer-clip:hover{color:var(--ink-2);background:var(--chalk-soft)}
.composer-clip svg{width:17px;height:17px}
.composer-atts{display:flex;flex-wrap:wrap;gap:.3rem;margin:.4rem 0 0}
.composer-att{display:inline-flex;align-items:center;gap:.3rem;font-size:.74rem;color:var(--ink-3);
  background:var(--surface);border:1px solid var(--line-2);border-radius:6px;padding:.15rem .4rem}
.composer-att b{font-weight:500;max-width:14rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.composer-att button{border:0;background:none;cursor:pointer;color:var(--ink-4);font-size:.9rem;line-height:1;padding:0}
.composer.dropping{outline:2px dashed var(--chalk-2);outline-offset:3px}

/* ---- Speed dial -----------------------------------------------------------------------------------
   Third of the family, same bare button as the flame and the moon. Off it is an outline. On it is
   charged. The discharge only ever happens on the press: a bolt that flickers all day would be the
   most annoying thing on the page. */
.spd{position:relative;background:none;border:0;cursor:pointer;padding:.3rem;color:var(--oak-dim);
  line-height:0;border-radius:10px;-webkit-tap-highlight-color:transparent;touch-action:manipulation;
  transition:transform .12s cubic-bezier(.34,1.56,.64,1),color .25s}
.spd:hover{color:#c9931f}
.spd:active{transform:scale(.86)}
.spd .ic{width:26px;height:26px;position:relative;z-index:2;overflow:visible}
.spd-ic{display:block;position:relative;z-index:2}
/* Off it is the outline of a bolt in the page's own muted ink. On it is charged amber. */
.spd .ic{opacity:.42;transition:opacity .28s ease, filter .28s ease}
.spd:hover .ic{opacity:.75}
.spd.on{color:#e8a317}
.spd.on .ic{opacity:1;filter:drop-shadow(0 0 5px rgba(240,180,41,.5))}

/* The ring is the discharge: it leaves the bolt and is gone. */
.spd-ring{position:absolute;inset:0;z-index:1;border-radius:50%;opacity:0;pointer-events:none;
  border:2px solid #f0b429}
.spd.zap .spd-ring{animation:spdRing .6s cubic-bezier(.2,.7,.3,1) forwards}
.spd.zap .spd-ic{animation:spdKick .45s cubic-bezier(.34,1.6,.5,1)}
@keyframes spdRing{
  0%{opacity:.85;transform:scale(.5)}
  100%{opacity:0;transform:scale(2.1)}
}
@keyframes spdKick{
  0%{transform:scale(1) rotate(0)}
  30%{transform:scale(1.32) rotate(-9deg)}
  60%{transform:scale(.94) rotate(5deg)}
  100%{transform:scale(1) rotate(0)}
}
@media (prefers-reduced-motion:reduce){ .spd.zap .spd-ring,.spd.zap .spd-ic{animation:none} }

/* ---- Snooze --------------------------------------------------------------------------------------
   The flame's twin. Same bare button, same size, same give under the thumb, sitting beside it: keep
   this in front of me, and let this rest. Awake it is an outline. Asleep it fills, tips back the way a
   head does, and breathes. */
.snz{position:relative;background:none;border:0;cursor:pointer;padding:.3rem;color:var(--oak-dim);margin-left:-12px;
  line-height:0;border-radius:10px;-webkit-tap-highlight-color:transparent;touch-action:manipulation;
  transition:transform .12s cubic-bezier(.34,1.56,.64,1),color .25s}
.snz:hover{color:#6f86c4}
.snz:active{transform:scale(.86)}
.snz .ic{width:26px;height:26px;position:relative;z-index:2;overflow:visible}
.snz-ic{display:block;position:relative;z-index:2;transform-origin:50% 56%;
  transition:transform .5s cubic-bezier(.34,1.4,.64,1)}
.snz .mn-body{fill:transparent;transition:fill .5s ease, stroke .5s ease}
.snz .mn-star{fill:currentColor;stroke:none;opacity:0}

/* Asleep: moonlight in the crescent, tipped back, with a soft halo that breathes. */
.snz.on{color:#8fa8e0}
.snz.on .mn-body{fill:url(#moonGrad);stroke:#c2d3f5}
.snz.on .snz-ic{transform:rotate(15deg)}
.snz.on .mn-star{fill:#cfdcf8}
.snz.on .mn-s1{animation:mnTwinkle 3.6s ease-in-out infinite}
.snz.on .mn-s2{animation:mnTwinkle 4.4s ease-in-out .7s infinite}
.snz.on .mn-s3{animation:mnTwinkle 3.1s ease-in-out 1.5s infinite}

/* The halo. Its own element rather than a filter on the icon, so the breathing costs nothing. */
.snz-sky{position:absolute;inset:-6px;z-index:1;border-radius:50%;opacity:0;pointer-events:none;
  background:radial-gradient(circle at 44% 54%, rgba(150,178,240,.5), rgba(150,178,240,0) 66%);
  transition:opacity .5s ease}
.snz.on .snz-sky{opacity:1;animation:mnBreathe 4.2s ease-in-out infinite}

/* The one-shot on the way down: it swings a little past where it settles, the way something heavy
   does, then comes to rest. This is the moment worth watching, so it plays in place and the page is
   never reloaded out from under it. */
.snz.settle .snz-ic{animation:mnSettle .78s cubic-bezier(.34,1.35,.5,1) both}
.snz.settle .mn-star{animation:mnStarPop .7s ease-out both}
.snz.settle .mn-s2{animation-delay:.1s}
.snz.settle .mn-s3{animation-delay:.19s}
/* Waking is the same move in reverse, brisker, because coming back is not a lullaby. */
.snz.rousing .snz-ic{animation:mnRouse .42s ease-out both}

@keyframes mnSettle{
  0%{transform:rotate(0deg) scale(1)}
  38%{transform:rotate(25deg) scale(1.15)}
  68%{transform:rotate(9deg) scale(.98)}
  100%{transform:rotate(15deg) scale(1)}
}
@keyframes mnRouse{
  0%{transform:rotate(15deg) scale(1)}
  45%{transform:rotate(-6deg) scale(1.1)}
  100%{transform:rotate(0deg) scale(1)}
}
@keyframes mnStarPop{
  0%{opacity:0;transform:scale(.2)}
  50%{opacity:1;transform:scale(1.4)}
  100%{opacity:.6;transform:scale(1)}
}
@keyframes mnTwinkle{0%,100%{opacity:.28}50%{opacity:.8}}
@keyframes mnBreathe{0%,100%{opacity:.55;transform:scale(.94)}50%{opacity:1;transform:scale(1.06)}}

/* Nothing here is load bearing, so under reduced motion it simply is what it is. */
@media (prefers-reduced-motion:reduce){
  .snz-ic,.snz.settle .snz-ic,.snz.rousing .snz-ic{animation:none;transition:none}
  .snz.on .mn-star{animation:none;opacity:.6}
  .snz.on .snz-sky{animation:none}
}

/* When it wakes, beside the moon rather than inside it, so the button stays a button. */
.snz-wake{font-family:var(--mono);font-size:.66rem;letter-spacing:.02em;color:#8fa8e0;margin-left:-.15rem}

/* How long. Four choices, because a fifth would be a month and a month is a decision, not a snooze. */
.snz-weeks{display:grid;grid-template-columns:repeat(4,1fr);gap:.45rem;margin:.7rem 0 .2rem}
.snz-wk{display:flex;flex-direction:column;align-items:center;gap:.1rem;padding:.5rem .3rem;cursor:pointer;
  border:1px solid var(--line);border-radius:10px;background:var(--surface);color:var(--ink-3);
  transition:border-color .14s ease, background .14s ease, color .14s ease}
.snz-wk b{font-size:1.05rem;font-weight:650;line-height:1}
.snz-wk span{font-size:.68rem;color:var(--ink-4)}
.snz-wk em{font-family:var(--mono);font-style:normal;font-size:.6rem;color:var(--ink-4);letter-spacing:.02em}
.snz-wk:hover{border-color:#b9c6e0}
.snz-wk.on{border-color:#41568a;background:#eef1f8;color:#2f3f6b}
.snz-wk.on span,.snz-wk.on em{color:#5b73a8}

/* The sleeping list, in the Cockpit and the Briefing. Deliberately quiet: it is there so nothing is
   lost, not to compete with the work you actually have to do today. */
.snoozed-l{margin-top:1.1rem;padding-top:.85rem;border-top:1px solid var(--line-2)}
.snoozed-h{display:flex;align-items:center;gap:.4rem;font-family:var(--mono);font-size:.66rem;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-4);margin-bottom:.5rem}
.snoozed-h svg{width:13px;height:13px}
.snoozed-i{display:flex;align-items:baseline;gap:.5rem;padding:.28rem 0;font-size:.84rem;color:var(--ink-3)}
.snoozed-i a{font-weight:600;color:var(--ink-2)}
.snoozed-i .sn-why{color:var(--ink-4);font-size:.79rem}
.snoozed-i .sn-when{margin-left:auto;font-family:var(--mono);font-size:.66rem;color:var(--ink-4);white-space:nowrap}
@media (max-width:640px){ .snz-wake{display:none} }

/* ---- Status marks -------------------------------------------------------------------------------
   One fixed size disc per job status, color from the status, stage icon on top. The pill it replaces
   was as wide as its words, which is why that column never lined up and wrapped on a phone. */
/* The status, in words. A wash of the status color so a column of them groups by eye, a solid dot
   so it still reads at a glance, and the words in --ink so the label never inherits a color that
   cannot be read. Below 900px the words fold away and the dot carries it, which is the same
   information in the space a phone has. */
.stag{display:inline-flex;align-items:center;gap:.42rem;font-size:.72rem;font-weight:600;
  padding:.24rem .6rem;border-radius:999px;white-space:nowrap;color:var(--ink);
  background:color-mix(in srgb, var(--sc,#9aa0a6) 13%, #fff);
  border:1px solid color-mix(in srgb, var(--sc,#9aa0a6) 32%, #fff)}
.stag i{width:7px;height:7px;border-radius:50%;background:var(--sc,#9aa0a6);flex:none}
.stag.stag-none{background:var(--line-2);border-color:var(--line);color:var(--faint)}
.stag.stag-none i{background:var(--faint)}
@media (max-width:900px){
  .stag{padding:.24rem;gap:0}
  .stag b{display:none}
}

.smark{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;flex:0 0 30px;
  border-radius:50%;background:var(--sc);color:#fff;vertical-align:middle;
  box-shadow:0 1px 2px rgba(24,18,14,.18), inset 0 0 0 1px rgba(255,255,255,.14);
  transition:transform .14s ease, box-shadow .14s ease}
.smark svg{width:17px;height:17px;display:block}
/* No status at all reads as an empty socket rather than a color that means something. */
.smark-none{background:transparent;box-shadow:inset 0 0 0 1.5px var(--line-2)}
/* The row is the link, so the mark lifts with it rather than being its own hover target. */
tr:hover .smark, .person:hover .smark{transform:translateY(-1px);box-shadow:0 3px 8px rgba(24,18,14,.24), inset 0 0 0 1px rgba(255,255,255,.2)}
.cust td.stat{width:1%;white-space:nowrap;text-align:left;padding-left:.7rem;padding-right:.7rem}

/* The heading you get once you have filtered to a single status: the same mark, larger, with the words
   spelled out. This is where the full label lives now that the rows carry icons. */
.sthead{display:flex;align-items:center;gap:.7rem;margin:0 0 .85rem}
.sthead .smark{width:38px;height:38px;flex:0 0 38px}
.sthead .smark svg{width:21px;height:21px}
.sthead-t{font-size:1.05rem;font-weight:650;letter-spacing:-.01em;color:var(--ink)}
.sthead-n{font-family:var(--mono);font-size:.7rem;letter-spacing:.04em;color:var(--ink-4)}
@media (max-width:640px){
  .smark{width:28px;height:28px;flex:0 0 28px}
  .smark svg{width:16px;height:16px}
  .cust td.stat{width:1%}
}
.ct-links{display:flex;flex-direction:column;gap:.4rem;margin-top:1rem;padding-top:.9rem;border-top:1px solid var(--line-2)}
/* Where a fact came from. Quiet: it is provenance, not content. */
.ct-src{margin-top:.9rem;padding-top:.7rem;border-top:1px solid var(--line-2);font-family:var(--mono);font-size:.68rem;letter-spacing:.02em;color:var(--ink-4)}
.ct-link{display:flex;align-items:center;gap:.5rem;padding:.45rem .6rem;border:1px solid var(--line);border-radius:9px;
  text-decoration:none;color:var(--ink);font-size:.85rem;font-weight:600;transition:border-color .12s ease}
.ct-link:hover{border-color:var(--oak)}
.ct-link .ic{width:14px;height:14px;color:var(--oak);flex:none}
.ct-link-u{margin-left:auto;font-family:'IBM Plex Mono',monospace;font-size:.7rem;color:var(--faint);font-weight:400;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:12rem}
a.person{text-decoration:none;color:inherit;transition:border-color .12s ease,background .12s ease}
a.person:hover{border-color:var(--oak);background:var(--paper)}

/* ---------- contact financials: what we still owe this vendor ---------- */
.fin-lede{color:var(--muted);font-size:.9rem;margin:.2rem 0 .8rem;max-width:60ch}
.fin-search{display:flex;gap:.5rem;flex-wrap:wrap;margin-bottom:.9rem}
.fin-search input{flex:1;min-width:14rem;font:inherit;font-size:.9rem;padding:.5rem .7rem;border:1px solid var(--line);border-radius:9px;background:var(--surface);color:var(--ink)}
.fin-hits{display:flex;flex-direction:column;gap:.4rem}
.fin-hit{display:flex;align-items:center;gap:.7rem;padding:.5rem .7rem;border:1px solid var(--line);border-radius:9px;background:var(--surface)}
.fin-hit-n{font-weight:600;font-size:.9rem}
.fin-hit-b{font-size:.78rem;color:var(--warn)}
.fin-hit .btn{margin-left:auto}
.fin-head{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;flex-wrap:wrap;
  padding-bottom:.9rem;margin-bottom:.9rem;border-bottom:1px solid var(--line-2)}
.fin-vendor{display:flex;align-items:center;gap:.4rem;font-weight:700;font-size:.98rem}
.fin-vendor .ic{width:14px;height:14px;color:var(--oak)}
.fin-sub{font-family:'IBM Plex Mono',monospace;font-size:.6rem;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-top:.2rem}
.fin-total{text-align:right;line-height:1.15}
.fin-total-n{display:block;font-size:1.5rem;font-weight:800;font-variant-numeric:tabular-nums}
.fin-total.owed .fin-total-n{color:var(--warn)}
.fin-total.clear .fin-total-n{font-size:1rem;color:var(--ok)}
.fin-total-l{font-size:.72rem;color:var(--muted)}
.fin-bills{display:flex;flex-direction:column}
.fin-bill{display:grid;grid-template-columns:1fr 6.5rem 9rem auto;align-items:center;gap:.7rem;
  padding:.55rem .1rem;border-bottom:1px solid var(--line-2);font-size:.86rem}
.fin-bill:last-child{border-bottom:0}
.fin-bill-no{font-weight:600}
.fin-bill-d,.fin-bill-due{font-family:'IBM Plex Mono',monospace;font-size:.72rem;color:var(--faint)}
.fin-bill-due.late{color:var(--lost);font-weight:600}
.fin-bill.late .fin-bill-no{color:var(--lost)}
.fin-bill-amt{text-align:right;font-weight:700;font-variant-numeric:tabular-nums}
.fin-bill-of{font-weight:400;font-size:.72rem;color:var(--faint)}
.fin-unlink{margin-top:1rem}
@media (max-width:640px){.fin-bill{grid-template-columns:1fr auto;gap:.2rem .6rem}.fin-bill-d,.fin-bill-due{grid-column:1}}

/* ---------- sortable column headings ----------
   Only the columns that really sort are links, so nothing looks clickable that is not. The arrow
   appears on the active one rather than sitting grayed out on all six. */
.cust th.th-sort{padding:0}
.cust th.th-sort a{display:flex;align-items:center;gap:.3rem;padding:.55rem .7rem;color:inherit;
  text-decoration:none;transition:color .12s ease}
.cust th.th-sort a:hover{color:var(--ink)}
.cust th.th-sort.on a{color:var(--oak)}
.th-a{font-size:.7rem;line-height:1;opacity:.9}
.cust th.th-sort a:focus-visible{outline:2px solid var(--oak);outline-offset:-2px;border-radius:4px}

/* The track sits with the filter buttons, not floating between them and the count.
   The toolbar is space-between with three children, so the middle one drifted every time the count
   changed width - "147 active jobs" and "2 jobs" are very different lengths, and the dots moved under
   the cursor between clicks. Pushing the track right anchors it against the buttons, so it stays
   exactly where you last clicked no matter what the count says. */
.toolbar .stk{margin-left:auto;margin-right:0}
@media (max-width:640px){ .toolbar .stk{margin-left:0} }

/* ---------- sidebar notifications: two lines, then stop ----------
   These were truncated at a character count in PHP and then wrapped by CSS, so a message lost its
   ending AND still took two lines. The ending is the part that matters - which customer, which job -
   so the cut is gone and the clamp does the work: it breaks on words, keeps two lines of room, and
   only shows an ellipsis when the text really does run past that. */
.pn-row.notif{align-items:flex-start}
.pn-row.notif .pn-row-t{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;line-height:1.35;font-weight:400}

/* ---- Contact top box: the job header, wearing a contact ------------------------------------
   Jon, 2026-07-29: the map, the numbers and the email belong under the name in the top box, and
   the whole ecosystem has to feel like one tool page to page. So these reuse the job classes
   (.prof-cover, .prof-id, .prof-loc, .prof-actions) and only add what a contact has that a job
   does not: a label on each line, because a person has two numbers and a job has one. */
.ct-cover .prof-main{align-items:flex-start;gap:1.4rem}
.ct-cover .prof-loc{align-items:center}
.prof-tag{font-family:var(--mono);font-size:.62rem;letter-spacing:.06em;text-transform:uppercase;
  color:rgba(255,255,255,.5);border:1px solid rgba(255,255,255,.16);border-radius:3px;
  padding:.08rem .3rem;white-space:nowrap}
.prof-loc-plain{color:rgba(255,255,255,.72);gap:.45rem}
.ct-cover-map{flex:0 0 clamp(180px,22vw,260px);display:flex;flex-direction:column;gap:.45rem}
.ct-cover-map .ct-map{width:100%;height:118px;margin:0}
.ct-cover-map .ct-place-acts{gap:.3rem}
.ct-cover-map .ct-chip{font-size:.66rem;padding:.2rem .45rem}
@media (max-width:900px){.ct-cover-map{flex-basis:100%;order:3}.ct-cover-map .ct-map{height:150px}}

/* The bolt, redrawn. One stroke, six points, nothing hanging off it. At rest it is a quiet
   outline; on press the charge runs up the blade and the ring goes out with it. */
.spd .ic{overflow:visible}

.spd.on .ic{filter:drop-shadow(0 0 6px rgba(240,180,41,.55))}
.spd.zap .ic{animation:spdCharge .5s ease-out}
@keyframes spdCharge{
  0%{opacity:.32;filter:none}
  30%{opacity:1;filter:drop-shadow(0 0 10px rgba(255,214,102,.95)) brightness(1.5)}
  100%{opacity:1;filter:drop-shadow(0 0 5px rgba(240,180,41,.5))}
}
.prof-loc .spd{padding:.15rem}
.prof-loc .spd .ic{width:19px;height:19px}
@media (prefers-reduced-motion:reduce){
  .spd.zap .ic,.spd.zap .spd-ic,.spd.zap .spd-ring{animation:none}
}

/* ---- Contact top box, two columns ---------------------------------------------------------
   Jon, 2026-07-29: identity and actions on the left, place on the right. The avatar leads and the
   facts sit beside it, which is the job page's arrangement. */
.ct-main{display:grid;grid-template-columns:minmax(0,1fr) clamp(200px,26%,300px);
  gap:1.6rem;align-items:start}
.ct-col-l{display:flex;flex-direction:column;gap:1rem;min-width:0}
.ct-col-r{min-width:0}
.ct-main .prof-actions{margin:0;grid-column:1 / -1;align-self:end}
.ct-cover .prof-id{gap:1.1rem;align-items:flex-start}
/* Bigger, to lead the column the way a job's does. */
.ct-cover .prof-id .av.xl{width:96px;height:96px;font-size:1.9rem;flex:0 0 96px}
.ct-cover .prof-id > div{min-width:0;flex:1 1 auto}
.ct-cover-map .ct-map{height:150px}
@media (max-width:900px){
  .ct-main{grid-template-columns:minmax(0,1fr);gap:1.1rem}
  .ct-cover .prof-id .av.xl{width:72px;height:72px;font-size:1.5rem;flex:0 0 72px}
}

/* ---- Product omnisearch on a job -----------------------------------------------------------
   Nobody knows a style number by heart. Type a fragment of anything and click the one you mean. */
.jps{margin-top:1rem;position:relative}
.jps-bar{display:flex;align-items:center;gap:.5rem;border:1px solid var(--line);border-radius:8px;
  background:var(--card);padding:.15rem .6rem;transition:border-color .15s ease,box-shadow .15s ease}
.jps-bar:focus-within{border-color:var(--oak);box-shadow:0 0 0 3px rgba(138,90,43,.12)}
.jps-bar .ic{width:17px;height:17px;color:var(--oak-dim);flex:0 0 auto}
.jps-bar input{flex:1 1 auto;min-width:0;border:0;background:none;padding:.6rem 0;font-size:.9rem;color:inherit}
.jps-bar input:focus{outline:none}
.jps-bar select{border:0;background:none;font-size:.76rem;color:var(--oak-dim);padding:.3rem;
  max-width:9.5rem;cursor:pointer}
.jps-results{position:absolute;z-index:80;left:0;right:0;top:calc(100% + .3rem);max-height:23rem;
  overflow-y:auto;background:var(--card);border:1px solid var(--line);border-radius:8px;
  box-shadow:0 12px 34px rgba(40,26,14,.16)}
.jps-r{display:flex;align-items:center;gap:.7rem;width:100%;text-align:left;background:none;
  border:0;border-bottom:1px solid var(--line-soft,rgba(0,0,0,.05));padding:.5rem .65rem;cursor:pointer;
  transition:background .12s ease}
.jps-r:last-child{border-bottom:0}
.jps-r:hover,.jps-r:focus-visible{background:rgba(138,90,43,.07);outline:none}
.jps-r:disabled{opacity:.5;cursor:default}
.jps-r img,.jps-noimg{width:44px;height:44px;flex:0 0 44px;border-radius:5px;object-fit:cover;
  background:rgba(138,90,43,.1)}
.jps-t{display:flex;flex-direction:column;gap:.05rem;min-width:0}
.jps-c{font-weight:600;font-size:.85rem;line-height:1.25}
.jps-s{font-size:.78rem;color:var(--ink-2,#5b5147);line-height:1.25}
.jps-b{font-family:var(--mono);font-size:.66rem;letter-spacing:.03em;color:var(--oak-dim);
  text-transform:uppercase}
.jps-c b,.jps-s b{background:rgba(232,163,23,.28);border-radius:2px;font-weight:700}
.jps-none{padding:.8rem .7rem;font-size:.82rem;color:var(--oak-dim)}
.jps-note{font-size:.78rem;color:var(--oak-dim);margin-top:.35rem;min-height:1rem}
.jps-note.err{color:#b3261e}

/* ---- Sample board ---------------------------------------------------------------------------
   One page, two audiences: staff get the board, everybody else gets the floor. */
.sm-swatch{width:96px;height:96px;flex:0 0 96px;border-radius:8px;object-fit:cover;
  box-shadow:0 2px 10px rgba(0,0,0,.22)}
.sm-swatch-none{display:block;background:rgba(255,255,255,.14)}
.sm-state{display:inline-flex;align-items:center;gap:.35rem;margin-top:.5rem;font-family:var(--mono);
  font-size:.7rem;letter-spacing:.05em;text-transform:uppercase;padding:.2rem .5rem;border-radius:3px}
.sm-state::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor}
.sm-state.in{color:#7fd1a0;background:rgba(127,209,160,.12)}
.sm-state.out{color:#e8c17a;background:rgba(232,193,122,.12)}
.sm-state.late{color:#ef9a91;background:rgba(239,154,145,.14)}
.sm-acts{margin-top:.8rem}
.sm-out{display:flex;flex-direction:column;gap:.5rem;position:relative;margin-top:.6rem}
.sm-out > input[type=text]{width:100%;border:1px solid var(--line);border-radius:8px;padding:.6rem .7rem;
  font-size:.9rem;background:var(--card);color:inherit}
.sm-out > input[type=text]:focus{outline:none;border-color:var(--oak);box-shadow:0 0 0 3px rgba(138,90,43,.12)}
.sm-out .jps-results{top:2.9rem}
.sm-due{font-size:.8rem;color:var(--oak-dim);display:flex;align-items:center;gap:.45rem}
.sm-due input{border:1px solid var(--line);border-radius:6px;padding:.3rem .45rem;font-size:.8rem;
  background:var(--card);color:inherit}
.val.late{color:#b3261e;font-weight:600}
.sm-links{margin-top:.7rem}
.sm-ask{margin-top:.8rem}
.sm-hist{display:flex;flex-direction:column;gap:.35rem}
.sm-ev{display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem;font-size:.82rem;
  padding:.35rem 0;border-bottom:1px solid var(--line-soft,rgba(0,0,0,.05))}
.sm-ev:last-child{border-bottom:0}
.sm-ev-a{font-family:var(--mono);font-size:.66rem;letter-spacing:.05em;text-transform:uppercase;
  padding:.1rem .35rem;border-radius:3px;background:rgba(138,90,43,.1);color:var(--oak-dim)}
.sm-ev-a.sm-out{background:rgba(232,163,23,.16);color:#8a6212}
.sm-ev-a.sm-in{background:rgba(60,150,100,.14);color:#2f6f4c}
.sm-ev-w{color:var(--oak-dim);font-size:.78rem}
.sm-ev-n{color:var(--ink-2,#5b5147);font-size:.78rem}
.sm-scans{margin-top:.6rem;font-size:.76rem;color:var(--oak-dim)}

/* The sticker. Small print affordance in the header rather than a button competing with the code. */
.sm-qr-card .card-h{display:flex;align-items:center;justify-content:space-between;gap:.5rem}
.sm-print{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;
  border-radius:4px;color:var(--oak-dim);opacity:.65;transition:opacity .15s ease,background .15s ease}
.sm-print .ic{width:14px;height:14px}
.sm-print:hover{opacity:1;background:rgba(138,90,43,.1);color:var(--oak)}
.sm-qr{display:block;width:100%;max-width:200px;margin:.2rem auto .5rem;height:auto}
.sm-qr-code{font-family:var(--mono);font-size:.68rem;text-align:center;color:var(--oak-dim);
  word-break:break-all}
.sm-qr-note{font-size:.76rem;color:var(--oak-dim);margin-top:.6rem}

/* ---- Product omnisearch: picking several before committing ---------------------------------- */
.jps-r.on{background:rgba(138,90,43,.13)}
.jps-r.on::after{content:"";position:absolute;right:.7rem;width:16px;height:16px;border-radius:50%;
  background:var(--oak);box-shadow:inset 0 0 0 2px #fff,inset 0 0 0 3px var(--oak)}
.jps-r{position:relative}
.jps-tray{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-top:.55rem;
  padding:.5rem .55rem;border:1px solid var(--line);border-radius:8px;background:rgba(138,90,43,.05)}
.jps-picks{display:flex;flex-wrap:wrap;gap:.35rem;flex:1 1 auto;min-width:0}
.jps-pick{display:inline-flex;align-items:center;gap:.35rem;background:var(--card);
  border:1px solid var(--line);border-radius:999px;padding:.15rem .3rem .15rem .15rem;font-size:.78rem}
.jps-pick img{width:20px;height:20px;border-radius:50%;object-fit:cover}
.jps-pick > span{padding-left:.15rem}
.jps-x{border:0;background:none;cursor:pointer;color:var(--oak-dim);font-size:1rem;line-height:1;
  padding:0 .15rem;border-radius:50%}
.jps-x:hover{color:#b3261e}
.jps-go{flex:0 0 auto;border:0;border-radius:6px;background:var(--oak);color:#fff;cursor:pointer;
  padding:.45rem .85rem;font-size:.82rem;font-weight:600}
.jps-go:hover{filter:brightness(1.08)}
.jps-go:disabled{opacity:.55;cursor:default}

/* ---- Products shown on a feed entry --------------------------------------------------------- */
.tl-prods{display:flex;flex-wrap:wrap;gap:.45rem;margin-top:.5rem}
.tl-prod{display:inline-flex;align-items:center;gap:.5rem;border:1px solid var(--line);
  border-radius:8px;padding:.3rem .55rem .3rem .3rem;background:var(--card);
  text-decoration:none;color:inherit;transition:border-color .15s ease,transform .15s ease}
.tl-prod:hover{border-color:var(--oak);transform:translateY(-1px)}
.tl-prod img,.tl-prod-noimg{width:38px;height:38px;flex:0 0 38px;border-radius:5px;object-fit:cover;
  background:rgba(138,90,43,.1)}
.tl-prod-t{display:flex;flex-direction:column;min-width:0}
.tl-prod-n{font-size:.83rem;font-weight:600;line-height:1.25}
.tl-prod-s{font-size:.72rem;color:var(--oak-dim);line-height:1.25}

/* The transcript accordion: folded by default, and honest about how much it is hiding. */
.tl-tr-n{font-family:var(--mono);font-size:.66rem;color:var(--oak-dim);margin-left:.35rem}

/* A company-wide call showing on a rep's feed says so, rather than reading as theirs. */
.tl-via{font-family:var(--mono);font-size:.62rem;letter-spacing:.05em;text-transform:uppercase;
  color:var(--oak-dim);border:1px solid var(--line);border-radius:3px;padding:.05rem .3rem;white-space:nowrap}


/* A chip sitting on the brown cover needs the cover's colors, not the card's. The default is dark
   ink on a pale surface, which on brown was very nearly unreadable. */
.ct-chip.on-cover{color:#f3e7d8;background:rgba(255,255,255,.10);border-color:rgba(255,255,255,.24)}
.ct-chip.on-cover:hover{background:rgba(255,255,255,.18);border-color:rgba(255,255,255,.42);color:#fff}
.ct-cover-map .ct-chip{font-size:.7rem;padding:.28rem .55rem}

/* Name level with the avatar, reading straight off its right edge. */
.ct-cover .prof-id{align-items:flex-start}
.ct-cover .prof-id > div{padding-top:.1rem}
.ct-cover .prof-id h2{margin:0;line-height:1.15}

/* ---- A contact's photo, and changing it ----------------------------------------------------- */
.ct-av{position:relative;display:inline-block;flex:0 0 auto;line-height:0}
.ct-av-edit{position:absolute;right:-2px;bottom:-2px;width:28px;height:28px;border-radius:50%;
  border:2px solid var(--walnut,#3b2a1a);background:rgba(20,14,8,.82);color:#f3e7d8;cursor:pointer;
  display:flex;align-items:center;justify-content:center;padding:0;opacity:0;transition:opacity .15s ease,background .15s ease}
.ct-av-edit .ic{width:14px;height:14px}
.ct-av:hover .ct-av-edit,.ct-av-edit:focus-visible{opacity:1}
.ct-av-edit:hover{background:rgba(20,14,8,.95)}
@media (hover:none){.ct-av-edit{opacity:1}}
.ct-av-card{max-width:26rem}
.ct-av-acts{display:flex;flex-wrap:wrap;gap:.5rem;margin:.2rem 0 .4rem}


/* No map, no second column: the identity block and its actions take the whole card. */

/* The action row is one row. It earns the width it needs before anything is allowed to wrap, and
   the rule above it runs the full width of the column rather than stopping short of the card. */
.ct-cover .prof-actions{flex-wrap:wrap;width:100%;padding-top:.9rem;
  border-top:1px solid rgba(255,255,255,.14);margin-top:.2rem}
@media (min-width:820px){.ct-cover .prof-actions{flex-wrap:nowrap}}


/* Avatar left, everything about them to its right. The facts sit in two columns when there is room,
   so a contact takes a few lines rather than a screenful. */
.ct-cover .prof-id{display:flex;flex-wrap:nowrap;align-items:flex-start;gap:1.1rem}
.ct-cover .prof-id > div{flex:1 1 auto;min-width:0}
.ct-facts{display:flex;flex-wrap:wrap;column-gap:1.6rem;row-gap:.1rem;margin-top:.45rem}
.ct-facts .prof-loc{margin:0}
@media (max-width:620px){.ct-cover .prof-id{flex-wrap:wrap}}


/* ---- Contact profile, tidied ----------------------------------------------------------------
   The cover holds the person and what you do about them, and nothing else. The building moved down
   beside the cards, which is where the job page has always kept it. */
.ct-cover .prof-actions{margin-top:1rem;padding-top:.9rem;border-top:1px solid rgba(255,255,255,.14);
  flex-wrap:wrap;width:100%}
@media (min-width:760px){.ct-cover .prof-actions{flex-wrap:nowrap}}

/* Street view, then one plain way to get there. */
.ct-directions{display:inline-flex;align-items:center;gap:.4rem;margin-top:.55rem;
  font-size:.8rem;font-weight:600;color:var(--oak);text-decoration:none;
  border:1px solid var(--line);border-radius:7px;padding:.4rem .7rem;background:var(--card);
  transition:border-color .13s ease,background .13s ease}
.ct-directions .ic{width:15px;height:15px}
.ct-directions:hover{border-color:var(--oak);background:var(--chalk-soft,rgba(138,90,43,.06))}

/* A feed shows the recent past. The rest is one click away, not four thousand pixels of scrolling. */
.tl-later{display:none}
.tl-more{display:block;width:100%;margin:.6rem 0 .2rem;padding:.6rem;border:1px dashed var(--line);
  border-radius:8px;background:none;cursor:pointer;font-size:.8rem;font-weight:600;color:var(--oak);
  transition:border-color .13s ease,background .13s ease}
.tl-more:hover{border-color:var(--oak);background:rgba(138,90,43,.05)}

/* The speed dial mark is a filled silhouette, so it takes color rather than stroke. */
.spd svg{overflow:visible}

/* ---- Link previews in the feed --------------------------------------------------------------
   A link shown as the thing it points at, so you know whether it is worth opening before you do. */
.lp-wrap{display:flex;flex-direction:column;gap:.5rem;margin-top:.6rem}
.lp{display:flex;gap:.8rem;align-items:stretch;text-decoration:none;color:inherit;
  border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--card);
  transition:border-color .14s ease,transform .14s ease}
.lp:hover{border-color:var(--oak);transform:translateY(-1px)}
.lp-img{flex:0 0 clamp(96px,26%,168px);background:rgba(138,90,43,.08);overflow:hidden}
.lp-img img{width:100%;height:100%;object-fit:cover;display:block;min-height:88px}
.lp-t{display:flex;flex-direction:column;gap:.16rem;padding:.6rem .75rem;min-width:0;justify-content:center}
.lp-site{font-family:var(--mono);font-size:.62rem;letter-spacing:.06em;text-transform:uppercase;color:var(--oak-dim)}
.lp-h{font-weight:650;font-size:.88rem;line-height:1.3;color:var(--ink)}
.lp-d{font-size:.78rem;line-height:1.4;color:var(--ink-2,#5b5147);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
@media (max-width:520px){.lp{flex-direction:column}.lp-img{flex-basis:auto}.lp-img img{min-height:140px}}

/* Asked us for, on its own rather than as the tail of a card of repeated facts. */
.jd-asked .jd-chips{display:flex;flex-wrap:wrap;gap:.35rem}


/* ---- Contact header: person left, building right, the way a job reads --------------------- */
.ct-cover .ct-main{display:grid;grid-template-columns:minmax(0,1fr) clamp(230px,30%,340px);
  gap:1.4rem;align-items:start}
.ct-cover .ct-col-l{min-width:0}
.ct-cover .prof-actions{grid-column:1 / -1}
.ct-site{min-width:0}
.ct-site .prof-site{margin:0}
@media (max-width:820px){
  .ct-cover .ct-main{grid-template-columns:minmax(0,1fr)}
  .ct-site{order:3}
}


/* ---- Contact header, laid out as a job header ------------------------------------------------
   Jon: the two pages have to feel like one tool. Same grid, same order, same sizes - identity and
   its facts on the left, the building on the right, actions across the bottom. */
.ct-cover .ct-main{display:grid;grid-template-columns:minmax(0,1fr) clamp(230px,28%,300px);
  gap:1.5rem;align-items:start}
/* The site column was overrunning the cover: its contents are sized for the job page's wider
   track, so they are held to this one. */
.ct-site,.ct-site *{max-width:100%}
.ct-site .site-photo,.ct-site .site-photo img{width:100%;height:auto}
/* A phone number is one thing and must never break across lines. */
.ct-cover .prof-loc{flex-wrap:nowrap}
.ct-cover .prof-loc .linkish{white-space:nowrap}
.ct-cover .ct-col-l{min-width:0;display:block}
.ct-cover .prof-actions{grid-column:1 / -1;margin-top:1.1rem;padding-top:.95rem;
  border-top:1px solid rgba(255,255,255,.14);flex-wrap:wrap}
@media (min-width:900px){.ct-cover .prof-actions{flex-wrap:nowrap}}
.ct-site{min-width:0}
.ct-site .prof-site{margin:0}

/* The facts block, sized as the job's is rather than as a card. */
.ct-pf{margin-top:1rem}
/* On a job, pf-meta is metadata UNDER the fact - the chips and the provenance. On a contact it is
   the LABEL, so it reads above the value like every other label in the app, and it has to be light
   enough to read on walnut: half-white was 3.2:1 against this header. */
.ct-pf .pf-meta{font-family:var(--mono);font-size:.62rem;font-weight:600;letter-spacing:.09em;
  text-transform:uppercase;color:rgba(255,255,255,.72);margin:0 0 .18rem}
.ct-pf .pf-rank{font-family:var(--mono);font-size:.66rem;color:rgba(255,255,255,.42);
  min-width:1rem;text-align:right;padding-top:.1rem}
.ct-pf .pf-fact{color:#f4ead8;font-size:.88rem;line-height:1.35}

@media (max-width:900px){
  .ct-cover .ct-main{grid-template-columns:minmax(0,1fr)}
  .ct-site{order:3}
}

/* No address, no second track. Otherwise a contact without a building reserves a third of the
   header for nothing, which is what squeezed the action row before. */
.ct-cover .ct-main:not(:has(.ct-site)){grid-template-columns:minmax(0,1fr)}

/* The one lookup you actually sign into, marked as such among the searches. */
.ct-chip.primary{color:var(--oak);border-color:var(--oak);background:rgba(138,90,43,.07);font-weight:650}
.ct-chip.primary:hover{background:var(--oak);color:#fff;border-color:var(--oak)}

/* Where a fact came from, sitting quietly under the facts it explains. */
.pf-src{margin-top:.5rem;font-size:.7rem;color:rgba(255,255,255,.42);font-style:italic}


/* Six buttons is the most any profile carries, and they belong on one line. The labels shorten
   before the row breaks - a wrapped action row reads as two groups of actions rather than one. */
@media (min-width:1100px){
  .prof-cover .prof-actions{flex-wrap:nowrap}
  .prof-cover .prof-actions > *{flex:0 1 auto;min-width:0}
  .prof-cover .prof-actions .pa{white-space:nowrap}
}

/* ---- Our brand marks, in Settings ------------------------------------------------------------ */
.bm-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:1rem;margin-top:.8rem}
.bm-slot{border:1px solid var(--line);border-radius:10px;padding:.9rem;background:var(--card)}
.bm-frame{display:flex;align-items:center;justify-content:center;border-radius:8px;
  background:repeating-conic-gradient(rgba(0,0,0,.045) 0% 25%, transparent 0% 50%) 50%/16px 16px;
  border:1px dashed var(--line);margin-bottom:.65rem;padding:.6rem}
.bm-frame.horizontal{height:88px}
.bm-frame.square{height:132px}
.bm-frame img{max-width:100%;max-height:100%;object-fit:contain}
.bm-frame.empty{color:var(--oak-dim);font-size:.78rem}
.bm-meta{display:flex;flex-direction:column;gap:.15rem}
.bm-meta strong{font-size:.86rem}
.bm-meta em{font-style:normal;font-size:.76rem;color:var(--oak-dim);line-height:1.4}
.bm-dim{font-family:var(--mono);font-size:.68rem;color:var(--oak-dim);margin-top:.15rem}
.bm-acts{display:flex;gap:.4rem;margin-top:.7rem}
.bm-suppliers{display:flex;align-items:center;flex-wrap:wrap;gap:.9rem;margin-top:1.1rem;
  padding-top:.9rem;border-top:1px solid var(--line)}
.bm-sup-h{font-family:var(--mono);font-size:.64rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--oak-dim);width:100%}
.bm-sup{display:inline-flex;align-items:center;height:34px}
.bm-sup img{max-height:34px;max-width:130px;object-fit:contain}

/* ------------------------------------------------ a product, opened on the job
   The dialog holds the real product page with its shell taken off, so it is sized for reading a spec
   sheet rather than for a confirmation: wide, tall, and scrolled inside itself. */
.jp{cursor:pointer;transition:border-color .12s,transform .1s}
.jp:hover{border-color:var(--oak);transform:translateY(-1px)}
.jp:focus-visible{outline:2px solid var(--chalk-2);outline-offset:2px}
.jp-sku{font-size:.68rem;letter-spacing:.04em;color:var(--faint);margin-top:.3rem}
.jp-price{display:flex;flex-wrap:wrap;gap:.1rem .7rem;margin-top:.35rem;font-size:.84rem;color:var(--ink)}
.jp-price b{font-weight:700}
.jp-inst{color:var(--muted)}
.jp-inst.none{color:var(--faint);font-size:.8rem}
.jpmodal{position:fixed;inset:0;z-index:1300;display:flex;align-items:center;justify-content:center;padding:2vh 2vw}
.jpmodal[hidden]{display:none}
.jpmodal-scrim{position:absolute;inset:0;background:rgba(22,18,13,.55);backdrop-filter:blur(3px)}
.jpmodal-card{position:relative;background:var(--paper);border-radius:16px;width:min(1100px,96vw);
  max-height:96vh;display:flex;flex-direction:column;overflow:hidden;box-shadow:0 30px 80px rgba(22,18,13,.35)}
.jpmodal-bar{display:flex;align-items:center;gap:1rem;padding:.7rem 1rem;background:var(--surface);
  border-bottom:1px solid var(--line);flex:none}
.jpmodal-full{font-size:.85rem;font-weight:600;color:var(--chalk);text-decoration:none}
.jpmodal-full:hover{text-decoration:underline}
.jpmodal-x{margin-left:auto;border:0;background:none;font-size:1.6rem;line-height:1;color:var(--muted);cursor:pointer}
.jpmodal-body{overflow:auto;padding:1.2rem 1.4rem 2rem;-webkit-overflow-scrolling:touch}
.jpmodal-load{padding:3rem;text-align:center;color:var(--muted)}

/* ------------------------------------------------- attachments on a draft */
.ob-files{display:flex;flex-wrap:wrap;gap:.4rem;margin:.7rem 0 0}
.ob-file{display:inline-flex;align-items:center;gap:.4rem;background:var(--paper);border:1px solid var(--line);
  border-radius:8px;padding:.3rem .5rem;font-size:.85rem}
.ob-file.auto{border-color:var(--warn);background:var(--warn-soft)}
.ob-file em{font-style:normal;font-size:.7rem;color:var(--label);font-family:'IBM Plex Mono',monospace;
  letter-spacing:.05em;text-transform:uppercase}
.ob-file .ic{width:14px;height:14px;color:var(--muted)}
.ob-file-x{border:0;background:none;color:var(--muted);font-size:1.1rem;line-height:1;cursor:pointer;padding:0 .1rem}
.ob-sugg{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem;margin-top:.7rem}
.ob-sugg-h{font:500 .68rem/1 'IBM Plex Mono',monospace;letter-spacing:.1em;text-transform:uppercase;color:var(--label)}
.ob-up{display:flex;gap:.5rem;align-items:center;margin-top:.7rem;font-size:.85rem}
.ob-attest{display:inline-flex;align-items:center;gap:.4rem;font-size:.85rem;margin-right:.7rem;color:var(--ink)}

/* ---------------------------------------------------------- correcting a record
   Folded away, because correcting a typo is not what anybody opened the page to do - but one click
   from the name, because a typo is noticed while looking at the name. */
.ed{border:1px solid var(--line);border-radius:12px;background:var(--surface);margin-bottom:1rem}
.ed>summary{cursor:pointer;padding:.7rem 1rem;font-size:.88rem;font-weight:600;color:var(--muted);
  display:flex;align-items:center;gap:.5rem;list-style:none}
.ed>summary::-webkit-details-marker{display:none}
.ed>summary:hover{color:var(--ink)}
.ed>summary .ic{width:15px;height:15px}
.ed[open]>summary{border-bottom:1px solid var(--line-2);color:var(--ink)}
.ed-form{display:grid;gap:.8rem;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));padding:1rem}
.ed-form label{display:flex;flex-direction:column;gap:.25rem;font:600 .64rem/1.6 'IBM Plex Mono',monospace;
  letter-spacing:.1em;text-transform:uppercase;color:var(--label)}
.ed-form input{font:inherit;font-size:.92rem;color:var(--ink);padding:.5rem .6rem;
  border:1px solid var(--line);border-radius:8px;background:var(--surface)}
.ed-form .wide{grid-column:1/-1}
.ed-save{grid-column:1/-1;display:flex;align-items:center;gap:.9rem;flex-wrap:wrap}
.ed-save button{background:#3f2a1d;color:#fff;border:0;border-radius:8px;padding:.55rem 1.1rem;
  font-weight:600;font-size:.88rem;cursor:pointer}
.ed-save span{font-size:.8rem;color:var(--faint)}

/* ------------------------------------------- a product card, in a feed
   It used to be a link that took you off the customer's page, which is almost never the intent when
   you click a floor on their feed. It opens the product in place now; the small link under it is the
   deliberate way out. */
.tl-prod{cursor:pointer;transition:border-color .12s,transform .1s}
.tl-prod:hover{border-color:var(--oak);transform:translateY(-1px)}
.tl-prod:focus-visible{outline:2px solid var(--chalk-2);outline-offset:2px}
.tl-prod-sku{display:block;font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.04em;
  color:var(--faint);margin-top:.2rem}
.tl-prod-p{display:block;font-size:.8rem;color:var(--ink);margin-top:.2rem}
.tl-prod-p b{font-weight:700}
.tl-prod-ins{color:var(--muted)}
.tl-prod-ins.none{color:var(--faint)}
.tl-prod-full{display:inline-block;margin-top:.3rem;font-size:.72rem;font-weight:600;color:var(--chalk);
  text-decoration:none}
.tl-prod-full:hover{text-decoration:underline}

/* ------------------------------------------ whispers, beside the facts they would become
   Facts and whispers are the same question a beat apart: what we know, and what we think we know and
   want a yes on. They were on two pages, so the second one lived somewhere you had to remember. */
.jw{margin-top:1.6rem;border-top:1px solid var(--line);padding-top:1.1rem}
.jw-h{display:flex;align-items:center;gap:.5rem;font-family:'IBM Plex Mono',monospace;font-size:.7rem;
  font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--label)}
.jw-h::before{content:'';width:4px;height:1.1em;border-radius:2px;background:var(--warn)}
.jw-n{background:var(--warn-soft);color:#7a5410;border-radius:999px;padding:.05rem .45rem;
  font-size:.7rem;letter-spacing:0}
.jw-lede{color:var(--muted);font-size:.88rem;margin:.5rem 0 .9rem;max-width:72ch;line-height:1.5}
.jw-row{display:flex;gap:1rem;align-items:flex-start;flex-wrap:wrap;border:1px solid var(--line);
  border-radius:10px;padding:.8rem .95rem;margin-bottom:.6rem;background:var(--surface)}
.jw-b{flex:1 1 22rem;min-width:0}
.jw-kind{display:inline-block;font-family:'IBM Plex Mono',monospace;font-size:.62rem;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--label);background:var(--line-2);
  border-radius:999px;padding:.14rem .45rem;margin-right:.45rem}
.jw-t{font-weight:700;font-size:.96rem}
.jw-d{color:var(--muted);font-size:.9rem;line-height:1.5;margin-top:.3rem}
.jw-src{display:inline-block;margin-top:.35rem;font-size:.78rem;font-weight:600;color:var(--chalk);text-decoration:none}
.jw-src:hover{text-decoration:underline}
.jw-act{display:flex;gap:.4rem;align-items:center;margin-left:auto}
.jw-btn{border:1px solid var(--line);background:var(--surface);border-radius:8px;padding:.45rem .9rem;
  font:inherit;font-size:.85rem;font-weight:600;cursor:pointer;display:inline-flex;align-items:center;gap:.35rem}
.jw-btn.go{background:#3f2a1d;color:#fff;border-color:#3f2a1d}
.jw-btn .ic{width:14px;height:14px}

/* The sibling color strip on a color page: one row you can scroll, the current color marked. */
.cl-siblings{display:flex;gap:.5rem;overflow-x:auto;padding:.2rem .1rem .6rem;margin:.2rem 0 .8rem;scrollbar-width:thin}
.cl-sib{flex:none;width:72px;text-align:center;text-decoration:none;color:var(--muted);font-size:.68rem;line-height:1.2}
.cl-sib img,.cl-sib-no{display:block;width:72px;height:52px;object-fit:cover;object-position:center bottom;border-radius:7px;background:var(--line-2);border:2px solid transparent}
.cl-sib.on img,.cl-sib.on .cl-sib-no{border-color:var(--chalk)}
.cl-sib.on{color:var(--chalk);font-weight:600}
.cl-sib.dropped{opacity:.45}
.cl-sib span{display:block;margin-top:.25rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---------- drafts: the recipient is a chip you can change ----------
   A draft CutPile could not place shows itself instead of hiding behind the customer's number. */
.draft-who{display:inline-flex;align-items:center;gap:.4rem;border:1px solid var(--line);background:var(--surface);
  border-radius:999px;padding:.15rem .6rem .15rem .55rem;font:inherit;font-size:.82rem;color:var(--ink);cursor:pointer}
.draft-who:hover{border-color:var(--oak)}
.draft-where{font-family:'IBM Plex Mono',monospace;font-size:.7rem;color:var(--faint)}
.draft-nowhere{font-family:'IBM Plex Mono',monospace;font-size:.68rem;letter-spacing:.06em;text-transform:uppercase;color:var(--lost)}
.draft-needs{border-color:var(--lost);background:var(--lost-soft,#fbecec)}
.draft-needs .draft-status{color:var(--lost);font-weight:600}
.draft-about{font-size:.78rem;color:var(--chalk);font-weight:600;text-decoration:none}
.draft-about:hover{text-decoration:underline}
.draft-pick{margin:.5rem 0;border:1px solid var(--line);border-radius:9px;background:var(--surface);padding:.5rem}
.draft-pick-q{width:100%;border:1px solid var(--line);border-radius:7px;padding:.45rem .6rem;font:inherit;font-size:.88rem}
.draft-pick-list{display:flex;flex-direction:column;gap:.2rem;margin-top:.4rem;max-height:14rem;overflow-y:auto}
.draft-pick-row{display:grid;grid-template-columns:1fr auto;gap:.1rem .8rem;align-items:center;text-align:left;
  border:0;background:none;padding:.4rem .5rem;border-radius:7px;cursor:pointer;font:inherit}
.draft-pick-row:hover{background:var(--paper)}
.draft-pick-row b{font-size:.88rem}.draft-pick-row small{grid-column:1;font-size:.72rem;color:var(--faint)}
.draft-pick-row em{grid-column:2;grid-row:1/3;font-style:normal;font-family:'IBM Plex Mono',monospace;font-size:.72rem;color:var(--muted)}
.draft-pick-row.none em{color:var(--lost)}
.draft-pick-none{padding:.5rem;font-size:.82rem;color:var(--faint)}

/* ---------- setting a price: say what kind it is ---------- */
.pr-flash{margin:.4rem 0 .6rem;padding:.5rem .7rem;border-radius:8px;background:var(--ok-soft,#e6f2e6);color:var(--ok);font-size:.85rem;font-weight:600}
.pr-flash.err{background:var(--lost-soft,#fbecec);color:var(--lost)}
.pr-types{display:flex;gap:.35rem;flex-wrap:wrap;margin-bottom:.5rem}
.pr-type{display:inline-flex;align-items:center;border:1px solid var(--line);border-radius:999px;padding:.25rem .7rem;font-size:.8rem;cursor:pointer;background:var(--surface)}
.pr-type input{position:absolute;opacity:0;pointer-events:none}
.pr-type.on{background:var(--walnut);color:#f4ece0;border-color:var(--walnut)}
.pr-scope{display:flex;gap:.9rem;flex-wrap:wrap;font-size:.8rem;color:var(--muted);margin-bottom:.5rem}
.pr-scope label{display:inline-flex;align-items:center;gap:.3rem;cursor:pointer}
.pr-form select,.pr-form input[type=date]{font:inherit;font-size:.82rem;border:1px solid var(--line);border-radius:7px;padding:.4rem .5rem;background:var(--surface);color:var(--ink)}
.pr-form select{flex:1;min-width:0}
.pr-form input[type=text]{margin:.4rem 0 0}
.pr-quotes{margin-top:.8rem;border-top:1px solid var(--line-2);padding-top:.6rem}
.pr-quote{display:grid;grid-template-columns:auto auto 1fr auto;gap:.2rem .6rem;align-items:baseline;padding:.3rem 0;border-bottom:1px solid var(--line-2);font-size:.82rem}
.pr-quote:last-child{border-bottom:0}
.pq-t{font-family:'IBM Plex Mono',monospace;font-size:.64rem;letter-spacing:.09em;text-transform:uppercase;color:var(--label)}
.pq-s{color:var(--muted)}.pq-d{font-family:'IBM Plex Mono',monospace;font-size:.7rem;color:var(--faint);text-align:right}
.pq-n{grid-column:1/-1;color:var(--faint);font-size:.76rem}
/* before and after pairs on the job page (v1.35.0) */
.bap-grid{display:grid;gap:1rem}
.bap{border:1px solid var(--line,#e2dcd3);border-radius:14px;padding:.8rem;background:var(--card,#fff);display:grid;grid-template-columns:1fr 1fr;gap:.8rem}
.bap.featured{border-color:#2f7a3f;box-shadow:inset 3px 0 0 #2f7a3f}
.bap-half{min-width:0}
.bap-thumb{display:block;width:100%;aspect-ratio:4/3;border:0;padding:0;border-radius:10px;overflow:hidden;background:#1e1913;cursor:zoom-in}
.bap-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.bap-wait{aspect-ratio:4/3;border-radius:10px;border:1px dashed var(--line,#e2dcd3);display:flex;align-items:center;justify-content:center;color:var(--muted,#6b625a);font-size:.85rem;text-align:center;padding:1rem}
.bap-cap{font-size:.78rem;color:var(--muted,#6b625a);margin-top:.35rem}
.bap-meta{grid-column:1/-1;display:flex;gap:.4rem;flex-wrap:wrap;align-items:center;font-size:.85rem}
/* ---- key rack, rebuilt (v1.40.1): one calm row per key ---- */
.cc-tabs{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}.cc-tabs::-webkit-scrollbar{display:none}
.cc-tab{white-space:nowrap;font-size:.86rem;padding:.55rem .7rem}
.kx-group{display:flex;align-items:baseline;justify-content:space-between;font-family:'IBM Plex Mono',ui-monospace,monospace;font-size:.64rem;letter-spacing:.12em;text-transform:uppercase;color:var(--label);margin:1.2rem 0 .45rem}
.kx-group:first-of-type{margin-top:.4rem}
.kx-count{color:var(--faint);letter-spacing:.06em}
.kx-list{border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--surface)}
.kx{display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,360px);gap:.6rem 1.4rem;align-items:start;padding:.8rem 1rem;border-bottom:1px solid var(--line-2)}
.kx:last-child{border-bottom:0}
.kx-id{min-width:0}
.kx-line{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;min-height:1.6rem}
.kx-dot{width:8px;height:8px;border-radius:50%;background:var(--line);flex:none}
.s-live .kx-dot{background:#3f8a5f}.s-stored .kx-dot{background:var(--oak)}.s-fail .kx-dot{background:var(--lost)}
.kx-name{font-weight:650;font-size:.93rem;color:var(--ink)}
.s-empty .kx-name{color:var(--muted)}
.kx-state{font-size:.76rem;color:var(--faint)}.kx-state .mono{font-size:.72rem;letter-spacing:.04em;color:var(--muted)}
.s-fail .kx-state{color:var(--lost);font-weight:600}
.kx-help{font-size:.78rem;color:var(--muted);line-height:1.45;max-width:62ch;margin-top:.15rem}
.kx-help a{color:var(--oak);font-weight:600;white-space:nowrap}.kx-help a:hover{color:var(--ink)}
.kx-do{display:grid;gap:.35rem;min-width:0}
.kx-form{display:flex;gap:.4rem;align-items:flex-start}
.kx-form input,.kx-form textarea{flex:1;min-width:0;border:1px solid var(--line);border-radius:8px;padding:.5rem .65rem;font:inherit;font-size:.84rem;background:var(--paper);color:var(--ink)}
.kx-form textarea{font:12px/1.4 'IBM Plex Mono',ui-monospace,monospace;resize:vertical}
.kx-form input:focus,.kx-form textarea:focus{outline:none;border-color:var(--chalk-2);box-shadow:0 0 0 3px var(--chalk-soft)}
.kx-form .btn.sm{flex:none;min-height:0;padding:.5rem .8rem}
.kx-acts{display:flex;gap:.9rem;align-items:center;font-size:.76rem;padding-left:.15rem}
.kx-acts form{margin:0}
.kx-acts button{border:0;background:transparent;padding:0;font:inherit;font-size:.76rem;font-weight:600;color:var(--oak);cursor:pointer}
.kx-acts button:hover{text-decoration:underline;color:var(--ink)}
.kx-acts .kx-rm{color:var(--faint);font-weight:500}.kx-acts .kx-rm:hover{color:var(--lost)}
.kx-when{color:var(--faint)}
@media(max-width:960px){.kx{grid-template-columns:1fr}.kx-do{max-width:none}}
.kx-note{font-size:.76rem;padding:.35rem .6rem;border-radius:7px;background:var(--paper);color:var(--muted)}
.kx-note.ok{color:#2f6a3f;background:#eef5ee}.kx-note.err{color:var(--lost);background:#f8ecea}
/* v1.47.1: the last text result beside each person on the notification card */
.nk-last{font-size:.68rem;font-weight:600;border-radius:999px;padding:.1rem .5rem;white-space:nowrap}
.nk-last.ok{background:#e4f2e6;color:#2f7a3f}.nk-last.bad{background:#fbe6e3;color:#a8321f}
/* v1.52.1: the board. Twelve cells, a price each, chalk on walnut; nothing pretends to be wood. */
.oak-modal .oak-card{width:min(78rem,100%);max-height:min(94vh,960px);display:flex;flex-direction:column;overflow:hidden;background:#16110d;color:#f3ede4;border:1px solid rgba(243,237,228,.12);padding:0}
.oak-top{display:flex;align-items:center;gap:1rem;padding:.9rem 1.2rem;border-bottom:1px solid rgba(243,237,228,.1)}
.oak-ey{font:500 .62rem/1 'IBM Plex Mono',ui-monospace,monospace;letter-spacing:.16em;text-transform:uppercase;color:#d9a86c;margin:0 0 .2rem}
.oak-modal .cp-modal-t{color:#f3ede4;font-family:'Bricolage Grotesque',sans-serif;font-weight:800;font-size:1.25rem;letter-spacing:-.02em}
.oak-market{display:flex;gap:1rem;margin-left:auto;font-size:.8rem;color:#c7bcad}.oak-market b{color:#f3ede4;font-family:'Bricolage Grotesque',sans-serif;font-size:1rem}.oak-market .warn b{color:#f2c26b}
.oak-dist{font:inherit;font-size:.85rem;border:1px solid rgba(243,237,228,.2);border-radius:999px;background:#1f1813;color:#f3ede4;padding:.45rem .8rem;max-width:14rem}
.oak-modal .cp-modal-x{position:static;color:#f3ede4;background:transparent;border:1px solid rgba(243,237,228,.2)}
.oak-body{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(300px,.9fr);gap:1.2rem;padding:1.1rem 1.2rem 1.3rem;overflow:auto;min-height:0}
.oak-board{border:1px solid rgba(243,237,228,.16);border-radius:16px;overflow:hidden;background:#1f1813;align-self:start}
.oak-board .b-head,.oak-board .b-row{display:grid;grid-template-columns:5.4rem repeat(4,minmax(0,1fr))}
.oak-board .b-head{border-bottom:1px solid rgba(243,237,228,.16)}
.oak-board .b-head .corner{grid-row:span 2}
.oak-board .b-head .corner2{display:none}
.oak-board .b-head .sp{grid-column:span 2;padding:.7rem .9rem .3rem;font:800 1.05rem/1 'Bricolage Grotesque',sans-serif;letter-spacing:-.02em;border-left:1px solid rgba(243,237,228,.1)}
.oak-board .b-head .sp:first-of-type{border-left:0}
.oak-board .b-head .gr{padding:.2rem .9rem .6rem;font:600 .6rem/1 'IBM Plex Mono',ui-monospace,monospace;letter-spacing:.12em;text-transform:uppercase;color:#8f8375;border-left:1px solid rgba(243,237,228,.1)}
.oak-board .b-head .gr.first{border-left:0}
.oak-board .b-row{border-top:1px solid rgba(243,237,228,.1)}
.oak-board .b-w{display:flex;flex-direction:column;justify-content:center;padding:.6rem .9rem;font:800 1.1rem/1 'Bricolage Grotesque',sans-serif;letter-spacing:-.02em;color:#c7bcad;border-right:1px solid rgba(243,237,228,.1)}
.oak-board .b-w small{font:500 .58rem/1.3 'IBM Plex Mono',ui-monospace,monospace;letter-spacing:.08em;text-transform:uppercase;color:#8f8375;margin-top:.3rem}
.oak-board .bc{position:relative;display:flex;flex-direction:column;justify-content:center;gap:.22rem;min-height:5.4rem;padding:.7rem .85rem;border:0;border-left:1px solid rgba(243,237,228,.1);background:transparent;color:#f3ede4;text-align:left;cursor:pointer;font:inherit;transition:background .15s}
.oak-board .bc:first-of-type{border-left:0}
.oak-board .bc:hover,.oak-board .bc:focus-visible{background:rgba(243,237,228,.045);outline:0}
.oak-board .bc.on{background:rgba(217,168,108,.12);box-shadow:inset 0 0 0 1.5px #d9a86c}
.oak-board .bc .pr{font:800 clamp(1.25rem,1.6vw,1.65rem)/1 'Bricolage Grotesque',sans-serif;letter-spacing:-.03em;font-variant-numeric:tabular-nums;display:flex;align-items:baseline;gap:.3rem}
.oak-board .bc .pr small{font:600 .58rem/1 'IBM Plex Mono',ui-monospace,monospace;color:#8f8375;letter-spacing:.06em}
.oak-board .bc.none .pr{color:#8f8375;font-weight:600}
.oak-board .bc .src{font-size:.72rem;color:#c7bcad;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.oak-board .bc .meta{display:flex;align-items:center;gap:.4rem;font:500 .6rem/1 'IBM Plex Mono',ui-monospace,monospace;letter-spacing:.06em;color:#8f8375;flex-wrap:wrap}
.oak-board .dot,.oak-offers .dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:#8f8375;flex:none;margin-right:.3rem}.oak-board .dot.fresh,.oak-offers .dot.fresh{background:#7ed957}.oak-board .dot.aging,.oak-offers .dot.aging{background:#f2c26b}.oak-board .dot.stale,.oak-offers .dot.stale{background:#ff8a70}
.oak-board .mv{font-weight:700;margin-left:auto}.oak-board .mv.up{color:#ff8a70}.oak-board .mv.down{color:#7ed957}
.oak-side{background:#1f1813;border:1px solid rgba(243,237,228,.16);border-radius:16px;padding:1rem 1.1rem;align-self:start;min-height:12rem}
.oak-side-empty{color:#8f8375;font-size:.95rem;line-height:1.45;padding:1.6rem .4rem;text-align:center}.oak-side-empty small{font-size:.8rem}
.oak-side-h{margin:0 0 .7rem}.oak-side-h b{display:block;font:800 1.3rem/1.1 'Bricolage Grotesque',sans-serif;letter-spacing:-.02em}.oak-side-h span{font:500 .62rem/1 'IBM Plex Mono',ui-monospace,monospace;letter-spacing:.12em;text-transform:uppercase;color:#d9a86c}
.oak-offers{width:100%;border-collapse:collapse;font-size:.84rem}
.oak-offers th{text-align:left;font:600 .58rem/1 'IBM Plex Mono',ui-monospace,monospace;letter-spacing:.12em;text-transform:uppercase;color:#8f8375;padding:.3rem .4rem;border-bottom:1px solid rgba(243,237,228,.14)}
.oak-offers td{padding:.55rem .4rem;border-bottom:1px solid rgba(243,237,228,.08);vertical-align:top;color:#c7bcad;white-space:nowrap}.oak-offers td:first-child{white-space:normal}.oak-offers th{white-space:nowrap}
.oak-offers td b{color:#f3ede4;display:block}.oak-offers td small{display:block;color:#8f8375;font-size:.72rem}
.oak-offers td.p{font:800 1.05rem 'Bricolage Grotesque',sans-serif;color:#f3ede4;font-variant-numeric:tabular-nums;white-space:nowrap}
.oak-offers tr.best td{background:rgba(217,168,108,.08)}.oak-offers tr.best td.p{color:#d9a86c}
.oak-offers tr.stale td{opacity:.6}.oak-offers td.none{color:#8f8375;text-align:center;padding:1rem}
.oak-calc{margin-top:1rem;padding-top:.9rem;border-top:1px solid rgba(243,237,228,.12)}
.oak-calc-h{font:600 .6rem/1 'IBM Plex Mono',ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;color:#8f8375;margin:0 0 .5rem}
.oak-calc-row{display:flex;gap:.5rem}.oak-calc-row input,.oak-calc-row select{font:inherit;font-size:.95rem;border:1px solid rgba(243,237,228,.2);border-radius:10px;background:#16110d;color:#f3ede4;padding:.5rem .7rem}.oak-calc-row input{width:8rem}
.oak-calc-out{margin-top:.5rem;font-size:.86rem;color:#c7bcad;line-height:1.45}
.oak-copy{margin-top:1rem}.oak-copy-row{display:flex;gap:.6rem;align-items:center;font-size:.82rem;color:#c7bcad;padding:.35rem 0;border-top:1px solid rgba(243,237,228,.08)}.oak-copy-row span{flex:1;min-width:0}
.oak-modal .btn.ghost{border:1px solid rgba(243,237,228,.25);color:#f3ede4;background:transparent;border-radius:999px;padding:.4rem .8rem;font:600 .78rem 'Instrument Sans',system-ui,sans-serif;cursor:pointer;white-space:nowrap}
.oak-frame{flex:1;display:flex;flex-direction:column;min-height:0}
.oak-frame-bar{display:flex;align-items:center;gap:.6rem;padding:.6rem 1.2rem;border-bottom:1px solid rgba(243,237,228,.1);font-weight:700}.oak-frame-bar span{flex:1}
.oak-frame iframe{width:100%;height:min(82vh,840px);border:0;display:block;background:#16110d}
@media(max-width:900px){.oak-body{grid-template-columns:1fr}.oak-market{display:none}.oak-dist{max-width:11rem}.oak-board .b-head,.oak-board .b-row{grid-template-columns:4rem repeat(4,minmax(0,1fr))}.oak-board .bc{padding:.5rem .5rem;min-height:4.6rem}.oak-board .bc .src{display:none}}
/* ---- v1.50.0 Measured: the job's areas by kind, in the sidebar under Asked us for ------------
   Two colours carry the whole widget: oak for new flooring (bought by the carton) and blue for
   sand and finish (sold by the foot), so the two kinds never read as one. A row is a tape-and-pad line: kind, name, number. The totals
   are two tiles, and each tile holds the calculator that belongs to it, so waste sits with the
   material and the price sits with the sanding. Anything switched off is greyed, not hidden. */
.jd-measure{padding:1.1rem 1.15rem 1rem}
.jd-measure .card-h{margin-bottom:.75rem}
.jm-saved{margin-left:auto;font-size:.62rem;letter-spacing:.08em;text-transform:none;color:var(--faint);transition:opacity .25s}
.jm-saved.ok{color:var(--ok)}.jm-saved.bad{color:var(--lost)}.jm-saved.busy{color:var(--muted)}
.jm-sheet{display:flex;gap:.7rem;align-items:center;margin:0 0 .85rem;padding:.55rem;border-radius:10px;
  background:linear-gradient(135deg,var(--chalk-soft),transparent 70%);border:1px solid var(--line-2)}
.jm-sheet.none{background:transparent;border-style:dashed}
.jm-sheet .att-thumb{flex:none;border-radius:8px}
.jm-sheet .att-thumb img{width:64px;height:64px}
.jm-sheet-ph{flex:none;width:64px;height:64px;border-radius:8px;background:var(--paper);border:1px dashed var(--line);
  background-image:repeating-linear-gradient(0deg,transparent 0 9px,var(--line-2) 9px 10px);opacity:.7}
.jm-sheet-t{display:flex;flex-direction:column;gap:.1rem;min-width:0;font-size:.78rem;line-height:1.3}
.jm-sheet-t b{font-size:.8rem;font-weight:650;color:var(--ink)}
.jm-sheet-t span{color:var(--muted)}
.jm-sheet-all{font-size:.72rem;color:var(--oak);text-decoration:none;margin-top:.15rem}
.jm-sheet-all:hover{text-decoration:underline}
.jm-sheet.none{position:relative;padding-right:2.6rem}
.jm-sheet-acts{display:flex;gap:.6rem;align-items:center;margin-top:.15rem;flex-wrap:wrap}
.jm-sheet-act{font:inherit;font-size:.72rem;color:var(--muted);background:none;border:0;padding:0;cursor:pointer;text-decoration:none}
.jm-sheet-act:hover{color:var(--oak);text-decoration:underline}
.jm-sheet-act.danger:hover{color:#a33a2a}
.jm-upload{position:absolute;right:.55rem;top:50%;transform:translateY(-50%);width:30px;height:30px;border-radius:50%;border:1px solid var(--line);
  background:var(--paper);color:var(--oak);display:grid;place-items:center;cursor:pointer;transition:background .15s,border-color .15s,color .15s}
.jm-upload:hover,.jm-upload:focus-visible{background:var(--oak);border-color:var(--oak);color:#fff;outline:none}
.jm-upload.busy{opacity:.55;cursor:progress}
.jm-upload.busy svg{animation:jm-lift .9s ease-in-out infinite}
@keyframes jm-lift{0%,100%{transform:translateY(0)}50%{transform:translateY(-2px)}}
.jm-sheet .att-thumb.jm-doc img{display:none}
.jm-sheet .att-thumb.jm-doc{width:64px;height:64px;background:var(--paper);border:1px solid var(--line);display:grid;place-items:center}
.jm-sheet .att-thumb.jm-doc::after{content:"PDF";font:600 .7rem/1 "IBM Plex Mono",monospace;color:var(--muted);letter-spacing:.06em}
.jm-areas{display:flex;flex-direction:column;gap:.35rem}
.jm-row{display:grid;grid-template-columns:2.6rem minmax(0,1fr) 4.6rem 1.2rem;gap:.35rem;align-items:center}
.jm-k{height:1.75rem;border:0;border-radius:6px;font:600 .62rem/1 'IBM Plex Mono',monospace;letter-spacing:.08em;text-transform:uppercase;
  cursor:pointer;transition:background .15s,color .15s,transform .12s}
.jm-k:active{transform:scale(.94)}
.jm-row.floor .jm-k{background:var(--oak-soft,rgba(201,168,124,.18));color:var(--walnut)}
.jm-row.sf .jm-k{background:rgba(41,110,178,.12);color:var(--cat-blue)}
.jm-label,.jm-sqft{height:1.75rem;border:1px solid var(--line);border-radius:6px;background:var(--surface);font:inherit;font-size:.85rem;padding:0 .5rem;min-width:0}
.jm-label:focus,.jm-sqft:focus{outline:none;border-color:var(--oak)}
.jm-row.sf .jm-label:focus,.jm-row.sf .jm-sqft:focus{border-color:var(--cat-blue)}
.jm-sqft{text-align:right;font-variant-numeric:tabular-nums;-moz-appearance:textfield}
.jm-sqft::-webkit-outer-spin-button,.jm-sqft::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.jm-del{border:0;background:transparent;color:var(--faint);font-size:1.1rem;line-height:1;cursor:pointer;padding:0;border-radius:4px}
.jm-del:hover{color:var(--lost)}
.jm-add{margin:.5rem 0 .9rem;border:1px dashed var(--line);background:transparent;border-radius:8px;width:100%;padding:.4rem;
  font:inherit;font-size:.78rem;color:var(--muted);cursor:pointer;transition:border-color .15s,color .15s}
.jm-add:hover{border-color:var(--oak);color:var(--ink)}
.jm-tot{border-radius:10px;padding:.7rem .8rem;border:1px solid var(--line-2);background:var(--paper)}
.jm-tot + .jm-tot{margin-top:.55rem}
.jm-tot.floor{border-left:3px solid var(--oak)}
.jm-tot.sf{border-left:3px solid var(--cat-blue)}
.jm-tot-r{display:flex;align-items:baseline;gap:.4rem}
.jm-tot .k,.jm-treads .k{font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.1em;text-transform:uppercase;color:var(--label)}
.jm-tot-r .k{flex:1}
.jm-tot-r b{font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:1.35rem;line-height:1;font-variant-numeric:tabular-nums}
.jm-tot .u{font-size:.68rem;color:var(--muted)}
.jm-sw{display:inline-flex;align-items:center;gap:.4rem;font-size:.74rem;color:var(--ink);cursor:pointer;user-select:none}
.jm-sw input{position:absolute;opacity:0;width:0;height:0}
.jm-sw-t{width:1.7rem;height:1rem;border-radius:999px;background:var(--line);position:relative;transition:background .18s;flex:none}
.jm-sw-t::after{content:'';position:absolute;top:2px;left:2px;width:.75rem;height:.75rem;border-radius:50%;background:#fff;transition:transform .18s;box-shadow:0 1px 2px rgba(0,0,0,.25)}
.jm-sw input:checked + .jm-sw-t{background:var(--oak)}
.jm-tot.sf .jm-sw input:checked + .jm-sw-t{background:var(--cat-blue)}
.jm-sw input:checked + .jm-sw-t::after{transform:translateX(.7rem)}
.jm-sw input:focus-visible + .jm-sw-t{outline:2px solid var(--chalk);outline-offset:2px}
.jm-waste{display:flex;align-items:center;flex-wrap:wrap;gap:.45rem .6rem;margin-top:.55rem;transition:opacity .2s}
.jm-waste.off .jm-seg,.jm-waste.off .jm-waste-out{opacity:.38}
.jm-seg{display:inline-flex;border:1px solid var(--line);border-radius:999px;overflow:hidden;background:var(--surface)}
.jm-seg button{border:0;background:transparent;font:600 .68rem/1 'IBM Plex Mono',monospace;padding:.32rem .5rem;cursor:pointer;color:var(--muted);transition:background .15s,color .15s}
.jm-seg button + button{border-left:1px solid var(--line-2)}
.jm-seg button.on{background:var(--oak);color:#fff}
.jm-seg button:disabled{cursor:default}
.jm-waste-out{font-size:.72rem;color:var(--muted);flex-basis:100%}
.jm-treads{display:flex;align-items:center;flex-wrap:wrap;gap:.4rem .55rem;margin-top:.6rem;padding-top:.55rem;border-top:1px dashed var(--line-2)}
.jm-treads .k{flex:1 1 auto}
.jm-step{display:inline-flex;align-items:center;border:1px solid var(--line);border-radius:999px;background:var(--surface);overflow:hidden}
.jm-step button,.jm-rate > button{border:0;background:transparent;width:1.6rem;height:1.6rem;font-size:1rem;line-height:1;cursor:pointer;color:var(--ink);transition:background .12s}
.jm-step button:hover,.jm-rate > button:hover:not(:disabled){background:rgba(41,110,178,.1)}
.jm-step input{width:2.3rem;border:0;background:transparent;text-align:center;font:inherit;font-size:.9rem;font-variant-numeric:tabular-nums;-moz-appearance:textfield}
.jm-step input::-webkit-outer-spin-button,.jm-step input::-webkit-inner-spin-button,#jm-tread-price::-webkit-outer-spin-button,#jm-tread-price::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.jm-tread-at{font-size:.72rem;color:var(--muted);flex-basis:100%}
.jm-tread-at input{width:2.6rem;border:0;border-bottom:1px solid var(--line);background:transparent;font:inherit;font-size:.78rem;text-align:center;-moz-appearance:textfield}
.jm-tread-at input:focus{outline:none;border-color:var(--cat-blue)}
.jm-price{margin-top:.6rem;padding-top:.55rem;border-top:1px dashed var(--line-2)}
.jm-sw-row{display:flex;flex-wrap:wrap;gap:.5rem 1rem}
.jm-sw.off{opacity:.38;pointer-events:none}
.jm-line.apart{color:var(--faint);font-style:italic}
.jm-line.apart b{color:var(--muted);font-weight:500}
.jm-price-body{transition:opacity .2s;margin-top:.5rem}
.jm-price.off .jm-price-body{opacity:.38}
.jm-rate{display:flex;align-items:center;gap:.3rem}
.jm-rate > button{border:1px solid var(--line);border-radius:50%;background:var(--surface)}
.jm-rate > button:disabled{cursor:default;color:var(--faint)}
.jm-rate-in{display:inline-flex;align-items:center;font-family:'Bricolage Grotesque',sans-serif;font-weight:700;font-size:1.15rem;color:var(--ink)}
.jm-rate-in input{width:3.4rem;border:0;border-bottom:1px solid var(--line);background:transparent;font:inherit;font-size:1.15rem;font-weight:700;text-align:center;font-variant-numeric:tabular-nums;padding:0}
.jm-rate-in input:focus{outline:none;border-color:var(--cat-blue)}
.jm-lines{margin-top:.5rem;display:flex;flex-direction:column;gap:.25rem}
.jm-line{display:flex;align-items:center;gap:.4rem;font-size:.76rem;color:var(--muted)}
.jm-line span{flex:1;min-width:0}
.jm-line b{font-variant-numeric:tabular-nums;font-weight:600;color:var(--ink)}
.jm-line.total{margin-top:.15rem;padding-top:.35rem;border-top:1px solid var(--line-2);font-size:.8rem;color:var(--ink)}
.jm-line.total b{font-family:'Bricolage Grotesque',sans-serif;font-size:1.05rem;font-weight:700}
.jm-copy{border:1px solid var(--line);background:var(--surface);border-radius:6px;width:1.5rem;height:1.5rem;display:inline-grid;place-items:center;color:var(--muted);cursor:pointer;position:relative;transition:color .15s,border-color .15s}
.jm-copy:hover:not(:disabled){color:var(--ink);border-color:var(--oak)}
.jm-copy.copied{color:var(--ok);border-color:var(--ok)}
.jm-copy.copied::after{content:'Copied'}
.jm-copy.copied::after{position:absolute;right:calc(100% + .35rem);font:600 .6rem/1 'IBM Plex Mono',monospace;letter-spacing:.08em;text-transform:uppercase;color:var(--ok);white-space:nowrap}
.jm-text{display:block;width:100%;margin-top:.65rem;text-align:left;border:1px solid var(--line-2);border-radius:8px;background:var(--surface);
  padding:.55rem .65rem .5rem;font:inherit;font-size:.74rem;line-height:1.4;color:var(--ink);cursor:copy;position:relative;transition:border-color .15s,background .15s}
.jm-text:hover{border-color:var(--cat-blue);background:rgba(41,110,178,.06)}
.jm-text-hint{display:block;margin-top:.3rem;font:600 .58rem/1 'IBM Plex Mono',monospace;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.jm-text.copied{border-color:var(--ok)}
.jm-text.copied .jm-text-hint{color:var(--ok)}
/* The carton calculator, told where its number came from. */
.calc-fromjob{font-size:.74rem;color:var(--muted);margin:-.3rem 0 .7rem;padding-left:.15rem}
.calc-fromjob::before{content:'';display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--oak);margin-right:.4rem;vertical-align:middle}
.bap-h{margin:1.4rem 0 .6rem;font-size:.95rem;display:flex;align-items:center;gap:.5rem}.bap-h .n{font-size:.75rem;color:var(--faint,#9a8f84);font-weight:500}
.bap-during{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.8rem}.bap-d{min-width:0}
