/* ============================================================
   Library Market Discovery - Unified Chrome + Hero (v2.7.16)

   Replaces THREE legacy systems with a single module:
     1. base.njk's old dark .lm-topbar (landing/admin/dashboard)
     2. tools/_shared/tool-chrome.css (shared tool two-strip nav)
     3. tools/colortest/index.html's bespoke .discovery-nav

   Surfaces using this module:
     - Landing  (Projects)
     - Admin    (Platform Admin)
     - Project Dashboard
     - Sitemap, Work Log, Design Proofs, Color Test
     - Future tools (DCD, Categories worksheet, etc.)

   The chrome is:
     - light/white slim bar
     - sticky to top
     - light shadow underneath
     - LM mark + divider + functional breadcrumb + RHS actions

   The hero pattern is:
     - h1 + lede
     - optional right-aligned actions
     - optional secondary strip (admin tabs, landing pills, tool toolbar)
     - optional state banner (readonly client view, warning, etc.)

   Both staff AND clients now see the chrome. base.njk no longer hides
   the topbar when ?ro=1 - clients get a gated action set instead.
   ============================================================ */

/* v2.10.5 D-008: respect the HTML `hidden` attribute authoritatively.
   Without !important, author rules like `.btn { display: inline-flex }`
   (which exist in all 4 tool files + lm.css `.btn-primary` /
   `.btn-secondary`) win over the UA `[hidden] { display: none }` rule
   by cascade order (same specificity, author wins). This defeats
   `element.hidden = true` from JS. Surfaced as the Log Work button
   rendering for clients in work-log despite L540's `addBtn.hidden =
   !state.isStaff || ...` correctly setting the attribute. The CSS
   was overriding the attribute. This rule makes the hidden attribute
   behave the way HTML semantics demand it should, everywhere, for
   any element type. lm-chrome.css is loaded by every surface (njk
   pages via base.njk + all 4 tools directly), so one rule here
   covers the whole platform. */
[hidden] { display: none !important; }

:root {
  /* Mockup design tokens, prefixed --lmc-* so they don't collide with
     existing platform --lm-* tokens (which stay defined in lm.css).
     Where a chrome token has an equivalent in lm.css we use the same
     value for visual continuity. */
  --lmc-teal:         #00a7a9;
  --lmc-teal-dark:    #008385;
  --lmc-teal-pale:    #e0f4f4;
  --lmc-coral:        #ef5223;
  --lmc-coral-pale:   #fde8e0;
  --lmc-purple:       #626494;          /* muted purple (non-action UI) */
  --lmc-purple-pale:  #eeeff5;
  /* v2.10.14 D-015: amber tokens for warn-banner. Replaces the
     coral-on-coral-pale .is-warn variant that read as orange-on-orange.
     amber-100 / amber-900 / amber-700-at-25% give a yellow-with-dark-text
     warning surface that's legible and distinct from the coral
     destructive/save-error palette. Consumers: .lm-hero-banner.is-warn
     and .dash-step-row .sc-revisions-chip (v2.11.0 Phase C). */
  --lmc-amber-pale:   #fef3c7;          /* amber-100 */
  --lmc-amber-dark:   #78350f;          /* amber-900 */
  --lmc-amber-border: rgba(180,83,9,0.25);  /* amber-700 at 25% alpha */
  /* Brand purple (primary action color). Matches existing --lm-purple. */
  --lmc-brand-purple:       #463287;
  --lmc-brand-purple-hover: #2F2160;
  --lmc-brand-purple-pale:  #ece8f5;
  --lmc-white:        #ffffff;
  /* Warm cream content background (matches --content-bg in lm.css and
     --paper in colortest). v5 mockup pinned these AGAINST the cooler
     DCD grays - the platform's warmth carries through these tokens. */
  --lmc-bg:           #f7f6f3;
  --lmc-bg-soft:      #fafaf7;
  --lmc-ink:          #1c2434;
  --lmc-ink-soft:     #4a5266;
  --lmc-ink-faded:    #8e95a5;
  --lmc-rule:         #e4e7ee;
  --lmc-rule-soft:    #eef0f4;
  --lmc-shadow-sm:    0 1px 2px rgba(28,36,52,.04), 0 1px 1px rgba(28,36,52,.03);
  --lmc-shadow-md:    0 2px 8px rgba(28,36,52,.06), 0 1px 2px rgba(28,36,52,.04);
  --lmc-poppins:      'Poppins', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --lmc-mono:         'JetBrains Mono', ui-monospace, monospace;
  /* Save-dot color states. Idle teal, saving teal pulse, saved green,
     error coral. */
  --lmc-save-idle:    var(--lmc-teal);
  --lmc-save-saved:   var(--lmc-teal);
  --lmc-save-error:   var(--lmc-coral);

  /* v2.7.21: platform-wide constrained content width. Two-mode model:
     (1) Constrained = hero + content both centered at --lm-constrained-width
     (Landing, Admin, Dashboard, WL, DP, Colortest). (2) Fluid = full-width
     hero + full-width content, sitemap-style, via .lm-hero.is-fullwidth +
     surface's own workspace layout. v2.7.20 set this to 880px (colortest
     doc width); v2.7.21 widens to 1100px per Steven's call. */
  --lm-constrained-width: 1100px;
}

/* ============================================================
   CHROME (slim sticky bar)
   ============================================================ */

.lm-chrome {
  /* v2.7.23: the chrome bar itself spans full viewport (white bg, sticky,
     shadow, border). The 32px horizontal padding is the narrow-viewport
     gutter. Flex layout moved to .lm-chrome-inner so the chrome's
     CONTENTS sit within the same 1100px constrained column as the hero
     and body content - breadcrumb / wordmark / actions all line up with
     the hero text and the cards below. */
  background: var(--lmc-white);
  border-bottom: 1px solid var(--lmc-rule);
  padding: 14px 32px;
  position: sticky;
  top: 0;
  z-index: 50;
  box-shadow: var(--lmc-shadow-sm);
}
.lm-chrome-inner {
  /* v2.7.23: real flex container, no longer display:contents. Max-width
     matches the platform's --lm-constrained-width so the chrome's
     contents align with .lm-hero-inner / .lp-content / .admin-main /
     .dash-main / .workspace at the same left edge. */
  max-width: var(--lm-constrained-width, 1100px);
  margin: 0 auto;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 20px;
}

.lm-mark {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  flex-shrink: 0;
  color: inherit;
}
/* Real Library Market wordmark SVG. Native teal+coral colors on the
   light chrome - no inversion needed (the dark-chrome filter:invert(1)
   approach is gone in v2.7.16). 22px height yields ~124px width. */
.lm-wordmark {
  display: block;
  height: 22px;
  width: auto;
}

.lm-chrome-divider {
  width: 1px;
  height: 24px;
  background: var(--lmc-rule);
  flex-shrink: 0;
}

.lm-crumbs {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 14px;
  font-family: var(--lmc-poppins);
}
.lm-crumb-link {
  color: var(--lmc-ink-soft);
  text-decoration: none;
  font-weight: 500;
  padding: 3px 6px;
  margin: -3px -6px;
  border-radius: 4px;
  transition: color 0.12s, background 0.12s;
}
.lm-crumb-link:hover {
  color: var(--lmc-ink);
  background: var(--lmc-bg);
}
.lm-crumb-sep {
  color: var(--lmc-ink-faded);
  font-size: 12px;
  opacity: 0.6;
  user-select: none;
}
.lm-crumb-current {
  font-weight: 600;
  color: var(--lmc-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.lm-crumb-label {
  /* For client view - same visual position as a link but not interactive */
  color: var(--lmc-ink-soft);
  font-weight: 500;
  padding: 3px 6px;
  margin: -3px -6px;
  cursor: default;
}
/* v2.10.13 CHROME-1: project logo in crumb slot (staff side only).
   Sized to fit within the existing topbar height; falls back to text
   via the JS renderer when no logoUrl is uploaded on the project.
   Width-capped to keep narrow viewports compact; max-height matches
   the visual weight of the surrounding 14px crumb text. */
.lm-crumb-logo {
  display: block;
  height: 22px;
  width: auto;
  max-width: 120px;
  object-fit: contain;
  vertical-align: middle;
}
.lm-crumb-link .lm-crumb-logo,
.lm-crumb-current .lm-crumb-logo,
.lm-crumb-label .lm-crumb-logo {
  /* Tighten link/current padding so the logo dominates its cell. */
  margin: -2px 0;
}

/* v2.13.2: back-to-dashboard label inside the project link crumb.
   Restores an obvious affordance that the icon is the way back (the
   icon-only render from v2.10.13 CHROME-1 left users guessing).
   Label is fixed-length so the original topbar compression win is
   preserved. The anchor flips to inline-flex so icon + label share a
   single row. */
.lm-crumb-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.lm-crumb-back-label {
  font-weight: 500;
  white-space: nowrap;
}

/* ============================================================
   v2.10.13 CHROME-2: project switcher dropdown removed
   ============================================================
   The v2.8.2-era .lm-project-switcher / .lm-project-switcher-trigger
   / .lm-project-switcher-pop / .lm-project-switcher-item / etc. CSS
   block (~130 lines) has been deleted along with the matching JS.
   v2.11.0 finished the cleanup by removing the recordProjectVisit()
   no-op stub and all feature-detected callers. */

.lm-chrome-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

/* ============================================================
   SAVE STATE (in chrome actions slot)
   ============================================================ */

.lm-save-state {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--lmc-ink-faded);
  padding: 0 10px;
  font-family: var(--lmc-poppins);
}
.lm-save-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--lmc-save-idle);
  flex-shrink: 0;
}
.lm-save-state.is-saving .lm-save-dot {
  animation: lm-pulse 1.2s ease-in-out infinite;
}
.lm-save-state.is-saved .lm-save-dot {
  background: var(--lmc-save-saved);
}
.lm-save-state.is-error .lm-save-dot {
  background: var(--lmc-save-error);
}
.lm-save-state.is-error {
  color: var(--lmc-coral);
}
@keyframes lm-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.5; transform: scale(1.3); }
}

/* ============================================================
   BUTTONS
   ============================================================ */

.lm-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: 6px;
  border: 1px solid var(--lmc-rule);
  background: var(--lmc-white);
  color: var(--lmc-ink);
  font-family: var(--lmc-poppins);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  text-decoration: none;
  line-height: 1.2;
}
.lm-btn:hover {
  background: var(--lmc-bg);
  border-color: var(--lmc-ink-faded);
}
.lm-btn:disabled,
.lm-btn[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}
.lm-btn-primary {
  background: var(--lmc-brand-purple);
  border-color: var(--lmc-brand-purple);
  color: #fff;
}
.lm-btn-primary:hover {
  background: var(--lmc-brand-purple-hover);
  border-color: var(--lmc-brand-purple-hover);
  color: #fff;
}
.lm-btn-coral {
  background: var(--lmc-coral);
  border-color: var(--lmc-coral);
  color: #fff;
}
.lm-btn-coral:hover {
  background: #d8451c;
  border-color: #d8451c;
}
.lm-btn-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.lm-btn-caret {
  margin-left: 2px;
  font-size: 14px;
}

/* ============================================================
   USER AVATAR + POPOVER
   ============================================================ */

.lm-user-menu {
  position: relative;
  display: inline-flex;
}
.lm-user-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--lmc-purple);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 600;
  font-family: var(--lmc-poppins);
  cursor: pointer;
  border: none;
  flex-shrink: 0;
  transition: box-shadow 0.15s;
}
.lm-user-avatar:hover,
.lm-user-avatar:focus {
  box-shadow: 0 0 0 3px rgba(98,100,148,0.18);
  outline: none;
}
/* v2.7.12: bright orange ring on the avatar when masquerading as a
   different role. Composes via box-shadow layering with focus state. */
.lm-user-avatar.is-previewing {
  box-shadow: 0 0 0 3px #ff8c1a;
}
.lm-user-avatar.is-previewing:hover,
.lm-user-avatar.is-previewing:focus {
  box-shadow: 0 0 0 3px #ff8c1a, 0 0 0 5px rgba(255,140,26,0.25);
}

.lm-user-popover {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--lmc-white);
  border: 1px solid var(--lmc-rule);
  border-radius: 10px;
  box-shadow: var(--lmc-shadow-md);
  padding: 12px;
  min-width: 240px;
  z-index: 200;
  font-family: var(--lmc-poppins);
}
.lm-user-popover-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--lmc-ink);
  margin-bottom: 2px;
}
.lm-user-popover-email {
  font-size: 12px;
  color: var(--lmc-ink-faded);
  margin-bottom: 10px;
  word-break: break-all;
}
.lm-user-popover-link {
  display: block;
  padding: 7px 8px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--lmc-ink);
  text-decoration: none;
  border: none;
  background: transparent;
  width: 100%;
  text-align: left;
  cursor: pointer;
  font-family: inherit;
}
.lm-user-popover-link:hover {
  background: var(--lmc-bg);
}

/* v2.7.27: bottom-of-popover actions group. Admin (when present) + Sign
   out moved out of their prior inline positions into their own section
   at the foot of the popover, mirroring the divider treatment used by
   .lm-preview-section and .lm-layout-section. Keeps the popover read
   top-to-bottom as: identity (name/email), context switches (preview-as,
   dashboard layout), then actions. */
.lm-user-popover-actions {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--lmc-rule-soft);
}

/* v2.7.4 masquerade Preview-as section (Owner-only) */
.lm-preview-section {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--lmc-rule-soft);
}
.lm-preview-section-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--lmc-ink-faded);
  margin-bottom: 6px;
}
.lm-preview-section-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.lm-preview-pill {
  padding: 4px 9px;
  font-size: 11px;
  font-weight: 500;
  font-family: var(--lmc-poppins);
  background: transparent;
  border: 1px solid var(--lmc-rule);
  border-radius: 999px;
  color: var(--lmc-ink-soft);
  cursor: pointer;
  transition: all 0.12s;
}
.lm-preview-pill:hover {
  color: var(--lmc-ink);
  border-color: var(--lmc-ink-faded);
}
.lm-preview-pill.is-active {
  /* v2.7.27: pill active state recolored from orange (#ff8c1a) to ink. The
     orange "you are previewing" signal is now carried solely by the avatar
     ring (.lm-user-avatar.is-previewing) so the dropdown pills can read as
     a neutral role selector. */
  background: var(--lmc-ink);
  border-color: var(--lmc-ink);
  color: #fff;
}

/* v2.7.26: dashboard layout toggle section in the avatar popover. Visible
   to all signed-in users (not gated to a role). Mirrors the preview-as
   structure but with a calmer ink-colored active pill - this is a layout
   preference, not an alarm-state masquerade, so it doesn't need the
   orange accent. */
.lm-layout-section {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--lmc-rule-soft);
  margin-bottom: 4px;
}
.lm-layout-section-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--lmc-ink-faded);
  margin-bottom: 6px;
}
.lm-layout-section-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.lm-layout-pill {
  padding: 4px 9px;
  font-size: 11px;
  font-weight: 500;
  font-family: var(--lmc-poppins);
  background: transparent;
  border: 1px solid var(--lmc-rule);
  border-radius: 999px;
  color: var(--lmc-ink-soft);
  cursor: pointer;
  transition: all 0.12s;
}
.lm-layout-pill:hover {
  color: var(--lmc-ink);
  border-color: var(--lmc-ink-faded);
}
.lm-layout-pill.is-active {
  background: var(--lmc-ink);
  border-color: var(--lmc-ink);
  color: #fff;
}

/* ============================================================
   ACTIONS DROPDOWN (anchored under an action button in chrome)
   ============================================================ */

.lm-actions-wrap {
  position: relative;
  display: inline-flex;
}
.lm-actions-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  background: var(--lmc-white);
  border: 1px solid var(--lmc-rule);
  border-radius: 10px;
  box-shadow: var(--lmc-shadow-md);
  padding: 6px;
  min-width: 280px;
  z-index: 200;
  font-family: var(--lmc-poppins);
  font-size: 13px;
}
.lm-actions-menu hr {
  border: none;
  border-top: 1px solid var(--lmc-rule-soft);
  margin: 4px 0;
}
.lm-actions-menu-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--lmc-ink);
  text-decoration: none;
  background: transparent;
  border: none;
  width: 100%;
  text-align: left;
  font-family: inherit;
  font-size: 13px;
  transition: background 0.1s;
}
.lm-actions-menu-item:hover {
  background: var(--lmc-bg);
}
.lm-actions-menu-item .ami-ico {
  width: 16px;
  height: 16px;
  margin-top: 1px;
  color: var(--lmc-ink-faded);
  flex-shrink: 0;
}
.lm-actions-menu-item .ami-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1;
  min-width: 0;
}
.lm-actions-menu-item .ami-lbl {
  font-size: 13px;
  font-weight: 500;
  color: var(--lmc-ink);
}
.lm-actions-menu-item .ami-hint {
  font-size: 11.5px;
  color: var(--lmc-ink-faded);
  display: block;
}
.lm-actions-menu-section-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--lmc-ink-faded);
  padding: 8px 10px 4px;
}
.lm-actions-menu-version {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12px;
  color: var(--lmc-ink);
}
.lm-actions-menu-version:hover {
  background: var(--lmc-bg);
}
.lm-actions-menu-version-tag {
  background: var(--lmc-purple-pale);
  color: var(--lmc-purple);
  font-family: var(--lmc-mono);
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 10px;
  font-weight: 600;
}
.lm-actions-menu-version-meta {
  color: var(--lmc-ink-faded);
  font-size: 11px;
  margin-left: auto;
}

/* ============================================================
   HERO (unified per-surface heading section)
   ============================================================ */

.lm-hero {
  background: var(--lmc-white);
  padding: 28px 32px 24px;
  border-bottom: 1px solid var(--lmc-rule);
}
.lm-hero-inner {
  /* v2.7.20: single platform-wide constrained width matching the colortest.
     Was per-surface --lm-hero-max-width var in v2.7.19; collapsed to one
     global --lm-constrained-width so hero + content always line up at the
     same width across every non-fullwidth surface. */
  max-width: var(--lm-constrained-width, 1100px);
  margin: 0 auto;
  display: flex;
  align-items: flex-start;
  gap: 24px;
}
.lm-hero-text {
  flex: 1;
  min-width: 0;
}
.lm-hero h1 {
  margin: 0 0 6px;
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--lmc-ink);
  line-height: 1.2;
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--lmc-poppins);
}
/* Eyebrow label for tool surfaces (Design Proofs, Work Log, etc.).
   Small uppercase teal label above the h1. v2.7.17. */
.lm-eyebrow {
  margin: 0 0 8px;
  font-family: var(--lmc-poppins);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--lmc-teal-dark);
  font-weight: 600;
}
/* Project logo (small icon inline with hero h1). Used on the dashboard
   when the project has a logoUrl set. v2.12.29: previously framed in a
   light-purple tile; the tile became visual noise once real client
   icons started rendering inside it, so the background + colored frame
   are removed. Image renders at 36px square, transparent backdrop. */
.lm-project-logo {
  width: 36px;
  height: 36px;
  display: inline-block;
  vertical-align: middle;
  flex-shrink: 0;
  object-fit: contain;
}
.lm-lede {
  margin: 0;
  font-size: 14px;
  font-weight: 400;
  color: var(--lmc-ink-soft);
  line-height: 1.5;
  max-width: 640px;
  font-family: var(--lmc-poppins);
}
.lm-meta-lines {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--lmc-ink-soft);
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  font-family: var(--lmc-poppins);
}
.lm-meta-lines span strong {
  color: var(--lmc-ink);
  font-weight: 500;
}
.lm-meta-lines a {
  color: var(--lmc-teal-dark);
  text-decoration: none;
}
.lm-meta-lines a:hover {
  text-decoration: underline;
}
.lm-hero-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  padding-top: 4px;
}

/* ============================================================
   HERO BANNER (state strip under hero h1/lede)
   ============================================================ */

.lm-hero-banner {
  background: var(--lmc-teal-pale);
  color: var(--lmc-teal-dark);
  border: 1px solid rgba(0,167,169,0.18);
  border-radius: 8px;
  padding: 10px 14px;
  margin: 14px auto 0;
  max-width: var(--lm-constrained-width, 1100px);
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--lmc-poppins);
}
.lm-hero-banner.is-readonly {
  background: var(--lmc-purple-pale);
  color: var(--lmc-purple);
  border-color: rgba(98,100,148,0.2);
}
.lm-hero-banner.is-warn {
  /* v2.10.14 D-015: amber yellow + dark amber text. Previously coral
     text on coral-pale read as orange-on-orange and was hard to scan. */
  background: var(--lmc-amber-pale);
  color: var(--lmc-amber-dark);
  border-color: var(--lmc-amber-border);
}
/* v2.13.12: is-progress (soft blue) for the colortest 'started' state -
   saved but not yet sent to the client. Matches the --status-started badge
   tone on the dashboard so the two surfaces read as the same state. */
.lm-hero-banner.is-progress {
  background: #e7f1fb;
  color: #1f5f86;
  border-color: rgba(31,95,134,0.22);
}
/* v2.10.9: is-success variant (green) for approved states. Mirrors the
   tone the legacy lm-colortest-approved-banner used, ported into the
   platform hero-banner system so colortest can drop its bespoke green
   strip and use the same surface treatment as sitemap.

   Sub-styles (.meta, .hint) match sitemap's .approval-banner layout:
   .meta hangs after the headline in muted tone; .hint is pushed to
   the far right via margin-left:auto and styled italic + subtle. JS
   toggles .hint visibility with [hidden] based on session role. */
.lm-hero-banner.is-success {
  background: rgba(47,133,90,0.08);
  color: #1d6b3f;
  border-color: rgba(47,133,90,0.22);
}
.lm-hero-banner.is-success strong { color: #14532d; font-weight: 600; }
.lm-hero-banner .meta {
  font-size: 12px;
  opacity: 0.78;
}
.lm-hero-banner .hint {
  margin-left: auto;
  font-size: 12px;
  font-style: italic;
  opacity: 0.72;
}
.lm-hero-banner svg {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
}

/* ============================================================
   SECONDARY STRIP (under hero - admin tabs, filter pills, tool toolbar)
   ============================================================ */

.lm-hero-secondary {
  background: var(--lmc-white);
  padding: 0 32px;
  border-bottom: 1px solid var(--lmc-rule);
}
.lm-hero-secondary-inner {
  max-width: var(--lm-constrained-width, 1100px);
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 18px;
  height: 48px;
}

/* Full-width hero variant. Drops the centered max-width on the inner so
   the hero contents align to the same left gutter as the surface below
   (e.g. sitemap two-pane workspace, colortest body when refactored).
   Outer .lm-hero padding (32px) still provides the gutter; only the
   centering goes away. The secondary strip follows suit when present. */
.lm-hero.is-fullwidth .lm-hero-inner,
.lm-hero.is-fullwidth + .lm-hero-secondary .lm-hero-secondary-inner {
  max-width: none;
  margin: 0;
}
/* v2.10.6 OBS-5: banner is a sibling of .lm-hero-inner (not a child), so the
   fullwidth override above does not catch it. Without this rule the banner
   keeps its default `margin: 14px auto 0` and the box sits centered while the
   h1/lede above sit flush-left - visible mismatch on sitemap client view. */
.lm-hero.is-fullwidth .lm-hero-banner {
  max-width: none;
  margin-left: 0;
  margin-right: 0;
}

/* Landing filter pills (Active / Archived / All). */
.lm-filter-pills {
  display: flex;
  gap: 2px;
  background: var(--lmc-bg);
  padding: 3px;
  border-radius: 8px;
}
.lm-filter-pill {
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 500;
  font-family: var(--lmc-poppins);
  background: transparent;
  border: none;
  border-radius: 5px;
  color: var(--lmc-ink-soft);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.lm-filter-pill:hover {
  color: var(--lmc-ink);
}
.lm-filter-pill.is-active {
  background: var(--lmc-white);
  color: var(--lmc-ink);
  box-shadow: var(--lmc-shadow-sm);
}

/* ============================================================
   TOOL TOOLBAR (cream secondary strip for tool-only controls)
   Used by Color Test for Version / Secondary / Colorblind / Palette
   ============================================================ */

.lm-tool-toolbar {
  background: var(--lmc-bg-soft);
  padding: 0 32px;
  border-bottom: 1px solid var(--lmc-rule);
}
.lm-tool-toolbar-inner {
  max-width: 1280px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 52px;
  flex-wrap: wrap;
  padding: 8px 0;
  font-size: 12px;
  font-family: var(--lmc-poppins);
}

/* ============================================================
   CLIENT VIEW MODIFIERS
   Toggled by lm-chrome.js based on cfg.isClient. Hides any action
   in .lm-chrome-actions that doesn't carry .lm-show-client.
   ============================================================ */

body.lm-client-view .lm-chrome-actions > *:not(.lm-show-client) {
  display: none;
}
/* v2.10.1: .lm-user-menu now carries .lm-show-client so the avatar
   renders for clients too (simplified popover: name + email + Sign
   out). The previous explicit hide rule that suppressed it
   regardless of class is gone with the new avatar treatment. */

/* ============================================================
   AUTH PENDING - hide chrome + hero + secondary while auth resolves
   ============================================================ */

body.auth-pending .lm-chrome,
body.auth-pending .lm-hero,
body.auth-pending .lm-hero-secondary,
body.auth-pending .lm-tool-toolbar {
  visibility: hidden;
}

/* ============================================================
   MOBILE BLOCK (moved from lm.css + tool-chrome.css)
   ============================================================ */

.lm-mobile-block {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--lmc-white);
  z-index: 100000;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
  text-align: center;
  font-family: var(--lmc-poppins);
}
.lm-mobile-block-logo {
  height: 28px;
  width: auto;
  margin-bottom: 14px;
}
.lm-mobile-block-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--lmc-ink-faded);
  margin-bottom: 24px;
}
.lm-mobile-block h1 {
  font-size: 22px;
  font-weight: 600;
  color: var(--lmc-ink);
  margin: 0 0 10px;
  max-width: 320px;
  line-height: 1.25;
}
.lm-mobile-block p {
  font-size: 14px;
  color: var(--lmc-ink-soft);
  margin: 0;
  max-width: 320px;
  line-height: 1.5;
}

/* v2.16.1: scoped to `screen`. Without a media type this fired during PRINT
   too - on a printed page the mobile "use a bigger screen" block took over and
   was then hidden by the print rules above, blanking any base.njk page (e.g.
   /help). Mobile layout is a screen-only concern; print now shows real content. */
@media screen and (max-width: 760px) {
  body > *:not(.lm-mobile-block):not(#auth-blocker):not(script):not(style) {
    display: none !important;
  }
  body > .lm-mobile-block {
    display: flex;
  }
}

/* ============================================================
   PRINT
   ============================================================ */

@media print {
  .lm-chrome,
  .lm-hero-secondary,
  .lm-tool-toolbar,
  .lm-mobile-block,
  /* v2.13.23: the slimline platform footer is position:fixed, so the browser
     reprints it at the bottom of every printed page - a dead giveaway that the
     PDF is a printed web page, not a document. Removed from print entirely.
     The colortest's own in-flow .doc-footer ("Prepared by Library Market") is
     separate and stays as the deliverable's footer. */
  .lm-platform-footer {
    display: none !important;
  }
  .lm-hero {
    padding: 0 0 16px;
    border: none;
    box-shadow: none;
  }
  .lm-hero-banner {
    display: none !important;
  }
}

/* ============================================================
   RESPONSIVE (collapse chrome paddings + hero on tablet/narrow)
   ============================================================ */

@media (max-width: 900px) {
  .lm-chrome {
    padding: 12px 20px;
  }
  .lm-chrome-inner {
    /* v2.7.23: gap moved here since .lm-chrome-inner is the flex container now */
    gap: 14px;
  }
  .lm-hero {
    padding: 22px 20px 18px;
  }
  .lm-hero-inner {
    flex-direction: column;
    gap: 14px;
  }
  .lm-hero-actions {
    align-self: stretch;
  }
  .lm-hero-secondary,
  .lm-tool-toolbar {
    padding: 0 20px;
  }
  .lm-crumbs {
    font-size: 13px;
  }
  .lm-hero h1 {
    font-size: 22px;
  }
}

/* v2.12.19 -> v2.12.20: platform-wide slimline footer. Pinned to the
   viewport bottom so it's always visible regardless of page scroll
   (v2.12.19 placed it at the end of document flow, which fell off
   screen on any page taller than 100vh). Solid white background
   blocks any content that would otherwise scroll underneath; body
   gets padding-bottom to clear the footer height.

   v2.12.20: attribution on the LEFT, version on the RIGHT (flipped
   from the original). Version font switched to Poppins (was JetBrains
   Mono). Heart is now LM green (var(--pass), #2d8c5c) instead of
   teal so it reads cleanly as a "green heart". */
body {
  /* Reserve room at the bottom of every page so fixed footer doesn't
     overlap real content. 34px = footer padding (8 top + 8 bottom) +
     ~18px text height + 1px border. */
  padding-bottom: 40px;
}
.lm-platform-footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 900;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 22px;
  border-top: 1px solid var(--hair, rgba(0,0,0,0.10));
  background: #ffffff;
  color: var(--lm-quiet, #8a857c);
  font-family: 'Poppins', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-size: 11px;
  letter-spacing: 0.04em;
  pointer-events: none;
  user-select: none;
}
.lm-platform-footer-version {
  font-family: 'Poppins', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-size: 11px;
  letter-spacing: 0.04em;
}
/* v2.16.2: right-hand group holds the Help link + version together. The footer
   itself is pointer-events:none (click-through over content); the Help link
   re-enables pointer-events just for itself so it stays clickable. */
.lm-platform-footer-right {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.lm-platform-footer-help {
  pointer-events: auto;
  color: var(--lm-quiet, #8a857c);
  text-decoration: none;
  font-family: 'Poppins', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  font-size: 11px;
  letter-spacing: 0.04em;
}
.lm-platform-footer-help:hover {
  color: var(--lm-purple, #463287);
  text-decoration: underline;
}
.lm-platform-footer-sep {
  color: var(--hair, rgba(0,0,0,0.25));
}
.lm-platform-footer-tag {
  font-family: inherit;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.lm-platform-footer-heart {
  color: var(--pass, #2d8c5c);
  font-size: 12px;
  line-height: 1;
  margin: 0 1px;
  display: inline-block;
  transform: translateY(0.5px);
}
.lm-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* Narrow viewports: stack the two halves so neither truncates. */
@media (max-width: 600px) {
  body {
    padding-bottom: 64px;
  }
  .lm-platform-footer {
    flex-direction: column;
    gap: 2px;
    padding: 10px 16px;
    align-items: center;
    text-align: center;
  }
}

/* v2.12.14: the .lm-hootie always-on bottom-left peek (v2.7.22 -> v2.7.27)
   was retired. Hootie now appears contextually only.

   Empty-state Hootie wrapper. Used in admin empty tabs, tool empty
   lists, conversation empty, login hero, invite landing, and 404 /
   fatal-error. The width + height are set inline on the wrapper so
   different surfaces can size Hootie appropriately (80px in the
   sitemap tree pane, 220px in the 404 hero). Centers the image and
   prevents it from stretching when placed inside flex/grid containers.

   Lives in lm-chrome.css because every surface imports this stylesheet
   (lm.css is only loaded by the layouts that use base.njk - tools
   like sitemap / colortest / design-proofs / work-log don't get lm.css). */
.lm-empty-hootie {
  display: block;
  margin: 0 auto 10px;
  flex-shrink: 0;
  pointer-events: none;
  user-select: none;
}
.lm-empty-hootie img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Circular avatar slot for the success-toast Hootie. The
   hootie-toaster-overlay.svg has its own clipPath internally but we
   crop with overflow:hidden too so the visual lands cleanly inside
   any toast variant. 48px slot, left-edge, vertically centered. */
.toast-hootie {
  position: absolute;
  left: 8px;
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  overflow: hidden;
  flex: 0 0 auto;
  background: rgba(255,255,255,0.12);
  pointer-events: none;
}
.toast-hootie img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Toasts that opt into the Hootie avatar shift their text right so
   the avatar doesn't overlap the message. Applied via .toast-hootie-slot
   on the toast element. The base .toast class (and per-tool variants)
   already pad on the right; we extend the left padding only. */
.toast.toast-hootie-slot {
  padding-left: 64px;
  min-height: 48px;
}

/* ============================================================
   v2.10.0 WIP C - PUBLIC CHROME + CENTERED CARD + CLIENT CARDS
   ============================================================ */

/* Public chrome modifier: same slim white bar, but the wordmark is
   centered and the divider / breadcrumb / actions slots are hidden.
   Used on unauthenticated surfaces (/, /login, /invite/accept, error
   pages from auth-callback and invite-accept) where there's no nav
   context and no user identity to display. */
.lm-chrome.lm-chrome-public .lm-chrome-inner {
  justify-content: center;
}
.lm-chrome.lm-chrome-public .lm-chrome-divider,
.lm-chrome.lm-chrome-public .lm-crumbs,
.lm-chrome.lm-chrome-public .lm-chrome-actions {
  display: none;
}

/* Centered card surface used by:
     - Public landing (/)
     - Sign-in page (/login)
     - Invite-accept loading state
     - All server-rendered error pages (callback + invite-accept)
     - The cross-project mismatch page on authenticated surfaces */
.lm-card-surface {
  background: var(--lmc-bg);
  padding: 64px 24px;
  min-height: calc(100vh - 64px);
  box-sizing: border-box;
}
.lm-card {
  max-width: 460px;
  margin: 0 auto;
  background: var(--lmc-white);
  border: 1px solid var(--lmc-rule);
  border-radius: 12px;
  padding: 36px 32px 32px;
  box-shadow: var(--lmc-shadow-md);
  font-family: var(--lmc-poppins);
}
.lm-card.lm-card-wide {
  max-width: 540px;
}
.lm-card-eyebrow {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--lmc-teal-dark);
}
.lm-card-eyebrow.is-warn {
  color: var(--lmc-coral);
}
.lm-card-eyebrow.is-mute {
  color: var(--lmc-ink-faded);
}
.lm-card h1 {
  margin: 0 0 10px;
  font-size: 22px;
  font-weight: 600;
  color: var(--lmc-ink);
  letter-spacing: -0.01em;
  line-height: 1.25;
  font-family: var(--lmc-poppins);
}
.lm-card p {
  margin: 0 0 16px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--lmc-ink-soft);
  font-family: var(--lmc-poppins);
}
.lm-card p:last-of-type {
  margin-bottom: 22px;
}
.lm-card .lm-btn-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.lm-card .lm-btn-block {
  width: 100%;
  justify-content: center;
}
/* Subtle helper text below the primary action. Used for trouble-signing-in
   links and similar low-prominence guidance. */
.lm-card-foot {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--lmc-rule-soft);
  font-size: 12px;
  color: var(--lmc-ink-faded);
  line-height: 1.5;
  font-family: var(--lmc-poppins);
}
.lm-card-foot a {
  color: var(--lmc-teal-dark);
  text-decoration: none;
}
.lm-card-foot a:hover {
  text-decoration: underline;
}

/* Definition-list-style detail block used on the email-mismatch error
   page. Stacks label + value pairs inside a soft tinted container. */
.lm-detail-dl {
  margin: 18px 0 22px;
  padding: 18px;
  background: var(--lmc-bg);
  border: 1px solid var(--lmc-rule-soft);
  border-radius: 8px;
  font-size: 13px;
  font-family: var(--lmc-poppins);
}
.lm-detail-dl dt {
  color: var(--lmc-ink-faded);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 3px;
}
.lm-detail-dl dt:not(:first-child) {
  margin-top: 14px;
}
.lm-detail-dl dd {
  margin: 0;
  color: var(--lmc-ink);
  font-weight: 500;
  word-break: break-word;
}
.lm-detail-dl dd a {
  color: var(--lmc-teal-dark);
  text-decoration: none;
}
.lm-detail-dl dd a:hover {
  text-decoration: underline;
}

/* Google "G" mark sized for inline use inside the lm-btn pill. */
.lm-google-g {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

/* Small inline spinner used by /invite/accept loading state and the
   /login redirect interstitial when an already-signed-in user lands
   there. */
.lm-spinner {
  display: inline-block;
  width: 14px;
  height: 14px;
  border: 2px solid var(--lmc-rule);
  border-top-color: var(--lmc-purple);
  border-radius: 50%;
  vertical-align: -2px;
  margin-right: 8px;
  animation: lm-spin 0.8s linear infinite;
}
@keyframes lm-spin { to { transform: rotate(360deg); } }

/* ============================================================
   CLIENT MULTI-PROJECT LANDING - card grid
   ============================================================ */

/* Slim card variant for /projects/ client landing. Compared with the
   staff Projects card (`.project-card` in lm.css), this version:
     - shows only project name + LM contact + small logo tile
     - no progress bar, no type badges, no admin gear
     - logo + name sit on the left, click target is the whole card */
.pc-client {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--lmc-white);
  border: 1px solid var(--lmc-rule);
  border-radius: 12px;
  padding: 18px 20px;
  text-decoration: none;
  color: inherit;
  box-shadow: var(--lmc-shadow-sm);
  transition: box-shadow 0.15s, border-color 0.15s, transform 0.15s;
  font-family: var(--lmc-poppins);
}
.pc-client:hover {
  box-shadow: var(--lmc-shadow-md);
  border-color: var(--lmc-purple);
  transform: translateY(-1px);
}
.pc-client-logo {
  width: 44px;
  height: 44px;
  border-radius: 8px;
  background: var(--lmc-purple-pale);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
}
.pc-client-logo img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
}
.pc-client-logo-fallback {
  font-family: var(--lmc-poppins);
  font-size: 14px;
  font-weight: 700;
  color: var(--lmc-purple);
  letter-spacing: 0.02em;
}
.pc-client-text {
  /* v2.10.2: markup is a <span> wrapping two child <span>s
     (.pc-client-name, .pc-client-meta). Without explicit display
     these were all inline, so the meta line sat to the right of the
     name inside the same baseline (overflowing the card) instead of
     stacking. Variant A intent: name on top, meta below. flex column
     forces the stack and gives child flex items the implicit block
     formatting needed for text-overflow:ellipsis to take effect on
     the children. min-width:0 keeps long names/meta from forcing the
     card to expand past its grid track. */
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.pc-client-name {
  display: block;
  max-width: 100%;
  font-size: 15px;
  font-weight: 600;
  color: var(--lmc-ink);
  margin: 0 0 3px;
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pc-client-meta {
  display: block;
  max-width: 100%;
  font-size: 12px;
  color: var(--lmc-ink-faded);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Client grid container - same constraints as staff project-grid but
   reusing the global landing shell. Kept separate so the staff grid
   keeps its own existing layout. */
.pc-client-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 14px;
}

/* Loading + empty states for client landing. Match the existing
   .lp-loading visual but expressed inside the client surface. */
.pc-client-empty {
  text-align: center;
  padding: 48px 16px;
  font-size: 14px;
  color: var(--lmc-ink-faded);
  font-family: var(--lmc-poppins);
}
