@import url('/css/tokens.css');
/* The app is dark everywhere, so say so at the root. Without this the browser
   assumes a light page and paints a WHITE canvas for any frame it has to draw
   before the page's own background is known - which is the white flash between
   pages. The <meta name="color-scheme"> in each head is the one that actually
   lands in time (the parser reads it before any stylesheet); this rule is the
   backstop for anything that reaches CSS first. */
:root { color-scheme: dark; }

/* The `hidden` attribute only hides via the UA stylesheet's `display: none`,
   which ANY author `display` rule outranks. So an element styled
   `display: grid` or `display: flex` stays fully visible while the DOM
   cheerfully reports hidden === true -- which is exactly how the Follow Up day
   collapse shipped doing nothing, and why three separate
   `.something[hidden] { display: none }` patches already exist further down
   this file. One reset, so the next person to reach for `el.hidden` gets what
   they expect. */
[hidden] { display: none !important; }

/* ── CSS Variables ───────────────────────────────────────────────────────────── */
:root {
  --blue-900: #002366;
  --blue-800: #003087;
  --blue-700: #004aad;
  --blue-100: #e8f0ff;
  --gold:     var(--brand-gold);
  --gold-light: #f5e8c0;
  --green:    #1a8a4a;
  --green-light: #e6f5ed;
  --orange:   #d46c1a;
  --orange-light: #fff0e0;
  --red:      #c0392b;
  --red-light: #fdecea;
  --yellow:   #e8a020;
  --yellow-light: #fffae0;
  --gray-900: #1a1a2e;
  --gray-700: #444466;
  /* Lifted from #7777aa, which measured 4.14:1 on navy -- just under the bar.
     Used for secondary lines like the pipeline address and email preview. */
  --gray-500: #8f8fbe;
  --gray-300: #c0c0d8;
  --gray-100: #f4f4f8;
  --white:    #ffffff;
  /* Aliases onto tokens.css. Kept so the existing references to --shadow and
     --radius keep working and simply pick up the new values, rather than
     rewriting every call site. --shadow-sm has no site equivalent and stays
     as it was, minus the blue tint. */
  --shadow-sm: 0 1px 4px rgba(0,0,0,0.20);
  --shadow:    var(--shadow-soft);
  --shadow-lg: var(--shadow-lift);
}

/* Brand tokens, type tokens: defined once in tokens.css and imported here.
   Pages with their own stylesheet link tokens.css directly -- see the note
   in that file about the three pages where an undefined var() silently
   dropped the gold. */

/* html { scrollbar-gutter: stable; } — removed; suspected source of blue right-edge artifact */
html { background: #0d1b2a; }
@keyframes pageIn { from { opacity: 0; } to { opacity: 1; } }

/* ── Reset & Base ────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
  font-family: var(--sans);
  background-color: var(--nav-navy);
  background-image: url('/backgrounds/castle-storm.jpg');
  background-size: cover;
  background-position: right top !important;
  background-attachment: fixed;
  color: var(--gray-900);
  /* 15px / 1.6, raised from 14 / 1.5 on 2026-08-19. The website is 17px, which
     this deliberately does not match: the pipeline and contact detail were laid
     out against 14 and 17 would break them. Measured both sizes on real data
     before moving: the count of clipped text was identical at 14 and 15 on both
     screens, so nothing new is cut off, and the cost is about 30px of extra
     scrolling per screen. */
  font-size: 15px;
  line-height: 1.6;
  min-height: 100vh;
  animation: pageIn 0.25s ease-out;
}

a { color: var(--blue-700); text-decoration: none; }
a:hover { text-decoration: underline; }
input, select, textarea, button { font-family: inherit; font-size: inherit; }
textarea { resize: vertical; }

/* ── Top Bar ─────────────────────────────────────────────────────────────────── */
.top-bar { height: 14px; background: #000; width: 100%; display: none; }

/* ── Header ──────────────────────────────────────────────────────────────────── */
.site-header {
  color: var(--white);
  /* Set here, not inherited: the sister pages give their body the system font
     in their own style block, which made the same header text a few pixels
     wider there than on the Dashboard, so it shifted between pages. */
  font-family: var(--sans);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  padding: 14px 0 28px 28px;
  position: sticky;
  top: 0;
  z-index: 100;
}

/* A sticky header over a transparent background is a scroll bleed: rows pass
   underneath and read straight through the crest and the date. It only shows
   on pages that scroll the DOCUMENT. The four listed here lock their height to
   the viewport and scroll an inner container instead, so nothing ever passes
   under their header and they keep the castle showing through, which is the
   look Rich settled.
   Values are the locked pair from CLAUDE.md, not new ones. */
body.has-sidebar:not(.dashboard-page):not(.contacts-manager):not(.contact-detail):not(.support-page) .site-header {
  background: rgba(13, 27, 42, 0.92);
  backdrop-filter: blur(8px);
}
.header-brand { display: flex; align-items: center; gap: 14px; padding-left: 280px; }
/* Placed by the shield's bottom point, not its left edge. The point sits at
   209.5 of the 440px-tall artwork's width, i.e. 0.47614 x its rendered
   height, and it has to land on 140px, the middle of the 280px rail the pills
   are centred in. A fixed left edge only did that on the tallest band: on
   shorter windows the crest shrank from the left and the point drifted up to
   25px off the pills' centre line. Rich, 2026-09-25: "make sure the bottom
   point of the shield still runs down the center of all the pills". */
.brand-logo {
  position: absolute;
  top: 14px;
  left: calc(140px - (var(--header-band) - 30px) * 0.47614);
  width: auto;
  height: auto;
  background: transparent;
  display: block;
  z-index: 5;
}
/* The crest is absolutely positioned, so it takes no space in the layout and
   nothing pushes back when it grows. It hangs into the top of the sidebar
   column, whose first pill sits at var(--header-band) + 8px (the nav's own
   padding). A hardcoded 270px therefore fit only the tallest band: at 250 it
   covered 26px of the Dashboard pill, at 215 it covered 61px of a 64px pill,
   and lower it swallowed the pill whole. That is why the crest appeared to
   grow into the nav whenever the window got SHORTER -- the bug is keyed on
   height, not width.

   Sizing off the band instead means the crest can never reach the nav: its
   bottom lands at 14 + (band - 30) = band - 16, a constant 24px above the
   Dashboard pill at every breakpoint. At the full 300px band this evaluates
   to exactly 270px, so the tall-screen look is unchanged.

   Partner to the --header-band breakpoints near the top of this file, and to
   the nav/quote shrink rules at the end -- those already scaled the pills and
   the quote to the band; the crest was the one piece left behind. */
.brand-logo img {
  height: calc(var(--header-band) - 30px) !important;
  width: auto !important;
  object-fit: contain;
}
.brand-name  { display: block; font-size: 16px; font-family: Georgia, 'Cormorant Garamond', serif; font-weight: 400; letter-spacing: 0.15em; color: #fff; }
/* min-height holds the line before the name arrives. It is filled in after the
   page appears, and until then the mailbox line sat one line higher, then
   dropped when the name landed: a jump on every arrival at the Dashboard. */
.brand-agent { display: block; font-size: 12px; opacity: .75; margin-top: 1px; min-height: 1.6em; }
/* max-width so the People pill lines up with the briefing button above it.
   The two artworks are nothing alike -- the briefing pill is 319x47 and the
   nav pills are all 1085x310 -- so left to itself People rendered 1085px wide
   and ran the header off the screen. Capping the column and letting the image
   fill it stacks them to the same edges without either size being typed in. */
.header-right { display: flex; flex-direction: column; align-items: center; gap: 8px; max-width: 320px; }
.header-quote {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-style: italic;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.78);
  max-width: 520px;
  margin: 0 auto;
  padding: 0 24px;
  text-align: center;
  line-height: 1.5;
  position: absolute;
  left: 50%;
  top: 14px;
  transform: translateX(-50%);
}
.header-quote span[style] {
  font-size: 22px !important;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-clamp: 2;
  max-height: 3em;
}
.header-quote #greeting-time { font-size: 26px; color: var(--brand-gold); }
.date-display { font-size: 13px; opacity: .85; white-space: nowrap; }
.auth-status  { display: flex; align-items: center; gap: 6px; font-size: 12px; opacity: .9; white-space: nowrap; }
.auth-dot     { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.auth-dot.connected    { background: #4cdb8a; }
.auth-dot.disconnected { background: #ff8c69; }
.auth-label a { color: #aad4ff; }

/* Its own colour, not the header's: on a phone sidebar-nav.js moves it out of
   the header to below the nav, where it inherited the body's dark navy and
   was all but invisible on the castle. */
.site-header__summary {
  color: #fff;
  width: calc(100% - 720px);
  margin-left: 280px;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--gold);
  font-size: 13px;
}
.summary-message { font-size: 14px; font-style: italic; opacity: .92; }
.summary-stats {
  gap: 12px;
  font-size: 12px;
  font-weight: 500;
  opacity: .85;
  color: var(--white);
  align-items: center;
  white-space: nowrap;
}
/* One line on a desktop; on a phone "2 emails · 2 overdue · 0 due" ran 40px
   past the edge of the screen. */
@media (max-width: 768px) {
  .summary-stats { white-space: normal; flex-wrap: wrap; row-gap: 4px; }
}

/* ── Inner-page nav links (shared by index.html + inner pages) ───────────────── */
.contacts-nav-link{color:var(--brand-gold);text-decoration:none;font-size:13px;font-weight:600;padding:6px 12px;border-radius:6px;transition:background 0.15s;background:transparent}
.contacts-nav-link:hover{background:color-mix(in srgb, var(--brand-gold) 10%, transparent)}
.contacts-nav-link.active{background:var(--brand-gold);color:var(--blue-900);font-weight:600}

/* ── Buttons ─────────────────────────────────────────────────────────────────── */
/* Buttons, restyled onto the site's treatment 2026-08-19.

   The old set was left over from before the app went dark: .btn-secondary was
   WHITE with a blue border and .btn-ghost was grey on grey, both of which read
   as a different product sitting on the navy.

   Class names, padding and font-size are unchanged on purpose. 282 elements
   carry .btn across the HTML and the JS that builds it, so keeping the box the
   same size means nothing reflows and no markup had to be touched.

   Case is left as authored rather than uppercased like the site. The site
   uppercases three or four landing-page calls to action; this app has hundreds
   of small controls reading Save, Edit, Scan now, and shouting all of them
   would be a different decision from matching the brand. */
.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 18px; border-radius: var(--radius-pill); border: 1px solid transparent;
  cursor: pointer;
  font-family: var(--sans);
  font-weight: 600; font-size: 13px; letter-spacing: .01em; white-space: nowrap;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease),
              background .18s var(--ease), color .18s var(--ease),
              border-color .18s var(--ease);
}
.btn-primary  {
  background: linear-gradient(135deg, var(--gold-bright), var(--brand-gold) 55%, var(--gold-deep));
  color: var(--nav-navy);
  box-shadow: 0 6px 18px color-mix(in srgb, var(--brand-gold) 26%, transparent);
}
.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 26px color-mix(in srgb, var(--brand-gold) 40%, transparent);
}

#generateBtn {
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  line-height: 0;
}
#generateBtn img {
  display: block;
  max-width: 100%;
  height: auto;
}
.btn-secondary{
  background: color-mix(in srgb, var(--nav-navy) 50%, transparent);
  border-color: color-mix(in srgb, var(--brand-gold) 55%, transparent);
  color: var(--gold-bright);
}
.btn-secondary:hover {
  background: color-mix(in srgb, var(--brand-gold) 12%, transparent);
  border-color: var(--brand-gold);
}
.btn-ghost    {
  background: transparent;
  border-color: color-mix(in srgb, var(--text-dim) 45%, transparent);
  color: var(--text-soft);
}
.btn-ghost:hover {
  background: color-mix(in srgb, var(--text-dim) 12%, transparent);
  color: var(--text);
}
/* Destructive. Uses the measured status red, not the old one that failed
   contrast on this background. */
.btn-danger   {
  background: color-mix(in srgb, var(--status-red) 14%, transparent);
  border-color: color-mix(in srgb, var(--status-red) 55%, transparent);
  color: var(--status-red);
}
.btn-danger:hover { background: color-mix(in srgb, var(--status-red) 24%, transparent); }
.btn-sm       { padding: 5px 12px; font-size: 12px; }
.btn-large    { padding: 13px 28px; font-size: 15px; }
.btn-icon     { font-size: 16px; }
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none !important; }

/* ── Main Layout ─────────────────────────────────────────────────────────────── */
.main-content { width: 100%; max-width: 1280px; margin: 0 auto; padding: 0 24px 36px; }
/* The inbox is a wide table and was stopping well short of the window on a
   large screen. Lifting the cap only while the Emails tab is showing, so the
   other tabs keep their reading width. Same :has() per-tab scoping the file
   already uses further down for this tab's flex chain. */
body:has(#tab-emails.tab-content.active) .main-content { max-width: none; }
/* Follow Up shares the Correspondence destination row with the Inbox and the
   sub-pages, and at the 1280px cap that row drew 199x33 pills against 216x36
   everywhere else, so every switch between them visibly resized it. */
body:has(#tab-contacts.tab-content.active) .main-content { max-width: none; }
.has-sidebar .main-content { width: calc(100% - 300px); margin-left: 300px; margin-right: 0; }
.has-sidebar .page { width: calc(100% - 300px); margin-left: 300px; }
.has-sidebar .layout { width: calc(100% - 300px); margin-left: 300px; }
.has-sidebar .page-pill-row { width: calc(100% - 300px); margin-left: 300px; }
.has-sidebar .back-bar { width: calc(100% - 300px); margin-left: 300px; }

/* ── Vertical budget ─────────────────────────────────────────────────────────
   The window height is shared by three fixed things: the header band, the
   stack of nav pills below it, and the footer. The band was pinned at 300px,
   which is fine on a tall window and ruinous on a short one - at a 695px
   viewport it took 43% of the screen and pushed the bottom nav pill 69px off
   the end, so the app only fitted if the user dropped their browser to 75%.

   One variable fixes it. The band shrinks as the window gets shorter, and
   because the nav pills and the content column are both positioned from this
   same value, they follow it automatically and stay aligned with each other.
   Content scales down; nothing is letterboxed and no bands are added.

   Keyed on height, not width, because height is what actually ran out. */
:root { --header-band: 300px; --nav-top: max(var(--header-band), var(--header-h, 0px)); }
@media (max-height: 900px) { :root { --header-band: 250px; } }
@media (max-height: 800px) { :root { --header-band: 215px; } }
@media (max-height: 700px) { :root { --header-band: 185px; } }

@media (max-height: 640px) { :root { --header-band: 150px; } }

/* The rules that shrink the header and nav CONTENTS to match these bands live
   at the very end of this file. They have to: they override .sidebar-nav and
   .sidebar-pill, which are defined just below here, and equal-specificity
   rules are decided by source order. */

/* ── Sidebar Navigation ──────────────────────────────────────────────────────── */
.sidebar-nav {
  position: fixed;
  left: 0;
  top: var(--nav-top);
  bottom: 0;
  width: 280px;
  /* 10px sides, not 6px, because cursor.js leans a hovered button up to CAP_X
     (10px) toward the pointer via --magnet-x. At 6px the lean pushed the pill
     4px past the rail's padding box, and the overflow-y below computes
     overflow-x to auto, so the rail grew a horizontal scrollbar under the
     bottom pill whenever the mouse crossed one. The pills stay centred either
     way, so this costs nothing on screen. */
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  /* Kept as a variable because .sidebar-pill's height cap has to subtract the
     gaps, and the two used to be tuned independently -- which is how the nav
     ended up overflowing at some window heights.
     Was 14px until 2026-09-23. Pointing at a pill now names it underneath, and
     a 26px caption in a 14px gap lands squarely on the next pill down. Rich:
     "move all pills above speak up enough to make it work", and keep Speak
     where it is.
     THE GAP TAKES WHATEVER ROOM IS GOING, UP TO WHAT THE CAPTION NEEDS. There
     is nothing above the rail to grow into -- it starts directly under the
     header band -- but there is room below the last pill. Rich, 2026-09-23:
     "if you can move speak down without creating a scroll bar that would be
     perfect." So the gap is the leftover room divided between the rows,
     floored at the 14px it always was and capped at 34px, a caption plus
     clearance. The stack grows down into room that was empty and stops before
     the rail ends.
     IT IS WORKED OUT AGAINST A PILL FLOOR, NOT THE PILL'S FULL SIZE. Against
     the full 64px it came to 29.6px on Rich's own screen and the caption went
     and sat beside the rail instead: his header carries the briefing
     paragraph, so --nav-top lands near 420px rather than the 300px band and
     there is that much less room left. Measuring against a 50px floor lets
     the pills give back a few pixels -- 64 to 60 there -- so the gap gets what
     it needs. When even that will not do, the gap closes and the caption goes
     beside, which is the right answer on a cramped window.
     That is the SEVEN-ROW rule, and it still sets the pill size: see below. */
  /* Eight rows since Contacts became its own section, 2026-09-25. Rich: "Just
     close the gaps between Pills, dont shrink them." So a pill is exactly the
     size seven rows gave it, and the eighth row is paid for out of the gaps,
     which close towards nothing. Only a window too short to hold eight at that
     size with no gap at all makes the pills give way, because the only other
     answer is a scrollbar that hides Speak.
     --nav-pill-art is the artwork's own height at its 225px max-width
     (225 x 310 / 1085), so the gap is worked out from what is really drawn. */
  --nav-rows: 8;
  --nav-pill-floor: 60px;
  --nav-room: calc(100dvh - var(--nav-top) - 20px);
  --nav-gap-seven: clamp(14px, calc((var(--nav-room) - 7 * var(--nav-pill-floor)) / 6), 34px);
  --nav-pill-art: 64.29px;
  --nav-pill-h: min(
    var(--nav-pill-art),
    calc((var(--nav-room) - 6 * var(--nav-gap-seven)) / 7),
    calc(var(--nav-room) / var(--nav-rows))
  );
  --nav-gap: clamp(0px, calc(
    (var(--nav-room) - var(--nav-rows) * var(--nav-pill-h)) / (var(--nav-rows) - 1)
  ), 34px);
  gap: var(--nav-gap);
  z-index: 50;
  overflow-y: auto;
  /* The rail never scrolls sideways. Belt to the padding's braces: overflow-y
     on its own computes overflow-x to auto, so any future overhang would put
     the bar straight back. */
  overflow-x: hidden;
}

.sidebar-btn {
  position: relative;
  display: block;
  width: 100%;
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.15s ease, filter 0.15s ease;
}

.sidebar-btn:hover {
  transform: translateX(4px);
  filter: brightness(1.1);
}

/* The section you are currently in. Marked by sidebar-nav.js, which is the
   only thing that knows -- the dashboard is one document with nine tabs, so
   this changes without a page load.
   Glow only, no size or position change, so the nav never shifts under the
   cursor. It stays a real link: on a sub-page like Templates, Correspondence
   is both where you are and the way back to the inbox. */
.sidebar-btn.is-active .sidebar-pill {
  filter: drop-shadow(0 0 9px color-mix(in srgb, var(--brand-gold) 90%, transparent))
          brightness(1.12);
}


button.sidebar-btn,
button.sidebar-btn:focus,
button.sidebar-btn:active {
  background: transparent !important;
  border: none !important;
  outline: none !important;
  box-shadow: none !important;
  -webkit-appearance: none;
  appearance: none;
}

button.sidebar-btn:focus-visible {
  outline: 2px solid var(--brand-gold) !important;
  outline-offset: 3px;
  border-radius: 8px;
}

.sidebar-pill {
  display: block;
  width: 100%;
  max-width: 225px;
  height: auto;
  /* Never taller than an equal share of the room the nav actually has: the
     viewport, less the header band it starts below, less its own 8px top and
     bottom padding, less the gaps between the items -- split evenly.
     This replaces a hand-tuned ladder of pill sizes that had to be kept in
     step with the --header-band ladder by hand. It was not: the band grows at
     641px, 701px and 801px tall, and at each of those the nav lost height
     while the pills stayed the same size, so it overflowed and grew its own
     scrollbar. The comment on the old rule still said "six pills"; there are
     seven. Deriving the cap means the two ladders cannot drift apart again.
     --nav-rows on .sidebar-nav is the only thing to change when a nav item is
     added; the height itself is worked out there as --nav-pill-h.
     20px in --nav-room = the nav's 8px top and bottom padding, plus 4px of
     cushion. In the tight ranges this fits to the pixel, and fractional pill
     heights round up, which is enough on its own to put the scrollbar back. */
  max-height: var(--nav-pill-h);
  object-fit: contain;
  margin: 0 auto;
  background: transparent;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5));
}

/* The operator link used to be an extra row in the rail, for the owner only,
   and the rail had to be told so or it overflowed. It is not in the rail any
   more. Rich, 2026-09-23: "since people is only on my screen... move the
   people pill and place it under the generate morning Briefing Pill on my
   screen. Then make my screen look like everyone elses on the left side like
   it was before."
   So the rail is seven rows for everybody, which is also what buys the room
   for a caption between the pills at the pills' full size. */
#adminLink.header-people {
  background: transparent;
  border: none;
  padding: 0;
  line-height: 0;
}
#adminLink.header-people img {
  display: block;
  width: 100%;
  height: auto;
}
#adminLink.header-people:hover img {
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--brand-gold) 55%, transparent))
          brightness(1.08);
}

.sidebar-label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.contact-filter-row {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 20px 0 16px;
  flex-wrap: wrap;
}
.contact-filter-label {
  color: #f0e6d0;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 600;
}
.contact-filter-dropdown {
  background: rgba(13, 27, 42, 0.85);
  border: 2px solid var(--brand-gold);
  color: #f0e6d0;
  padding: 10px 38px 10px 18px;
  border-radius: 999px;
  font-size: 0.95rem;
  font-weight: 600;
  min-width: 220px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14'><path d='M3 5l4 4 4-4' fill='none' stroke='%23d4a017' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 14px center;
  letter-spacing: 0.02em;
}
.contact-filter-dropdown:focus {
  outline: none;
  border-color: #f4c440;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-gold) 25%, transparent);
}
.contact-filter-dropdown option,
.contact-filter-dropdown optgroup {
  background: #0d1b2a;
  color: #f0e6d0;
}
.contact-filter-dropdown optgroup {
  font-weight: 700;
  color: var(--brand-gold);
  font-style: normal;
}

/* ── Tab Navigation ──────────────────────────────────────────────────────────── */
.tab-nav {
  display: flex;
  justify-content: center;
  gap: 8px;
  padding: 12px 0 0;
  border-bottom: none;
  margin: 0 auto 8px;
  max-width: 1400px;
  flex-wrap: wrap;
}
.tab-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--brand-gold);
  color: var(--nav-navy);
  border: 1px solid var(--brand-gold);
  border-radius: 999px;
  padding: 8px 16px;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.2px;
  cursor: pointer;
  transition: background 0.15s, transform 0.15s;
  white-space: nowrap;
}
.tab-btn:hover {
  background: #E0C16B;
  border-color: #E0C16B;
  transform: translateY(-1px);
}
.tab-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-gold) 40%, transparent);
}
.tab-btn.active {
  background: var(--nav-navy);
  color: var(--brand-gold);
  border: 1px solid var(--brand-gold);
}
.tab-btn.active:hover { background: #1a2a3f; }
.badge {
  background: var(--red); color: var(--white);
  font-size: 10px; font-weight: 700;
  padding: 2px 6px; border-radius: 10px; min-width: 18px; text-align: center;
}
.badge-warning { background: var(--orange); }
.badge-blue    { background: var(--blue-700); }
.tab-btn.active .badge { background: var(--brand-gold); color: var(--nav-navy); }

/* ── Tab Content ─────────────────────────────────────────────────────────────── */
.tab-content { display: none; }
.tab-content.active { display: block; }

/* ── Movement between pages ────────────────────────────────────────────────
   Contacts, Scheduled Messages, Call Notes, Email Drafts and Help are separate
   documents, so moving to or from them is a full navigation. Rich,
   2026-09-25: "it is anytime you goto Contacts or change from Contacts when it
   does the flash." The flash was each page fading itself in from nothing over
   the navy page colour, with the castle gone for a moment.

   So the browser cross-fades the two pages instead, holding the old one on
   screen until the new one can paint, and the rail and the crest are named so
   they stay put rather than fading out and back. look.js marks a page that
   arrived this way (vt-arrived), which switches its own fade-in off: fading in
   from nothing inside a cross-fade is the same dip over again.

   An earlier version of this was removed on 2026-08-02 as never firing. That
   was a measuring mistake, not the rule: Playwright's bundled headless browser
   does not run cross-document transitions at all, and the listing search
   iframe fires its own pagereveal with none, which overwrote the result. In
   real Chrome, pageswap and pagereveal both report the transition, both ways.
   Browsers without it simply navigate as before. */
@view-transition { navigation: auto; }
nav.sidebar-nav { view-transition-name: seneschal-rail; }
.brand-logo { view-transition-name: seneschal-crest; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 180ms; }
html.vt-arrived body,
html.vt-arrived :is(.main-content, .layout, .support-main, .page) { animation: none !important; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* The content fade-in for a browser that cannot cross-fade pages, or a page
   opened directly. A page that arrived by cross-fade switches it off (see
   vt-arrived above). */
@keyframes seneschalPageIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* .page is the wrapper on Contacts, Templates, Call Notes and Scheduled
   Messages. It was missing here, so those four were the only pages that
   snapped in instead of easing in. */
.main-content, .layout, .support-main, .page {
  animation: seneschalPageIn 190ms ease-out;
}

/* Tab switches inside the Dashboard are an instant show/hide. A short fade
   takes the edge off without adding a wait - 140ms is under the threshold
   where a transition starts to feel like latency. */
@keyframes seneschalTabIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.tab-content.active { animation: seneschalTabIn 140ms ease-out; }

/* Reduced motion: no fades anywhere. */
@media (prefers-reduced-motion: reduce) {
  .main-content, .layout, .support-main, .page,
  .tab-content.active { animation: none; }
}

/* ── Section Cards ───────────────────────────────────────────────────────────── */
.section-card {
  background: transparent; border: none; border-radius: var(--radius-lg);
  padding: 18px; margin-bottom: 15px;
}
.section-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 13px; }
.section-header-row {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 12px;
}
.section-title {
  display: inline-block;
  font-size: 14px;
  font-weight: 600;
  color: var(--brand-gold);
  background: #0D1B2A;
  border: 1px solid var(--brand-gold);
  border-radius: 999px;
  padding: 4px 14px;
}

/* ── Auth notice ──────────────────────────────────────────────────────────────── */
.auth-notice {
  background: var(--yellow-light); border: 1.5px solid #f5d070;
  color: var(--yellow); border-radius: 8px; padding: 8px 14px; font-size: 13px;
  display: flex; align-items: center; gap: 6px;
}

/* ── Overview Cards ──────────────────────────────────────────────────────────── */
.summary-stats {
  font-size: 13px;
  color: rgba(255,255,255,0.7);
  gap: 0;
  margin: 8px 0 6px;
  letter-spacing: 0.01em;
}
.overview-grid {
  display: grid; grid-template-columns: repeat(auto-fill, 175px); justify-content: start;
  gap: 12px; margin-bottom: 6px;
}
@media (max-width: 780px) { .overview-grid { grid-template-columns: repeat(2, 1fr); } }
.overview-card {
  /* solid, not frosted -- see --navy-panel in tokens.css */
  background: var(--navy-panel);
  border: 1px solid var(--brand-gold);
  border-radius: var(--radius-lg);
  padding: 10px; text-align: center; cursor: pointer;
  transition: all .15s;
  color: var(--brand-gold);
}
.overview-card:hover {
  background: rgba(13, 27, 42, 0.98);
  border-color: #E0C16B;
  transform: translateY(-1px);
}
.overview-number { font-size: 30px; font-weight: 800; color: var(--brand-gold); line-height: 1; letter-spacing: 0.5px; }
.overview-label  { margin-top: 8px; }

/* KPI tiles: a distinct accent per card so the four dashboard tiles read as
   separate metrics instead of four identical gold cards. Navy card + gold
   theme is preserved; only a top accent bar and the big number are colored. */
.overview-card.card-red    { border-top: 3px solid #d9534f; }
.overview-card.card-orange { border-top: 3px solid #e0913b; }
.overview-card.card-blue   { border-top: 3px solid #4c86c6; }
.overview-card.card-green  { border-top: 3px solid #4f9d5d; }
.overview-card.card-red    .overview-number { color: #ea7a74; }
.overview-card.card-orange .overview-number { color: #e6a457; }
.overview-card.card-blue   .overview-number { color: #77aee0; }
.overview-card.card-green  .overview-number { color: #6fbf7e; }
.oval-pill {
  display: inline-block;
  background: var(--nav-navy);
  color: #cdd5e0;
  border: 1px solid var(--brand-gold);
  border-radius: 999px;
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.3px;
}

/* ── Today's Priorities ──────────────────────────────────────────────────────── */
.section-card.priorities-section {
  background: transparent;
  border: none;
  border-radius: var(--radius-lg);
  padding: 20px 24px;
}
.section-card.priorities-section .section-title {
  display: inline-block;
  background: var(--nav-navy);
  color: var(--brand-gold);
  border: 1px solid var(--brand-gold);
  border-radius: 999px;
  padding: 6px 16px;
  font-family: var(--serif);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.5px;
  margin-bottom: 14px;
}
/* Today's Priorities: a compact 3-across grid of cards instead of a tall
   vertical stack. Each card is one line of pill + name, with the days-since
   note under it. Three people wide fits far more on screen than one clipped
   row, so the section rarely needs to scroll at all. Drops to two columns on a
   narrower window and one on a small one. */
.priority-list {
  display: grid;
  /* --priority-cols is set by renderPriorityColumns; the media queries below
     are the fallback and use the same breakpoints. */
  grid-template-columns: repeat(var(--priority-cols, 3), minmax(0, 1fr));
  gap: 8px;
  max-width: none;
  align-content: start;
  align-items: start;
}
/* The last card's own bottom margin pushed this pane 1px past its height,
   which is enough to draw a scrollbar track for nothing. */
#overviewContent > *:last-child { margin-bottom: 0; }

/* Each column packs to the top independently, so a tall deal card cannot leave
   a hole beside it the way a stretched grid row did. */
.priority-col {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}
.priority-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
  padding: 9px 12px;
  background: rgba(13, 27, 42, 0.55);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 32%, transparent);
  border-radius: 12px;
}
.priority-left {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  width: 100%;
}
.priority-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brand-gold);
  flex-shrink: 0;
}
.priority-pill {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  flex-shrink: 0;
}
.priority-pill--overdue { background: rgba(226,75,74,0.18); color: #e24b4a; border: 1px solid #e24b4a; }
.priority-pill--due     { background: rgba(232,168,56,0.18); color: #e8a838; border: 1px solid #e8a838; }
.priority-pill--contact { background: var(--nav-navy); color: var(--brand-gold); border: 1px solid var(--brand-gold); }
.priority-name {
  color: #e8edf4;
  font-size: 14px;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
/* In the compact card the meta is plain text under the name, not a bordered
   pill on the right - a full pill does not fit a third-width cell and wrapped
   awkwardly. */
.priority-meta-pill {
  display: block;
  background: transparent;
  color: #aeb8c6;
  border: none;
  border-radius: 0;
  padding: 0 0 0 16px;
  font-size: 11px;
  letter-spacing: 0.2px;
  line-height: 1.35;
  margin-left: 0;
}

/* The deadlines belonging to one deal, stacked inside that deal's card. */
.priority-tasks {
  list-style: none;
  width: 100%;
  margin: 2px 0 0;
  padding: 0 0 0 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.priority-tasks li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  min-width: 0;
}
.priority-task-name {
  color: #e8edf4;
  font-size: 12px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.priority-task-due {
  color: #aeb8c6;
  font-size: 11px;
  white-space: nowrap;
  flex-shrink: 0;
}

/* Only the column count changes per breakpoint. The track itself is declared
   once above as minmax(0, 1fr), never a bare 1fr: a bare 1fr means
   minmax(auto, 1fr), and auto refuses to shrink below min-content, so with
   white-space:nowrap on .priority-name one long client name made the column
   wider than the screen and the row hung off the edge (measured 387px in a
   375px viewport). */
@media (max-width: 1150px) {
  .priority-list { --priority-cols: 2; }
}
@media (max-width: 760px) {
  .priority-list { --priority-cols: 1; }
}

/* ── Email Cards ─────────────────────────────────────────────────────────────── */
.email-card {
  background: transparent; border-radius: var(--radius-lg);
  margin-bottom: 10px; overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 40%, transparent); border-top: 3px solid var(--brand-gold);
}
.email-card-header {
  padding: 10px 14px;
  display: flex; align-items: flex-start; gap: 14px;
  border-bottom: 1px solid var(--gray-100);
  background: transparent; color: #FFFFFF;
}
.email-avatar {
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--blue-800); color: var(--white);
  font-size: 16px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.email-meta    { flex: 1; min-width: 0; }
.email-from    { font-weight: 700; font-size: 14px; color: var(--gray-900); }
.email-subject { font-size: 13px; color: var(--gray-700); margin-top: 2px; }
.email-preview { font-size: 12px; color: var(--gray-500); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.email-time    { font-size: 11px; color: var(--gray-500); white-space: nowrap; margin-left: auto; }
.email-client-tag {
  display: inline-block; font-size: 11px; font-weight: 600;
  padding: 2px 8px; border-radius: 10px; margin-top: 4px;
}
.tag-buyer  { background: var(--green-light); color: var(--green); }
.tag-seller { background: var(--gold-light);  color: #7a5a00; }
.tag-contact{ background: var(--blue-100);    color: var(--blue-800); }
.tag-unknown{ background: var(--gray-100);    color: var(--gray-700); }

.email-draft-section { padding: 12px 16px; background: transparent; }
.email-draft-label   { font-size: 12px; font-weight: 700; color: var(--blue-800); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 8px; }
.email-draft-text {
  background: transparent; border-radius: 8px; padding: 14px 16px;
  font-size: 13px; line-height: 1.7; white-space: pre-wrap; border: 1.5px solid var(--gray-300);
  max-height: 220px; overflow-y: auto;
}
.email-draft-actions { display: flex; gap: 8px; margin-top: 10px; }

/* ── Transaction Cards ───────────────────────────────────────────────────────── */
.txn-card {
  background: transparent; border-radius: var(--radius-lg);
  margin-bottom: 12px; overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 40%, transparent); border-top: 3px solid var(--brand-gold);
}
.txn-card-header {
  padding: 10px 14px;
  display: flex; align-items: center; justify-content: space-between;
  border-bottom: 1px solid var(--gray-100);
  background: transparent; color: #FFFFFF;
}
.txn-type-badge {
  font-size: 11px; font-weight: 700; padding: 3px 10px; border-radius: 10px;
  text-transform: uppercase; letter-spacing: .5px; margin-right: 10px;
}
.txn-type-badge.buyer  { background: var(--green-light); color: var(--green); }
.txn-type-badge.seller { background: var(--gold-light);  color: #7a5a00; }
.txn-client-name   { font-size: 16px; font-weight: 700; color: var(--brand-gold); font-family: var(--serif); }
.txn-property-addr { font-size: 13px; color: #D1D5DB; margin-top: 2px; }
.txn-stage-label   { font-size: 12px; color: #D1D5DB; font-style: italic; }
.txn-closing-date  { font-size: 13px; font-weight: 600; color: var(--blue-800); }

.txn-progress-bar {
  height: 6px; background: var(--gray-100); position: relative;
}
.txn-progress-fill {
  height: 100%; border-radius: 3px; transition: width .5s;
  background: linear-gradient(90deg, var(--blue-700), var(--gold));
}

.txn-body { padding: 10px 14px; }
.txn-info-row {
  display: flex; gap: 24px; flex-wrap: wrap;
  font-size: 12px; color: var(--gray-500); margin-bottom: 8px;
}
.txn-info-item strong { color: var(--gray-900); display: block; margin-bottom: 1px; }

.task-list { display: flex; flex-direction: column; gap: 0; }
.task-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 0; border-bottom: 1px solid var(--gray-100);
  font-size: 13px;
}
.task-item:last-child { border-bottom: none; }
.task-checkbox {
  width: 18px; height: 18px; border: 2px solid var(--gray-300);
  border-radius: 4px; cursor: pointer; flex-shrink: 0; appearance: none;
  display: flex; align-items: center; justify-content: center;
  transition: all .1s; position: relative;
}
.task-checkbox:checked {
  background: var(--green); border-color: var(--green);
}
.task-checkbox:checked::after {
  content: '✓'; color: white; font-size: 11px; font-weight: 700;
  position: absolute;
}
.task-label { flex: 1; }
.task-item.completed .task-label { text-decoration: line-through; color: var(--gray-500); }
.task-due {
  font-size: 11px; white-space: nowrap; padding: 2px 7px; border-radius: 6px;
}
.task-due.overdue   { background: var(--red-light);    color: var(--red);    font-weight: 700; }
.task-due.due-today { background: var(--orange-light);  color: var(--orange); font-weight: 700; }
.task-due.due-soon  { background: var(--yellow-light);  color: var(--yellow); }
.task-due.future    { color: var(--gray-500); }
.task-due.done      { color: var(--green); }

.txn-notes {
  margin-top: 14px; padding: 12px 14px;
  background: transparent; border-radius: 8px;
  font-size: 12px; color: var(--blue-800); font-style: italic;
}
.txn-notes strong { font-style: normal; }

/* ── Alerts ──────────────────────────────────────────────────────────────────── */
.alert-banner {
  border-radius: var(--radius); padding: 12px 16px; margin-bottom: 12px;
  display: flex; align-items: flex-start; gap: 10px; font-size: 13px;
}
.alert-overdue { background: var(--red-light);    border-left: 4px solid var(--red); }
.alert-due     { background: var(--orange-light); border-left: 4px solid var(--orange); }
.alert-icon    { font-size: 16px; flex-shrink: 0; margin-top: 1px; }
.alert-text    { flex: 1; }
.alert-count   { font-weight: 700; }

/* ── Contact Cards ───────────────────────────────────────────────────────────── */
.contact-card {
  /* solid, not frosted -- see --navy-panel in tokens.css */
  background: var(--navy-panel);
  border-radius: var(--radius-lg);
  margin-bottom: 10px; overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 40%, transparent); border-top: 3px solid var(--brand-gold);
}
/* Follow-Up: collapsed cards shrink to fit the contact line (ending after "new lead")
   with the +/- pill; expanding opens the card to full width to show the message. */
.contact-card.collapsed { width: fit-content; max-width: 100%; }
.contact-card.collapsed .draft-toggle-btn { margin-left: 8px; }
.contact-meta-block { flex: 1; }
.contact-card-header {
  padding: 10px 14px;
  display: flex; align-items: center; gap: 10px;
  border-bottom: 1px solid var(--gray-100);
  background: transparent; color: #FFFFFF;
}
.contact-avatar {
  width: 46px; height: 46px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 700; color: var(--white); flex-shrink: 0;
}
.contact-meta-block { min-width: 0; }
.contact-name { font-size: 14px; font-weight: 700; color: var(--brand-gold); font-family: var(--serif); overflow-wrap: anywhere; }
.contact-meta { font-size: 11px; color: #D1D5DB; margin-top: 2px; display: flex; gap: 10px; flex-wrap: nowrap; overflow: hidden; }
.days-since {
  font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 10px;
  margin-left: auto; white-space: nowrap; flex-shrink: 0;
}
.days-since.urgent   { background: var(--red-light);    color: var(--red); }
.days-since.moderate { background: var(--orange-light); color: var(--orange); }
.days-since.mild     { background: var(--yellow-light); color: var(--yellow); }

/* Round +/- open-close pill on the right of each lead card: + to open, - to close. */
.draft-toggle-btn {
  flex: none; margin-left: auto; width: 30px; height: 30px; border-radius: 999px;
  background: var(--brand-gold); color: #0d1b2a; border: none; cursor: pointer;
  font-size: 20px; font-weight: 700; line-height: 1; display: grid; place-items: center; padding: 0;
}
.draft-toggle-btn::before { content: '\2212'; }
.contact-card.collapsed .draft-toggle-btn::before { content: '+'; }
/* Social suggestion cards collapse the same way: +/- pill, title trimmed to one line,
   the "why now" note and the format buttons hidden until opened. */
#tab-social .card.collapsed .title {
  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden;
}
#tab-social .card.collapsed .card-sub-inline { display: none; }
#tab-social .card.collapsed .format-pill-row { display: none; }
#tab-social .card.collapsed .draft-toggle-btn::before { content: '+'; }
.contact-notes-section { padding: 6px 14px; border-top: 1px solid var(--gray-100); font-size: 12px; color: var(--gray-700); font-style: italic; overflow-wrap: anywhere; }
.category-badge {
  display: inline-block; font-size: 11px; font-weight: 600;
  padding: 2px 8px; border-radius: 10px;
  margin-left: auto; flex-shrink: 0; white-space: nowrap;
}
.cat-past_client  { background: var(--green-light); color: var(--green); }
.cat-lead         { background: var(--blue-100);    color: var(--blue-800); }
.cat-referral     { background: var(--gold-light);  color: #7a5a00; }
.cat-professional { background: var(--gray-100);    color: var(--gray-700); }
.cat-sphere       { background: #f0e8ff;            color: #6a3db5; }

/* ── Social Media — Theme Bar ────────────────────────────────────────────────── */
.social-theme-bar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  background: transparent;
  border-radius: var(--radius-lg); padding: 16px 24px; margin-bottom: 20px;
  color: var(--white);
}
.social-theme-badge {
  background: var(--gold); color: #0D1B2A; font-size: 11px; font-weight: 800;
  padding: 4px 11px; border-radius: 20px; white-space: nowrap;
  text-transform: uppercase; letter-spacing: .5px; flex-shrink: 0;
}
.social-theme-name { font-size: 16px; font-weight: 700; color: var(--gold); }
.social-theme-desc { font-size: 12px; opacity: .75; font-style: italic; }

/* ── Social Section Wrapper ──────────────────────────────────────────────────── */
.social-section {
  background: transparent; border-radius: var(--radius-lg);
  margin-bottom: 20px; overflow: hidden;
}
.social-section-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 20px; border-bottom: 2px solid var(--gray-100);
  background: transparent; gap: 12px; flex-wrap: wrap;
}
.social-section-title-block { display: flex; align-items: center; gap: 12px; }
.social-section-icon {
  font-size: 22px; flex-shrink: 0;
  width: 38px; height: 38px; display: flex; align-items: center; justify-content: center;
}
.social-section-icon.platform-fb { background: #1877f2; border-radius: 8px; color: white; font-size: 18px; font-weight: 900; }
.social-section-icon.platform-li { background: #0a66c2; border-radius: 8px; color: white; font-size: 14px; font-weight: 900; }
.social-section-label { font-size: 15px; font-weight: 700; color: var(--blue-900); }
.social-section-sublabel { font-size: 11px; color: var(--gray-500); margin-top: 2px; }
.social-section-body { padding: 20px; }

/* ── Carousel Slides ─────────────────────────────────────────────────────────── */
.carousel-slides-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; padding: 20px;
}
.carousel-slide-card {
  border: 2px solid var(--gray-100); border-radius: 10px;
  padding: 16px; display: flex; flex-direction: column; gap: 8px;
  transition: border-color .15s;
}
.carousel-slide-card:hover { border-color: var(--brand-gold); }
.carousel-slide-number {
  font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .8px;
  color: var(--white); background: #0D1B2A;
  display: inline-block; padding: 3px 9px; border-radius: 6px; width: fit-content;
}
.carousel-slide-headline {
  font-size: 15px; font-weight: 800; color: #0D1B2A; line-height: 1.3;
}
.carousel-slide-body {
  font-size: 12px; color: var(--gray-700); line-height: 1.65; flex: 1;
}
.carousel-slide-design {
  font-size: 11px; color: var(--gray-500); font-style: italic;
  background: var(--gray-100); border-radius: 6px; padding: 7px 9px; line-height: 1.5;
}

/* ── Reel Script ─────────────────────────────────────────────────────────────── */
.reel-hook {
  background: linear-gradient(135deg, var(--brand-gold) 0%, #dfc070 100%);
  border-radius: 10px; padding: 16px 20px; margin-bottom: 14px;
}
.reel-hook-label {
  font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .8px;
  color: #0D1B2A; margin-bottom: 6px;
}
.reel-hook-text { font-size: 18px; font-weight: 800; color: #0D1B2A; line-height: 1.3; }
.reel-slides-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.reel-slide-item {
  display: flex; align-items: center; gap: 12px;
  background: transparent; border-radius: 8px; padding: 10px 14px;
}
.reel-slide-num {
  width: 26px; height: 26px; border-radius: 50%;
  background: #0D1B2A; color: var(--white);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; flex-shrink: 0;
}
.reel-slide-text { font-size: 13px; font-weight: 600; color: var(--gray-900); }
.reel-cta-block {
  background: transparent; border-left: 4px solid var(--blue-700);
  border-radius: 8px; padding: 12px 16px; margin-bottom: 12px;
}
.reel-cta-label {
  font-size: 10px; font-weight: 800; color: var(--blue-800);
  text-transform: uppercase; letter-spacing: .6px; margin-bottom: 4px;
}
.reel-cta-text { font-size: 13px; font-weight: 700; color: var(--blue-900); }
.reel-broll-block {
  background: transparent; border-left: 4px solid var(--gray-300);
  border-radius: 8px; padding: 12px 16px;
}
.reel-broll-label {
  font-size: 10px; font-weight: 800; color: var(--gray-700);
  text-transform: uppercase; letter-spacing: .6px; margin-bottom: 4px;
}
.reel-broll-text { font-size: 12px; color: var(--gray-700); font-style: italic; line-height: 1.6; }

/* ── Long-form text boxes (Facebook, LinkedIn, Caption) ──────────────────────── */
.long-post-box {
  background: transparent; border-radius: 10px; padding: 18px 20px;
  font-size: 13px; line-height: 1.8; color: var(--gray-900);
  white-space: pre-wrap; border: 1.5px solid var(--gray-300);
  max-height: 300px; overflow-y: auto; margin-bottom: 12px;
}
.comment-question-box {
  background: transparent; border-left: 4px solid var(--blue-700);
  border-radius: 8px; padding: 12px 16px; font-size: 13px; color: var(--blue-900);
  margin-bottom: 12px;
}
.hashtag-box {
  background: transparent; border: 1.5px solid #c0d4ff; border-radius: 8px;
  padding: 12px 16px; font-size: 13px; color: #1877f2;
  font-weight: 600; line-height: 1.8; margin-bottom: 12px; word-break: break-word;
}

/* ── Canva Design Brief ───────────────────────────────────────────────────────── */
.canva-brief-meta {
  display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 18px;
  padding-bottom: 18px; border-bottom: 1px solid var(--gray-100);
}
.canva-meta-item {
  background: transparent; border-radius: 8px; padding: 12px 14px; flex: 1; min-width: 180px;
}
.canva-meta-label {
  font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .6px;
  color: var(--gray-500); margin-bottom: 5px;
}
.canva-meta-value { font-size: 13px; color: var(--gray-900); line-height: 1.55; }
.canva-color-chips { display: flex; gap: 8px; align-items: center; margin-top: 8px; }
.canva-color-chip {
  width: 28px; height: 28px; border-radius: 6px; border: 2px solid var(--gray-300);
  display: inline-block; flex-shrink: 0; cursor: default;
}
.canva-slides-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
}
.canva-slide-brief {
  border: 1.5px solid var(--brand-gold); border-radius: 10px; padding: 14px;
  background: transparent;
}
.canva-slide-num {
  font-size: 10px; font-weight: 800; color: #7a5a00;
  text-transform: uppercase; letter-spacing: .6px; margin-bottom: 6px;
}
.canva-slide-layout {
  font-size: 12px; color: var(--gray-900); line-height: 1.65; margin-bottom: 6px;
}
.canva-slide-image { font-size: 11px; color: var(--gray-500); font-style: italic; }

/* ── Legacy social grid kept for fallback ────────────────────────────────────── */
.social-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.social-card { background: transparent; border-radius: var(--radius-lg); overflow: hidden; }
.social-header { padding: 14px 18px; display: flex; align-items: center; gap: 10px; border-bottom: 1px solid var(--gray-100); }
.social-icon { width: 34px; height: 34px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0; }
.social-icon.facebook  { background: #1877f2; }
.social-icon.instagram { background: linear-gradient(135deg, #e1306c, #833ab4); }
.social-icon.linkedin  { background: #0a66c2; }
.social-platform { font-size: 15px; font-weight: 700; color: var(--gray-900); }
.social-theme    { font-size: 11px; color: var(--gray-500); margin-top: 2px; }
.social-body     { padding: 16px 18px; }
.social-text { font-size: 13px; line-height: 1.7; color: var(--gray-900); white-space: pre-wrap; min-height: 80px; }
.social-hashtags { font-size: 12px; color: #1877f2; margin-top: 8px; font-weight: 500; }
.social-footer { padding: 12px 18px; border-top: 1px solid var(--gray-100); display: flex; gap: 8px; }

/* ── Empty State ─────────────────────────────────────────────────────────────── */
.empty-state {
  text-align: center;
  padding: 32px 28px;
  color: #ffffff;
  background: rgba(13, 27, 42, 0.78);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 35%, transparent);
  border-radius: 14px;
  max-width: 520px;
  margin: 40px auto;
  text-shadow: 0 1px 4px rgba(0,0,0,0.7);
}
.empty-icon { font-size: 48px; margin-bottom: 16px; }
.empty-state h2 { font-size: 22px; font-weight: 700; color: #ffffff; margin-bottom: 8px; }
.empty-state p  { font-size: 14px; max-width: 400px; margin: 0 auto 24px; color: #cdd5e0; }
#overviewEmpty {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
  max-height: none !important;
  height: auto !important;
  overflow: visible !important;
  margin-top: 0 !important;
}
#overviewEmpty .briefing-empty-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0;
  width: 100vw;
  margin-left: calc(-1 * (100vw - 100%) / 2 - 100px);
}
.briefing-empty-shield {
  max-width: 340px;
  max-height: 46vh;
  width: auto;
  height: auto;
  display: block;
  margin: 0 auto;
}

/* ── Contact Import Welcome Pill ───────────────────────────────────────────────── */
.welcome-pill-wrap {
  position: relative;
  max-width: 100%;
  margin: 0 auto 16px;
  text-align: center;
}
.welcome-pill-bg {
  width: 100%;
  height: auto;
  display: block;
  pointer-events: none;
  user-select: none;
}
.welcome-pill-text {
  position: absolute;
  top: 55%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #fff;
  font-family: 'Cinzel', var(--serif);
  font-size: 1.5rem;
  font-weight: 600;
  white-space: nowrap;
  margin: 0;
  letter-spacing: 0.5px;
  text-shadow: 0 2px 8px rgba(0,0,0,0.7);
}

/* Contact import card sits flush on the castle-storm bg — no card chrome */
#contactImportCard {
  background: transparent !important;
  background-color: transparent !important;
  border: none !important;
  box-shadow: none !important;
  transform: translateX(-150px) !important;
}
.skip-import-link-wrap {
  display: block;
  text-align: center;
  margin-top: 16px;
}
.skip-import-link {
  background: none;
  border: none;
  padding: 0;
  color: rgba(255, 255, 255, 0.72);
  font-size: 14px;
  font-family: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.skip-import-link:hover { color: var(--brand-gold); }
@keyframes contactReminderPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.2; }
}
.contact-import-reminder {
  display: inline-block;
  margin-top: 8px;
  color: var(--brand-gold);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  animation: contactReminderPulse 2s ease-in-out infinite;
}
.contact-import-reminder[hidden] { display: none; }
.contact-import-reminder:hover {
  text-decoration: underline;
  animation: none;
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .contact-import-reminder { animation: none; opacity: 1; }
}

/* ── Loading ──────────────────────────────────────────────────────────────────── */
.loading-overlay {
  position: fixed; inset: 0; background: rgba(0,3,40,0.65); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; z-index: 1000;
}
.loading-card {
  background: var(--white); border-radius: var(--radius-lg);
  padding: 36px 48px; text-align: center; box-shadow: var(--shadow-lg); min-width: 340px;
}
.spinner {
  width: 44px; height: 44px; border: 4px solid var(--gray-100);
  border-top-color: var(--blue-800); border-radius: 50%;
  animation: spin .8s linear infinite; margin: 0 auto 20px;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loading-title { font-size: 17px; font-weight: 700; color: var(--blue-900); margin-bottom: 16px; }
.loading-steps { text-align: left; }
.loading-step {
  font-size: 13px; color: var(--gray-300); padding: 5px 0 5px 22px; position: relative;
}
.loading-step::before { content: '○'; position: absolute; left: 0; }
.loading-step.active  { color: var(--blue-800); font-weight: 600; }
.loading-step.active::before  { content: '●'; color: var(--gold); }
.loading-step.done    { color: var(--green); }
.loading-step.done::before    { content: '✓'; }

/* ── Modals ──────────────────────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0,3,40,0.55); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; z-index: 200; padding: 20px;
}
.modal {
  background: var(--white); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); width: 100%; max-width: 640px; max-height: 90vh;
  display: flex; flex-direction: column;
}
.modal-header {
  padding: 20px 24px; border-bottom: 1px solid var(--gray-100);
  display: flex; align-items: center; justify-content: space-between;
}
.modal-header h3 { font-size: 18px; font-weight: 700; color: var(--blue-900); }
.modal-close { background: none; border: none; font-size: 18px; cursor: pointer; color: var(--gray-500); padding: 4px 8px; }
.modal-close:hover { color: var(--gray-900); }
.modal-body  { padding: 20px 24px; overflow-y: auto; flex: 1; }
.modal-footer{ padding: 16px 24px; border-top: 1px solid var(--gray-100); display: flex; justify-content: flex-end; gap: 10px; }

.form-row    { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
.form-group  { display: flex; flex-direction: column; gap: 5px; }
.form-group label { font-size: 12px; font-weight: 600; color: var(--gray-700); text-transform: uppercase; letter-spacing: .4px; }
.form-group input,
.form-group select,
.form-group textarea {
  padding: 8px 12px; border: 1.5px solid var(--gray-300); border-radius: 8px;
  font-size: 14px; color: var(--gray-900); background: var(--white);
  transition: border-color .15s;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus { outline: none; border-color: var(--blue-700); }

/* ── Site Footer ─────────────────────────────────────────────────────────────── */
.site-footer {
  background: transparent;
  color: rgba(255, 255, 255, 0.65);
  text-align: center;
  padding: 6px 28px;
  margin-top: auto;
  /* The page bodies are 100vh flex columns; without this the footer is a
     shrinkable flex child and the disclaimer gets clipped. Several tabs already
     set this individually - this covers the rest (overview, pipeline,
     contact-detail, email-drafts, opportunity). */
  flex-shrink: 0;
}
.footer-disclaimer {
  font-size: 12px;
  line-height: 1.6;
  max-width: 720px;
  margin: 0 auto 8px;
  color: rgba(255, 255, 255, 0.8);
}
.footer-legal {
  font-size: 11px;
  opacity: 0.5;
  letter-spacing: 0.2px;
}

/* ── Toast ────────────────────────────────────────────────────────────────────── */
.toast-container { position: fixed; bottom: 24px; right: 24px; z-index: 500; display: flex; flex-direction: column; gap: 10px; }
.toast {
  background: var(--gray-900); color: var(--white);
  padding: 12px 18px; border-radius: 10px; font-size: 13px; font-weight: 500;
  box-shadow: var(--shadow-lg); animation: slideIn .2s; max-width: 320px;
}
.toast.success { background: var(--green); }
.toast.error   { background: var(--red); }
@keyframes slideIn { from { transform: translateX(120%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }

/* ── Pipeline (Dashboard Overview) ─────────────────────────────────────────────── */
.pipeline-section { margin-bottom: 18px; }
.pipeline-section .section-title { margin-bottom: 14px; }
.pipeline-empty { color: var(--gray-500); padding: 8px 0; }

/* Fills top-to-bottom, left-to-right: the first deal sits top-left, the row
   fills rightward, then the next row stacks beneath it. With seven deals that
   is four along the top and three underneath.

   This used to run the other way, on flex-wrap: wrap-reverse, so the first
   deal sat bottom-left and rows stacked upward. That existed because the whole
   pipeline was anchored to the bottom of the screen and the ragged row read
   better at the top of a bottom-anchored stack. The tab now starts at the top
   like every other tab (see the pipeline block near the end of this file), so
   the cards read downward from the top, the way everything else does.

   Was a 4-column grid. The flex-basis breakpoints below reproduce its column
   counts exactly, subtracting the shared gap so the maths matches what
   grid-template-columns was doing. */
.pipeline-cards,
.pipeline-stage__cards {
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  justify-content: flex-start;
  gap: 8px;
}
.pipeline-cards > *,
.pipeline-stage__cards > * { flex: 0 0 calc(25% - 6px); max-width: 250px; }
@media (max-width: 1300px) { .pipeline-cards > *, .pipeline-stage__cards > * { flex-basis: calc(33.333% - 5.34px); } }
@media (max-width: 1000px) { .pipeline-cards > *, .pipeline-stage__cards > * { flex-basis: calc(50% - 4px); max-width: none; } }
@media (max-width: 600px)  { .pipeline-cards > *, .pipeline-stage__cards > * { flex-basis: 100%; } }

/* Holding stage sections, the board is a column of them rather than a row of
   cards, so the two-class selector has to outrank the breakpoints above. */
.pipeline-cards.pipeline-stages {
  flex-direction: column;
  flex-wrap: nowrap;
  gap: 3px;
}
.pipeline-cards.pipeline-stages > * { flex: 0 0 auto; max-width: none; }

/* The heading IS the control, and it carries its own count so a folded stage
   still says how many deals are behind it. */
.pipeline-stage__label {
  margin: 0 0 6px;
  padding-bottom: 1px;
  border-bottom: 1px solid color-mix(in srgb, var(--brand-gold) 25%, transparent);
}
.pipeline-stage.is-collapsed .pipeline-stage__label { margin-bottom: 0; }
.pipeline-stage__toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  background: transparent;
  border: 0;
  padding: 1px 0;
  cursor: pointer;
  font-family: 'Cinzel', Georgia, serif;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--brand-gold);
}
.pipeline-stage__toggle:hover { color: var(--gold-bright); }
.pipeline-stage__chev {
  font-size: 10px;
  line-height: 1;
  transition: transform 0.15s ease;
}
.pipeline-stage.is-collapsed .pipeline-stage__chev { transform: rotate(-90deg); }
/* A count drawn over the empty right-hand end of a pill, the way the inbox
   piles do it, rather than trailing outside the artwork. Positioned from the
   right because the bar ends at a fixed fraction of the image whatever the
   render height, while the label lengths differ. Shared by the pipeline stage
   headings and the follow-up week. */
.art-pill {
  position: relative;
  display: inline-block;
  line-height: 0;
  min-width: 0;
  flex-shrink: 1;
}
.art-pill__count {
  position: absolute;
  /* The bar interior ends at about 86% of the artwork, the rest being the
     pointed end. 6% put the number on the flourish; this keeps it on the bar. */
  right: 16%;
  top: 50%;
  transform: translateY(-50%);
  pointer-events: none;
  line-height: 1;
}

/* The stage name as artwork rather than as type. Sized so the pill's BODY
   reads at roughly the heading size it replaced: only about 70% of the image
   height is the bar, the rest being the pointed ends, so 30px of image gives a
   21px bar against the 13px Cinzel it stands in for. The name still reaches a
   screen reader through the alt text. */
.pipeline-stage__pill {
  display: block;
  /* Deliberately just under the 38px of the Active pipeline / Closed
     transactions switch below the board: a group heading should not outrank
     the control that switches the whole view, but at 30px it read as a
     different size of thing rather than a quieter one. */
  height: 35px;
  width: auto;
  max-width: 100%;
  flex-shrink: 1;
  min-width: 0;
}

.pipeline-stage__count {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0;
  color: #0d1b2a;
  background: var(--brand-gold);
  border-radius: 999px;
  padding: 1px 7px;
}

.pipeline-card {
  /* solid, not frosted -- see --navy-panel in tokens.css */
  background: var(--navy-panel);
  border: 1px solid var(--brand-gold);
  border-radius: 8px;
  padding: 8px 10px;
  color: #f0e6d0;
  font-size: 11px;
  transition: border-color 0.15s, transform 0.15s;
}
.pipeline-card:hover {
  border-color: #E0C16B;
  transform: translateY(-1px);
}

.pipeline-card__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
  margin-bottom: 5px;
}
/* The header used to hold exactly two children, so space-between put the stage
   left and the day count right. Adding the edit button made it a three-way
   spread that pushed the day count to the middle. Anchoring the day count with
   margin-left:auto keeps the original look and lets the button sit beside it.
   On a card with no deal to edit the button is absent and this is a no-op. */
.pipeline-card__days { margin-left: auto; }
.card-edit-btn {
  flex-shrink: 0;
  padding: 2px 8px;
  border-radius: 4px;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 45%, transparent);
  background: transparent;
  color: var(--brand-gold);
  font-size: 10px;
  font-weight: 600;
  cursor: pointer;
}
.card-edit-btn:hover { background: color-mix(in srgb, var(--brand-gold) 14%, transparent); }
.pipeline-card__stage {
  padding: 3px 8px;
  border-radius: 4px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.pipeline-card__stage--active_buyer   { background: #4ade80; color: #052e16; }
.pipeline-card__stage--active_seller  { background: #2dd4bf; color: #042f2e; }
/* Signed listing agreement, listing not live yet (List Date in the future).
   Rendered as a chip NEXT TO the Active Seller PNG banner, not instead of it. */
.pipeline-card__stage--pre_listing {
  background: color-mix(in srgb, var(--brand-gold) 22%, transparent);
  color: #E0C16B;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 55%, transparent);
  margin-left: 6px;
}
.pipeline-card__stage--buyer_seller   { background: #8b5cf6; color: #fff; }
.pipeline-card__stage--under_contract { background: var(--brand-gold); color: #000; }
.pipeline-card__stage--pending        { background: #f59e0b; color: #2a1700; }
.pipeline-card__stage--contingent     { background: #e67e22; color: #fff; }
/* Closed Transactions archive. Muted on purpose: a finished deal should read
   as history beside a live card, not compete with it for attention. Only a
   completed sale gets the gold; the three ways a deal ends without closing are
   deliberately grey rather than red, because a fallen-through deal is a normal
   part of the job, not an error state. */
.pipeline-card__stage--closed         { background: var(--brand-gold); color: #000; }
.pipeline-card__stage--cancelled,
.pipeline-card__stage--fell_through,
.pipeline-card__stage--expired {
  background: color-mix(in srgb, var(--brand-gold) 14%, transparent);
  color: #c9cdd4;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 35%, transparent);
}
.pipeline-card--cancelled,
.pipeline-card--fell_through,
.pipeline-card--expired { opacity: 0.82; }

/* Go-live prompts. A question, not an alert: the yard sign not being up two
   days before go-live is normal, so this must not read like something is
   wrong. Gold border, no red. */
.go-live-prompts { margin: 0 0 16px; display: flex; flex-direction: column; gap: 8px; }
/* Getting started (7A, 2026-09-25). Compact and to the left, clear of the
   castle. */
.getting-started {
  max-width: 620px;
  margin: 0 0 14px;
  padding: 12px 16px;
  background: rgba(13, 27, 42, 0.92);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 45%, transparent);
  border-radius: 8px;
}
.getting-started[hidden] { display: none; }
.getting-started__head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.getting-started__title { color: var(--brand-gold); font-weight: 700; font-size: 15px; }
.getting-started__count { color: #b9c2ce; font-size: 13px; }
.getting-started__hide {
  margin-left: auto; padding: 0; background: none; border: 0;
  color: #b9c2ce; font-size: 12px; text-decoration: underline; cursor: pointer;
}
.getting-started__list { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 8px; }
.getting-started__item { display: flex; gap: 10px; align-items: flex-start; }
.getting-started__mark {
  flex: 0 0 18px; height: 18px; margin-top: 2px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid color-mix(in srgb, var(--brand-gold) 70%, transparent);
  border-radius: 50%; font-size: 11px; font-weight: 800; color: #0d1b2a;
}
.getting-started__item.is-done .getting-started__mark { background: var(--brand-gold); border-color: var(--brand-gold); }
.getting-started__text { display: flex; flex-direction: column; min-width: 0; }
.getting-started__label { color: #fff; font-size: 14px; font-weight: 600; }
a.getting-started__label { color: var(--gold-bright); text-decoration: underline; }
.getting-started__item.is-done .getting-started__label { color: #9fb0c0; font-weight: 500; }
.getting-started__why { color: #b9c2ce; font-size: 12px; line-height: 1.4; }
.getting-started .sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

.go-live-prompt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 10px 14px;
  background: rgba(13, 27, 42, 0.92);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 45%, transparent);
  border-radius: 8px;
}
.go-live-prompt__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.go-live-prompt__question { color: var(--brand-gold); font-size: 14px; font-weight: 600; }
.go-live-prompt__where { color: #c9cdd4; font-size: 11px; }
.go-live-prompt__actions { display: flex; gap: 8px; flex-shrink: 0; }
.go-live-prompt__yes,
.go-live-prompt__no {
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 45%, transparent);
}
.go-live-prompt__yes { background: var(--brand-gold); color: #000; }
.go-live-prompt__yes:disabled { opacity: 0.5; cursor: default; }
.go-live-prompt__no { background: transparent; color: #c9cdd4; }
.go-live-prompt__no:hover { background: color-mix(in srgb, var(--brand-gold) 12%, transparent); }

.archive-card__dates {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid color-mix(in srgb, var(--brand-gold) 18%, transparent);
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.archive-card__date {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 11px;
  color: #c9cdd4;
}
.archive-card__date span:last-child { color: var(--brand-gold); white-space: nowrap; }

.archive-link {
  display: inline-block;
  margin: 18px 0 0;
  padding: 8px 14px;
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 45%, transparent);
  border-radius: 6px;
  color: var(--brand-gold);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  cursor: pointer;
}
/* The two Pipeline views sit side by side so neither disappears and neither
   moves. It keeps the single link's old spot at the foot of the section:
   putting a nav row above the cards would push them down and undo the top
   alignment. The margin is on the row now that it holds ornate pills rather
   than text buttons, which carried their own. */
.pipeline-switch {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin: 0 0 14px;
}
/* Sized to the deal cards beside them rather than to the nav rows, which run
   48px in a full-width bar. The current one is marked by the shared
   .section-pill.is-active glow. */
.pipeline-switch .section-pill img { height: 38px; }
/* Beside the two pills, not out on the right: in the medieval look the right
   side of the page is the castle, and content stays compact and left of it. */
.pipeline-switch .pipeline-add { margin-left: 8px; }

/* How much is on the board behind each destination, drawn over the right end of
   the bar rather than trailing outside the artwork. Same circle as
   .pipeline-stage__count, so the two counts on screen together match. */
.pipeline-switch__count {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0;
  color: #0d1b2a;
  background: var(--brand-gold);
  border-radius: 999px;
  padding: 1px 7px;
}
/* Whether 75-84% is clear bar or the last two letters of the label depends
   entirely on the artwork, and the two pills are not alike. The first Closed
   Transactions pill ran its label to 79.5% of the image, so the count sat on
   the end of it and the pill read "Closed Transactio"; it was switched off
   here until Rich drew one with room. Both now stop around 65% and clear it.
   Measure a replacement on the GLYPH BAND -- rows 38-62% of height, luminance
   over 110. The wider, brighter measurement that looks equivalent (30-70% of
   height, luminance 150) washes gold-on-navy lettering out and reports a full
   label as empty bar, which is how the broken one shipped.
   tests/unit/pipelineSwitch.test.js pins both files so a new pill cannot
   inherit a position that was only ever measured against the old one. */

.archive-link:hover { background: color-mix(in srgb, var(--brand-gold) 12%, transparent); }
.archive-link:focus-visible { outline: 2px solid var(--brand-gold); outline-offset: 2px; }

.pipeline-card__days { color: var(--brand-gold); font-size: 11px; }

.pipeline-card__names {
  font-size: 13px;
  font-weight: 500;
  color: #ffffff;
  margin-bottom: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pipeline-card__name { color: var(--brand-gold); cursor: pointer; }
.pipeline-card__name:hover { color: #E0C16B; text-decoration: underline; }
.pipeline-card__name:focus-visible { outline: 2px solid var(--blue-700); outline-offset: 2px; }

.pipeline-card__phones {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 10px;
  color: #c8b98a;
  margin-bottom: 4px;
}

.pipeline-card__address {
  font-size: 11px;
  font-weight: 600;
  color: var(--gray-500);
  margin-bottom: 3px;
}
/* Closing / contingency alert, on its own line under the address so the
   pill never wraps mid-text. line-height gives the padded pill room. */
.pipeline-card__closing {
  font-size: 11px;
  line-height: 1.7;
  margin-bottom: 3px;
}
.closing--ok     { color: #e8e8e8; }
.closing--soon   { color: var(--brand-gold); }
.closing--urgent { color: var(--status-red); }   /* 4.62:1 on --navy-panel; #ef4444 measured 4.42 and missed the bar */
.closing--past   { color: #9ca3af; font-style: italic; }
/* Active-deal alerts (pending/contingent only). See buildAddressLine in app.js. */
.closing--overdue {
  color: #fff;
  background: var(--status-red-solid);   /* white needs the darker red, see tokens.css */
  border-radius: 4px;
  padding: 1px 8px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.closing--missing {
  color: #9ca3af;
  font-style: italic;
}

.pipeline-card__last-contact {
  font-size: 10px;
  color: rgba(240, 230, 208, 0.6);
  margin-bottom: 5px;
}

.pipeline-card__progress {
  margin-top: 3px;
  padding-top: 5px;
  border-top: 1px solid color-mix(in srgb, var(--brand-gold) 25%, transparent);
}
.pipeline-card__progress-text {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: #E5E7EB;
  margin-bottom: 6px;
}
.pipeline-card__progress-count {
  font-weight: 600;
  color: var(--brand-gold);
}
.pipeline-card__progress-bar {
  height: 4px;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 3px;
  overflow: hidden;
}
.pipeline-card__progress-fill {
  height: 100%;
  background: var(--brand-gold);
  border-radius: 3px;
  width: 0;
  transition: width 0.3s ease;
  box-shadow: 0 0 6px color-mix(in srgb, var(--brand-gold) 40%, transparent);
}
.pipeline-card__overdue {
  color: #F87171;
  font-weight: 700;
  font-size: 12px;
  white-space: nowrap;
}
.pipeline-card__urgent {
  color: #F59E0B;
  font-weight: 700;
  font-size: 12px;
  white-space: nowrap;
  margin-right: 8px;
}
.urgent-deadlines-banner {
  /* Amber over 18%/8% transparency put this text straight on top of the castle,
     which is why it was hard to read. It went to 92% navy; 2026-08-19 it went
     the last 8% to fully solid, with the amber kept for the border and the
     type. Nothing shows through a warning. */
  background: var(--navy-panel);
  border: 1px solid #F59E0B;
  color: #F59E0B;
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 12px;
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.75);
}
.urgent-deadlines-banner strong { color: #FBBF24; }

/* ── Checklist email reference (pill + attach + picker/viewer modals) ── */
.checklist-row__ref {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 4px;
}
.checklist-row__ref-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: color-mix(in srgb, var(--brand-gold) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 40%, transparent);
  color: var(--brand-gold);
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  max-width: 340px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.checklist-row__ref-link:hover { background: color-mix(in srgb, var(--brand-gold) 24%, transparent); }
.checklist-row__ref-link span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 280px;
}
.checklist-row__ref-remove {
  background: transparent;
  border: none;
  color: #8b95a0;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.checklist-row__ref-remove:hover { color: #F87171; }
.checklist-row__attach {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: 1px dashed color-mix(in srgb, var(--brand-gold) 35%, transparent);
  color: #8b95a0;
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 11px;
  cursor: pointer;
  margin-top: 4px;
  opacity: 0.7;
  transition: opacity 0.15s, color 0.15s;
}
.checklist-row__attach:hover { opacity: 1; color: var(--brand-gold); border-color: var(--brand-gold); }
.checklist-row.done .checklist-row__attach { display: none; }
.checklist-row.done .checklist-row__suggest { display: none; }
.checklist-row__attach-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
}
.checklist-row__suggest {
  background: transparent;
  border: 1px dashed rgba(59,130,246,0.35);
  color: #8b95a0;
  border-radius: 4px;
  padding: 2px 8px;
  font-size: 11px;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.15s, color 0.15s;
}
.checklist-row__suggest:hover { opacity: 1; color: #60A5FA; border-color: #60A5FA; }
.checklist-row__suggestions {
  flex-basis: 100%;
  margin-top: 4px;
  border: 1px solid #1f2f3f;
  border-radius: 4px;
  background: rgba(13,27,42,0.6);
  padding: 4px;
  max-height: 220px;
  overflow-y: auto;
}
.checklist-row__suggestion {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-bottom: 1px solid #1f2f3f;
  color: #e8e8e8;
  padding: 6px 8px;
  cursor: pointer;
}
.checklist-row__suggestion:last-child { border-bottom: none; }
.checklist-row__suggestion:hover { background: rgba(96,165,250,0.10); }
.checklist-row__suggestion-subj { font-size: 12px; font-weight: 600; margin-bottom: 2px; }
.checklist-row__suggestion-meta { font-size: 10px; color: #8b95a0; }
.checklist-row__suggest-loading,
.checklist-row__suggest-empty,
.checklist-row__suggest-error { color: #8b95a0; font-size: 11px; padding: 6px 8px; }
.checklist-row__suggest-error { color: #F87171; }
.checklist-row__conf {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: 700;
  margin-right: 4px;
  vertical-align: middle;
}
.checklist-row__conf--high { background: rgba(34,197,94,0.20); color: #4ADE80; border: 1px solid rgba(34,197,94,0.4); }
.checklist-row__conf--med  { background: rgba(245,158,11,0.20); color: #FBBF24; border: 1px solid rgba(245,158,11,0.4); }
.checklist-row__conf--low  { background: rgba(107,114,128,0.20); color: #9CA3AF; border: 1px solid rgba(107,114,128,0.4); }
.checklist-row__conf-reason { color: #c9cdd4; font-style: italic; }

.email-picker-modal, .email-viewer-modal {
  position: fixed; inset: 0;
  display: none;
  align-items: center; justify-content: center;
  background: rgba(0,0,0,0.72);
  z-index: 1000;
}
.email-picker-modal__panel, .email-viewer-modal__panel {
  background: #0D1B2A;
  border: 1px solid var(--brand-gold);
  border-radius: 8px;
  padding: 20px;
  max-width: 640px;
  width: 92%;
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  color: #e8e8e8;
}
.email-viewer-modal__panel { max-width: 800px; }
.email-picker-modal__title, .email-viewer-modal__title {
  color: var(--brand-gold);
  font-size: 18px;
  font-weight: 700;
  margin-bottom: 8px;
}
.email-picker-modal__desc {
  color: #c9cdd4;
  font-size: 13px;
  margin-bottom: 12px;
}
.email-picker-modal__filter {
  background: #1a2a3a;
  border: 1px solid #2a3a4a;
  color: #e8e8e8;
  padding: 8px 10px;
  border-radius: 4px;
  font-size: 13px;
  margin-bottom: 12px;
  width: 100%;
  box-sizing: border-box;
}
.email-picker-modal__error {
  color: #F87171;
  font-size: 13px;
  padding: 8px 0;
}
#email-picker-results {
  overflow-y: auto;
  flex: 1;
  min-height: 0;
  margin-bottom: 12px;
}
.email-picker-row {
  padding: 10px 12px;
  border-bottom: 1px solid #1f2f3f;
  cursor: pointer;
  transition: background 0.1s;
}
.email-picker-row:hover { background: color-mix(in srgb, var(--brand-gold) 10%, transparent); }
.email-picker-row__subject {
  color: #e8e8e8;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.email-picker-row__meta {
  color: #8b95a0;
  font-size: 11px;
}
.email-empty-hint { color: #8b95a0; font-size: 13px; padding: 12px 0; }
.email-picker-modal__actions { display: flex; justify-content: flex-end; gap: 8px; }

.email-viewer-modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 4px;
}
.email-viewer-modal__close {
  background: transparent;
  border: none;
  color: #8b95a0;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.email-viewer-modal__close:hover { color: #e8e8e8; }
.email-viewer-modal__meta {
  color: #c9cdd4;
  font-size: 12px;
  margin-bottom: 12px;
}
.email-viewer-modal__frame {
  flex: 1;
  min-height: 400px;
  border: 1px solid #1f2f3f;
  border-radius: 4px;
  background: #0D1B2A;
  width: 100%;
}

/* Day-count thresholds (shared by days-badge and last-contact row) */
.days--none, .days--ok { color: #C9CDD4; }
.days--warn            { color: #eab308; }
.days--late            { color: var(--status-red); }   /* see .closing--urgent */

/* ── Client Names ────────────────────────────────────────────────────────────── */
.client-name { color: var(--brand-gold); font-weight: 600; }
a.client-name:hover { color: #E0C16B; text-decoration: underline; }

/* ── Responsive ──────────────────────────────────────────────────────────────── */
/* .pipeline-cards is capped at 3 columns (see base rule + its own 1000px/600px
   breakpoints above) so Under Contract fills the top row, then active buyers/sellers. */
@media (max-width: 900px) {
  .social-grid          { grid-template-columns: 1fr; }
  .carousel-slides-grid { grid-template-columns: repeat(2, 1fr); }
  .canva-slides-grid    { grid-template-columns: repeat(2, 1fr); }
  .form-row             { grid-template-columns: 1fr; }
  .site-header          { flex-wrap: wrap; gap: 10px; padding: 12px 16px; }
  .header-right         { width: 100%; justify-content: space-between; }
  .main-content         { padding: 0 16px 32px; }
}
@media (max-width: 600px) {
  .carousel-slides-grid { grid-template-columns: 1fr; }
  .canva-slides-grid    { grid-template-columns: 1fr; }
  .canva-brief-meta     { flex-direction: column; }
  .social-theme-bar     { flex-direction: column; align-items: flex-start; gap: 8px; }
  .tab-btn span:first-child { display: none; }
  .txn-card-header      { flex-wrap: wrap; gap: 8px; }
}

/* ── Transaction modal typeahead picker (June 2026) ──────────────────────── */
.typeahead-wrap { position: relative; }

.typeahead-input {
  width: 100%;
  background: #1a1a1a;
  border: 1px solid #2a2a2a;
  border-radius: 8px;
  padding: 10px 12px;
  color: #e8e8e8;
  font-size: 14px;
  outline: none;
  box-sizing: border-box;
}
.typeahead-input:focus { border-color: var(--brand-gold); }
.typeahead-input::placeholder { color: #999; }

.typeahead-results {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 4px;
  background: #1a1a1a;
  border: 1px solid #2a2a2a;
  border-radius: 8px;
  max-height: 260px;
  overflow-y: auto;
  z-index: 100;
}
.typeahead-result {
  padding: 10px 12px;
  cursor: pointer;
  border-bottom: 1px solid #2a2a2a;
}
.typeahead-result:last-child { border-bottom: none; }
.typeahead-result:hover { background: color-mix(in srgb, var(--brand-gold) 8%, transparent); }
/* Keyboard cursor. Stronger than hover so it stays followable while arrowing. */
.typeahead-result.is-active {
  background: color-mix(in srgb, var(--brand-gold) 28%, transparent);
  box-shadow: inset 2px 0 0 var(--brand-gold);
}
.typeahead-result strong {
  display: block;
  color: #e8e8e8;
  font-size: 14px;
  margin-bottom: 2px;
}
.typeahead-result small {
  display: block;
  color: #888;
  font-size: 11px;
}
.typeahead-result .phase-tag {
  display: inline-block;
  background: #2a2a2a;
  color: var(--brand-gold);
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 10px;
  text-transform: capitalize;
  margin-left: 8px;
}
.typeahead-empty {
  padding: 10px 12px;
  color: #999;
  font-style: italic;
  font-size: 13px;
}

.selected-contact {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: color-mix(in srgb, var(--brand-gold) 10%, transparent);
  border: 1px solid var(--brand-gold);
  border-radius: 8px;
  padding: 10px 12px;
  color: #e8e8e8;
}
.selected-contact .selected-name { font-weight: 500; }
.selected-contact .clear-btn {
  background: none;
  border: none;
  color: var(--brand-gold);
  cursor: pointer;
  font-size: 14px;
  padding: 0 6px;
}
.selected-contact .clear-btn:hover { color: #fff; }

/* ─── Settings tab (Phase 4 continued) ───────────────────────────── */

/* One contained panel over the background image, with a category rail on the
   left and a detail pane on the right. Only the selected category renders, so
   the panel fits a single screen however many settings exist. */
.settings-shell {
  display: flex;
  width: 100%;
  min-height: 0;
  background: rgba(13, 27, 42, 0.5);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 45%, transparent);
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(10px);
  overflow: hidden;
}

.settings-rail {
  flex: 0 0 186px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 8px;
  border-right: 1px solid color-mix(in srgb, var(--brand-gold) 28%, transparent);
  background: rgba(9, 19, 30, 0.55);
  overflow-y: auto;
}
.settings-rail-item {
  display: flex;
  flex-direction: column;
  gap: 1px;
  text-align: left;
  font: inherit;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 7px 10px;
  cursor: pointer;
}
.settings-rail-item:hover { background: color-mix(in srgb, var(--brand-gold) 10%, transparent); }
.settings-rail-item.is-active {
  background: color-mix(in srgb, var(--brand-gold) 16%, transparent);
  border-color: color-mix(in srgb, var(--brand-gold) 55%, transparent);
}
.settings-rail-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--brand-gold, var(--brand-gold));
}
/* Help & Support leaves Settings, so it sits apart from the categories. */
.settings-rail-item--link {
  margin-top: auto;
  text-decoration: none;
  border-top-color: color-mix(in srgb, var(--brand-gold) 20%, transparent);
}
.settings-rail-item--link + .settings-rail-item--link {
  margin-top: 0;
  border-top-color: transparent;
}
#settings-panel { container-type: inline-size; }
@container (max-width: 600px) {
  .settings-shell { flex-direction: column; }
  .settings-rail {
    flex: 0 0 auto;
    flex-direction: row;
    flex-wrap: wrap;
    overflow-x: hidden;
    border-right: none;
    border-bottom: 1px solid color-mix(in srgb, var(--brand-gold) 28%, transparent);
  }
  .settings-rail-item { flex: 0 1 auto; min-width: 0; padding: 5px 9px; }
  .settings-rail-item--link { margin-top: 0; border-top-color: transparent; }
}
#settings-panel .settings-section-title,
#settings-panel .ai-quota-title {
  font-size: 15px;
}
.settings-pill[aria-checked="true"] {
  background: linear-gradient(135deg, var(--gold-bright), var(--brand-gold) 55%, var(--gold-deep));
  color: var(--nav-navy);
  font-weight: 600;
}
#agentBioInput,
#igTagsInput {
  field-sizing: content;
  min-height: 5lh;
  resize: none;
}
#emailSignaturePreview img,
#emailSignaturePreview table {
  max-width: 100% !important;
  height: auto !important;
}

.footer-support-link {
  color: var(--brand-gold, var(--brand-gold));
  text-decoration: none;
}
.footer-support-link:hover { text-decoration: underline; }

.settings-detail {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: 12px 16px 14px;
}
.settings-detail-head { flex: 0 0 auto; margin-bottom: 10px; }
.settings-detail-title {
  margin: 0;
  font-size: 17px;
  color: var(--brand-gold, var(--brand-gold));
}
.settings-detail-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
}

/* Inside the panel the sections drop their own boxes — the panel is the
   surface. Hairline rules separate them instead. */
#settings-panel .settings-detail-body .settings-section {
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0;
  margin: 0 0 14px;
}
#settings-panel .settings-detail-body .settings-section + .settings-section {
  border-top: 1px solid color-mix(in srgb, var(--brand-gold) 18%, transparent);
  padding-top: 12px;
}
#settings-panel .settings-detail-body .settings-section:last-child { margin-bottom: 0; }

.settings-section {
  margin-bottom: 4px;
  background: rgba(13, 27, 42, 0.75);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 35%, transparent);
  border-radius: 8px;
  padding: 6px 10px;
}

.settings-section h3 {
  margin: 0 0 4px 0;
}

.settings-section-title {
  color: var(--brand-gold, var(--brand-gold));
  font-weight: 600;
  font-size: 13px;
  margin-bottom: 4px;
}

.settings-section .settings-help {
  color: rgba(255, 255, 255, 0.85);
  font-size: 12px;
  margin: 0 0 5px 0;
}

/* AI monthly quota bar (Account section) */
.ai-quota-title {
  color: var(--brand-gold, var(--brand-gold));
  font-weight: 600;
  font-size: 13px;
  margin-bottom: 6px;
}
.ai-quota-bar {
  height: 8px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.12);
  overflow: hidden;
}
.ai-quota-fill {
  height: 100%;
  background: var(--brand-gold, var(--brand-gold));
  transition: width 0.3s ease;
}
.ai-quota-fill.is-full { background: #d9534f; }
.ai-quota-line {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.85);
  margin-top: 4px;
}
.ai-quota-note {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.7);
  margin-top: 4px;
}
.ai-quota-note--out { color: #ea9b97; }

.settings-import-actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.sync-status-bar {
  margin-top: 10px;
  padding: 8px 12px;
  font-size: 13px;
  color: var(--brand-gold);
  font-style: italic;
}
.sync-status-bar--active {
  color: #fff;
  background: color-mix(in srgb, var(--brand-gold) 12%, transparent);
  border-radius: 6px;
  font-style: normal;
}
.sync-pulse {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brand-gold);
  margin-right: 8px;
  vertical-align: middle;
  animation: syncPulse 1.2s ease-in-out infinite;
}
@keyframes syncPulse {
  0%, 100% { opacity: 0.3; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.4); }
}
.settings-import-status {
  color: var(--brand-gold);
  font-size: 14px;
  margin-top: 12px;
  padding: 10px 14px;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 35%, transparent);
  border-radius: 6px;
}
.settings-import-status[hidden] { display: none; }

.settings-account {
  background: transparent;
}

.settings-account-name {
  font-size: 16px;
  font-weight: 600;
  color: #fff;
  margin-bottom: 4px;
  min-width: 0;
  overflow-wrap: anywhere;
}

.settings-account-email {
  color: var(--brand-gold);
  font-size: 14px;
}

.settings-logout-btn {
  display: inline-block;
  padding: 8px 16px;
  background: transparent;
  color: var(--brand-gold);
  border: 1px solid var(--brand-gold);
  border-radius: 4px;
  text-decoration: none;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s ease;
}

.settings-logout-btn:hover {
  background: color-mix(in srgb, var(--brand-gold) 15%, transparent);
}

.bg-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(180px, 100%), 1fr));
  gap: 12px;
}

.bg-picker-item {
  background: transparent;
  border: 2px solid transparent;
  border-radius: 6px;
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  transition: border-color 0.15s ease, transform 0.15s ease;
  font: inherit;
}

.bg-picker-item:hover {
  border-color: color-mix(in srgb, var(--brand-gold) 50%, transparent);
  transform: translateY(-2px);
}

.bg-picker-item.selected {
  border-color: var(--brand-gold);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-gold) 30%, transparent);
}

.bg-picker-item img {
  display: block;
  width: 100%;
  height: 100px;
  object-fit: cover;
}

.bg-picker-label {
  display: block;
  padding: 8px;
  color: #fff;
  font-size: 13px;
  text-align: center;
}

.settings-error {
  color: #ff6b6b;
  padding: 12px;
  background: rgba(255, 107, 107, 0.1);
  border-radius: 4px;
}

/* ─── Settings tab v2: inline pills + full-screen gallery ────────── */

.settings-account-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.settings-account-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.settings-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  background: rgba(13, 27, 42, 0.9);
  color: var(--brand-gold);
  border: 1px solid var(--brand-gold);
  border-radius: 999px;
  text-decoration: none;
  font-weight: 500;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.15s ease;
  font-family: inherit;
  white-space: nowrap;
}

.settings-pill:hover {
  background: color-mix(in srgb, var(--brand-gold) 15%, transparent);
  transform: translateY(-1px);
}

/* Per-page background overrides section */

.team-seat-who {
  color: rgba(255, 255, 255, 0.92);
}

.settings-hint {
  color: rgba(255, 255, 255, 0.85);
  font-size: 13px;
  margin: 0 0 8px 0;
}

.per-page-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.per-page-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
}
#settings-panel .settings-section .per-page-row { padding-left: 0; padding-right: 0; }

.per-page-arrow {
  color: var(--brand-gold);
  font-size: 18px;
  margin: 0 4px;
  flex-shrink: 0;
}

.per-page-label {
  flex: 0 0 90px;
  font-size: 14px;
  font-weight: 600;
  color: var(--brand-gold);
}

.per-page-brokerage-select {
  background: transparent;
  color: var(--brand-gold);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 40%, transparent);
  border-radius: 6px;
  padding: 6px 28px 6px 10px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' stroke='%23d4a017' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
}
.per-page-brokerage-select option {
  background: #0D1B2A;
  color: var(--brand-gold);
}
.per-page-brokerage-select:focus {
  outline: none;
  border-color: var(--brand-gold);
}

.per-page-current {
  flex: 1;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.7);
}

.settings-pill.btn-sm {
  padding: 4px 12px;
  font-size: 13px;
  flex-shrink: 0;
}

@keyframes bgGalleryFadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ─── Sticky footer ──────────────────────────────────────────────────
   Keep the Seneschal disclaimer at the bottom of the viewport when
   page content is short (e.g. Settings tab with only the Account row).
   Without this, the footer rides up the page and the body's fixed
   background image shows below it. Flexbox column on <body>: header +
   brief banner + main share the top, footer locks to the bottom. */

html, body {
  min-height: 100vh;
}

/* Every page is a full document load, so without a base colour the browser
   paints white between navigations - the flash between pages. */
html {
  background-color: #0d1b2a;
}

body {
  display: flex;
  flex-direction: column;
}

main {
  flex: 0 0 auto;
}

footer {
  flex-shrink: 0;
}

/* Account card: gold separator lines under name and under email-row,
   echoing the accent treatment on the .brand-banner card. */

.settings-account-name {
  display: inline-block;
  padding-bottom: 4px;
  margin-bottom: 8px;
}

/* .settings-account-row — border removed; flex layout preserved above */

/* Border under email text only, not the whole row */
.settings-account-email {
  padding-bottom: 4px;
  border-bottom: 1px solid color-mix(in srgb, var(--brand-gold) 40%, transparent);
}

/* === Onboarding page === */
body.onboarding-body {
  background: #0a0a0a;
  color: #fff;
  min-height: 100vh;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 60px 20px;
}

.onboarding-main { max-width: 1000px; width: 100%; }

.onboarding-header { text-align: center; margin-bottom: 48px; }
.onboarding-header h1 { font-size: 2.4rem; margin: 0 0 12px; color: var(--gold, #d4af37); }
.onboarding-sub { font-size: 1.05rem; color: #c4c4c4; margin: 0 auto; max-width: 600px; }

.onboarding-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-bottom: 32px;
}
@media (max-width: 720px) { .onboarding-cards { grid-template-columns: 1fr; } }

.onboarding-card {
  background: #1a1a1a;
  border: 1px solid #2a2a2a;
  border-radius: 12px;
  padding: 32px 28px;
  text-align: center;
  transition: border-color .2s, transform .2s;
}
.onboarding-card:hover { border-color: var(--gold, #d4af37); transform: translateY(-2px); }
.onboarding-card-icon { font-size: 2.4rem; margin-bottom: 12px; }
.onboarding-card h2 { margin: 0 0 8px; font-size: 1.3rem; color: #fff; }
.onboarding-card p { color: #bdbdbd; font-size: 0.95rem; margin: 0 0 24px; min-height: 60px; }

.onboarding-btn {
  background: #2a2a2a;
  color: #fff;
  border: 1px solid #3a3a3a;
  padding: 12px 24px;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  width: 100%;
  transition: background .15s, border-color .15s;
}
.onboarding-btn:hover { background: #333; border-color: var(--gold, #d4af37); }
.onboarding-btn.primary { background: var(--gold, #d4af37); color: #0a0a0a; border-color: var(--gold, #d4af37); }
.onboarding-btn.primary:hover { background: #e6c14a; }

.onboarding-status {
  margin-top: 16px;
  padding: 10px 14px;
  border-radius: 6px;
  font-size: 0.9rem;
  background: #222;
  color: #ddd;
}
.onboarding-status.working { background: #1f2a3a; color: #8ec6ff; }
.onboarding-status.success { background: #1f3a2a; color: #8effa3; }
.onboarding-status.error   { background: #3a1f1f; color: #ff8e8e; }

.onboarding-footer { text-align: center; margin-top: 16px; }
.onboarding-later { color: #999; text-decoration: none; font-size: 0.95rem; }
.onboarding-later:hover { color: var(--gold, #d4af37); }

/* ── Today's Calendar widget ─────────────────────────────────────────────── */
.calendar-card {
  background: transparent;
  border: none;
  border-radius: 10px;
  padding: 18px 20px;
  margin-bottom: 20px;
}
.calendar-card-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 12px;
}
.calendar-card-header .section-title { margin: 0; }
.calendar-count {
  color: var(--brand-gold);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.calendar-events {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.calendar-event {
  display: grid;
  grid-template-columns: 90px 1fr;
  gap: 12px;
  padding: 10px 12px;
  background: color-mix(in srgb, var(--brand-gold) 4%, transparent);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 15%, transparent);
  border-radius: 7px;
  cursor: default;
  transition: background 0.15s;
}
.calendar-event[data-weblink] { cursor: pointer; }
.calendar-event[data-weblink]:hover { background: color-mix(in srgb, var(--brand-gold) 10%, transparent); }
.calendar-event-time {
  color: var(--brand-gold);
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.calendar-event-body {
  /* A grid item defaults to min-width:auto, so one long unbroken run in a
     subject or a location (a Teams link, a joined address) widened the whole
     card past a phone's viewport instead of wrapping. */
  min-width: 0;
  overflow-wrap: anywhere;
}
.calendar-event-subject {
  color: #e8e8e8;
  font-size: 13px;
  font-weight: 500;
  overflow-wrap: anywhere;
}
.calendar-event-location {
  color: #888;
  font-size: 12px;
  margin-top: 2px;
}
.calendar-empty, .calendar-loading, .calendar-error {
  color: #888;
  font-size: 13px;
  padding: 6px 0;
}
.calendar-error a { color: var(--brand-gold); }

/* ============================================================
   MOBILE LAYOUT — phones (≤ 640px wide).
   Catches .header-right overflow on dashboard: the existing 900px
   rule gives it full width but never wraps, so the four items
   (date + Contacts + Outlook UPN + Generate button) sum to ~630px+
   in a ~390px phone viewport. Fix: wrap + ellipsis-truncate UPN.
   ============================================================ */
@media (max-width: 640px) {
  /* Header right row: allow items to wrap to multiple lines */
  .header-right {
    flex-wrap: wrap;
    gap: 8px;
    justify-content: flex-start;
  }

  /* Outlook status label: truncate the long UPN with ellipsis so it
     doesn't push the row past the viewport. Rich already knows his
     own email — showing "Outlook: Rich_Demoors@windermer..." is fine. */
  .auth-label {
    max-width: 60vw;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* Date and Contacts link — make sure they have breathing room */
  .header-right > * {
    min-height: 32px;
    display: inline-flex;
    align-items: center;
  }
}

/* ── Briefing error banner ──────────────────────────────────────────────────── */
.briefing-error-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 12px 24px 0;
  padding: 12px 18px;
  background: rgba(232, 168, 56, 0.18);
  border: 1px solid var(--amber);
  border-radius: var(--radius-lg);
  color: #fff;
  font-size: 14px;
  line-height: 1.4;
}
.briefing-error-banner[hidden] { display: none; }
.briefing-error-banner__icon {
  font-size: 20px;
  color: var(--amber);
  flex-shrink: 0;
}
.briefing-error-banner__message { flex: 1; }

/* ── Phase pill — canonical helper. Replaces .phase-badge (contact-detail), .phase-pill+.phase-* (contacts-manager), .p-*+.dot-* (email-drafts). Used by sister pages post-#8 migration. ── */
.phase-pill {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.3px;
  line-height: 1.4;
  white-space: nowrap;
  border: 1px solid;
}
/* Contact tag chips (e.g. CBA broadcast brokers). */
.contact-tag {
  display: inline-block;
  padding: 1px 7px;
  margin-left: 6px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.4px;
  vertical-align: middle;
  white-space: nowrap;
}
.contact-tag--cba {
  background: color-mix(in srgb, var(--brand-gold) 16%, transparent);
  color: var(--brand-gold, var(--brand-gold));
  border: 1px solid var(--brand-gold, var(--brand-gold));
}
/* One canonical palette, promoted out of the Contacts page's inline styles so
   every surface shows the same pill. Dark fill, gold border, white uppercase
   text: sphere used to come out pale lavender on the Follow Up board and
   solid yellow elsewhere, because three different pill systems were in play. */
.phase-pill {
  color: #fff;
  border-color: var(--brand-gold);
  text-transform: uppercase;
  font-weight: 700;
}
.phase-pill--cold_lead     { background: #1f4e79; }
.phase-pill--new_lead      { background: #8a5e22; }
.phase-pill--nurture       { background: #5f6771; }
.phase-pill--active_buyer  { background: #2a1e3a; }
.phase-pill--active_seller { background: #3a2210; }
.phase-pill--buyer_seller  { background: #2e1e2e; }
.phase-pill--under_contract{ background: #2a1e1e; }
.phase-pill--post_close    { background: #1e2a2a; }
.phase-pill--sphere        { background: #2a2a1e; }
.phase-pill--family        { background: #24303a; }
.phase-pill--agent         { background: #1e5235; }
.phase-pill--lender        { background: #2b7249; }
.phase-pill--title         { background: #9e5427; }
.phase-pill--contractor    { background: #4b525a; }

/* ── Data table — dark theme, used by sister pages ── */
.data-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.data-table thead { background: transparent; }
.data-table th {
  text-align: left;
  padding: 12px 16px;
  color: #ccc;
  font-weight: 600;
  border-bottom: 1px solid #2a2a2a;
}
.data-table td {
  padding: 12px 16px;
  border-bottom: 1px solid #1e1e1e;
  color: #e8e8e8;
}
.data-table tbody tr:hover { background: rgba(255, 255, 255, 0.03); }

/* ── Pending-assignment banner ── */
.pending-assignment-banner {
  margin: 12px 24px 0;
  padding: 12px 16px;
  /* Was transparent, which put small body text straight onto the castle and
     made it unreadable over the bright areas. Same translucent-navy treatment
     every other card uses, a touch stronger because this banner carries small
     text rather than a big number. */
  /* solid, not frosted -- see --navy-panel in tokens.css */
  background: var(--navy-panel);
  border: 1px solid var(--brand-gold);
  border-radius: var(--radius-lg);
  color: var(--brand-gold);
}
.pending-assignment-banner[hidden] { display: none; }
.pending-assignment-banner__header {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
}
.pending-assignment-banner__icon { font-size: 18px; }
.pending-assignment-banner__title { flex: 1; }
.pending-assignment-banner__toggle {
  background: transparent;
  border: 1px solid var(--brand-gold);
  color: var(--brand-gold);
  border-radius: 6px;
  padding: 4px 12px;
  font-size: 12px;
  cursor: pointer;
  min-height: 28px;
}
.pending-assignment-banner__toggle:hover { background: color-mix(in srgb, var(--brand-gold) 15%, transparent); }
.pending-assignment-banner__list { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.pending-assignment-banner__list[hidden] { display: none; }
.pending-assignment-row {
  background: transparent;
  border: 1px solid #2a2a2a;
  border-radius: 8px;
  padding: 10px 12px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
  align-items: center;
}
.pending-assignment-row__meta { font-size: 12px; color: #ccc; }
.pending-assignment-row__meta strong { color: #fff; font-weight: 600; }
.pending-assignment-row__subject-btn {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  font-weight: 600;
  color: var(--brand-gold);
  text-align: left;
  cursor: pointer;
  display: inline;
}
.pending-assignment-row__subject-btn:hover { text-decoration: underline; }
.pending-assignment-row__meta-detail { color: #888; margin-top: 2px; font-size: 11px; }
.pending-assignment-row__date-row { display: flex; align-items: center; gap: 6px; margin-top: 6px; }
.pending-assignment-row__date-label { font-size: 10px; color: #888; text-transform: uppercase; letter-spacing: 0.05em; white-space: nowrap; }
.pending-assignment-row__signed-date { font-size: 11px; color: #ccc; background: rgba(255,255,255,0.06); border: 1px solid #444; border-radius: 3px; padding: 2px 4px; }
.pending-assignment-row__assign { display: flex; gap: 6px; align-items: center; }
.pending-assignment-row__select {
  background: #161616;
  border: 1px solid #2a2a2a;
  color: #fff;
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 12px;
  min-height: 32px;
}
.pending-assignment-row__btn {
  background: var(--brand-gold);
  color: #000;
  border: none;
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  min-height: 32px;
}
.pending-assignment-row__btn:disabled { background: #3a2f00; color: #999; cursor: not-allowed; }
.pending-assignment-banner__section { display: flex; flex-direction: column; gap: 8px; }
.pending-assignment-banner__section[hidden] { display: none; }
.pending-assignment-banner__section-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--brand-gold);
  font-weight: 600;
}
.pending-assignment-banner__divider {
  height: 1px;
  background: color-mix(in srgb, var(--brand-gold) 25%, transparent);
  margin: 4px 0;
}
.pending-assignment-banner__divider[hidden] { display: none; }
.unsent-forward-row__error {
  /* Lifted from #d45a5a, which sat just under the 4.5:1 bar on navy. */
  color: #e88b8b;
  font-size: 11px;
  margin-top: 2px;
  font-family: monospace;
}
.pending-assignment-row__btn--secondary {
  background: transparent;
  color: var(--brand-gold);
  border: 1px solid var(--brand-gold);
}

/* ── Contact-detail edit modal ─────────────────────────────────────────────── */
.cd-edit-modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
  z-index: 100;
  align-items: center;
  justify-content: center;
}

.cd-edit-modal__panel {
  background: #1a1a1a;
  border: 1px solid #2a2a2a;
  border-radius: 14px;
  padding: 28px;
  width: 540px;
  max-width: 95vw;
  max-height: 90vh;
  overflow-y: auto;
}

.cd-edit-modal__title {
  font-size: 16px;
  font-weight: 600;
  color: #e8e8e8;
  margin-bottom: 20px;
}

.cd-edit-modal__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

.cd-edit-modal__field {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.cd-edit-modal__field--span {
  grid-column: 1 / -1;
}

.cd-edit-modal__field--na {
  opacity: 0.4;
  pointer-events: none;
}

.cd-edit-modal__label {
  font-size: 11px;
  font-weight: 600;
  color: #999;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

.cd-edit-modal__input {
  background: #111;
  border: 1px solid #2a2a2a;
  border-radius: 7px;
  padding: 9px 12px;
  color: #e8e8e8;
  font-size: 13px;
  outline: none;
  width: 100%;
  color-scheme: dark;
}

/* The rule above strips the native outline on all ~28 fields in the edit
   modal, so keyboard focus needs a replacement or tabbing through the modal
   shows nothing at all. */
.cd-edit-modal__input:focus-visible {
  outline: 2px solid var(--brand-gold);
  outline-offset: 2px;
}

.cd-edit-modal__textarea {
  resize: vertical;
  min-height: 80px;
  font-family: inherit;
}

.cd-edit-modal__hint {
  font-size: 11px;
  color: #999;
  margin-top: 2px;
}

.cd-edit-modal__txn-section {
  grid-column: 1 / -1;
  border-top: 1px solid #2a2a2a;
  padding-top: 14px;
  margin-top: 4px;
}

.cd-edit-modal__txn-heading {
  font-size: 11px;
  font-weight: 700;
  color: var(--brand-gold);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  margin-bottom: 12px;
}

.cd-edit-modal__actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  margin-top: 20px;
}

.cd-edit-modal__btn {
  border-radius: 8px;
  font-size: 13px;
  padding: 9px 16px;
  cursor: pointer;
  font-family: inherit;
}

.cd-edit-modal__btn--cancel {
  background: transparent;
  border: 1px solid #2a2a2a;
  color: #888;
}

.cd-edit-modal__btn--save {
  background: var(--brand-gold);
  color: #000;
  border: none;
  padding: 9px 20px;
  font-weight: 600;
}

@media (max-width: 640px) {
  .cd-edit-modal__panel { padding: 20px; }
  .cd-edit-modal__grid { grid-template-columns: 1fr; }
  .cd-edit-modal__input,
  .cd-edit-modal__textarea { font-size: 16px; min-height: 44px; }
  .cd-edit-modal__btn { min-height: 44px; }
}

/* ===== Pending dismiss controls ===== */
.pending-controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 12px 0;
}
.pending-filter-input {
  width: 100%;
  padding: 10px 12px;
  background: rgba(13, 27, 42, 0.6);
  border: 1px solid var(--brand-gold);
  border-radius: var(--radius-lg);
  color: #fff;
  font-size: 16px;
  min-height: 44px;
  box-sizing: border-box;
}
.pending-filter-input::placeholder { color: rgba(255,255,255,0.45); }
.pending-filter-input:focus { outline: 2px solid var(--brand-gold); outline-offset: 1px; }

.pending-bulk-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 12px;
  background: color-mix(in srgb, var(--brand-gold) 8%, transparent);
  border: 1px solid var(--brand-gold);
  border-radius: var(--radius-lg);
}
.pending-bulk-count { color: var(--brand-gold); font-weight: 600; }
.pending-bulk-btn {
  background: var(--brand-gold);
  color: var(--nav-navy);
  border: none;
  border-radius: var(--radius-lg);
  padding: 8px 16px;
  font-weight: 600;
  min-height: 44px;
  min-width: 88px;
  cursor: pointer;
  font-size: 14px;
}
.pending-bulk-btn:hover { filter: brightness(1.08); }

.action-btn.dismiss-row-btn {
  color: var(--brand-gold);
  border-color: var(--brand-gold);
  background: color-mix(in srgb, var(--brand-gold) 10%, transparent);
}
.action-btn.dismiss-row-btn:hover {
  background: var(--red);
  color: #fff;
  border-color: var(--red);
}

[data-pending-row-id].pending-row--hidden { display: none; }

/* ===== Dismiss confirm modal ===== */
.dismiss-modal { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; }
.dismiss-modal[hidden] { display: none; }
.dismiss-modal__overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.6); }
.dismiss-modal__content {
  position: relative;
  background: var(--header-navy);
  border: 1px solid var(--brand-gold);
  border-radius: var(--radius-lg);
  padding: 24px;
  max-width: 480px;
  width: calc(100% - 32px);
  color: #fff;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}
.dismiss-modal__title { margin: 0 0 12px; color: var(--brand-gold); font-size: 18px; }
.dismiss-modal__body { margin: 0 0 20px; line-height: 1.5; }
.dismiss-modal__footer { display: flex; justify-content: flex-end; gap: 12px; }
.dismiss-modal__btn {
  padding: 10px 20px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--brand-gold);
  font-weight: 600;
  font-size: 14px;
  min-height: 44px;
  min-width: 88px;
  cursor: pointer;
}
.dismiss-modal__btn--cancel { background: transparent; color: var(--brand-gold); }
.dismiss-modal__btn--cancel:hover { background: color-mix(in srgb, var(--brand-gold) 12%, transparent); }
.dismiss-modal__btn--confirm { background: var(--red); color: #fff; border-color: var(--red); }
.dismiss-modal__btn--confirm:hover { filter: brightness(1.08); }

@media (max-width: 640px) {
  .pending-bulk-bar { flex-direction: column; align-items: stretch; }
  .pending-bulk-btn { width: 100%; }
  .dismiss-modal__footer { flex-direction: column-reverse; }
  .dismiss-modal__btn { width: 100%; }
}

/* ===== Folder match button ===== */
.pending-match-btn {
  align-self: flex-start;
  background: transparent;
  color: var(--brand-gold);
  border: 1px solid var(--brand-gold);
  border-radius: var(--radius-lg);
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 600;
  min-height: 36px;
  cursor: pointer;
}
.pending-match-btn:hover { background: color-mix(in srgb, var(--brand-gold) 12%, transparent); }
.pending-match-btn:disabled { opacity: 0.5; cursor: progress; }

/* ===== Folder annotation on pending rows ===== */
.pending-assignment-row__folder {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 4px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.65);
}
.pending-assignment-row__folder::before {
  content: "📁";
  font-size: 13px;
}
.pending-assignment-row__folder--deleted {
  color: rgba(192, 57, 43, 0.85);
}
.pending-assignment-row__folder--deleted::before {
  content: "⚠️";
}
.pending-assignment-row__folder--unknown {
  color: rgba(255, 255, 255, 0.35);
  font-style: italic;
}
.pending-assignment-row__folder--unknown::before {
  content: "—";
  margin-right: 2px;
}

@media (max-width: 640px) {
  .pending-match-btn { align-self: stretch; width: 100%; }
}

/* ── Viewport-fit dashboard: overview tab caps at 100vh, priorities scroll internally ── */
@media (min-width: 641px) {
  body:has(#tab-overview.tab-content.active) {
    height: 100vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
  body:has(#tab-overview.tab-content.active) .top-bar,
  body:has(#tab-overview.tab-content.active) .site-header {
    flex-shrink: 0;
  }
  body:has(#tab-overview.tab-content.active) .main-content {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
  body:has(#tab-overview.tab-content.active) .main-content > * {
    flex-shrink: 0;
  }
  body:has(#tab-overview.tab-content.active) .main-content > #tab-overview {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
  /* The content area is the single scroll region. Header and footer are its
     siblings in the body flex column, so they stay pinned while only this
     scrolls - the internal-scroll pattern, not a whole-page scroll. One clean
     scroll here beats a tiny nested scroll strip inside the priorities. */
  body:has(#tab-overview.tab-content.active) #overviewContent {
    flex: 1 1 auto;
    min-height: 0;
    /* MUST be auto - the comment above calls this "the single scroll region".
       hidden was clipping the second row of Today's Priorities off the bottom
       of shorter viewports (widescreen ultrawides included). */
    overflow-y: auto;
    display: flex;
    flex-direction: column;
  }
  /* Viewport-responsive Overview: all vertical dimensions use clamp() so the
     dashboard scales smoothly between short viewports (widescreen monitors,
     high-DPI) and tall ones (laptop). At the laptop viewport the max values
     reproduce the original look; on shorter viewports everything compresses
     proportionally. Scoped to the dashboard tab only. */
  body:has(#tab-overview.tab-content.active) #overviewContent > .section-card {
    padding: clamp(4px, 1vh, 10px) 14px;
    margin-bottom: clamp(2px, 0.8vh, 8px);
  }
  /* Must live here, not with the plain #overviewContent rule near the top of
     this file: the clamp above carries an ID inside :has() plus a second ID,
     so it beats anything written outside this block. Equal specificity and a
     later source position is what actually wins. That trailing 7px was the
     whole of the pane's 1px overflow, and 1px still draws a scrollbar. */
  body:has(#tab-overview.tab-content.active) #overviewContent > *:last-child {
    margin-bottom: 0;
  }
  body:has(#tab-overview.tab-content.active) #overviewContent .section-header {
    margin-bottom: clamp(2px, 0.8vh, 8px);
  }
  body:has(#tab-overview.tab-content.active) #overviewContent .overview-grid {
    gap: clamp(4px, 1vh, 12px);
    margin-bottom: clamp(0px, 0.4vh, 4px);
  }
  body:has(#tab-overview.tab-content.active) .overview-number {
    font-size: clamp(18px, 3vh, 30px);
  }
  body:has(#tab-overview.tab-content.active) .overview-card {
    padding: clamp(4px, 1vh, 10px);
  }
  body:has(#tab-overview.tab-content.active) .overview-label {
    margin-top: clamp(2px, 0.6vh, 8px);
    font-size: clamp(11px, 1.4vh, 13px);
  }
  body:has(#tab-overview.tab-content.active) #overviewContent .summary-stats {
    display: none !important;
  }
  body:has(#tab-overview.tab-content.active) main.main-content {
    padding-bottom: clamp(2px, 0.6vh, 8px);
  }
  body:has(#tab-overview.tab-content.active) #overviewContent .calendar-card {
    padding: clamp(3px, 0.7vh, 8px) 14px;
    margin-bottom: clamp(2px, 0.5vh, 6px);
  }
  body:has(#tab-overview.tab-content.active) #overviewContent .calendar-card-header {
    margin-bottom: clamp(2px, 0.5vh, 6px);
  }
  body:has(#tab-overview.tab-content.active) #overviewContent > * {
    flex-shrink: 0;
  }
  body:has(#tab-overview.tab-content.active) #overviewContent > .section-card.priorities-section {
    flex: 0 0 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: clamp(6px, 1.5vh, 20px) clamp(10px, 2vh, 24px);
  }
  body:has(#tab-overview.tab-content.active) .priorities-section > .section-header {
    flex-shrink: 0;
  }
  body:has(#tab-overview.tab-content.active) .priorities-section .section-title {
    font-size: clamp(11px, 1.4vh, 14px);
    padding: clamp(3px, 0.5vh, 6px) 16px;
    margin-bottom: clamp(4px, 1vh, 14px);
  }
  body:has(#tab-overview.tab-content.active) .priority-row {
    padding: clamp(4px, 0.8vh, 9px) clamp(6px, 1vh, 12px);
    gap: clamp(2px, 0.4vh, 5px);
  }
  body:has(#tab-overview.tab-content.active) .priority-name {
    font-size: clamp(11px, 1.5vh, 14px);
  }
  body:has(#tab-overview.tab-content.active) .priority-pill {
    font-size: clamp(9px, 1.1vh, 11px);
    padding: clamp(1px, 0.3vh, 3px) clamp(6px, 0.9vh, 10px);
  }
  body:has(#tab-overview.tab-content.active) .priority-meta-pill {
    font-size: clamp(9px, 1.1vh, 11px);
  }
  body:has(#tab-overview.tab-content.active) .priority-tasks {
    gap: clamp(2px, 0.4vh, 4px);
  }
  body:has(#tab-overview.tab-content.active) .priority-task-name {
    font-size: clamp(10px, 1.3vh, 12px);
  }
  body:has(#tab-overview.tab-content.active) .priority-task-due {
    font-size: clamp(9px, 1.1vh, 11px);
  }
  body:has(#tab-overview.tab-content.active) .priorities-section .priority-list {
    flex: 0 0 auto;
    min-height: 0;
    overflow-y: visible;
    gap: clamp(4px, 0.7vh, 8px);
  }
}

@media (min-width: 641px) {
  /* Settings tab flex-fill chain ignition — same pattern as social tab 00e528b. */
  body.dashboard-page:has(#tab-settings.tab-content.active) {
    display: flex;
    flex-direction: column;
  }
  body.dashboard-page:has(#tab-settings.tab-content.active) .site-header,
  body.dashboard-page:has(#tab-settings.tab-content.active) .site-footer {
    flex-shrink: 0;
  }
  body.dashboard-page:has(#tab-settings.tab-content.active) main.main-content {
    padding-bottom: 0;
    min-height: 0;
    overflow: hidden;
  }
  /* Settings tab content fills available height and centers vertically
     so the disclaimer hugs the bottom of content instead of getting a
     big gap above it. Same scope pattern as the overview empty state. */
  body.dashboard-page:has(#tab-settings.tab-content.active) main,
  body.dashboard-page:has(#tab-settings.tab-content.active) .main-content {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  /* Carry the fill down to the panel so the shell spans the available height
     and .settings-detail-body is the only thing that scrolls. */
  body.dashboard-page:has(#tab-settings.tab-content.active) #tab-settings {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  body.dashboard-page:has(#tab-settings.tab-content.active) #tab-settings::before {
    flex: 0 0 8px;
  }
  body.dashboard-page:has(#tab-settings.tab-content.active) #settings-panel {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
  }
}

@media (min-width: 641px) {
  /* Social tab flex-fill chain. Starts at body — every downstream
     flex rule requires a flex parent, so this is the chain ignition.
     Mirrors the overview tab's working :has() pattern. */
  body.dashboard-page:has(#tab-social.tab-content.active) {
    display: flex;
    flex-direction: column;
  }
  body.dashboard-page:has(#tab-social.tab-content.active) .site-header {
    flex-shrink: 0;
  }
  body.dashboard-page:has(#tab-social.tab-content.active) .site-footer {
    flex-shrink: 0;
    margin-top: 0;
    padding: 3px 28px;
  }
  body.dashboard-page:has(#tab-social.tab-content.active) .footer-disclaimer {
    display: none;
  }
  body.dashboard-page:has(#tab-social.tab-content.active) .footer-legal {
    margin: 0;
  }
  body.dashboard-page:has(#tab-social.tab-content.active) main.main-content {
    padding-bottom: 0;
  }
  body.dashboard-page:has(#tab-social.tab-content.active) main {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  body.dashboard-page:has(#tab-social.tab-content.active) #tab-social {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  body.dashboard-page:has(#tab-social.tab-content.active) #socialContent,
  body.dashboard-page:has(#tab-social.tab-content.active) #tab-social .social-content,
  body.dashboard-page:has(#tab-social.tab-content.active) #tab-social .social-view-wrapper {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  body.dashboard-page:has(#tab-social.tab-content.active) .social-cards-list {
    flex: 1 1 auto;
    height: auto;
    max-height: none;
    min-height: 120px;
    overflow-y: auto;
    overflow-x: visible;
    /* No scroll bar (Rich, 2026-09-24: "no need for a scroll bar there").
       The week's posts plus the note under them came to a few pixels more
       than the pane on a laptop, so a bar appeared with nothing to show. The
       list still scrolls by wheel, trackpad and finger if a week runs long. */
    padding-bottom: 0;
    scrollbar-width: none;
  }
  body.dashboard-page:has(#tab-social.tab-content.active) .social-cards-list::-webkit-scrollbar {
    display: none;
  }
}

/* Vertical baseline: non-Dashboard tabs start at Dashboard sidebar pill top edge.
   The header is now a fixed 300px band, so main-content already begins on the
   nav line and each tab only needs a small gap. The old per-tab values (130/80/
   70/12/4) predate that band and pushed every tab to a different height. */
.tab-content:not(#tab-overview)::before { content: ''; display: block; height: 8px; }
/* Round 5: zero margin-top on direct children so non-overview tabs sit at Pipeline baseline */
.tab-content:not(#tab-overview) > * { margin-top: 0 !important; }

/* Pipeline card stage PNG pills — natural aspect, no background */
.pipeline-card .stage-pill-img {
  display: block;
  height: 32px;
  width: auto;
  max-width: 100%;
  background: transparent;
  flex-shrink: 1;
  min-width: 0;
}

/* The deal-update bar belongs to the Dashboard. It sits above the tabs in the
   markup, so without this it rides along on Pipeline, Emails, Follow Up, Social
   and Settings too. */
body.dashboard-page:not(:has(#tab-overview.tab-content.active)) #statusReviewBanner {
  display: none;
}

/* Every tab shares the 8px baseline above so they all line up with the
   Dashboard pill. */
#tab-emails::before,
#tab-social::before,
#tab-contacts::before,
#tab-settings::before { content: ''; display: block; height: 8px !important; }
#tab-emails .email-table { margin-top: 0 !important; }
#tab-emails .email-table { margin-top: 0 !important; }

/* Social tab — scroll only the post cards list; goals + header stay fixed */
#tab-social .social-cards-list {
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  padding-bottom: 48px;
}
/* Empty states inside cards-list center vertically */
.social-cards-list > .empty-state-social {
  margin: auto 0;
}

/* Social tab header row: intro text on left, subpills on right */
.social-intro-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin: 8px 0 24px;
  flex-wrap: wrap;
}
.social-intro-row .social-intro-text {
  margin: 0;
  flex: 1 1 auto;
}
.social-intro-row .social-header-pills-slot {
  flex: 0 0 auto;
}
.social-header-pills-slot #socialSubpills {
  margin: 0;
}

/* Dashboard never gets a body-level scrollbar — inner panes scroll.

   dvh, NOT vh. On Android and iOS, 100vh means the viewport WITHOUT the
   browser's address bar and the system navigation bar. This body is
   overflow:hidden, so the strip that those bars cover is not merely hidden --
   it is unreachable, because there is nothing left to scroll. A folding phone
   opened up lands above the 768px unlock below and gets this locked layout on
   a screen that still has both bars, which is how Rich's Fold 7 showed a
   pipeline whose cards were cut off at the bottom edge and would not move.

   dvh is the height actually visible at this moment. The vh line is kept
   first as the fallback for anything too old to know dvh; on a desktop the
   two are the same number anyway. */
body.dashboard-page {
  height: 100vh;
  height: 100dvh;
  max-height: 100vh;
  max-height: 100dvh;
  overflow: hidden;
}

/* === Sidebar expandable groups (Correspondence, Proclamations) === */
.sidebar-group {
  width: 100%;
}
.sidebar-group > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
}
.sidebar-group > summary::-webkit-details-marker { display: none; }
.sidebar-group > summary::marker { display: none; }

.sidebar-sub {
  list-style: none;
  margin: 4px 0 8px 0;
  padding: 0 0 0 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.sidebar-sub-item {
  display: block;
  width: 100%;
  text-align: left;
  background: #0d1b2a;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 25%, transparent);
  color: #f5e9c8;
  font-family: inherit;
  font-size: 13px;
  padding: 6px 10px;
  border-radius: 6px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.sidebar-sub-item:hover:not(.is-coming-soon) {
  background: color-mix(in srgb, var(--brand-gold) 15%, transparent);
  border-color: color-mix(in srgb, var(--brand-gold) 60%, transparent);
  color: #fff5d6;
}

.sidebar-sub-item.is-coming-soon {
  opacity: 0.5;
  cursor: not-allowed;
  border-color: color-mix(in srgb, var(--brand-gold) 10%, transparent);
}

.coming-soon-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  background: color-mix(in srgb, var(--brand-gold) 20%, transparent);
  color: var(--brand-gold);
  border-radius: 8px;
  vertical-align: middle;
}

/* Ornate pill submenu (Correspondence / Proclamations). Same treatment as the
   OI nav pills: the item carries no box, only the transparent PNG shows.
   Coming-soon pills are dimmed and non-interactive. */
.sidebar-sub.sidebar-sub-pills {
  align-items: center;
  padding-left: 0;
  gap: 3px;
}
.sidebar-sub-pill {
  background: transparent !important;
  border: none !important;
  padding: 0 !important;
  border-radius: 0;
  line-height: 0;
  display: block;
  width: 100%;
  max-width: 200px;
}
.sidebar-sub-pill img {
  display: block;
  width: 100%;
  height: auto;
  filter: brightness(0.9);
  transition: filter 120ms ease;
}
.sidebar-sub-pill:hover:not(.is-coming-soon) img {
  filter: brightness(1.05) drop-shadow(0 0 4px color-mix(in srgb, var(--brand-gold) 30%, transparent));
}
.sidebar-sub-pill.is-coming-soon {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

/* Desktop three-column nav (matches the OI page). Opening Correspondence or
   Proclamations reveals its sub-pills as a fixed column to the right of the
   main pills, vertically centered on the main pill stack (top 308, height 456,
   center 536) instead of pushing the main pills down. A gutter is reserved so
   page content starts in the same spot on every page whether or not a submenu
   is open. Below 1024px this yields to the in-flow dropdown; mobile (<=768px,
   with !important) resets the gutter entirely. Accordion behavior (only one
   group open at a time) is in /js/subnav-accordion.js. */
@media (min-width: 1024px) {
  /* Uniform header band so page content begins on the same line as the
     Dashboard nav pill (fixed at top:300) on every page. Header content is
     shorter than this on all pages, so min-height fixes the band at 300 and
     main-content always starts there - no per-page magic offsets that break
     whenever a header gains a line. */
  .site-header {
    min-height: var(--header-band);
    /* The header wraps onto a second line for the summary bar. Without this the
       300px band spreads those lines apart and drops the summary into the
       middle of the header; pack them to the top instead. */
    align-content: flex-start;
  }

  nav.sidebar-nav details.sidebar-group[open] > .sidebar-sub.sidebar-sub-pills {
    position: fixed;
    left: 280px;
    top: calc(var(--nav-top) + 8px);
    height: 456px;
    width: 232px;
    z-index: 60;
    margin: 0;
    padding: 0 0 0 14px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 3px;
  }
  .has-sidebar .main-content,
  .has-sidebar .page,
  .has-sidebar .page-pill-row,
  .has-sidebar .back-bar,
  .has-sidebar .layout {
    width: calc(100% - 546px);
    margin-left: 526px;
  }
}

/* ── Emails pane inside Activity Log ─────────────────────────── */
.emails-pane {
  margin-top: 14px;
  background: rgba(13, 27, 42, 0.75);
}
.emails-pane .email-list-empty {
  padding: 28px 0;
  text-align: center;
  color: rgba(255, 255, 255, 0.5);
  font-style: italic;
}
.emails-pane .email-list-header,
.emails-pane .email-row {
  display: grid;
  grid-template-columns: 24px 90px 130px 1fr 2fr;
  gap: 12px;
  align-items: center;
}
.emails-pane .email-header-select,
.emails-pane .email-select-cell {
  display: flex;
  align-items: center;
  justify-content: center;
}
.emails-pane .email-list-header {
  padding: 10px 12px;
  border-bottom: 1px solid color-mix(in srgb, var(--brand-gold) 35%, transparent);
  color: var(--brand-gold);
  font-size: 11px;
  letter-spacing: 0.08em;
  font-weight: 600;
}
.emails-pane .email-row {
  padding: 10px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  cursor: pointer;
  transition: background 0.12s;
}
.emails-pane .email-row:hover {
  background: color-mix(in srgb, var(--brand-gold) 6%, transparent);
}
.emails-pane .email-row.unread {
  background: color-mix(in srgb, var(--brand-gold) 4%, transparent);
  font-weight: 600;
}
.emails-pane .email-topic-link {
  cursor: pointer;
  color: var(--white);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block;
}
.emails-pane .email-topic-link:hover {
  color: var(--brand-gold);
}
.emails-pane .email-date {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.5);
  white-space: nowrap;
}
.emails-pane .email-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.emails-pane .email-summary {
  color: rgba(255, 255, 255, 0.55);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ============================================================
   Mobile responsive: sidebar collapses to top horizontal row
   Below 768px the fixed-left vertical sidebar becomes a wrapping
   row of pill buttons at the top of the page, and .main-content
   reclaims the full viewport width. Keeps all 5 brand pills
   visible (no hamburger drawer) so the layout structure stays
   consistent across screen sizes.
   ============================================================ */
@media (max-width: 768px) {
  nav.sidebar-nav {
    position: static !important;
    width: 100% !important;
    height: auto !important;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-items: flex-start;
    gap: 6px 8px;
    padding: 8px 6px;
    box-sizing: border-box;
  }

  .has-sidebar .main-content,
  .has-sidebar .page,
  .has-sidebar .page-pill-row,
  .has-sidebar .back-bar,
  .has-sidebar .layout {
    margin-left: 0 !important;
    width: 100% !important;
  }

  .has-sidebar .main-content {
    padding-left: 12px;
    padding-right: 12px;
  }

  nav.sidebar-nav .sidebar-btn {
    flex: 0 0 auto;
    margin: 0;
    padding: 0;
    background: transparent;
    border: 0;
    cursor: pointer;
  }

  nav.sidebar-nav .sidebar-group {
    flex: 0 0 auto;
    margin: 0;
    padding: 0;
  }

  nav.sidebar-nav .sidebar-pill {
    max-width: 150px;
    /* The nav is a horizontal wrapping row here, not a column, so the
       one-row-per-item height cap does not describe anything. */
    max-height: none;
    width: 100%;
    height: auto;
    display: block;
  }

  nav.sidebar-nav .sidebar-group .sidebar-sub {
    list-style: none;
    padding: 6px 0 0 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    min-width: 160px;
  }

  nav.sidebar-nav .sidebar-sub .sidebar-sub-item {
    min-height: 44px;
    text-align: center;
  }
}

/* ============================================================
   Mobile shell (<=768px): the desktop header is an absolute-
   positioned overlay with a 280px gutter reserved for a 270px
   crest, plus an absolute greeting and a summary sized
   calc(100% - 720px). On a phone that gutter + crest overflow
   and the summary width goes negative. Collapse the whole
   header into a simple stacked flow. Desktop is untouched.
   ============================================================ */
@media (max-width: 768px) {
  .site-header {
    padding: 12px;
    gap: 8px;
    position: static;
  }
  .header-brand {
    padding-left: 0;
    flex-wrap: wrap;
    gap: 10px;
    width: 100%;
    box-sizing: border-box;
  }
  .brand-logo {
    position: static;
    top: auto;
    left: auto;
  }
  .brand-logo img {
    height: 48px !important;
  }
  .brand-text { min-width: 0; }
  .brand-name { white-space: normal; }
  .header-quote {
    position: static;
    left: auto;
    top: auto;
    transform: none;
    width: 100%;
    max-width: 100%;
    padding: 4px 0;
  }
  .site-header__summary {
    width: 100%;
    margin-left: 0;
  }
  .header-right {
    width: 100%;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
  }
  .header-right img,
  #generateBtn img {
    max-width: 100%;
    height: auto;
  }

  /* Compact the nav into a centered wrapping row of tappable pills so every
     tab sits near the top instead of a tall full-width stack pushing lower
     tabs below the fold. */
  nav.sidebar-nav { align-items: center; gap: 6px 8px; }
  /* Center every pill graphic (plain buttons default left because the pill is a
     max-width block); groups already center, so this lines all 5 up. */
  nav.sidebar-nav .sidebar-pill { margin-left: auto; margin-right: auto; }
  nav.sidebar-nav .sidebar-group .sidebar-sub {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    min-width: 0;
    padding-top: 4px;
  }
  nav.sidebar-nav .sidebar-sub .sidebar-sub-item {
    width: auto;
    max-width: none;
    min-height: 44px;
    padding: 8px 14px;
  }

  /* Natural document scroll on phones. The dashboard body is locked to 100vh
     with overflow:hidden and its inner panes scroll on desktop; on mobile that
     clips everything below the first screen. Unlock the body and neutralize the
     internal-scroll chain so the page scrolls normally. !important beats the
     min-width:641 :has() overview lock and the per-tab locked-scroll rules. */
  /* CLIP, not hidden, and for the reason spelled out on the pointer:coarse
     block at the end of this file: hidden beside visible makes the visible
     axis compute to auto, which turns this into a scroll box and stops
     anything inside it sticking. This rule is the more specific of the two
     below 768px, so leaving it as hidden quietly beat the fix. */
  body.dashboard-page {
    height: auto !important;
    max-height: none !important;
    overflow-x: clip !important;
    overflow-y: visible !important;
  }
  body.dashboard-page .main-content,
  body.dashboard-page .tab-content,
  body.dashboard-page .tab-content.active,
  body.dashboard-page #tab-overview,
  body.dashboard-page #overviewContent,
  body.dashboard-page #overviewContent > .section-card.priorities-section,
  body.dashboard-page .priorities-section .priority-list,
  body.dashboard-page .activity-panel,
  body.dashboard-page .emails-pane .email-list-wrapper {
    height: auto !important;
    max-height: none !important;
    min-height: 0 !important;
    overflow: visible !important;
  }

  /* Settings: the category rail becomes a wrapping row of compact chips above
     the detail pane. Wrapping rather than a horizontal scroll strip, so every
     category is reachable without sideways scrolling and nothing sits off the
     edge of a 320px screen. */
  .settings-shell { flex-direction: column; }
  .settings-rail {
    flex: 0 0 auto;
    flex-direction: row;
    flex-wrap: wrap;
    overflow-x: hidden;
    border-right: none;
    border-bottom: 1px solid color-mix(in srgb, var(--brand-gold) 28%, transparent);
  }
  .settings-rail-item {
    flex: 0 1 auto;
    min-width: 0;
    padding: 5px 9px;
  }
  .settings-rail-item--link { margin-top: 0; border-top-color: transparent; }
  .settings-rail-label { font-size: 13px; }

  /* Overflow backstop + cap the fixed-width undo toast to the viewport.
     clip, not hidden: hidden on one axis computes the other to AUTO, which
     turns the body into a scroll box, and a scroll box between a sticky
     element and the viewport stops it sticking. That is what dropped the
     header off the People page -- the only page that scrolls the document
     rather than an inner container. Same pairing as the (pointer: coarse)
     block near the end of this file, for the same reason. */
  html, body { overflow-x: clip; }
  .undo-toast { max-width: calc(100vw - 24px); box-sizing: border-box; }
}

/* ============================================================
   Mid-desktop header (769-1300px): the wide header centers the
   rotating greeting with position:absolute (left:50%), which
   overlaps the SENESCHAL wordmark once the window is narrower
   than the wide layout assumes (longer quotes overlap sooner).
   Between the mobile stack (<=768px) and the wide layout, use a
   compact inline crest with the greeting on its own line. The
   sidebar is untouched (this only restyles the header).
   ============================================================ */
@media (min-width: 769px) and (max-width: 1300px) {
  .header-brand { padding-left: 0; flex-wrap: wrap; gap: 12px; }
  .brand-logo { position: static; top: auto; left: auto; }
  .brand-logo img { height: 72px !important; }
  .header-quote {
    position: static;
    left: auto;
    top: auto;
    transform: none;
    order: 10;
    flex-basis: 100%;
    max-width: 100%;
    margin-top: 8px;
    justify-content: flex-start;
    text-align: left;
  }
  .site-header__summary { width: 100%; margin-left: 0; }
  .header-right { width: auto; margin-left: auto; }
  /* The greeting is pushed to the end of the header here, and that put it
     after the briefing paragraph: "Good evening, Rich." read as a sign-off.
     The summary follows the greeting instead. */
  .site-header__summary { order: 11; }
  /* Compact and left of the castle, never across it. */
  html:not([data-look="modern"]) .site-header__summary { max-width: 640px; }
}

@media (min-width: 769px) {
  .has-sidebar .site-header { min-height: var(--header-band); align-content: flex-start; }
  .has-sidebar .site-footer { padding-left: 300px; }
}

/* ============================================================
   Wide header (>=1301px): keep the big-crest layout but let the
   greeting FLOW between the brand block and the Generate button
   instead of absolute-centering across the whole header. A long
   rotating quote centered on the full width overlaps the SENESCHAL
   wordmark even on wide screens; flowing as a flex item guarantees
   it can never overlap the brand or the button at any width.
   ============================================================ */
@media (min-width: 1301px) {
  .header-quote {
    position: static;
    left: auto;
    top: auto;
    transform: none;
  }
}

/* ============================================================
   Activity log email pane: internal scroll with sticky header
   The .email-list-wrapper inside .emails-pane is capped in
   height and scrolls internally. The .email-list-header row
   stays pinned at the top while rows scroll beneath it.
   ============================================================ */
.emails-pane .email-list-wrapper {
  max-height: calc(100vh - 480px);
  min-height: 250px;
  overflow-y: auto;
}

.emails-pane .email-list-header {
  position: sticky;
  top: 0;
  z-index: 2;
  /* The rows scroll under this, so it has to be opaque rather than nearly so.
     At 92% the top row of text used to ghost through as it passed beneath. */
  background: var(--navy-panel);
}

/* ============================================================
   Activity log box: fixed-height outer container fix
   Caps .activity-panel to viewport-relative height so the gold
   border closes the box on screen. Children flex to fill; the
   .timeline (default) and .emails-pane (Email tab) share the
   same flex slot. All 5 tabs (Note/Call/Text/Email/Meeting)
   get the same box height because the box is sized on the
   outer container, not the inner content.

   Double-class selectors lift specificity to 0,2,0 to beat the
   inline CSS in contact-detail.html lines 88-127 and 236-273.

   Supersedes v1 (1efa8c9), v2 (3293311), v3 (bf56079) which
   all sized .email-list-wrapper instead of .activity-panel.
   ============================================================ */
@media (min-width: 768px) {
  .activity-panel.activity-panel {
    max-height: calc(100vh - 300px);
  }

  .emails-pane.emails-pane {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }

  .emails-pane .email-list-wrapper {
    flex: 1;
    min-height: 0;
    max-height: none;
    overflow-y: auto;
  }
}

/* ============================================================
   Activity log hotfix on top of 10bb89b
   
   10bb89b set max-height calc(100vh - 300px) on .activity-panel
   AND wiped v3's cap on .email-list-wrapper (max-height: none).
   Result: panel undershot, email scroll dead.
   
   This block:
   - .activity-panel: height calc(100vh - 290px). Fixed height
     (not max) so the box stays the same size across all 5 tabs
     (Note/Call/Text/Email/Meeting) regardless of content length.
   - .emails-pane: revert to display: block. 10bb89b's flex
     declarations were inert because the parent wasn't flex.
   - .email-list-wrapper: restore an explicit scroll cap. The
     ~150px gap between panel height and wrapper max-height
     fits the tab row + column header + padding inside the box.
   ============================================================ */
@media (min-width: 768px) {
  .activity-panel.activity-panel {
    height: calc(100vh - 290px);
  }

  .emails-pane.emails-pane {
    display: block;
  }

  .emails-pane.emails-pane .email-list-wrapper {
    max-height: calc(100vh - 440px);
    overflow-y: auto;
  }
}

/* ============================================================
   Activity log re-tune on top of ad40b9d
   
   ad40b9d at calc(100vh - 290px) undershot by ~150px on Rich's
   laptop. Pic 3 shows the gold bar could come down ~150px more
   before hitting the page bottom.
   
   Suspect cause: .activity-card (child of .activity-panel) has
   its own gold border and was content-sized, not parent-height.
   ad40b9d's height rule landed on the wrong element.
   
   This block:
   - .activity-panel: height calc(100vh - 140px)
   - .activity-card: same height (covers case where it's the
     actual bordered element). If it's a child of the panel
     and the panel has overflow:hidden, the card gets clipped
     to the panel bounds either way.
   - .email-list-wrapper: max-height calc(100vh - 290px) so
     the email scroll fills the now-taller panel.
   ============================================================ */
@media (min-width: 768px) {
  .activity-panel.activity-panel {
    height: calc(100vh - 140px);
  }

  .activity-card.activity-card {
    height: calc(100vh - 140px);
  }

  .emails-pane.emails-pane .email-list-wrapper {
    max-height: calc(100vh - 290px);
    overflow-y: auto;
  }
}

/* ============================================================
   Fix cf71a1e: card-height was on the wrong element + panel
   still too high.
   
   Gold border lives on .activity-panel (styles.css ~line 236:
   border + border-radius:16px + overflow:hidden). cf71a1e put
   height on .activity-card too, which blew up every individual
   log entry card. Reset it to auto.
   
   Panel subtraction 140 -> 50 so the gold bottom border sits
   near the viewport bottom (pic showed ~130px of dead space).
   Wrapper 290 -> 200 to fill the now-taller box.
   ============================================================ */
@media (min-width: 768px) {
  .activity-card.activity-card {
    height: auto;
  }

  .activity-panel.activity-panel {
    height: calc(100vh - 50px);
  }

  .emails-pane.emails-pane .email-list-wrapper {
    max-height: calc(100vh - 200px);
    overflow-y: auto;
  }
}

/* ============================================================
   FINAL fix from live DevTools getBoundingClientRect numbers
   (viewportH 824, panel top 148 bottom 672 -> 153px dead gap;
    .email-row outline 3px #1a1a2e = the left line;
    wrapper 624px overflowing 388px pane by 236px).
   
   1. .email-row outline:none  -> kills the left vertical line
   2. .activity-panel height calc(100vh - 160px) accounts for
      the 148px top offset so the gold bottom border lands ~12px
      off the viewport bottom (was guessing 50px before, which
      never applied because panel top offset wasn't in the math)
   3. .email-list-wrapper max-height calc(100vh - 295px) so the
      scroll area fits inside the panel instead of overflowing
   ============================================================ */
.email-row.email-row {
  outline: none;
}

@media (min-width: 768px) {
  .activity-panel.activity-panel {
    height: calc(100vh - 160px);
  }

  .emails-pane.emails-pane .email-list-wrapper {
    max-height: calc(100vh - 295px);
    overflow-y: auto;
  }
}

/* ============================================================
   FINAL: release clamp + fill pane + kill .layout left bleed
   
   1. .activity-panel max-height:none releases the 10bb789
      calc(100vh - 300px) clamp (styles.css ~2539) that froze
      the panel at 524px and silently beat all 6 height rules.
      Then height calc(100vh - 160px) lands the bottom ~12px
      off the viewport bottom (panel top offset is 148px).
   
   2. .emails-pane flex-fills the panel column so the wrapper
      stops overflowing (was 529px wrapper in a 388px pane).
      Panel is flex-direction:column; pane gets flex:1 + min-
      height:0; wrapper inside gets flex:1 + overflow-y:auto,
      max-height removed so it fills naturally.
   
   3. Left line = DIV.layout background bleeding through the
      panel's rounded-corner left edge. background-clip:border-
      box + an explicit left padding-box paint stops the
      underlying .layout from showing at the seam.
   ============================================================ */
@media (min-width: 768px) {
  .activity-panel.activity-panel {
    max-height: none;
    height: calc(100vh - 160px);
    background-clip: padding-box;
  }

  .emails-pane.emails-pane {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }

  .emails-pane.emails-pane .email-list-wrapper {
    flex: 1;
    min-height: 0;
    max-height: none;
    overflow-y: auto;
  }
}

/* ============================================================
   From live JSON (wrap_h 3691 in a 528 pane = no scroll;
   docScrollH 888 vs viewport 824 = 64px page overflow).
   
   1. .email-list-wrapper explicit max-height restores scroll.
      Pane measured 528px; cap wrapper at calc(100vh - 296px)
      ~= 528 so overflow-y:auto fires regardless of the flex
      chain (the pane computed display:block, so flex:1 on the
      wrapper had no flex parent to clamp it).
   
   2. Page overflow: the activity panel fits (bottom 748 < 824)
      but doc scrollHeight is 888. Trim the panel's bottom
      margin so the page stops generating a scrollbar.
   ============================================================ */
@media (min-width: 768px) {
  .emails-pane.emails-pane .email-list-wrapper {
    flex: none;
    max-height: calc(100vh - 296px);
    overflow-y: auto;
  }

  .activity-panel.activity-panel {
    margin-bottom: 0;
  }
}

/* ============================================================
   Kill stranded left line + page scrollbar.
   
   The gold left line below the box = .activity-panel border-left
   (color-mix(in srgb, var(--brand-gold) 35%, transparent)) painting past the panel's bottom edge.
   Force overflow:hidden so nothing renders past the border, and
   clip the 64px page overflow (docScrollH 888 vs viewport 824)
   at the document root.
   ============================================================ */
@media (min-width: 768px) {
  .activity-panel.activity-panel {
    overflow: hidden;
  }

  /* clip, not hidden: see the note on the same pair in the max-width block
     above. hidden here made the body a scroll box and the sticky header
     scrolled away on any page that scrolls the document itself. */
  html, body {
    overflow-x: clip;
  }

  .layout {
    overflow: hidden;
    max-height: 100vh;
  }
}

/* ============================================================
   Remove the gold left border from .activity-panel. This is
   the stranded vertical line on the left. The top/right/bottom
   borders still close the box. Double-class beats the inline
   border rule at contact-detail.html line 236.
   ============================================================ */
@media (min-width: 768px) {
  .activity-panel.activity-panel {
    border-left: none;
  }
}

/* ============================================================
   The stranded left line is .profile-panel's right border
   (1px solid #2a2a2a) — proven by DevTools: profile-panel
   rect bottom 808 vs activity box bottom 748, so it overhangs
   by 60px below the box. Remove it.
   ============================================================ */
.profile-panel.profile-panel {
  border-right: none;
}

/* ============================================================
   Two measured fixes:
   1. Restore .activity-panel left border (was 0px none after
      the profile-panel fix) to 1px solid color-mix(in srgb, var(--brand-gold) 35%, transparent)
      matching the other three sides so the box closes left.
   2. Panel was 64px too tall (bottom 812, viewport 824, body
      888 = 64px page overflow). Subtraction 160 -> 224 fits
      the panel in the viewport and kills the page scrollbar.
      Wrapper cap follows: 296 -> 360.
   ============================================================ */
@media (min-width: 768px) {
  .activity-panel.activity-panel {
    border-left: 1px solid color-mix(in srgb, var(--brand-gold) 35%, transparent);
    height: calc(100vh - 224px);
  }

  .emails-pane.emails-pane .email-list-wrapper {
    max-height: calc(100vh - 360px);
    overflow-y: auto;
  }
}

/* ============================================================
   From DevTools JSON:
   1. Page overflow 64px (body 888 vs viewport 824). Panel fits
      and email list scrolls in its wrapper; the residual page
      scroll is clipped at root. Fixed dashboard layout = panels
      scroll internally, no page scroll needed.
   2. .back-bar used to clear the shield with its own padding-left
      of 270. It now rides the same margin-left as .page-pill-row,
      which both clears the shield and lines the link up with the
      Emails pill underneath it at every breakpoint.
   ============================================================ */
@media (min-width: 768px) {
  body.contact-detail {
    height: 100vh;
    overflow: hidden;
  }
}

.btn-sync-emails {
  background: var(--brand-gold, var(--brand-gold));
  color: #0D1B2A;
  border: none;
  padding: 6px 14px;
  border-radius: 6px;
  font-weight: 600;
  font-size: 12px;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
}
.btn-sync-emails:disabled { opacity: 0.6; cursor: not-allowed; }
.sync-status { color: var(--brand-gold, var(--brand-gold)); font-size: 11px; white-space: nowrap; }
.sync-needed-reason { margin: 0 0 10px; font-size: 13px; color: #e8e8e8; line-height: 1.5; }

/* ============================================================
   Activity log pill buttons — image pills replace text/emoji
   buttons. Buttons keep their data-action='open-log' + data-
   log-type / data-log-label so existing JS event delegation
   stays untouched; only the visible inner content changed.
   Higher specificity (.log-bar .log-btn = 0,2,0) beats the
   inline .log-btn rules (0,1,0) in the HTML head style block.
   ============================================================ */
.log-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.log-bar .log-bar-label {
  font-family: var(--serif);
  font-size: 18px;
  color: var(--brand-gold, var(--brand-gold));
  font-weight: 600;
  margin-right: 8px;
}

.log-bar .log-btn {
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  line-height: 0;
}

.log-bar .log-btn img.log-pill-img {
  display: block;
  height: 36px;
  width: auto;
  opacity: 0.7;
  transition: opacity 150ms ease, transform 150ms ease;
}

.log-bar .log-btn:hover img.log-pill-img,
.log-bar .log-btn.active img.log-pill-img {
  opacity: 1;
}

.log-bar .log-btn:active img.log-pill-img {
  transform: scale(0.96);
}

/* ============================================================
   Ensure top-left and top-right corners are rounded on both
   the outer .activity-panel AND the inner .activity-card.
   The inner card may have been the visually-square edge since
   it sits inside the panel with its own gold border.
   ============================================================ */
.activity-panel.activity-panel,
.activity-card.activity-card {
  border-top-left-radius: 16px;
  border-top-right-radius: 16px;
}

/* ============================================================
   Shift right column (contact card + activity panel) down 64px
   so .profile-panel's "Edit contact" button vertically aligns
   with the "Settings" nav pill on the left.
   
   Measured from DevTools JSON:
   - settings pill top: 795
   - edit contact top:  731
   - gap to align:      64px
   
   Height of activity panel intentionally NOT reduced.
   ============================================================ */
@media (min-width: 768px) {
  .profile-panel.profile-panel,
  .activity-panel.activity-panel {
    margin-top: 64px;
  }
}

/* ============================================================
   Phase A: checklist header swaps to PNG status pill + count
   text below. .checklist-header was a row (title left, progress
   right); becomes a column stack with the image centered and
   the X/Y complete text below it. Click target on the header
   itself is unchanged - children just laid out vertically.
   ============================================================ */
.checklist .checklist-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.checklist-pill-img {
  display: block;
  max-width: 100%;
  height: auto;
}

.checklist .checklist-header .checklist-progress {
  text-align: center;
}

/* ============================================================
   Phase B: checklist view inside the activity panel.
   ============================================================ */
.checklist-pill-img {
  cursor: pointer;
  transition: opacity 150ms ease;
}
.checklist-pill-img:hover {
  opacity: 0.85;
}

.checklist-view {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.checklist-view-header {
  padding: 10px 16px;
  border-bottom: 1px solid color-mix(in srgb, var(--brand-gold) 20%, transparent);
  display: flex;
  gap: 16px;
  align-items: center;
}

.checklist-view-title {
  color: #e8e8e8;
  font-size: 14px;
  font-family: var(--serif);
}

.checklist-filter-pills {
  display: flex;
  gap: 6px;
  margin-left: 12px;
}
.checklist-filter-pill {
  background: transparent;
  border: none;
  padding: 0;
  cursor: pointer;
  line-height: 0;
  opacity: 0.5;
}
.checklist-filter-pill img {
  height: 28px;
}
.checklist-filter-pill:hover {
  opacity: 0.8;
}
.checklist-filter-pill.active {
  opacity: 1;
}

.checklist-view-body {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  /* Narrow panel: sized for the 2-column grid only. Border removed --
     the outer .activity-panel gold border (constrained via :has() rule
     below) is what encloses this now, so it hugs the checklist width
     instead of spanning the whole column. */
  background: rgba(13, 27, 42, 0.75);
  border-radius: 8px;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

/* Shrink the outer gold-bordered activity panel so it doesn't stretch
   across the whole right column. Applies to the empty timeline state
   AND the checklist view. Left-aligned so it hugs the profile card
   on the left instead of leaving a gap. */
.activity-panel {
  max-width: 900px;
  margin-left: 0;
  margin-right: auto;
}

/* Double-scrollbar fix (checklist view only). The outer .activity-panel grew
   its own scrollbar because .checklist-view is sized to the full panel height
   while sitting below the 68px log-bar, so panel content overflowed by ~70px
   AND the long list inside .checklist-view-body scrolled -- two bars side by
   side. While the checklist is the visible view, make the panel a flex column
   so the log-bar pins, the checklist-view fills only the remaining height, and
   .checklist-view-body is the single scroller. Scoped by :not(display:none) so
   the activity-log and email views keep their own height rules untouched. */
.activity-panel:has(> .checklist-view:not([style*="display: none"])) {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.activity-panel:has(> .checklist-view:not([style*="display: none"])) > .log-bar {
  flex: 0 0 auto;
}
.activity-panel:has(> .checklist-view:not([style*="display: none"])) > .checklist-view {
  flex: 1 1 auto;
  min-height: 0;
  height: auto;
}

/* Grid layout for items inside the view. Targets common item
   wrappers; falls back to generic child styling if class names
   in the .checklist-body differ. */
.checklist-view-body .checklist-category {
  margin-bottom: 20px;
}

.checklist-view-body .checklist-category-items,
.checklist-view-body .checklist-items,
.checklist-view-body .checklist-item-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: 8px;
}

.checklist-view-body .checklist-category > *:first-child {
  font-family: var(--serif);
  color: var(--brand-gold, var(--brand-gold));
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 10px;
  display: block;
}

.checklist-view-body .checklist-item {
  background: rgba(0,0,0,0.3);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 20%, transparent);
  border-radius: 6px;
  padding: 10px 14px;
  font-size: 13px;
  color: var(--brand-gold, var(--brand-gold));
}

/* ============================================================
   Retarget grid layout in the checklist view to .checklist-row
   (the actual item wrapper). 3 columns across, items wrap to
   next row left -> right. Category headers stay full-width
   above each group.
   
   Higher specificity (.checklist-view-body .checklist-row)
   beats whatever block layout .checklist-row has elsewhere.
   The parent of .checklist-row becomes the grid container.
   ============================================================ */
.checklist-view-body .checklist-category,
.checklist-view-body .checklist-body {
  display: block;
}

/* The container holding the .checklist-row siblings becomes
   the grid. Targets both possible structures: rows direct
   under a category, or rows direct under the body. */
.checklist-view-body > div,
.checklist-view-body .checklist-category {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  align-items: start;
}

/* Category header (if rendered as a sibling/heading) spans
   the full row */
.checklist-view-body .checklist-category-header,
.checklist-view-body h3,
.checklist-view-body h4 {
  grid-column: 1 / -1;
  font-family: var(--serif);
  color: var(--brand-gold, var(--brand-gold));
  font-size: 16px;
  font-weight: 600;
  margin: 12px 0 4px;
}

/* Each .checklist-row becomes a grid cell */
.checklist-view-body .checklist-row {
  background: rgba(0,0,0,0.3);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 20%, transparent);
  border-radius: 6px;
  padding: 10px 12px;
  font-size: 13px;
  min-width: 0;
}

/* Deadline flags so overdue/urgent items stand out at a glance instead of
   only recolouring the small date field. Double class beats the base row. */
.checklist-view-body .checklist-row.checklist-row--overdue {
  border-color: #ef4444;
  border-left-width: 3px;
  background: rgba(239, 68, 68, 0.10);
}
.checklist-view-body .checklist-row.checklist-row--urgent {
  border-color: #e0a83c;
  border-left-width: 3px;
  background: rgba(224, 168, 60, 0.10);
}
.deadline-badge {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 1px 6px;
  border-radius: 4px;
  margin-left: 6px;
  vertical-align: middle;
  white-space: nowrap;
}
.deadline-badge--overdue { background: var(--status-red-solid); color: #fff; }   /* 4.98:1 */
.deadline-badge--urgent  { background: #e0a83c; color: #1a1a1a; }
/* Factual "form was signed after its deadline" record. Informational
   amber-brown, distinct from the red overdue and gold urgent states. */
.deadline-badge--late    { background: #b45309; color: #fff; }

/* Date input inside each row should not break the grid cell */
.checklist-view-body .checklist-row input[type="date"] {
  max-width: 100%;
  margin-top: 6px;
  /* Gold date text on dark backing -- matches brand + easier to read than
     the default white/system color inside the navy chip. */
  color: var(--brand-gold);
  background: rgba(13, 27, 42, 0.6);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 35%, transparent);
  border-radius: 4px;
  padding: 2px 4px;
}
/* Force gold on the date text spans that Chrome injects inside the field.
   Chrome's -webkit-datetime-edit shadow controls the visible number text. */
.checklist-view-body .checklist-row input[type="date"]::-webkit-datetime-edit,
.checklist-view-body .checklist-row input[type="date"]::-webkit-datetime-edit-fields-wrapper,
.checklist-view-body .checklist-row input[type="date"]::-webkit-datetime-edit-text,
.checklist-view-body .checklist-row input[type="date"]::-webkit-datetime-edit-month-field,
.checklist-view-body .checklist-row input[type="date"]::-webkit-datetime-edit-day-field,
.checklist-view-body .checklist-row input[type="date"]::-webkit-datetime-edit-year-field {
  color: var(--brand-gold);
}
/* Calendar-picker icon: keep visible + gold-tinted */
.checklist-view-body .checklist-row input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(75%) sepia(29%) saturate(571%) hue-rotate(4deg) brightness(92%) contrast(89%);
  cursor: pointer;
}

@media (max-width: 1100px) {
  .checklist-view-body > div,
  .checklist-view-body .checklist-category {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 700px) {
  .checklist-view-body > div,
  .checklist-view-body .checklist-category {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   1. Category title (.checklist-category-title) was getting
      treated as a grid cell, eating column 1 of each row.
      Span full width so items start fresh on the next row.
   2. Drop the dark card background + gold border on each
      .checklist-row inside the view — cleaner, less busy.
   ============================================================ */
.checklist-view-body .checklist-category-title {
  grid-column: 1 / -1;
  font-family: var(--serif);
  color: var(--brand-gold, var(--brand-gold));
  font-size: 16px;
  font-weight: 600;
  margin: 16px 0 6px;
}

.checklist-view-body .checklist-row {
  background: transparent;
  border: none;
  padding: 6px 4px;
}

/* ============================================================
   Scope gold form-name rule to active rows only. The existing
   .checklist-row.done .checklist-row__name { color: #999 }
   strikethrough rule was being overridden by my prior global
   gold rule. Adding a higher-specificity restore for .done
   rows that explicitly sets the #777 back, so completed items
   keep their dimmed strikethrough look.
   ============================================================ */
/* Completed items: strikethrough + muted gold. Reads as visually secondary
   to the still-active gold items above, but stays on-brand instead of
   dropping to grey/white. */
.checklist-view-body .checklist-row.done .checklist-row__name,
.checklist-view-body .checklist-row.done label,
.checklist-view-body .checklist-row.done span:not(.na-pill):not(.checklist-toggle) {
  color: #a08e5c;
}

/* ============================================================
   Form names go gold on active rows. Targets the actual class
   .checklist-row__name (BEM). Completed rows (.done) are NOT
   included, so the existing .checklist-row.done rule keeps the
   #777 strikethrough on those.
   ============================================================ */
.checklist-view-body .checklist-row:not(.done) .checklist-row__name {
  color: var(--brand-gold, var(--brand-gold));
}

/* ============================================================
   Not-applicable rows: item is real but disabled by a
   transaction flag (e.g. Form 22B when has_buyer_sale_contingency=false).
   Distinct from .done: no strikethrough, no bright gold; muted
   italic so the row reads as "skip this, doesn't apply here"
   instead of blending into completed items.
   Both the leading N/A badge and the item name follow the same
   muted tone.
   ============================================================ */
.checklist-view-body .checklist-row.not-applicable .checklist-row__name {
  /* Was #8a7a4c, which measured 4.12:1 on navy. Lifted just past the 4.5 bar;
     still clearly dimmer than the active gold, so the "skip this" read survives. */
  color: #a1946a;
  font-style: italic;
  /* Dotted strikethrough differentiates N/A ("never had to happen") from
     completed ("we did this"). Line is white so it stays visible against
     the dark panel; the text stays muted grey so the row still reads as
     "skip, doesn't apply". */
  text-decoration: line-through dotted;
  text-decoration-color: rgba(255, 255, 255, 0.85);
  text-decoration-thickness: 1.5px;
}
.checklist-view-body .checklist-row.not-applicable .checklist-row__check {
  opacity: 0.35;
  pointer-events: none;
}
.checklist-view-body .checklist-row.not-applicable {
  opacity: 0.75;
}

.checklist-row .na-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: #bfbfbf;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 3px;
  vertical-align: middle;
  font-style: normal;
}

/* Contacts page — internal scroll container, same locked pattern
   as Emails (3a704bd) and Follow Up (7edb7cc). Body 100vh + flex
   chain → .rows-scroll scrolls within its own box. Toolbar, count
   row, and column-header table stay in normal flow above.
   Replaces former calc(100vh - 130px) magic-number approach. */
@media (min-width: 641px) {
  body.contacts-manager {
    display: flex;
    flex-direction: column;
    height: 100vh;
    max-height: 100vh;
    overflow: hidden;
  }
  body.contacts-manager .site-header,
  body.contacts-manager .site-footer {
    flex-shrink: 0;
  }
  body.contacts-manager .page {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
    margin-top: 0;
  }
  body.contacts-manager .toolbar,
  body.contacts-manager .contact-count {
    flex: 0 0 auto;
  }
  body.contacts-manager .table-wrap {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
  }
  body.contacts-manager .table-wrap .data-table {
    table-layout: fixed;
    width: 100%;
    margin: 0;
  }
  body.contacts-manager .data-table--head {
    flex: 0 0 auto;
  }
  body.contacts-manager .rows-scroll {
    flex: 1 1 auto;
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
  }
  body.contacts-manager .data-table { font-size: 12px; }
  body.contacts-manager .data-table th { padding: 6px 10px; }
  body.contacts-manager .data-table td { padding: 6px 10px; }
}

/* ── Wizard Stone-Rune Roundel Pill (steps 1-4) ──────────────────────────── */
.rune-pill-wrap {
  position: relative;
  display: inline-block;
  width: 280px;
  max-width: 90vw;
  cursor: pointer;
  user-select: none;
}
.rune-pill-wrap.rune-pill--input {
  cursor: text;
}
.rune-pill-bg {
  width: 100%;
  height: auto;
  display: block;
  pointer-events: none;
  user-select: none;
}
.rune-pill-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #fff;
  font-family: 'Cinzel', var(--serif);
  font-weight: 600;
  font-size: 1.15rem;
  letter-spacing: 0.5px;
  text-align: center;
  white-space: nowrap;
  margin: 0;
  text-shadow: 0 2px 6px rgba(0,0,0,0.7);
  pointer-events: none;
}
.rune-pill-subtext {
  display: block;
  font-size: 0.7rem;
  font-weight: 400;
  font-family: Georgia, serif;
  color: var(--brand-gold);
  letter-spacing: 0;
  margin-top: 2px;
  font-style: italic;
}
.rune-pill-wrap:hover .rune-pill-bg {
  filter: brightness(1.15);
  transition: filter 0.15s ease;
}
.rune-pill-wrap.selected .rune-pill-bg {
  filter: brightness(1.25) drop-shadow(0 0 8px color-mix(in srgb, var(--brand-gold) 60%, transparent));
}

/* Input variant — transparent input centered on pill */
.rune-pill-input {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: transparent;
  border: none;
  outline: none;
  color: #fff;
  font-family: 'Cinzel', var(--serif);
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: 0.5px;
  text-align: center;
  width: 65%;
  padding: 0;
  text-shadow: 0 2px 6px rgba(0,0,0,0.7);
}
.rune-pill-input:focus {
  outline: none;
}
.rune-pill-input::-webkit-calendar-picker-indicator {
  filter: invert(0.7) sepia(1) hue-rotate(20deg) saturate(2);
  cursor: pointer;
}
.rune-pill-select {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23d4a017' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  padding-right: 28px;
}
.rune-pill-select option {
  background: #0d1b2a;
  color: #fff;
}

/* Two-pill side-by-side group */
.rune-pill-group {
  display: flex;
  gap: 24px;
  justify-content: center;
  flex-wrap: wrap;
  margin: 0 auto;
}

/* ── Wizard arrows — smaller, lifted off the gold pillar line ────────────── */
.wizard-arrow {
  width: 64px;
  height: auto;
  display: block;
}

/* ── Wizard nav buttons with gold text labels ────────────────────────────── */
.wizard-nav {
  background: transparent;
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 0;
  color: var(--brand-gold);
  font-family: 'Cinzel', var(--serif);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  text-shadow: 0 2px 6px rgba(0,0,0,0.7);
}
.wizard-nav:hover .wizard-arrow {
  filter: brightness(1.25);
  transition: filter 0.15s ease;
}
.wizard-nav-label {
  display: inline-block;
}

/* Pill groups on choice steps sit flush on the castle bg — no container chrome */
.step .step-actions,
.step-actions {
  background: transparent !important;
  background-color: transparent !important;
  border: none !important;
  box-shadow: none !important;
}

/* Strip legacy choice-card chrome when paired with rune-pill-wrap */
.choice-card.rune-pill-wrap {
  background: transparent !important;
  background-color: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
}
.choice-card.rune-pill-wrap:hover,
.choice-card.rune-pill-wrap:focus,
.choice-card.rune-pill-wrap.selected {
  background: transparent !important;
  background-color: transparent !important;
  border: none !important;
  box-shadow: none !important;
}

@media (min-width: 641px) {
  /* Pipeline — internal scroll container, same pattern as Emails / Follow Up.
     It previously unlocked the body and let the whole document scroll, which
     dragged the crest, header and deadline banner up off the top. Body stays
     locked to 100vh and only the card grid scrolls, so everything above it
     holds still. */
  body.dashboard-page:has(#tab-pipeline.tab-content.active) {
    display: flex;
    flex-direction: column;
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .site-header,
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .site-footer {
    flex-shrink: 0;
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) main.main-content {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    padding-bottom: 0;
    display: flex;
    flex-direction: column;
  }
  /* Banners above the tab (deal updates, unmatched signings) hold their size. */
  body.dashboard-page:has(#tab-pipeline.tab-content.active) main.main-content > *:not(#tab-pipeline) {
    flex: 0 0 auto;
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) #tab-pipeline,
  body.dashboard-page:has(#tab-pipeline.tab-content.active) #pipeline-section {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  /* The 48-hour deadline banner is part of the fixed top, not the scroll area. */
  body.dashboard-page:has(#tab-pipeline.tab-content.active) #urgent-deadlines-banner {
    flex: 0 0 auto;
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) #pipeline-cards {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
  }
  /* Reclaim margins so the grid clears the scrollbar: the section's bottom
     margin sits below the grid inside a locked-height layout where it buys
     nothing, and the banner gap can give up 4px. */
  body.dashboard-page:has(#tab-pipeline.tab-content.active) #pipeline-section {
    margin-bottom: 0;
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) #urgent-deadlines-banner {
    margin-bottom: 8px;
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-section {
    margin-bottom: clamp(6px, 1.5vh, 18px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-section .section-title {
    margin-bottom: clamp(6px, 1.2vh, 14px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-card {
    padding: clamp(4px, 0.8vh, 8px) clamp(6px, 1vh, 10px);
    font-size: clamp(10px, 1.2vh, 11px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-card__header {
    margin-bottom: clamp(2px, 0.5vh, 5px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-card__stage {
    padding: clamp(2px, 0.3vh, 3px) 8px;
    font-size: clamp(9px, 1vh, 10px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-card__names {
    font-size: clamp(11px, 1.4vh, 13px);
    margin-bottom: clamp(1px, 0.3vh, 3px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-card__phones {
    font-size: clamp(9px, 1vh, 10px);
    margin-bottom: clamp(2px, 0.4vh, 4px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-card__address {
    font-size: clamp(10px, 1.1vh, 11px);
    margin-bottom: clamp(1px, 0.3vh, 3px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-card__closing {
    font-size: clamp(10px, 1.1vh, 11px);
    margin-bottom: clamp(1px, 0.3vh, 3px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-card__last-contact {
    font-size: clamp(9px, 1vh, 10px);
    margin-bottom: clamp(2px, 0.4vh, 5px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-card__progress {
    margin-top: clamp(1px, 0.3vh, 3px);
    padding-top: clamp(2px, 0.5vh, 5px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-card__progress-text {
    font-size: clamp(10px, 1.2vh, 12px);
    margin-bottom: clamp(2px, 0.5vh, 6px);
  }
  body.dashboard-page:has(#tab-pipeline.tab-content.active) .pipeline-cards {
    gap: clamp(4px, 0.7vh, 8px);
  }
}

/* Emails — internal scroll container. Body stays locked 100vh,
   dashboard header + search/pills are above the scroll box in
   normal flow, .email-table itself is the scroll container.
   Email rows scroll within the box; everything above cannot move
   because the page itself doesn't scroll. Mirrors Social tab's
   .social-cards-list pattern. */
body.dashboard-page:has(#tab-emails.tab-content.active) {
  display: flex;
  flex-direction: column;
}
body.dashboard-page:has(#tab-emails.tab-content.active) .site-header,
body.dashboard-page:has(#tab-emails.tab-content.active) .site-footer {
  flex-shrink: 0;
}
body.dashboard-page:has(#tab-emails.tab-content.active) main.main-content {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  padding-bottom: 0;
  display: flex;
  flex-direction: column;
}
body.dashboard-page:has(#tab-emails.tab-content.active) #tab-emails {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
body.dashboard-page:has(#tab-emails.tab-content.active) #tab-emails .inbox-search-bar {
  flex: 0 0 auto;
}
body.dashboard-page:has(#tab-emails.tab-content.active) #tab-emails .email-table {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
}
/* Column header pins to top of the .email-table scroll box, with
   navy fill so scrolled rows don't show through it. This fill is
   contained inside the email-table card, not spanning the page. */
body.dashboard-page:has(#tab-emails.tab-content.active) #tab-emails .email-row--header {
  position: sticky;
  top: 0;
  z-index: 5;
  background: rgba(13, 27, 42, 0.95);
}
body.dashboard-page:has(#tab-emails.tab-content.active) .emails-pane .email-row {
  padding: clamp(5px, 1vh, 10px) 12px;
  gap: clamp(6px, 1vh, 12px);
}
body.dashboard-page:has(#tab-emails.tab-content.active) .emails-pane .email-list-header {
  padding: clamp(5px, 1vh, 10px) 12px;
  font-size: clamp(10px, 1.1vh, 11px);
}
body.dashboard-page:has(#tab-emails.tab-content.active) .emails-pane .email-date {
  font-size: clamp(10px, 1.1vh, 12px);
}
body.dashboard-page:has(#tab-emails.tab-content.active) .emails-pane .email-summary {
  font-size: clamp(10px, 1.1vh, 12px);
}

/* Follow Up — internal scroll container. Same pattern as Emails (3a704bd).
   Body locked 100vh, dashboard header + .section-header-row sit in normal
   flow above the scroll box, #contactsContainer is the scroll container.
   Cards scroll within the box; above-box elements structurally cannot move. */
body.dashboard-page:has(#tab-contacts.tab-content.active) {
  display: flex;
  flex-direction: column;
}
body.dashboard-page:has(#tab-contacts.tab-content.active) .site-header,
body.dashboard-page:has(#tab-contacts.tab-content.active) .site-footer {
  flex-shrink: 0;
}

/* Video — the rules below were interleaved into the Follow Up block and the
   body-level flex rule was missing entirely, so `flex: 1 1 auto` on
   main.main-content and `height: 100%` on #tab-video were both acting on a
   non-flex, auto-height ancestor and did nothing. The chain only ignites once
   the body is a flex column. */
body.dashboard-page:has(#tab-video.tab-content.active) {
  display: flex;
  flex-direction: column;
}
body.dashboard-page:has(#tab-video.tab-content.active) .site-header,
body.dashboard-page:has(#tab-video.tab-content.active) .site-footer {
  flex-shrink: 0;
}
body.dashboard-page:has(#tab-video.tab-content.active) main.main-content {
  flex: 1 1 auto;
  overflow: hidden;
  padding-bottom: 0;
  min-height: 0;
}
body.dashboard-page:has(#tab-video.tab-content.active) #tab-video {
  height: 100%;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
body.dashboard-page:has(#tab-contacts.tab-content.active) .site-footer {
  flex-shrink: 0;
}
body.dashboard-page:has(#tab-contacts.tab-content.active) main.main-content {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  padding-bottom: 0;
  display: flex;
  flex-direction: column;
}
body.dashboard-page:has(#tab-contacts.tab-content.active) #tab-contacts {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
body.dashboard-page:has(#tab-contacts.tab-content.active) #tab-contacts .section-header-row {
  flex: 0 0 auto;
}
body.dashboard-page:has(#tab-contacts.tab-content.active) #tab-contacts #contactsContainer {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
}
/* Fade the bottom of the Follow Up list so the last partly-visible card
   dissolves into "keep scrolling" rather than looking sliced. 64px is tall
   enough to actually dim the folding card, not just its bottom sliver.
   scroll-fade.js adds .scroll-fade-active only while there is more below, so
   the fade clears the moment you reach the end and the final card is whole. */
body.dashboard-page:has(#tab-contacts.tab-content.active) #tab-contacts #contactsContainer.scroll-fade-active {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 64px), transparent);
          mask-image: linear-gradient(to bottom, #000 calc(100% - 64px), transparent);
}
body.dashboard-page:has(#tab-contacts.tab-content.active) .contact-card {
  margin-bottom: clamp(2px, 0.4vh, 10px);
}
body.dashboard-page:has(#tab-contacts.tab-content.active) .contact-card-header {
  padding: clamp(4px, 0.7vh, 10px) 12px;
  gap: clamp(4px, 0.6vh, 10px);
}
body.dashboard-page:has(#tab-contacts.tab-content.active) .contact-avatar {
  width: clamp(28px, 3.5vh, 46px);
  height: clamp(28px, 3.5vh, 46px);
  font-size: clamp(12px, 1.5vh, 18px);
}
body.dashboard-page:has(#tab-contacts.tab-content.active) .contact-name {
  font-size: clamp(11px, 1.3vh, 14px);
}
body.dashboard-page:has(#tab-contacts.tab-content.active) .contact-meta {
  font-size: clamp(9px, 1vh, 11px);
  margin-top: 0;
}
body.dashboard-page:has(#tab-contacts.tab-content.active) .days-since {
  font-size: clamp(9px, 1vh, 12px);
  padding: clamp(1px, 0.2vh, 3px) 8px;
}
body.dashboard-page:has(#tab-contacts.tab-content.active) .draft-toggle-btn {
  width: clamp(22px, 2.5vh, 30px);
  height: clamp(22px, 2.5vh, 30px);
  font-size: clamp(14px, 1.6vh, 20px);
}

/* ── Viewport-responsive Settings ────────────────────────────────────────── */
body.dashboard-page:has(#tab-settings.tab-content.active) .settings-rail-item {
  padding: clamp(4px, 0.7vh, 7px) 10px;
}
body.dashboard-page:has(#tab-settings.tab-content.active) .settings-rail-label {
  font-size: clamp(12px, 1.4vh, 14px);
}
body.dashboard-page:has(#tab-settings.tab-content.active) .settings-detail {
  padding: clamp(6px, 1vh, 12px) 16px clamp(8px, 1.2vh, 14px);
}
body.dashboard-page:has(#tab-settings.tab-content.active) .settings-detail-title {
  font-size: clamp(14px, 1.7vh, 17px);
}
body.dashboard-page:has(#tab-settings.tab-content.active) .settings-section {
  padding: clamp(4px, 0.6vh, 6px) 10px;
  margin-bottom: clamp(2px, 0.4vh, 4px);
}
body.dashboard-page:has(#tab-settings.tab-content.active) .bg-picker-grid {
  gap: clamp(6px, 1vh, 12px);
}
body.dashboard-page:has(#tab-settings.tab-content.active) .bg-picker-item img {
  height: clamp(60px, 10vh, 100px);
}
body.dashboard-page:has(#tab-settings.tab-content.active) .bg-picker-label {
  padding: clamp(4px, 0.6vh, 8px);
  font-size: clamp(11px, 1.2vh, 13px);
}
/* ── Pending-assignment pill + modal ── */
.pa-pill-toolbar {
  display: flex;
  justify-content: center;
  padding: 12px 24px 0;
}
.pa-pill-toolbar[hidden] { display: none; }
.pa-pill {
  background: rgba(13, 27, 42, 0.92);
  border: 1.5px solid var(--brand-gold);
  color: var(--brand-gold);
  border-radius: 999px;
  padding: 8px 20px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.05em;
  cursor: pointer;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.3), 0 4px 12px rgba(0,0,0,0.5), 0 0 18px color-mix(in srgb, var(--brand-gold) 25%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: background 0.15s, box-shadow 0.15s, transform 0.1s;
  animation: paPillPulse 2.4s ease-in-out infinite;
}
.pa-pill:hover {
  background: rgba(13, 27, 42, 1);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.3), 0 4px 14px rgba(0,0,0,0.6), 0 0 24px color-mix(in srgb, var(--brand-gold) 45%, transparent);
  transform: translateY(-1px);
}
@keyframes paPillPulse {
  0%, 100% { box-shadow: 0 0 0 1px rgba(0,0,0,0.3), 0 4px 12px rgba(0,0,0,0.5), 0 0 12px color-mix(in srgb, var(--brand-gold) 15%, transparent); }
  50%       { box-shadow: 0 0 0 1px rgba(0,0,0,0.3), 0 4px 12px rgba(0,0,0,0.5), 0 0 24px color-mix(in srgb, var(--brand-gold) 40%, transparent); }
}
.pa-modal {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pa-modal[hidden] { display: none; }
.pa-modal__backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.7); }
.pa-modal__panel {
  position: relative;
  background: #0d0d0d;
  border: 1px solid var(--brand-gold);
  border-radius: 8px;
  width: min(680px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.pa-modal__header {
  display: flex;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid color-mix(in srgb, var(--brand-gold) 25%, transparent);
  flex-shrink: 0;
}
.pa-modal__title {
  flex: 1;
  margin: 0;
  font-size: 16px;
  color: var(--brand-gold);
  font-family: 'Cinzel', serif;
  font-weight: 700;
}
.pa-modal__close {
  background: none;
  border: none;
  color: #888;
  font-size: 22px;
  line-height: 1;
  padding: 2px 6px;
  cursor: pointer;
}
.pa-modal__close:hover { color: #fff; }
.pa-modal__body {
  overflow-y: auto;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.pa-modal__loading,
.pa-modal__empty,
.pa-modal__error {
  color: #888;
  font-size: 13px;
  text-align: center;
  padding: 24px 0;
}
.pa-modal__error { color: #d45a5a; }
.pa-row {
  background: rgba(255,255,255,0.03);
  border: 1px solid #2a2a2a;
  border-radius: 6px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: opacity 0.2s;
}
.pa-row__meta { display: flex; flex-direction: column; gap: 2px; }
.pa-row__subject { font-size: 13px; color: #e8e8e8; font-weight: 500; }
.pa-row__detail { font-size: 11px; color: #888; }
.pa-row__chips { display: flex; flex-wrap: wrap; gap: 6px; }
.pa-chip {
  background: color-mix(in srgb, var(--brand-gold) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 40%, transparent);
  color: var(--brand-gold);
  border-radius: 14px;
  padding: 3px 12px;
  font-size: 11px;
  cursor: pointer;
  transition: background 0.15s;
}
.pa-chip:hover { background: color-mix(in srgb, var(--brand-gold) 25%, transparent); }
.pa-chip--active { background: var(--brand-gold); color: #000; font-weight: 700; }
.pa-row__actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.pa-row__select {
  flex: 1;
  min-width: 160px;
  background: #161616;
  border: 1px solid #2a2a2a;
  color: #ccc;
  border-radius: 4px;
  padding: 5px 8px;
  font-size: 12px;
}
.pa-row__assign-btn {
  background: var(--brand-gold);
  color: #000;
  border: none;
  border-radius: 4px;
  padding: 5px 14px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}
.pa-row__assign-btn:disabled { background: #3a2f00; color: #999; cursor: not-allowed; }
.pa-row__ignore-btn {
  background: transparent;
  border: 1px solid #444;
  color: #888;
  border-radius: 4px;
  padding: 5px 12px;
  font-size: 12px;
  cursor: pointer;
}
.pa-row__ignore-btn:hover { border-color: #666; color: #ccc; }
.pa-row__done { color: #4caf50; font-size: 12px; font-weight: 600; }

/* ── Status Review (Block 3): banner + modal rows + confidence badges ── */
.status-review-banner .status-review-banner__review {
  background: var(--brand-gold);
  color: #000;
  border-color: var(--brand-gold);
  font-weight: 700;
}
.status-review-banner .status-review-banner__review:hover {
  background: var(--gold-bright);
  color: #000;
}
/* Scan button: subtle at count=0 (transparent, gold border), same shape as Review. */
.status-review-banner__scan {
  margin-left: 8px;
}
.status-review-banner__scan:disabled {
  opacity: 0.6;
  cursor: wait;
}
/* Modal-header Scan button */
.sr-modal__scan-btn {
  margin-right: 12px;
  background: transparent;
  border: 1px solid var(--brand-gold);
  color: var(--brand-gold);
  border-radius: 6px;
  padding: 4px 12px;
  font-size: 12px;
  cursor: pointer;
  min-height: 28px;
}
.sr-modal__scan-btn:hover:not(:disabled) { background: color-mix(in srgb, var(--brand-gold) 15%, transparent); }
.sr-modal__scan-btn:disabled { opacity: 0.6; cursor: wait; }
/* Toast fallback used when window.toast is not defined. */
.sr-toast-host {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2000;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  pointer-events: none;
}
.sr-toast {
  background: rgba(13,27,42,0.95);
  color: #e8e8e8;
  border: 1px solid var(--brand-gold);
  border-radius: 6px;
  padding: 8px 16px;
  font-size: 13px;
  box-shadow: 0 4px 14px rgba(0,0,0,0.5);
  max-width: 400px;
  text-align: center;
}
.sr-toast--success { border-color: #10b981; }
.sr-toast--error   { border-color: #ef4444; color: #fecaca; }
.sr-row { gap: 6px; }
.sr-row__deal {
  font-size: 13px;
  color: #e8e8e8;
  font-weight: 600;
}
.sr-row__event {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 2px;
}
.sr-row__event-label {
  font-size: 12px;
  color: var(--brand-gold);
  font-weight: 600;
}
.sr-row__confidence {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 1px 8px;
  border-radius: 10px;
  font-weight: 700;
}
/* Navy pill -> gold text; gold pill -> navy text. Contrast, don't repeat prior bug. */
.sr-row__confidence--high   { background: var(--brand-gold); color: #0D1B2A; }
.sr-row__confidence--medium { background: color-mix(in srgb, var(--brand-gold) 20%, transparent); color: var(--brand-gold); border: 1px solid color-mix(in srgb, var(--brand-gold) 50%, transparent); }
.sr-row__confidence--low    { background: rgba(255,255,255,0.06); color: #9ca3af; border: 1px solid #444; }
.sr-row__evidence {
  font-size: 12px;
  color: #ccc;
  font-style: italic;
  padding: 6px 10px;
  border-left: 2px solid var(--brand-gold);
  background: color-mix(in srgb, var(--brand-gold) 6%, transparent);
  border-radius: 0 4px 4px 0;
  margin-top: 4px;
}
.sr-row__suggested {
  font-size: 12px;
  color: #e8e8e8;
  margin-top: 4px;
}
.sr-row__suggested strong { color: var(--brand-gold); font-weight: 700; }
.sr-row__suggested--info { color: #888; font-style: italic; }
.sr-row__why {
  font-size: 12px;
  color: #f0c86a;
  margin-top: 4px;
  padding: 5px 9px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--brand-gold) 12%, transparent);
}
.sr-row__why--done { color: #9fdcc4; background: color-mix(in srgb, #1d9e75 14%, transparent); }
.sr-row__source { font-size: 11px; color: #999; margin-top: 4px; }
.sr-row__source-link { color: var(--brand-gold); text-decoration: none; }
.sr-row__source-link:hover { text-decoration: underline; }
.sr-row__source-link:focus-visible { outline: 2px solid var(--brand-gold); outline-offset: 2px; }
.sr-row__source-open { white-space: nowrap; opacity: 0.85; }
.sr-row__source--nolink { color: #999; }
.sr-row__source-note { font-style: italic; opacity: 0.7; }
.sr-row__doclink { color: inherit; text-decoration: none; }
.sr-row__doclink:hover { text-decoration: underline; }
.sr-row__doclink:focus-visible { outline: 2px solid var(--brand-gold); outline-offset: 2px; }
.sr-row__assign { margin-top: 6px; font-size: 12px; }
.sr-row__assign-label { color: #999; margin-right: 4px; }
.sr-row__txnpick {
  max-width: 100%;
  padding: 3px 6px;
  border: 1px solid var(--brand-gold);
  border-radius: 4px;
  background: #fff;
  font-size: 12px;
}
.sr-row__actions { justify-content: flex-end; gap: 8px; margin-top: 6px; }
.sr-row__btn {
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  min-height: 32px;
}
.sr-row__btn--confirm {
  background: var(--brand-gold);
  color: #0D1B2A;
  border-color: var(--brand-gold);
}
.sr-row__btn--confirm:hover:not(:disabled) { background: var(--gold-bright); }
.sr-row__btn--confirm:disabled { opacity: 0.5; cursor: not-allowed; }
.sr-row__btn--dismiss {
  background: transparent;
  color: #ccc;
  border-color: #444;
}
.sr-row__btn--dismiss:hover:not(:disabled) { background: rgba(255,255,255,0.06); color: #fff; }
.sr-row__btn--dismiss:disabled { opacity: 0.5; cursor: not-allowed; }
/* Ornate action pills (transparent PNGs carry their own label) on failure rows. */
.sr-row__pill {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 0;
  line-height: 0;
  cursor: pointer;
  transition: transform 150ms ease, filter 150ms ease;
}
.sr-row__pill:hover:not(:disabled) { transform: translateY(-1px); filter: brightness(1.08) drop-shadow(0 0 8px color-mix(in srgb, var(--brand-gold) 36%, transparent)); }
.sr-row__pill:focus-visible { outline: 2px solid var(--brand-gold); outline-offset: 2px; border-radius: 6px; }
.sr-row__pill.is-busy, .sr-row__pill:disabled { opacity: 0.5; cursor: not-allowed; }
.sr-row__pill-img { height: 36px; width: auto; display: block; user-select: none; pointer-events: none; }

/* ── Short-window content scaling ─────────────────────────────────────────────
   Partner to the --header-band breakpoints near the top of this file. The band
   moves the header and the nav; these shrink what sits inside them, or the
   contents simply overflow the smaller band.

   Deliberately at the END of the stylesheet. They override .sidebar-nav and
   .sidebar-pill at the same specificity, so source order decides, and an
   earlier copy of these rules silently lost - the band shrank while the pills
   stayed full size and still ran off the bottom.

   The quote's font size is written inline by banner-rotator.js as it measures
   each quote, so beating it needs !important. */
@media (min-width: 1024px) and (max-height: 800px) {
  .sidebar-nav { --nav-gap-seven: 10px; }
  .header-quote span { font-size: 26px !important; }
}
@media (min-width: 1024px) and (max-height: 700px) {
  .sidebar-nav { --nav-gap-seven: 8px; }
  .header-quote span { font-size: 22px !important; }
  .site-header__summary { font-size: 12px; }
}
/* Below about 640px the band alone stops buying back enough room - six
   full-size pills do not fit wherever the header ends - so the pills come down
   too. This is where a 125% zoom or a short laptop lands. */
@media (min-width: 1024px) and (max-height: 640px) {
  /* 52.86px is 185px of artwork (185 x 310 / 1085), matching the max-width. */
  .sidebar-nav { --nav-gap-seven: 6px; --nav-pill-art: 52.86px; }
  /* Kept alongside the derived height cap: at this size the cap alone would
     allow slightly larger pills than the look Rich signed off on. */
  .sidebar-pill { max-width: 185px; }
  .header-quote span { font-size: 19px !important; }
}

/* ============================================================
   Contact detail: fit the two columns, scroll each internally.

   The .layout grid correctly fills the space between the header
   and the footer, but its single implicit row grew to the taller
   column's content, so the profile and activity panels spilled
   180px+ past the bottom and were clipped with no way to scroll
   to them. The old .activity-panel { height: calc(100vh - 160px) }
   rules were a fixed guess tuned to a 300px header and are wrong
   now that the band is a variable.

   Fill the row to the container, then let each column scroll on
   its own. Keyed >=768 to stay clear of the stacked mobile layout,
   and specific enough to beat the doubled-class calc rules above.
   ============================================================ */
@media (min-width: 768px) {
  body.contact-detail .layout {
    grid-template-rows: minmax(0, 1fr);
  }
  body.contact-detail .profile-panel,
  body.contact-detail .activity-panel.activity-panel {
    height: auto;
    min-height: 0;
    max-height: 100%;
    overflow-y: auto;
  }
  body.contact-detail .activity-card.activity-card {
    height: auto;
    min-height: 0;
  }
}

/* ============================================================
   Block 23 — Mobile Responsiveness Pass (768px tablet)
   Tab pills scroll horizontally, data tables get overflow
   wrappers, and remaining elements that weren't already
   addressed by existing breakpoints get mobile treatment.
   ============================================================ */
@media (max-width: 768px) {
  .tab-nav {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    justify-content: flex-start;
    padding-left: 12px;
    padding-right: 12px;
    scrollbar-width: none;
  }
  .tab-nav::-webkit-scrollbar { display: none; }
  .tab-btn { flex-shrink: 0; }

  .data-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }

  .modal { max-width: 95vw; }

  .emails-pane .email-list-header,
  .emails-pane .email-row {
    grid-template-columns: 24px 80px 1fr 2fr;
    gap: 8px;
  }
  .emails-pane .email-date { font-size: 11px; }
}

/* ============================================================
   Block 23 — Mobile Responsiveness Pass (480px phone)
   Tighter spacing, single-column grids, and smaller type
   for phone-width viewports.
   ============================================================ */
@media (max-width: 480px) {
  .tab-btn { padding: 6px 12px; font-size: 12px; }

  /* Two up, not one. Four full-width tiles put the last number most of a
     screen below the first, so the morning check-in became a scroll. Two
     columns fit a 390px phone comfortably and keep all four in one glance. */
  .overview-grid { grid-template-columns: repeat(2, 1fr); }
  .overview-number { font-size: 20px; }

  /* minmax(0, ...) for the same reason as the 760px rule above. */
  .priority-list { grid-template-columns: minmax(0, 1fr); }
  .priority-row { padding: 7px 10px; font-size: 12px; }

  .oval-pill { padding: 3px 8px; font-size: 11px; }

  .contact-card-header { padding: 8px 10px; gap: 8px; }
  .contact-avatar { width: 32px; height: 32px; font-size: 14px; }

  .pipeline-cards { grid-template-columns: 1fr !important; }

  .modal { margin: 8px; }

  .emails-pane .email-list-header,
  .emails-pane .email-row {
    grid-template-columns: 24px 1fr;
    gap: 6px;
  }
  .emails-pane .email-date,
  .emails-pane .email-name { display: none; }
}

/* ── Listing Search Tab ──────────────────────────────────────────────────── */
.listing-search-content {
  padding: 20px 24px;
  max-width: 1200px;
  overflow-y: auto;
  height: 100%;
}

/* Listing Search — internal scroll container, same pattern as Emails.
   This tab had no chain at all: .listing-search-content asked for height:100%
   inside a plain auto-height .tab-content, so the percentage resolved to auto
   and overflow-y never engaged. With the body still locked at 100vh, results
   past the first screen were clipped with no scrollbar at all -- worse than the
   list-grows-the-page regression this pattern exists to prevent. */
body.dashboard-page:has(#tab-listings.tab-content.active) {
  display: flex;
  flex-direction: column;
}
body.dashboard-page:has(#tab-listings.tab-content.active) .site-header,
body.dashboard-page:has(#tab-listings.tab-content.active) .site-footer {
  flex-shrink: 0;
}
body.dashboard-page:has(#tab-listings.tab-content.active) main.main-content {
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  padding-bottom: 0;
  display: flex;
  flex-direction: column;
}
body.dashboard-page:has(#tab-listings.tab-content.active) #tab-listings {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
body.dashboard-page:has(#tab-listings.tab-content.active) .listing-search-content {
  flex: 1 1 auto;
  min-height: 0;
  height: auto;
  overflow-y: auto;
}

/* The way back out of the search, kept on screen.
   The search is an iframe, so on a touch screen every swipe over it scrolls
   the page INSIDE it and never the page around it. Once the header has
   scrolled away there is nothing left on screen that belongs to the app, and
   the only way back was to close it and start again -- Rich on a Fold 7,
   2026-09-21. Pinning the row means the Dashboard button cannot be scrolled
   out of reach by the thing it exists to escape.
   Under the header's z-index 100 on purpose, so the two never fight over the
   top of the screen. A solid background because an iframe paints its own. */
@media (pointer: coarse) {
  body.dashboard-page #tab-listings .subpill-row {
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--navy-panel);
    margin: 0 0 8px !important;
    padding: 8px 0;
  }
}
.ls-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 16px;
}
.ls-title {
  font-size: 20px;
  font-weight: 600;
  color: var(--brand-gold, var(--brand-gold));
  margin: 0;
}
.ls-mock-badge {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1px;
  background: #8b0000;
  color: #fff;
  padding: 2px 8px;
  border-radius: 4px;
}
.ls-filters {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 16px;
}
.ls-filter-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.ls-filter-row:last-child { margin-bottom: 0; }
.ls-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-width: 120px;
}
.ls-field label {
  font-size: 11px;
  color: rgba(255,255,255,0.5);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.ls-field select,
.ls-field input {
  background: rgba(13, 27, 42, 0.85);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 40%, transparent);
  border-radius: 6px;
  color: #f0e6d0;
  padding: 8px 28px 8px 10px;
  font-size: 13px;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
}
.ls-field select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' stroke='%23d4a017' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
  cursor: pointer;
}
.ls-field select option {
  background: #0D1B2A;
  color: #f0e6d0;
}
.ls-dropdown {
  position: relative;
  width: 100%;
}
.ls-dropdown-trigger {
  background: rgba(13, 27, 42, 0.85);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 40%, transparent);
  border-radius: 6px;
  color: #f0e6d0;
  padding: 8px 28px 8px 10px;
  font-size: 13px;
  cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' stroke='%23d4a017' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ls-dropdown-trigger:hover {
  border-color: var(--brand-gold, var(--brand-gold));
}
.ls-dropdown-list {
  display: none;
  position: fixed;
  z-index: 9999;
  background: rgba(13, 27, 42, 0.97);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 40%, transparent);
  border-top: none;
  border-radius: 0 0 6px 6px;
  max-height: 245px;
  overflow-y: auto;
}
.ls-dropdown.is-open .ls-dropdown-list {
  display: block;
}
.ls-dropdown.is-open .ls-dropdown-trigger {
  border-color: var(--brand-gold, var(--brand-gold));
  border-radius: 6px 6px 0 0;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand-gold) 20%, transparent);
}
.ls-dropdown-item {
  padding: 7px 10px;
  color: #f0e6d0;
  font-size: 13px;
  cursor: pointer;
  line-height: 18px;
}
.ls-dropdown-item:hover,
.ls-dropdown-item.is-selected {
  background: color-mix(in srgb, var(--brand-gold) 15%, transparent);
}
/* The keyboard cursor. Deliberately stronger than the selected/hover tint so
   arrowing through the list is followable when one of them is also selected. */
.ls-dropdown-item.is-active {
  background: color-mix(in srgb, var(--brand-gold) 32%, transparent);
  box-shadow: inset 2px 0 0 var(--brand-gold);
}
.ls-dropdown-trigger:focus-visible {
  outline: 2px solid var(--brand-gold);
  outline-offset: 2px;
}
.ls-dropdown-list::-webkit-scrollbar {
  width: 6px;
}
.ls-dropdown-list::-webkit-scrollbar-track {
  background: rgba(13, 27, 42, 0.5);
}
.ls-dropdown-list::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--brand-gold) 40%, transparent);
  border-radius: 3px;
}
.ls-field input {
  padding: 8px 10px;
}
.ls-field select:focus,
.ls-field input:focus {
  outline: none;
  border-color: var(--brand-gold, var(--brand-gold));
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand-gold) 20%, transparent);
}
.ls-field--btn {
  justify-content: flex-end;
}
.ls-search-btn {
  background: var(--brand-gold, var(--brand-gold));
  color: #0D1B2A;
  border: none;
  border-radius: 6px;
  padding: 6px 20px;
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
}
.ls-search-btn:hover { opacity: 0.9; }
.ls-results-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.ls-result-count {
  font-size: 14px;
  color: rgba(255,255,255,0.6);
}
.ls-share-btn {
  background: transparent;
  border: 1px solid var(--brand-gold, var(--brand-gold));
  color: var(--brand-gold, var(--brand-gold));
  border-radius: 6px;
  padding: 5px 14px;
  font-size: 12px;
  cursor: pointer;
}
.ls-share-btn:hover { background: color-mix(in srgb, var(--brand-gold) 10%, transparent); }
.ls-share-btn:disabled { opacity: 0.5; cursor: default; }
.ls-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr));
  gap: 14px;
  margin-bottom: 16px;
}
.ls-card {
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 8px;
  overflow: hidden;
}
.ls-card-photo {
  background: linear-gradient(135deg, #1a2a3a, #0d1b2a);
  height: 80px;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: 8px 10px;
}
.ls-photo-count, .ls-dom {
  font-size: 10px;
  background: rgba(0,0,0,0.5);
  color: rgba(255,255,255,0.7);
  padding: 2px 6px;
  border-radius: 3px;
}
.ls-card-body { padding: 10px 12px; }
.ls-card-price {
  font-size: 18px;
  font-weight: 700;
  color: var(--brand-gold, var(--brand-gold));
  margin-bottom: 2px;
}
.ls-card-address {
  font-size: 13px;
  color: #e8e8e8;
  margin-bottom: 6px;
}
.ls-card-stats {
  display: flex;
  gap: 10px;
  font-size: 12px;
  color: rgba(255,255,255,0.6);
  margin-bottom: 6px;
}
.ls-card-desc {
  font-size: 12px;
  color: rgba(255,255,255,0.45);
  line-height: 1.4;
  margin-bottom: 6px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ls-card-meta {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: rgba(255,255,255,0.3);
}
.ls-disclaimer {
  font-size: 11px;
  color: rgba(255,255,255,0.3);
  font-style: italic;
  text-align: center;
  margin-top: 12px;
}
.ls-loading, .ls-error, .ls-empty {
  text-align: center;
  color: rgba(255,255,255,0.5);
  padding: 40px 0;
  font-size: 14px;
}
.ls-error { color: #ff6b6b; }
.ls-share-result {
  background: color-mix(in srgb, var(--brand-gold) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 25%, transparent);
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 14px;
}
.ls-share-result p { margin: 0 0 6px; font-size: 13px; color: #e8e8e8; }
.ls-share-url-row { display: flex; gap: 8px; }
.ls-share-url {
  flex: 1;
  background: rgba(0,0,0,0.3);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 6px;
  color: #e8e8e8;
  padding: 6px 8px;
  font-size: 12px;
}
.ls-copy-btn {
  background: var(--brand-gold, var(--brand-gold));
  color: #0D1B2A;
  border: none;
  border-radius: 6px;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.ls-share-expiry {
  font-size: 11px;
  color: rgba(255,255,255,0.3);
  margin-top: 4px;
}
.sidebar-pill--text {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  font-size: 10px;
  font-weight: 700;
  color: var(--brand-gold, var(--brand-gold));
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

@media (max-width: 768px) {
  .ls-filter-row { flex-direction: column; }
  .ls-card-grid { grid-template-columns: 1fr; }
}
@media (max-width: 480px) {
  .listing-search-content { padding: 12px 10px; }
  .ls-filters { padding: 8px 10px; }
  .ls-card-grid { grid-template-columns: 1fr; }
}

/* ============================================================
   Dashboard layout: sit the content beside the nav, resting on the footer.

   .main-content normally starts at 526px, not at the 280px where the sidebar
   ends. The extra 246px is a reserved lane for the Correspondence and
   Proclamations flyout submenus, which are fixed at left:280px and 232px wide.
   Nothing was ever drawn in that lane on the Dashboard, so the content sat a
   quarter of the way into the page and covered the castle, while a strip of
   empty gradient ran down the left.

   Two changes, both Dashboard-only:
     - Pull the content left to 296px, one gutter clear of the pills. Width is
       untouched, so this reveals ~250px of castle on the right rather than
       stretching anything.
     - margin-top:auto on the first block, which sinks the whole stack to the
       bottom of its pane so it rests just above the footer. Deliberately an
       auto margin and not justify-content:flex-end -- an auto margin resolves
       to 0 once the content is taller than the pane, where flex-end would put
       the top of the stack out of reach above the scroll origin.

   Now unscoped. It began as :has(#tab-<name>.active) so tabs could opt in one
   at a time while the flyouts still needed their lane. The flyouts are gone --
   their four destinations moved out to the pages they belong to -- so the lane is
   every tab, and leaving the rest indented to a menu that no longer exists
   would read as a bug. The bottom-align stays per-tab: each names its own
   content wrapper, and only the tabs that have had a layout pass get it.

   Trade-off worth knowing: an open flyout submenu now overlaps this content
   instead of sitting in its own lane. It is fixed at z-index 60 so it draws on
   top, which is how a menu should behave, but it does cover the KPI tiles
   while open.
   ============================================================ */
@media (min-width: 1024px) {
  /* The sub-pages lost their flyout too (their destinations moved to a row
     across the top), so .page / .layout reclaim the same lane the main app
     did rather than staying indented to a menu that no longer exists. */
  .has-sidebar .main-content,
  .has-sidebar .page,
  .has-sidebar .page-pill-row,
  .has-sidebar .back-bar,
  .has-sidebar .layout {
    margin-left: 296px;
    width: calc(100% - 320px);
  }
  .has-sidebar .page .page-pill-row,
  .has-sidebar .main-content .page-pill-row { margin-left: 0; width: auto; }
  #overviewContent > :first-child,
  #tab-pipeline > :first-child {
    margin-top: auto;
  }
}

/* ============================================================
   Section pills.

   These four destinations began as two flyout menus off the Correspondence and
   Proclamations nav pills, which needed a reserved 246px lane beside the
   sidebar that nothing else could use. They then spent a while in one shared
   bar across the top of every page, which reclaimed the lane but put Social
   Posts on the inbox and Contacts on the social planner.

   Now they sit with the page they belong to: the Correspondence three join the
   inbox search bar beside the Unread-only toggle, and the Proclamations two
   ride at the end of the Social tab's own subpill row. The group is a plain
   inline flex run so it inherits whichever control bar it lands in.
   ============================================================ */
.section-pill-group {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.section-pill {
  flex: 0 0 auto;
  display: block;
  padding: 0;
  margin: 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  line-height: 0;
}

/* Sized so the ornate pill BODY matches the plain pills, not so the files
   match. The artwork is 96px tall but only the middle 70px is the bar you
   see -- the rest is the pointed end flourishes -- so rendering at 35px gave
   a 25px body against the 35px of .compose-btn / .cat-pill. 48px puts the
   bar at 70/96 * 48 = 35px, the same as the category row. */
.section-pill img {
  display: block;
  width: auto;
  height: 48px;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5));
  transition: filter 0.15s ease, transform 0.15s ease;
}

.section-pill:hover img {
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--brand-gold) 55%, transparent));
  transform: translateY(-1px);
}

.section-pill:focus-visible {
  outline: 2px solid var(--brand-gold);
  outline-offset: 3px;
  border-radius: 4px;
}

/* The destination you are already on. It stays in the row at full size so the
   pills never shift; the glow is what says "you are here". A span, not a link,
   because it has nowhere to go -- which also keeps it out of the tab order. */
.section-pill.is-active img {
  filter: drop-shadow(0 0 9px color-mix(in srgb, var(--brand-gold) 90%, transparent))
          drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5))
          brightness(1.12);
}
.section-pill.is-active { cursor: default; }
.section-pill.is-active:hover img { transform: none; }

/* No height step-down on narrow screens: .cat-pill stays 35px there too, so
   shrinking these would reintroduce the mismatch on exactly the screens
   where the two rows stack on top of each other. */
@media (max-width: 768px) {
  .section-pill-group { gap: 6px; }
}

/* Sub-pages carry their section's destinations in a row across the top of the
   content instead of a sidebar flyout, matching how the Emails tab does it.
   Coming-soon pills keep the dimmed, non-interactive treatment they had in
   the flyout. */
.page-pill-row {
  display: flex;
  padding: 10px 24px 0;
}
.section-pill.is-coming-soon {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}
/* Reads at full strength alongside the live destinations, but does not
   navigate, because the page behind it does not exist yet. */
.section-pill--pending { cursor: default; }

/* Nested inside an already-offset container, the row must not add the sidebar
   margin a second time. .page covers the sub-pages, .main-content covers the
   in-app tabs; without the second one the Follow Up tab row landed at x=616
   against x=320 everywhere else. */
.page .page-pill-row,
.main-content .page-pill-row {
  margin-left: 0;
  width: auto;
  padding: 4px 0 0;
}

/* Same height reserved above the row on every page, so moving between them
   does not shift the pills up or down. The count line and the toolbar vary
   in natural height from page to page -- a select is taller than a text
   input -- which is what made them sit 13px apart. */
/* .page declares margin:4px ... but that top margin collapses on some pages
   and not others, which left the sub-pages starting 4px apart. Zeroed so they
   all begin at the same y. */
.has-sidebar .page { margin-top: 0; }

/* 28px, not the natural 20px: the Emails tab's two control rows (search then
   the category piles) come to 8px more than a count line plus a toolbar, and
   that tab cannot give the 8px back without squashing the piles. Everything
   else absorbs it here so all six surfaces put the row on the same line. */
.page > .contact-count,
.page > .call-count,
.page > .tpl-count,
.page > .sm-count {
  min-height: 28px;
}

/* The Follow Up tab has a title row where the other pages have a count line
   and a toolbar, so it reserves the same total height rather than sitting
   50px higher than everything else. */
/* Follow Up as a working week: five weekday rows, three cards across each.
   The container only becomes a grid when there are follow-ups -- the empty
   state renders as a plain block. */
#contactsContainer.followup-week {
  display: flex;
  flex-direction: column;
  /* Tight enough that the week reads as one block. The day label already
     separates the rows, so 18px on top of it was doubling the break. */
  gap: 3px;
  /* A little clear air under the destination row, which sits directly above. */
  margin-top: 6px;
}
.followup-day__label {
  margin: 0 0 3px;
  padding-bottom: 1px;
  border-bottom: 1px solid color-mix(in srgb, var(--brand-gold) 25%, transparent);
}
/* The heading IS the control. Days with nothing due are not rendered at all,
   so every heading on the board has something behind it. */
.followup-day__toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  background: transparent;
  border: 0;
  padding: 1px 0;
  cursor: pointer;
  font-family: 'Cinzel', Georgia, serif;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--brand-gold);
}
.followup-day__toggle:hover { color: var(--gold-bright); }
.followup-day__chev {
  font-size: 10px;
  line-height: 1;
  transition: transform 0.15s ease;
}
.followup-day.is-collapsed .followup-day__chev { transform: rotate(-90deg); }
/* The count is what a folded day still says about itself. */
/* The weekday as artwork. Same 35px as the pipeline stage headings, so the two
   boards read as the same kind of heading; see .pipeline-stage__pill for why
   that number rather than a round one. */
.followup-day__pill {
  display: block;
  height: 35px;
  width: auto;
  max-width: 100%;
  flex-shrink: 1;
  min-width: 0;
}

.followup-day__count {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0;
  color: #0d1b2a;
  background: var(--brand-gold);
  border-radius: 999px;
  padding: 1px 7px;
}
.followup-day.is-collapsed .followup-day__label { margin-bottom: 0; }
.followup-day__cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  /* stretch, not start: a card with a note is taller than one without, and
     top-aligning left ragged empty space under the short ones in the same row. */
  align-items: stretch;
}
.followup-day__cards .contact-card { display: flex; flex-direction: column; }
/* The note is hidden on the board, not dropped: one card carrying a note made
   its whole row 79px against 48px for a row without one, so two days looked
   unlike the other three and the week needed a scrollbar. It is still on the
   card as a tooltip, and in full on the contact page. */
.followup-day__cards .contact-notes-section { display: none; }
.followup-day__cards .phase-pill { font-size: 9px; padding: 2px 7px; letter-spacing: .3px; }
/* A drafted follow-up waiting on approval, inside its contact card. */
.followup-draft {
  margin-top: 7px;
  padding-top: 7px;
  border-top: 1px dashed color-mix(in srgb, var(--brand-gold) 30%, transparent);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.followup-draft__subject,
.followup-draft__body {
  background: #0c1622;
  border: 1px solid #24384c;
  border-radius: 6px;
  padding: 6px 9px;
  color: #e8e8e8;
  font-size: 12px;
  font-family: inherit;
  width: 100%;
}
.followup-draft__body { resize: vertical; line-height: 1.5; }
.followup-draft__subject:focus,
.followup-draft__body:focus { border-color: var(--brand-gold); outline: none; }
.followup-draft__actions { display: flex; gap: 5px; flex-wrap: wrap; align-items: center; }
/* Five pills (six on a text card) share one card-width row; the stock btn-sm
   padding wraps the last onto a second line. */
.followup-draft__actions .btn-sm { padding: 5px 9px; font-size: 11.5px; }

/* History modal: the contact's past texts and emails in one scrollable list.
   Fixed over body -- the board's scroll containers are locked and clip, so it
   never lives inside a card. */
.followup-history__bg {
  position: fixed;
  inset: 0;
  z-index: 500;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
}
.followup-history {
  background: #0c1622;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 45%, transparent);
  border-radius: 12px;
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.6);
  width: min(560px, 92vw);
  max-height: 78vh;
  display: flex;
  flex-direction: column;
}
.followup-history__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid color-mix(in srgb, var(--brand-gold) 25%, transparent);
}
.followup-history__title { color: var(--brand-gold); font-weight: 600; }
.followup-history__list {
  overflow-y: auto;
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.followup-history__item {
  border: 1px solid color-mix(in srgb, var(--brand-gold) 18%, transparent);
  border-radius: 8px;
  padding: 8px 10px;
}
.followup-history__meta {
  display: flex;
  gap: 8px;
  align-items: baseline;
  font-size: 11px;
  color: #9aa7b8;
}
.followup-history__kind { color: var(--brand-gold); font-weight: 600; }
.followup-history__date { margin-left: auto; }
.followup-history__subject { color: #e8e8e8; font-size: 13px; font-weight: 600; margin-top: 3px; }
.followup-history__snippet { color: #c2ccd8; font-size: 12px; margin-top: 2px; white-space: pre-wrap; }

/* A card with nothing drafted has no content to show, so it says so on one
   line beside its action instead of holding a full-height slot. */
.followup-draft--compact {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 4px;
  padding-top: 4px;
}
.followup-draft--compact .followup-draft__empty {
  font-size: 11px;
  color: #9fb0c0;
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.followup-draft--compact .followup-draft__actions { flex-wrap: nowrap; flex: 0 0 auto; }

@media (max-width: 640px) {
  .followup-draft--compact { flex-wrap: wrap; }
}
/* The draft holds the editable fields, so a drag started inside it would
   fight text selection. */
.followup-draft { cursor: default; }

/* Drag to swap. grab/grabbing rather than move, because the card does not go
   anywhere on its own -- it trades places with whatever it is dropped on. */
.followup-day__cards .contact-card { cursor: grab; }
.followup-day__cards .contact-card:active { cursor: grabbing; }
.followup-day__cards .contact-card.is-dragging {
  opacity: 0.45;
  outline: 1px dashed var(--brand-gold);
}
.followup-day__cards .contact-card.is-drop-target {
  outline: 2px solid var(--brand-gold);
  outline-offset: 2px;
  box-shadow: 0 0 12px color-mix(in srgb, var(--brand-gold) 45%, transparent);
}

.followup-day__empty {
  font-size: 12px;
  color: #7c8797;
  font-style: italic;
  grid-column: 1 / -1;
}
/* The card was built for a full-width row; in a third of one the meta line has
   to be allowed to wrap rather than being clipped. */
.followup-day__cards .contact-card { width: 100%; margin: 0; }
.followup-day__cards .contact-meta {
  flex-wrap: wrap !important;
  overflow: visible !important;
  row-gap: 2px;
}

@media (max-width: 1100px) {
  .followup-day__cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .followup-day__cards { grid-template-columns: 1fr; }
}

#tab-contacts .section-header-row {
  /* Reserved block is height plus the 12px bottom margin this row already
     carries, so 73 + 12 matches a count line plus a toolbar. */
  min-height: 73px;
  align-items: center;
}
.page > .toolbar {
  /* 53px is the tallest natural toolbar (the Contacts filter select, measured
     in the real app -- 52 left it 1px short and the row drifted). Pinning the
     rest to it keeps the row underneath at the same height everywhere instead
     of drifting with whatever control the page happens to use. */
  min-height: 53px;
  align-items: center;
  margin-bottom: 0;
}

/* Five across on one line, whatever the window width. Sizing by share of the
   row rather than a fixed height is what guarantees it: a fixed size only
   fits five at the width it was picked for. Height follows the aspect ratio. */
.page-pill-row .section-pill-group { width: 100%; }
.page-pill-row .section-pill {
  flex: 0 1 calc((100% - 32px) / 5);
  max-width: 240px;
}
/* Five is the usual count, because a page leaves out the pill pointing at
   itself. Support and Opportunity Intel are not destinations in this set, so
   they show all six, and six at the five-across width dropped the last one
   onto a line of its own -- a second row for one pill, which on Opportunity
   Intel pushed the whole sub-nav down by its height. Six share the same lane
   instead.

   Scoped to the width where five already fit: below 900px the row drops to two
   across, and this selector is specific enough to beat that rule from outside
   the media query, which would have put all six on one phone-width line. */
@media (min-width: 901px) {
  .page-pill-row .section-pill-group:has(.section-pill:nth-child(6)) .section-pill {
    flex-basis: calc((100% - 40px) / 6);
  }
}
.page-pill-row .section-pill img { width: 100%; height: auto; }

/* Five would be unreadably small on a phone. */
@media (max-width: 900px) {
  .page-pill-row .section-pill {
    flex-basis: calc((100% - 8px) / 2);
    max-width: calc((100% - 8px) / 2);
  }
}
@media (max-width: 768px) {
  .page-pill-row { padding: 8px 16px 0; }
}

/* ============================================================
   Dashboard: close the gap above the follow-up cards.

   The dashboard already has a compaction system further up this file, every
   rule of it prefixed with body:has(#tab-overview.tab-content.active) and
   sized in vh-based clamps. A first attempt at this used plain
   #overviewContent selectors, which lost the cascade to that prefix and did
   nothing -- the label disappeared (that rule was specific enough) while every
   margin stayed exactly where it was.

   So these carry the same prefix, and sit at the end of the file to win the
   tie on source order.

   With the "Today's Priorities" label gone, the priorities card's top padding
   is no longer separating a heading from its list; it is just dead space
   between the KPI tiles and the first follow-up card. Removing it and
   shrinking the margin closes the run from about 36px to under 10px.
   ============================================================ */
body:has(#tab-overview.tab-content.active) #overviewContent .priorities-section > .section-header {
  display: none;
}
body:has(#tab-overview.tab-content.active) #overviewContent > .section-card.priorities-section {
  padding-top: 0;
  margin-top: clamp(2px, 0.5vh, 6px);
}
body:has(#tab-overview.tab-content.active) #overviewContent .pending-assignment-banner {
  margin-bottom: clamp(2px, 0.5vh, 6px);
}

/* ============================================================
   Pipeline: the deadline banner sits directly on top of the card stack.

   The cards grow bottom-to-top, so the banner used to sit pinned at the top of
   the section with the growing gap between them: on a light day it floated
   alone with a third of the page between it and the deals it refers to.

   The fix is #pipeline-cards sizing to its content (flex:0 1 auto) rather than
   filling the section, so the leftover space collects at the section level
   instead of inside the card container above its bottom-packed rows. The
   banner then lands right on top of the cards with nothing between them.

   Prefixed to match the dashboard compaction block further up this file, which
   sets flex:1 1 auto on #pipeline-cards at a specificity plain selectors lose
   to.

   This block ALSO used to give the banner margin-top:auto, which pushed the
   banner and everything after it to the bottom of the section. That closed the
   gap, but it left the whole tab hanging off the bottom of the screen while
   every other tab started at the top, which is what Rich saw on 2026-08-19.
   Removed: the flex:0 1 auto above is what actually closes the gap, and it
   does it while leaving the stack where the rest of the app starts. Do not put
   it back without checking the pipeline against the dashboard side by side.

   max-height:100% with min-height:0 and overflow-y:auto is deliberately kept:
   flex-shrink is still 1, so once there are more deals than fit, the container
   goes back to filling the space and scrolling rather than overflowing.
   ============================================================ */
@media (min-width: 641px) {
  body.dashboard-page:has(#tab-pipeline.tab-content.active) #pipeline-cards {
    flex: 0 1 auto;
    max-height: 100%;
    min-height: 0;
    overflow-y: auto;
  }
}

/* ============================================================
   Phone layout: legibility and getting to the numbers.

   Measured on a 390x844 phone before this block: the header alone ran 406px
   and the nav another 303px, so 709px of an 844px screen was spent before a
   single number appeared. An agent checking their morning over coffee had to
   scroll past the entire menu to see anything useful.

   Two causes, both fixed here.

   1. Every .sidebar-btn was 354px wide -- the full row -- because the base
      rule sizes it to 100% and the mobile block only set flex, never width.
      The 150px pill inside was then centred by auto margins that had 102px of
      slack to burn on each side. Six buttons, six rows. Sizing the button to
      its pill puts two per row and takes the nav from 303px to about 150px.

   2. Body copy sat straight on the bright half of the castle photo. This
      darkens the PHOTO with a gradient rather than putting a panel behind the
      text -- the castle still reads, the words become legible, and it is not
      the banner treatment Rich has rejected before.

   Everything here is inside a max-width query, so the desktop layout Rich
   works on is untouched.
   ============================================================ */
@media (max-width: 768px) {
  /* A separate layer, NOT a second background-image on body. The background is
     assigned inline by JS (the weather-driven background picker), and an inline
     style beats any stylesheet rule -- a gradient added here was silently
     discarded, which is why the first attempt at this changed nothing on screen.
     A fixed ::before at z-index -1 sits above the photo and below every bit of
     content, so it cannot be overwritten and cannot swallow taps.
     Heavier than it first looks it needs to be: the castle's brightest area is
     the sky behind the towers, which lands exactly where the greeting and the
     briefing paragraph sit, so a light wash still left white italic text on a
     glare. The photo reads as atmosphere here rather than as the subject. */
  /* isolation, not decoration. Without a stacking context on body, a z-index -1
     child is not contained by body at all -- it joins the root context and
     paints UNDERNEATH body's own background, which is why the layer measured
     perfectly (fixed, full size, right gradient) and still changed nothing on
     screen. isolation creates the context without touching layout, which
     position/transform would not. */
  body { isolation: isolate; }

  body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: linear-gradient(
      to bottom,
      rgba(13, 27, 42, 0.90) 0%,
      rgba(13, 27, 42, 0.86) 55%,
      rgba(13, 27, 42, 0.92) 100%
    );
  }

  /* Size the button to the pill it contains so the row can hold two. */
  nav.sidebar-nav .sidebar-btn {
    width: auto;
    max-width: 150px;
  }
  nav.sidebar-nav .sidebar-pill {
    margin-left: 0;
    margin-right: 0;
  }
  nav.sidebar-nav {
    gap: 8px;
    padding: 6px;
  }

  /* Header: the same information, in a good deal less of the screen. */
  .site-header { padding: 10px 12px; gap: 4px; }
  .brand-logo img { height: 38px !important; }
  .brand-name { font-size: 15px; line-height: 1.25; }
  .header-brand { gap: 8px; }
  .header-quote {
    font-size: 14px;
    line-height: 1.3;
    padding: 2px 0;
  }
  .header-right { gap: 4px; }
  .header-right img,
  #generateBtn img { max-width: min(300px, 100%); }
}

/* ============================================================
   Follow Up board on a phone: closed by default.

   Measured at 390px: 15 cards at about 492px each, page 3,546px. A card is
   43px of name and contact details and roughly 435px of suggested message plus
   editable draft. On a desktop that is fine -- the board is five columns and an
   open card costs nothing. In one column it is a page nobody reaches the bottom
   of.

   Collapsing already hid the suggested message; the editable draft was left
   showing, which is most of the remaining height. Hidden here too, with a line
   saying it is there, because a draft that vanishes with no trace reads as a
   draft that was lost. Phone only -- the desktop board is untouched.
   ============================================================ */
@media (max-width: 768px) {
  .contact-card.collapsed .followup-draft { display: none; }

  .contact-card.collapsed[data-followup-id]:not([data-followup-id=""])::after {
    content: 'Draft ready to send — open to read it';
    display: block;
    padding: 0 12px 10px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--brand-gold);
  }
}

/* Key dates strip -- birthdays, wedding anniversaries and closing
   anniversaries in the next 7 days, above the Follow Up board. */
.keydates { margin: 0 0 12px; }
.keydates-title { font-size: 11px; font-weight: 700; color: var(--brand-gold);
  text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; }
.keydates-list { display: flex; flex-wrap: wrap; gap: 8px; }
.keydate { display: flex; align-items: center; gap: 8px; text-decoration: none;
  background: rgba(13,27,42,0.55); border: 1px solid color-mix(in srgb, var(--brand-gold) 35%, transparent);
  border-radius: 999px; padding: 6px 14px; }
.keydate:hover { border-color: var(--brand-gold); }
.keydate.is-today { border-color: var(--brand-gold); background: color-mix(in srgb, var(--brand-gold) 14%, transparent); }
.keydate-icon { font-size: 13px; line-height: 1; }
.keydate-name { color: #f0e6d0; font-size: 12px; font-weight: 600; }
.keydate-what { color: #9fb0c0; font-size: 11px; }
@media (max-width: 640px) {
  .keydates-list { flex-direction: column; }
  .keydate { width: 100%; border-radius: 10px; }
}

/* Skipped strip -- who Skip is currently hiding, above the Follow Up board.
   Collapsed to a single count line by default so it costs almost nothing when
   he is not looking for it. Sits in normal flow beside the key-dates strip;
   the scroll container below it is untouched. */
/* Did anybody answer. Sits above the scroll box in normal flow like the two
   strips below it, so the Follow Up scroll architecture is untouched. */
.reply-strip { margin: 0 0 12px; flex: 0 0 auto;
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 14px;
  background: rgba(13,27,42,0.55);
  border: 1px solid color-mix(in srgb, var(--brand-gold) 25%, transparent);
  border-radius: 10px; padding: 8px 14px; }
.reply-strip__rate { color: var(--brand-gold); font-size: 15px; font-weight: 700; }
.reply-strip__detail { color: #cdd5e0; font-size: 12px; }
.reply-strip__waiting { color: #9fb0c0; font-size: 11px; }
@media (max-width: 640px) { .reply-strip { flex-direction: column; gap: 4px; } }

.skipped-strip { margin: 0 0 12px; flex: 0 0 auto; }
.skipped-toggle {
  background: rgba(13,27,42,0.55); border: 1px solid color-mix(in srgb, var(--brand-gold) 35%, transparent);
  border-radius: 999px; padding: 5px 14px; cursor: pointer;
  color: var(--brand-gold); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.5px;
}
.skipped-toggle:hover { border-color: var(--brand-gold); }
.skipped-list { list-style: none; margin: 8px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 8px; }
.skipped-row {
  display: flex; align-items: center; gap: 10px;
  background: rgba(13,27,42,0.55); border: 1px solid color-mix(in srgb, var(--brand-gold) 25%, transparent);
  border-radius: 999px; padding: 5px 8px 5px 14px;
}
.skipped-name { color: #f0e6d0; font-size: 12px; font-weight: 600; }
.skipped-back { color: #9fb0c0; font-size: 11px; }
@media (max-width: 640px) {
  .skipped-list { flex-direction: column; }
  .skipped-row { width: 100%; border-radius: 10px; justify-content: space-between; }
}

.followup-draft--none {
  display: flex; flex-direction: row; align-items: center; justify-content: space-between;
  gap: 10px; padding: 10px 12px;
}
.followup-draft__empty { margin: 0; color: var(--gray-500); font-size: 0.88rem; }
.followup-draft__reason {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 8px; font-size: 0.8rem; color: var(--gray-500);
}
.followup-draft__angle {
  flex: 1; padding: 4px 6px; border-radius: 6px;
  border: 1px solid color-mix(in srgb, var(--brand-gold) 35%, transparent);
  background: rgba(13, 27, 42, 0.6); color: #e8e8e8; font-size: 0.82rem;
}
.followup-draft__angle option:disabled { color: var(--gray-500); }

/* ══ Site components ═══════════════════════════════════════════════════════════
   Ported from the website (Seneschal Webpage/src/assets/css/site.css) so the
   app and the site share the same furniture. Additive: these are new class
   names, so nothing that exists changes appearance unless a template opts in.
   The exception is the focus ring below, which is deliberately global.
   ═════════════════════════════════════════════════════════════════════════════ */

/* Keyboard focus, app-wide.
   The app had focus styling on eight scattered controls and nothing anywhere
   else, so tabbing through most of it showed the browser default or nothing.
   Deliberately NOT !important and deliberately low specificity: the one
   existing rule that matters, .email-row:focus-visible, uses an INSET offset
   because rows sit edge to edge and a +3px ring would be clipped. That rule
   is more specific and still wins, which is the intent. */
:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 3px;
  border-radius: 3px;
}

/* Eyebrow label: the small gold caps the site uses over a section heading. */
.eyebrow {
  display: inline-block;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--brand-gold);
}

/* Gold hairline. Cheap, and it does more than anything else here to make a
   panel read as part of the same product as the site. */
.rule-gold {
  height: 1px;
  border: 0;
  background: linear-gradient(90deg, transparent, var(--brand-gold), transparent);
  opacity: .45;
}

/* Buttons. Same shape and motion as the site, at the app's smaller scale --
   the site's 15px/32px padding is sized for a landing page, not for a toolbar
   a broker clicks twenty times a day. */
.btn-site {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 22px;
  border-radius: var(--radius-pill);
  font-family: var(--sans);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  border: 1px solid transparent;
  white-space: nowrap;
  cursor: pointer;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease),
              background .18s var(--ease), color .18s var(--ease),
              border-color .18s var(--ease);
}
.btn-site--gold {
  background: linear-gradient(135deg, var(--gold-bright), var(--brand-gold) 55%, var(--gold-deep));
  color: var(--nav-navy);
  box-shadow: 0 8px 24px color-mix(in srgb, var(--brand-gold) 28%, transparent);
}
.btn-site--gold:hover {
  box-shadow: 0 12px 32px color-mix(in srgb, var(--brand-gold) 42%, transparent);
}
.btn-site--ghost {
  background: color-mix(in srgb, var(--nav-navy) 50%, transparent);
  border-color: color-mix(in srgb, var(--brand-gold) 55%, transparent);
  color: var(--gold-bright);
}
.btn-site--ghost:hover {
  background: color-mix(in srgb, var(--brand-gold) 12%, transparent);
  border-color: var(--brand-gold);
}

/* Panel: the site's flat card. Offered as a class rather than applied to the
   app's existing cards, which float frosted glass over the castle photo. That
   swap is a separate decision. */
.panel-site {
  background: var(--navy-panel);
  border: 1px solid var(--navy-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-soft);
}

/* Everything above animates. Honour the system setting rather than assuming
   nobody has switched it on. */
@media (prefers-reduced-motion: reduce) {
  .btn-site { transition: none; }
}

/* ── Custom cursor ────────────────────────────────────────────────────────────
   The website's pointer: a small gold dot that tracks the mouse closely and a
   larger ring that trails behind it and swells over anything clickable.

   Values copied from Seneschal Webpage/src/assets/css/site.css so the two read
   as one product. The app does not load GSAP, so the motion is done in
   /js/cursor.js with requestAnimationFrame instead; the appearance is the same.

   Text fields deliberately keep their native I-beam. On the website nothing is
   typed into, so hiding it costs nothing there. Here the address and note
   fields are used all day and losing the caret cursor would be a real
   regression.
   ------------------------------------------------------------------------- */
html.has-cursor,
html.has-cursor a,
html.has-cursor button,
html.has-cursor [role="button"] { cursor: none; }

/* wins over the rule above, because these are typed into */
html.has-cursor input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
html.has-cursor textarea { cursor: text; }

.cursor-dot,
.cursor-ring {
  position: fixed; top: 0; left: 0; z-index: 10000;
  pointer-events: none; border-radius: 50%;
  will-change: transform;
  /* Centring is handled once, in JavaScript, by subtracting half the size.
     Do NOT add a negative margin here as well or the two offsets stack and
     the ring drifts away from the dot. */
}
.cursor-dot {
  width: 7px; height: 7px;
  background: var(--gold-bright);
  box-shadow: 0 0 12px rgba(232, 200, 116, 0.9);
}
.cursor-ring {
  width: 34px; height: 34px;
  border: 1px solid rgba(212, 160, 23, 0.6);
  transition: width .3s var(--ease), height .3s var(--ease),
              background .3s var(--ease), border-color .3s var(--ease);
}
.cursor-ring.is-hot {
  width: 62px; height: 62px;
  background: rgba(212, 160, 23, 0.10);
  border-color: var(--gold-bright);
}

/* A trailing ring is decoration. If the machine is set to reduce motion the
   whole effect is skipped in JavaScript, and this is the belt to that braces:
   should the elements ever exist anyway, they stay out of the way. */
@media (prefers-reduced-motion: reduce) {
  .cursor-dot, .cursor-ring { display: none !important; }
  html.has-cursor, html.has-cursor a, html.has-cursor button,
  html.has-cursor [role="button"] { cursor: auto; }
}

/* ── Magnetic buttons ─────────────────────────────────────────────────────────
   /js/cursor.js writes --magnet-x and --magnet-y on whichever button the
   pointer is crossing, and this carries them.

   It uses the standalone `translate` property rather than `transform` quite
   deliberately. `translate` is applied alongside `transform`, not instead of
   it, so every hover lift the app already has -- .btn-primary, .tab-btn,
   .sidebar-btn -- keeps working with nothing folded in by hand. Writing it as
   a transform meant every one of those rules had to remember to re-add the
   magnet or it would silently pin the button in place mid-hover.

   The selector is deliberately wide and the JavaScript is what decides
   eligibility: it skips anything disabled, and anything too big to be a button
   (a full-width stage header is a `button`, and a 1232px-wide element pulled
   by the website's factors would slide 170px across the screen). An element
   the script never touches resolves both properties to 0px and sits still.

   Smoothing happens in the same animation loop that moves the cursor, so there
   is no transition declared here to collide with the ones these buttons carry
   already. */
html.has-cursor button,
html.has-cursor .btn,
html.has-cursor .btn-site {
  translate: var(--magnet-x, 0px) var(--magnet-y, 0px);
}


/* Scroll containment. Each of these is a box that scrolls inside a page whose
   body is locked to 100vh. Without this, reaching the end of the inner list
   hands the remaining scroll to whatever is behind it, so finishing the inbox
   moves the page instead of stopping. Adding only overscroll-behavior keeps
   this off the locked scroll ARCHITECTURE -- no layout property is touched, so
   the flex chain and the single-scroll-container pattern are unchanged. */
#tab-emails .email-table,
#tab-contacts #contactsContainer,
body.contacts-manager .rows-scroll,
body.contact-detail .profile-panel,
body.contact-detail .activity-panel,
.social-cards-list,
.settings-detail-body,
.listing-search-content,
.emails-pane .email-list-wrapper,
.checklist-view-body,
#pipeline-cards,
.modal-body {
  overscroll-behavior: contain;
}

html[data-text-size="large"] { --text-zoom: 1.15; }
html[data-text-size="extra-large"] { --text-zoom: 1.3; }
html[data-text-size="large"] .tab-content,
html[data-text-size="large"] body > .page > *,
html[data-text-size="large"] body > .layout > *,
html[data-text-size="large"] body > .back-bar > *,
html[data-text-size="large"] .support-main > *,
html[data-text-size="large"] .header-brand .brand-text,
html[data-text-size="large"] .date-display,
html[data-text-size="large"] .site-header__summary > * {
  zoom: 1.15;
}
html[data-text-size="large"] body > .page { padding-top: calc(10px * 1.15); }
html[data-text-size="extra-large"] .tab-content,
html[data-text-size="extra-large"] body > .page > *,
html[data-text-size="extra-large"] body > .layout > *,
html[data-text-size="extra-large"] body > .back-bar > *,
html[data-text-size="extra-large"] .support-main > *,
html[data-text-size="extra-large"] .header-brand .brand-text,
html[data-text-size="extra-large"] .date-display,
html[data-text-size="extra-large"] .site-header__summary > * {
  zoom: 1.3;
}
html[data-text-size="extra-large"] body > .page { padding-top: calc(10px * 1.3); }

/* ── Add-to-home-screen offer ────────────────────────────────────────────────
   Shown once, on phone widths, by public/js/pwa.js. Fixed to the bottom so it
   never displaces the briefing, and it sits above the bottom safe area so the
   buttons are not under an iPhone's home indicator.

   Built as real elements with classes rather than inline styles: an inline
   style beats everything in the cascade, which makes it the one thing a later
   fix cannot override. */
.pwa-install {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  z-index: 9000;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: rgba(13, 27, 42, 0.97);
  border: 1px solid var(--brand-gold, #D4A017);
  border-radius: 10px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.55);
}
.pwa-install__text {
  flex: 1 1 14rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.pwa-install__text strong {
  color: var(--brand-gold, #D4A017);
  font-size: 0.98rem;
  font-weight: 700;
}
.pwa-install__text span {
  color: #C7D3DE;
  font-size: 0.85rem;
  line-height: 1.45;
}
.pwa-install__buttons {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}
.pwa-install__go {
  padding: 9px 18px;
  font: inherit;
  font-size: 0.9rem;
  color: #000;
  background: linear-gradient(180deg, #E8C874, #D4A017 55%, #A87C0C);
  border: 1px solid #A87C0C;
  border-radius: 7px;
  cursor: pointer;
}
.pwa-install__close {
  padding: 9px 12px;
  font: inherit;
  font-size: 0.85rem;
  color: #9FB0C0;
  background: none;
  border: 1px solid rgba(159, 176, 192, 0.35);
  border-radius: 7px;
  cursor: pointer;
}
.pwa-install__go:active,
.pwa-install__close:active { transform: translateY(1px); }

/* Never shown to somebody already running the installed app. The script checks
   this too; the media query is the belt to its braces, because a card that
   appears inside the installed app is the most obviously broken version of
   this feature. */
@media all and (display-mode: standalone) {
  .pwa-install { display: none !important; }
}

/* ── Touch devices scroll the document, however wide the screen ──────────────
   The locked dashboard above is a DESKTOP affordance: hold the crest, header
   and banner still, and let one inner pane scroll. It quietly assumes a mouse
   and a window you can size, and it was gated on WIDTH -- unlocked below
   768px, locked above.

   A folding phone opened up breaks that assumption: it is a touch device
   832px wide, so it sailed past the cutoff and got the desktop layout. The
   Active pipeline's card container sizes to its content by design (flex:0 1
   auto, further down this file), so on a short screen it ran off the bottom
   of a body that cannot scroll -- and there was no way to reach the cards
   below. Rich's Fold 7, 2026-09-21: cards cut at the edge, nothing moved.
   Folded it was fine, because folded it is under 768px.

   Closed pipeline scrolled and Active did not, which is what narrowed it to
   the per-tab locked-scroll rules rather than the body height. An earlier
   attempt at 100dvh was a real improvement for browser chrome and did NOT fix
   this; it is kept, above, on its own merits.

   pointer:coarse asks the question that actually matters -- is the primary
   input a finger -- instead of inferring it from width, which is what got
   this wrong twice. A touchscreen laptop with a trackpad reports "fine" and
   is left on the desktop layout. */
@media (pointer: coarse) {
  /* 1. No page is pinned to the viewport, and nothing above the content is a
     scroll box either.

     CLIP, not hidden, and the difference is the whole point. overflow-x:hidden
     beside overflow-y:visible makes the visible axis compute to AUTO, which
     turns the body into a scroll box of its own -- and a scroll box anywhere
     between a sticky element and the viewport stops it sticking. That is what
     broke the Listing Search escape hatch: the row reported position:sticky
     and did not stick. overflow-x:clip is the pairing the spec allows to sit
     beside visible without forcing it to auto, so it clips without ever
     becoming a scroller.

     Measured on a 375px screen, three ways: with hidden the pinned row sat at
     -88px and its button was off the top of the screen; with plain visible it
     sat at 0 but the document grew sideways and three overflow guards failed;
     with clip it sits at 0, elementFromPoint at the button's centre returns
     the button, and scrollWidth equals clientWidth. */
  body {
    height: auto !important;
    max-height: none !important;
    overflow-x: clip !important;
    overflow-y: visible !important;
  }
  body.dashboard-page,
  body.contacts-manager,
  body.contact-detail,
  body.support-page {
    display: block !important;
  }

  /* 2. Every link in the chain those pages build between the body and their
     one scroll box, released together. Any one left bounded re-creates the
     trap, and the Contacts page is what that looks like: its header, toolbar
     and pill rows ate the screen, .table-wrap was squeezed to a sliver, and
     the list of contacts simply was not there. Rich, 2026-09-21: "Doesnt open
     any contacts, doesnt scroll."

     A modal keeps its own scroller on purpose -- it is a fixed overlay rather
     than part of the document, so releasing it would make a long dialog
     unreachable instead of reachable. */
  body.dashboard-page .main-content,
  body.dashboard-page .tab-content,
  body.dashboard-page .tab-content.active,
  body.dashboard-page #tab-overview,
  body.dashboard-page #overviewContent,
  body.dashboard-page #overviewContent > .section-card.priorities-section,
  body.dashboard-page .priorities-section .priority-list,
  body.dashboard-page .activity-panel,
  body.dashboard-page .emails-pane .email-list-wrapper,
  body.dashboard-page .email-table,
  body.dashboard-page #contactsContainer,
  body.dashboard-page #tab-pipeline,
  body.dashboard-page #pipeline-section,
  body.dashboard-page #pipeline-cards,
  body.dashboard-page #tab-closed,
  body.dashboard-page #closed-section,
  body.dashboard-page #settings-panel,
  body.dashboard-page .settings-detail-body,
  body.dashboard-page #socialContent,
  body.dashboard-page .social-content,
  body.dashboard-page .social-view-wrapper,
  body.dashboard-page .social-cards-list,
  body.dashboard-page .listing-search-content,
  body.contacts-manager .page,
  body.contacts-manager .table-wrap,
  body.contacts-manager .rows-scroll,
  body.contact-detail .page,
  body.contact-detail .profile-panel,
  body.contact-detail .activity-panel,
  body.contact-detail .checklist-view,
  body.contact-detail .checklist-view-body,
  /* Help & Support builds the same chain in its own page's <style> rather
     than here, so it is easy to miss when this list is read. It is a Settings
     page and it has to behave like one. */
  body.support-page main.support-main,
  body.support-page .support-shell,
  body.support-page .support-rail,
  body.support-page .support-detail,
  body.support-page .support-detail-body {
    height: auto !important;
    max-height: none !important;
    min-height: 0 !important;
    overflow: visible !important;
  }
}

/* Listings, 2026-09-24 (Rich: clean it up). The way-out button exists for a
   touch screen, where the search swallows every swipe; with a mouse the nav
   rail is always there beside it, so it only repeated the Dashboard link. */
@media (pointer: fine) and (min-width: 769px) {
  #idxBack { display: none; }
}

/* Rich, 2026-09-24: Follow Up's heading repeated the lit Follow Up tab; the
   Add Contact button beside it stays, at the right. */
#tab-contacts > .section-header-row > .section-title { display: none; }
#tab-contacts > .section-header-row { justify-content: flex-end; }

/* The description line used to separate a page's destination row from the
   table under it. With it gone (Rich, 2026-09-24) the row keeps a gap. */
.page > .page-pill-row { margin-bottom: 10px; }
