/* ============================================================
 * project-panel.css — D47 project panel styles
 *
 * Standalone stylesheet for the new lens-based project panel.
 * Doesn't extend devmap.css; the new panel is a separate module
 * per Lloyd's "no append to old" rule. Old popup styles in
 * devmap.css are deleted in D47.2.L.
 *
 * Design language: aligns with the existing gold/charcoal palette
 * but more typographic. Apple-leaning over Bloomberg per Lloyd's
 * v0.13 direction. Citation pills are first-class — they are the
 * panel's primary visual signature.
 * ============================================================ */

/* D76.A — :root token declarations migrated to developments/css/_tokens.css
 * (canonical source per HIG §3). --pp-* names remain in use throughout
 * this file via aliases declared in _tokens.css. Convergent values:
 *   --pp-ink:   #1a1a1a → #111111 (canonical ink-1)
 *   --pp-ink-2: #4a4a4a → #374151 (canonical ink-2)
 *   --pp-ink-3: #767676 → #6b7280 (canonical ink-3)
 *   --pp-line:  #e2e0db → #e7e5e4 (canonical line)
 *   --pp-line-strong: #cfcdc6 → #d1d5db (canonical line-strong)
 *   --pp-radius: 10px → 6px (HIG radius-md cap)
 * Other tokens (--pp-gold, --pp-ok, --pp-flash, --pp-uncited) unchanged.
 * Two --pp-bg-2 / --pp-bg-3 not in _tokens.css yet — declared below
 * as panel-local exceptions until D76.E chip-system cycle decides. */
:root {
  --pp-bg-2:    #f7f6f3;
  --pp-bg-3:    #ecebe7;
}

/* D68.14 — Mobile breakpoint tightens panel padding + ensures
   long values wrap rather than overflow horizontally. */
@media (max-width: 480px) {
  :root {
    --pp-pad: 12px;
    --pp-pad-sm: 8px;
  }
  .project-panel {
    overflow-x: hidden;
  }
  /* Tighter typography for the project name on narrow viewports */
  .lens-id__name {
    font-size: 22px !important;
    line-height: 1.15 !important;
  }
  /* Heritage list: allow the adjacency tag to wrap below the name
     instead of overflowing horizontally */
  .lens-id__heritage-item {
    flex-wrap: wrap;
  }
  /* Zoning row: same — let the cap value wrap below its label rather
     than push the permit suffix off-screen */
  .lens-id__zoning-row {
    flex-wrap: wrap;
  }
  /* Identity meta row (stage / community / pids): wrap chips */
  .lens-id__meta {
    flex-wrap: wrap;
  }
  /* Tab bar: enable horizontal scrolling rather than hiding tabs */
  .project-panel__tabs {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* Document list links: allow long names to wrap mid-word so they
     don't overflow the panel */
  .lens-planning__doc-link {
    word-break: break-word;
  }
}

/* ─── Panel shell ─── */

.project-panel {
  font-family: 'Inter', system-ui, sans-serif;
  color: var(--pp-ink);
  background: var(--pp-bg);
  height: 100%;
  overflow-y: auto;
}

.project-panel[data-state="loading"] .project-panel__loading,
.project-panel[data-state="error"] .project-panel__error {
  padding: 24px var(--pp-pad);
  color: var(--pp-ink-3);
  font-size: 14px;
}

.project-panel[data-state="error"] .project-panel__error {
  color: var(--pp-uncited);
  background: #fff8f5;
  border-left: 3px solid var(--pp-uncited);
}

.project-panel__body {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* D58.D — Tab bar under the identity header. Identity stays visible above
   the tabs; the active tab's lens is the only rendered content below. */
.project-panel__tabs {
  display: flex;
  gap: 0;
  padding: 0 8px;
  border-bottom: 1px solid var(--pp-line);
  background: var(--pp-bg);
  position: sticky;
  top: 0;
  z-index: 4;
  /* D65.B — no overflow scroll. Tabs share width equally and truncate
     long labels with ellipsis. Combined with the wider panel column
     (minmax(420px,540px)) this fits 5–7 tabs without horizontal
     scrolling at any breakpoint. */
}
.project-panel__tab {
  appearance: none;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  padding: 10px 6px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--pp-ink-3);
  cursor: pointer;
  /* D65.B — equal-width tabs that truncate cleanly. flex: 1 1 0 ensures
     every tab takes equal share of the bar; min-width: 0 lets text-
     overflow:ellipsis kick in when a label can't fit. */
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
  transition: color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
}
.project-panel__tab:hover { color: var(--pp-ink); }
.project-panel__tab.is-active {
  color: var(--pp-ink);
  border-bottom-color: var(--pp-gold);
  font-weight: 600;
}
.project-panel__tab-content {
  padding-top: 4px;
  /* D81.2 — D80.C13 cross-fade removed. The 120ms opacity dip-then-
     restore + double-RAF wait was layering ~150ms of intentional
     "loading" delay on top of a tab swap that's actually a pure
     client-side DOM replace from pre-rendered HTML (~30-80ms of real
     work). The fade made tab clicks feel half-a-second slow even
     though the content was already in memory. Now instant — content
     just appears like a native browser tab strip. */
}

/* D80.C10 (C1) — Project-panel skeleton. Replaces the bare
   "Reading sources…" text node with a shape-matching skeleton:
   identity-row + tab strip + content block. Same shimmer as
   dev-states.css. */
.project-panel__loading-shell {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-5) var(--pp-pad, 24px);
}
.project-panel__skel-identity {
  display: grid;
  gap: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--line);
}
.project-panel__skel-tabs {
  display: flex; gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--line);
}
.project-panel__skel-tabs span {
  display: block;
  width: 56px; height: 8px;
  background: var(--surface-2);
  border-radius: var(--radius-sm);
}
.project-panel__skel-content {
  display: grid; gap: var(--space-2);
  padding-top: var(--space-2);
}
.project-panel__skel-row {
  height: 14px;
  background: linear-gradient(
    90deg,
    var(--surface-2) 0%,
    var(--bg-sunken) 40%,
    var(--surface-2) 80%
  );
  background-size: 200% 100%;
  border-radius: var(--radius-sm);
  animation: project-panel-shimmer 1300ms var(--ease-in-out) infinite;
}
.project-panel__skel-row--wide  { width: 75%; }
.project-panel__skel-row--mid   { width: 50%; }
.project-panel__skel-row--short { width: 30%; }
@keyframes project-panel-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .project-panel__skel-row {
    animation: none;
    background: var(--surface-2);
    opacity: 0.7;
  }
}

/* D68.10 — Data-source freshness footer (collapsed by default).
   Shows last-successful-run timestamps per worker that fed the panel.
   Honest staleness signal — complements per-fact observation_date in
   citation popovers. */
.project-panel__freshness {
  margin: 12px var(--pp-pad) var(--pp-pad);
  padding: 8px 12px;
  background: rgba(0, 0, 0, 0.02);
  border: 1px solid var(--pp-line);
  border-radius: 4px;
  font-size: 11.5px;
}
.project-panel__freshness-head {
  font: 500 11px/1.2 var(--font-body, 'Inter', sans-serif);
  color: var(--pp-ink-3, #6b6b6b);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
  list-style: none;
}
.project-panel__freshness-head::-webkit-details-marker { display: none; }
.project-panel__freshness-head::before {
  content: "▸ ";
  display: inline-block;
  width: 1em;
  transition: transform var(--duration-fast) var(--ease-out);
}
.project-panel__freshness[open] .project-panel__freshness-head::before {
  transform: rotate(90deg);
}
.project-panel__freshness-list {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
}
.project-panel__freshness-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 2px 0; gap: 12px;
}
.project-panel__freshness-label {
  color: var(--pp-ink-2, #3a3a3a);
}
.project-panel__freshness-date {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  color: var(--pp-ink-3, #6b6b6b);
}

/* ─── Lens — shared shell ─── */

.lens {
  padding: var(--pp-pad);
  border-bottom: 1px solid var(--pp-line);
  background: var(--pp-bg);
}

.lens:last-child {
  border-bottom: none;
}

.lens__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 12px;
}

.lens__title {
  font-family: 'Outfit', system-ui, sans-serif;
  font-weight: 600;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--pp-ink-2);
  margin: 0;
}

.lens__count {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  color: var(--pp-ink-3);
}

.lens__empty {
  color: var(--pp-ink-3);
  font-size: 14px;
  font-style: italic;
  margin: 0;
}

/* ─── Citation (D65.A) ─────────────────────────────────────────────────
   Citation pill replaced by dotted-underline + hover/focus popover.
   Anchors (cite--has-source) open the source URL in a new tab on click;
   spans (cite--no-link) are non-clickable but still focusable for kbd.
   .cite__value / .cite__pill kept as no-ops for any stragglers. */

.cite {
  /* Inline behavior — flows with surrounding text. */
  display: inline;
  color: var(--pp-ink);
  font-weight: inherit;
}

.cite--has-source,
.cite--no-link {
  /* The dotted-underline IS the source-visibility affordance. */
  text-decoration: underline dotted var(--pp-ink-3);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  cursor: help;
  transition: color var(--duration-fast) var(--ease-out), text-decoration-color var(--duration-fast) var(--ease-out);
}

.cite--has-source {
  cursor: pointer;
  color: inherit;
}

a.cite--has-source { color: inherit; }
a.cite--has-source:hover,
.cite--has-source:focus-visible,
.cite--no-link:focus-visible {
  color: var(--pp-ink);
  text-decoration-color: var(--pp-gold-dark);
  text-decoration-thickness: 1.5px;
  outline: none;
}

.cite__note {
  font-size: 11px;
  color: var(--pp-ink-3);
  font-style: italic;
  margin-left: 4px;
}

.cite--empty {
  color: var(--pp-ink-3);
  font-style: italic;
}

.cite--uncited {
  color: var(--pp-uncited);
  background: rgba(200, 74, 42, 0.08);
  border-bottom: 1px dashed var(--pp-uncited);
  padding: 0 2px;
}

/* Legacy .cite__value / .cite__pill — kept inert for any unmigrated callers.
   D65.A pill model is gone; these resolve to plain inline text. */
.cite__value { font-weight: inherit; color: inherit; }
.cite__pill { display: none; }

/* ─── Citation popover (D65.A) ─────────────────────────────────────── */

.cite-popover {
  position: absolute;
  z-index: 9000;
  display: none;
  max-width: 320px;
  background: var(--pp-bg, #ffffff);
  border: 1px solid var(--pp-line, rgba(0,0,0,0.12));
  border-radius: 6px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);
  padding: 10px 12px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--pp-ink, #1a1a1a);
  pointer-events: auto;  /* allow mouse hover to keep alive */
}

.cite-popover__source {
  display: block;
  font-weight: 600;
  font-size: 13px;
  color: var(--pp-ink, #1a1a1a);
}

.cite-popover__date {
  display: block;
  margin-top: 2px;
  font-size: 11.5px;
  color: var(--pp-ink-3, #6b6b6b);
}

.cite-popover__url {
  display: block;
  margin-top: 6px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  color: var(--pp-ink-2, #3a3a3a);
  word-break: break-all;
}

.cite-popover__hint {
  display: block;
  margin-top: 6px;
  font-size: 11px;
  color: var(--pp-gold-dark, #8a6d1f);
  font-weight: 500;
}

/* D68.11 — Source-priority chain "Also seen" section in popover */
.cite-popover__sep {
  margin: 8px 0;
  border: 0;
  border-top: 1px dashed var(--pp-line);
}
.cite-popover__alt-head {
  display: block;
  font: 600 10.5px/1.2 var(--font-body, 'Inter', sans-serif);
  color: var(--pp-ink-3, #6b6b6b);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 4px;
}
.cite-popover__alt-row {
  display: block;
  font-size: 11.5px;
  color: var(--pp-ink-2, #3a3a3a);
  padding: 1px 0;
  line-height: 1.4;
}

/* Reduced-motion users: no smooth fade, just instant show/hide. */
@media (prefers-reduced-motion: reduce) {
  .cite-popover { transition: none; }
}

/* D66.E.2 — Active street closures list */
.lens-id__closures {
  margin-top: 12px; padding: 8px 12px;
  background: rgba(216, 160, 53, 0.06);
  border: 1px solid rgba(216, 160, 53, 0.25);
  border-radius: 4px;
}
.lens-id__closures-head {
  margin: 0 0 6px;
  font: 600 11px/1.2 var(--font-body, 'Inter', sans-serif);
  color: var(--pp-ink-2, #3a3a3a);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.lens-id__closures-list { list-style: none; margin: 0; padding: 0; }
.lens-id__closure {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px; padding: 2px 0;
}
.lens-id__closure-segment { font-weight: 500; color: var(--pp-ink, #1a1a1a); }
.lens-id__closure-range {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px; color: var(--pp-ink-3, #6b6b6b);
}

/* D68.10 — Archived-case chip: closed case with no public URL */
.lens-id__archived {
  margin-top: 10px; padding: 6px 12px;
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  background: rgba(100, 100, 100, 0.05);
  border: 1px dashed rgba(100, 100, 100, 0.30);
  border-radius: 4px;
}
.lens-id__archived-head {
  flex: 0 0 auto;
  font: 600 11px/1.2 var(--font-body, 'Inter', sans-serif);
  color: var(--pp-ink-2, #3a3a3a);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.lens-id__archived-body {
  flex: 1 1 auto; min-width: 0;
  font-size: 12.5px;
  color: var(--pp-ink-3, #6b6b6b);
  font-style: italic;
}

/* D67.A — Heritage Properties chip */
.lens-id__heritage {
  margin-top: 10px; padding: 8px 12px;
  background: rgba(120, 80, 40, 0.05);
  border: 1px solid rgba(120, 80, 40, 0.20);
  border-radius: 4px;
}
.lens-id__heritage-head {
  display: block; margin-bottom: 4px;
  font: 600 11px/1.2 var(--font-body, 'Inter', sans-serif);
  color: var(--pp-ink-2, #3a3a3a);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.lens-id__heritage-list { list-style: none; margin: 0; padding: 0; }
.lens-id__heritage-item {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px;
  font-size: 12.5px; padding: 1px 0;
  color: var(--pp-ink, #1a1a1a);
}
.lens-id__heritage-name { flex: 1 1 auto; min-width: 0; }
/* D68.8 — adjacency tag with rank-aware styling */
.lens-id__heritage-adj {
  flex: 0 0 auto;
  font: 500 10.5px/1.2 var(--font-body, 'Inter', sans-serif);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 1px 6px;
  border-radius: 3px;
}
.lens-id__heritage-item--on .lens-id__heritage-adj {
  color: #6b4014; background: rgba(120, 80, 40, 0.15);
}
.lens-id__heritage-item--partial .lens-id__heritage-adj {
  color: #7a5a30; background: rgba(120, 80, 40, 0.08);
}
.lens-id__heritage-item--adjacent .lens-id__heritage-adj {
  color: var(--pp-ink-3, #6b6b6b); background: transparent; font-weight: 400;
}
.lens-id__heritage-item--adjacent .lens-id__heritage-name {
  color: var(--pp-ink-3, #6b6b6b);
}
.lens-id__heritage-more { color: var(--pp-ink-3, #6b6b6b); font-style: italic; }

/* D69.C.1 — .lens-id__hcd{,-head,-list,-item,-status} and
 * .lens-id__shadow{,-head,-list,-item} CSS removed. The matching
 * markup now uses .lens-chip-group{,__head,__list,__item,__sub} with
 * --hcd / --shadow tone modifiers (defined above). */

/* D69.C.1 — shared chip-group component. Replaces the per-family
 * .lens-id__hcd, .lens-id__shadow, etc. blocks above. New chip families
 * are one tone-modifier rule away. */
.lens-chip-group {
  margin-top: 8px; padding: 6px 12px;
  background: rgba(110, 110, 110, 0.05);
  border: 1px solid rgba(110, 110, 110, 0.20);
  border-radius: 4px;
}
.lens-chip-group--hcd {
  padding: 8px 12px;  /* HCD historically had slightly more padding */
  background: rgba(140, 95, 50, 0.06);
  border-color: rgba(140, 95, 50, 0.22);
}
.lens-chip-group--shadow {
  background: rgba(70, 70, 90, 0.05);
  border-color: rgba(70, 70, 90, 0.20);
}
.lens-chip-group__head {
  display: block; margin-bottom: 4px;
  font: 600 11px/1.2 var(--font-body, 'Inter', sans-serif);
  color: var(--pp-ink-2, #3a3a3a);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.lens-chip-group__list { list-style: none; margin: 0; padding: 0; }
.lens-chip-group__item {
  font-size: 12.5px; padding: 1px 0;
  color: var(--pp-ink, #1a1a1a);
}
.lens-chip-group__sub {
  margin-left: 6px; padding: 1px 5px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10.5px; color: var(--pp-ink-3, #6b6b6b);
  background: rgba(140, 95, 50, 0.10);
  border-radius: 3px;
}

/* D67.A — Zoning maximum height chip */
.lens-id__zoning {
  margin-top: 8px; padding: 6px 12px;
  background: rgba(60, 90, 130, 0.05);
  border: 1px solid rgba(60, 90, 130, 0.20);
  border-radius: 4px;
}
.lens-id__zoning-head {
  display: block; margin-bottom: 4px;
  font: 600 11px/1.2 var(--font-body, 'Inter', sans-serif);
  color: var(--pp-ink-2, #3a3a3a);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.lens-id__zoning-list { list-style: none; margin: 0; padding: 0; }
.lens-id__zoning-row {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 1px 0; gap: 12px;
}
/* D68.7 — Zoning row layout: "Max storeys" / "Max height" label on the
   left, comma-separated values on the right, both in their natural type. */
.lens-id__zoning-label {
  font-size: 12px; color: var(--pp-ink-2, #3a3a3a);
}
.lens-id__zoning-cap {
  font: 500 12.5px/1.2 'JetBrains Mono', ui-monospace, monospace;
  color: var(--pp-ink, #1a1a1a);
}
/* D68.13 — Permit-derived value next to the zoning cap. Muted +
   small so the user reads it as supporting context, not an
   alternate cap. No computed percentage (fact-engine direction). */
.lens-id__zoning-permit {
  margin-left: 8px;
  font-size: 10.5px;
  font-weight: 400;
  color: var(--pp-ink-3, #6b6b6b);
  text-transform: lowercase;
}

/* D66.B — Completed badge under stage chip */
.lens-id__completed {
  font: 500 11px/1.2 'JetBrains Mono', ui-monospace, monospace;
  color: #2c7a4a;
  background: rgba(44, 122, 74, 0.08);
  border: 1px solid rgba(44, 122, 74, 0.25);
  padding: 2px 8px;
  border-radius: 3px;
  letter-spacing: 0.02em;
}

/* ─── Identity lens ─── */

.lens--identity {
  padding: 24px var(--pp-pad) 20px;
  background: linear-gradient(180deg, #fafaf7 0%, var(--pp-bg) 100%);
}

.lens-id {
  display: flex;
  flex-direction: column;
  gap: 8px;
  position: relative;
  /* D80.E6 — Hairline grid texture as a paper-quiet hero treatment.
     24px grid; gold lines. Reads as a planning-document grid.
     D80.ITERATE.2 — bumped 3% → 6% after the walkthrough showed
     3% was below perception threshold (the identity area read as
     flat white). 6% is still quiet but now actually visible. */
  background-image:
    linear-gradient(to right, rgba(212, 168, 75, 0.06) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(212, 168, 75, 0.06) 1px, transparent 1px);
  background-size: 24px 24px;
  background-position: 0 0;
  /* D82.R1.4 was a 3px coloured border-top here; reverted in
     D82.iterate per Lloyd's read — the right place for the stage
     signal is the close bar at the very top of the panel (a header
     band + label), not a thin accent inside the identity. */
}

.lens-id__name {
  font-family: 'Outfit', system-ui, sans-serif;
  font-size: 26px;
  font-weight: 600;
  line-height: 1.15;
  color: var(--pp-ink);
  margin: 0;
  letter-spacing: -0.01em;
}

.lens-id__name .cite__value { font-weight: 600; }

.lens-id__address {
  font-size: 14px;
  color: var(--pp-ink-2);
  margin: 0;
  letter-spacing: 0.01em;
}

.lens-id__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 6px;
  align-items: center;
}

.lens-id__meta-item {
  font-size: 12px;
  color: var(--pp-ink-3);
}

/* D76.E (partial) — Panel-header chip family unified to canonical
 * HIG §4 patterns. Four selectors retained for back-compat with JS
 * that renders them; their styles now follow one chip system:
 *
 *   .lens-id__stage-chip — 'stage' modifier (left-border accent + muted bg)
 *   .lens-id__path       — 'path' modifier (tinted bg per regime kind)
 *   .lens-id__tier       — 'tier' modifier (solid + mono uppercase)
 *   .lens-id__pids       — identifier pill (HIG §4.3 — pill shape for IDs)
 *
 * Common base: caption type, weight-medium, hairline border, canonical
 * spacing + radius tokens. Each modifier overrides what's distinctive
 * to its semantic. Drift between the 4 historical chip languages is
 * dissolved. */

.lens-id__pids,
.lens-id__stage-chip,
.lens-id__path,
.lens-id__tier {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font: var(--weight-medium) var(--text-caption)/1.4 var(--font-body);
  border: 1px solid transparent;
  white-space: nowrap;
}

.lens-id__pids {
  font-family: var(--font-mono);
  color: var(--ink-3);
  background: var(--surface-2);
  padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  border-color: var(--line);
  cursor: help;
}

.lens-id__stage-chip {
  padding: 3px var(--space-3) 3px var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border-left: 3px solid var(--chip-color, var(--ink-3));
  font-size: var(--text-sm);  /* 12.5 — slightly larger; the stage is the headline chip */
}
.lens-id__stage-chip .cite__value { color: var(--ink-1); }

.lens-id__tier {
  position: absolute;
  top: 0;
  right: 0;
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 3px var(--space-2);
  border-radius: var(--radius-sm);
}
.lens-id__tier--major {
  background: var(--ink-1);
  color: #fff;
}
.lens-id__tier--minor {
  background: transparent;
  color: var(--ink-3);
  border-color: var(--line-strong);
}

/* D72.E — path chip: regulatory pipeline (orthogonal to stage + kind).
 * Renders inline next to the stage chip in the meta row. */
.lens-id__path {
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  letter-spacing: 0.02em;
  cursor: help;
}
.lens-id__path--permit_only {
  background: var(--chip-ok-bg);
  color: var(--chip-ok-fg);
  border-color: var(--chip-ok-bg);
}
.lens-id__path--planning_application {
  background: var(--chip-info-bg);
  color: var(--chip-info-fg);
  border-color: var(--chip-info-bg);
}
.lens-id__path--subdivision {
  background: rgba(120, 80, 30, 0.10);
  color: #6f4615;
  border-color: rgba(120, 80, 30, 0.20);
}
.lens-id__path--heritage {
  background: rgba(140, 95, 50, 0.10);
  color: #6b4220;
  border-color: rgba(140, 95, 50, 0.20);
}

.lens-id__premise {
  margin-top: 10px;
  padding: 12px 0 0;
  border-top: 1px solid var(--pp-line);
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--pp-ink-2);
  font-style: italic;
}

.lens-id__premise .cite__value { font-style: italic; }

/* D59.A — Curator team row (developer / builder / architect) */
.lens-id__team {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 8px;
  margin-top: 12px;
  padding: 10px 12px;
  background: var(--pp-muted-bg);
  border-radius: 6px;
}
.lens-id__team-cell { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lens-id__team-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pp-ink-3);
}
.lens-id__team-value {
  font-size: 13px;
  font-weight: 500;
  color: var(--pp-ink);
  word-break: break-word;
}

.lens-id__links {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
}

.lens-id__link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--pp-ink-2);
  background: var(--pp-bg);
  border: 1px solid var(--pp-line-strong);
  border-radius: 4px;
  text-decoration: none;
  transition: all var(--duration-fast) var(--ease-out);
}

.lens-id__link:hover,
.lens-id__link:focus-visible {
  background: var(--pp-gold);
  color: #1f1500;
  border-color: var(--pp-gold-dark);
}

.lens-id__link-arrow {
  font-size: 10px;
  opacity: 0.7;
}

/* D51.8 — parent breadcrumb + phases list */
.lens-id__parent {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  margin-bottom: 8px;
  font-size: 12px;
  color: var(--pp-ink-muted, #6c6c6c);
  background: var(--pp-bg-soft, rgba(0,0,0,0.04));
  border-radius: 12px;
  text-decoration: none;
  transition: background-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
}
.lens-id__parent:hover,
.lens-id__parent:focus-visible {
  background: var(--pp-bg-hover, rgba(0,0,0,0.08));
  color: var(--pp-ink, #1a1a1a);
}
.lens-id__parent strong { font-weight: 600; }
.lens-id__parent-arrow { font-size: 11px; opacity: 0.7; }

.lens-id__phases {
  margin-top: 14px;
  padding: 12px;
  background: var(--pp-bg-soft, rgba(0,0,0,0.04));
  border-radius: 8px;
}
.lens-id__phases-head {
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--pp-ink-muted, #6c6c6c);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.lens-id__phases-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 6px;
}
.lens-id__phase a {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 6px 10px;
  background: var(--pp-bg, #fff);
  border-radius: 6px;
  text-decoration: none;
  color: inherit;
  border: 1px solid transparent;
  transition: border-color var(--duration-fast) var(--ease-out), background-color var(--duration-fast) var(--ease-out);
}
.lens-id__phase a:hover,
.lens-id__phase a:focus-visible {
  border-color: var(--pp-gold, #c89938);
  background: var(--pp-bg-hover, rgba(0,0,0,0.02));
}
.lens-id__phase-label {
  font-weight: 600;
  font-size: 12px;
  color: var(--pp-gold-dark, #8d6920);
  min-width: 56px;
}
.lens-id__phase-name {
  font-size: 13px;
  color: var(--pp-ink, #1a1a1a);
}


/* ========== D84.B — Constellation strip ===================================
 * Above the identity lens. Shows one dot per project regime. Single-regime
 * projects (~70% of corpus) render one quiet pill; multi-regime projects
 * render N pills with the active one filled.
 *
 * Visual: low-key by default — these are scoping affordances, not the
 * project hero. The active regime gets a filled treatment; inactive
 * regimes are outlined. Hover deepens the outline. Click toggles active.
 *
 * Orphan variant: when a project has no regime[] (the 91 'Tracked but
 * unclassified' cohort), the strip shows a single dimmed pill so the user
 * sees the gap honestly per ADR §10.4.
 * ========================================================================== */
.constellation {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 12px 0;
  padding: 0;
  align-items: center;
}

.constellation__dot {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 1px solid var(--pp-border, #d1d5db);
  border-radius: 999px;
  padding: 4px 10px;
  font: 500 11px/1.4 var(--font-display, "Inter", system-ui, sans-serif);
  letter-spacing: 0.02em;
  color: var(--pp-ink-2, #4b5563);
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease,
              color 120ms ease, transform 80ms ease;
  white-space: nowrap;
  min-height: 28px;          /* WCAG-respectful but quiet */
  display: inline-flex;
  align-items: center;
}

.constellation__dot:hover {
  border-color: var(--pp-ink-2, #4b5563);
  color: var(--pp-ink, #1a1a1a);
}

.constellation__dot:focus-visible {
  outline: 2px solid var(--pp-gold, #d4a84b);
  outline-offset: 2px;
}

.constellation__dot--active {
  background: var(--pp-ink, #1a1a1a);
  border-color: var(--pp-ink, #1a1a1a);
  color: var(--pp-bg, #ffffff);
}

.constellation__dot--active:hover {
  /* Don't shift on hover when already active — feels glitchy */
  background: var(--pp-ink, #1a1a1a);
  border-color: var(--pp-ink, #1a1a1a);
  color: var(--pp-bg, #ffffff);
}

.constellation__label {
  font-weight: inherit;
}

/* Single-regime variant: quiet, doesn't fight for attention since
 * there's no choice to make. Removes the active treatment so it reads
 * as a label, not a button. Click still works (D84.C1+C2 will use it). */
.constellation--single .constellation__dot {
  border-color: transparent;
  background: var(--pp-bg-2, #f3f4f6);
  color: var(--pp-ink-2, #4b5563);
  cursor: default;
}

.constellation--single .constellation__dot:hover {
  /* No hover deepening — single regime is not an interactive choice */
  border-color: transparent;
  background: var(--pp-bg-2, #f3f4f6);
  color: var(--pp-ink-2, #4b5563);
}

/* ========== D87.4.3 (K2) — Stacked-card regime metaphor ============
 * Multi-regime projects (~30% of the corpus — projects with both a
 * planning case AND a building permit, for example) get the literal
 * Z-axis stack: active regime as the front-most card, others peeking
 * behind it with offset down+right. Click a peek to swap it forward.
 *
 * Implementation:
 *   - Container is position:relative so cards can absolute-stack at
 *     the same baseline
 *   - All cards share the same width; active card is z-index:5 with
 *     no offset; peek cards offset via translate per data-peek-depth
 *   - Container reserves enough min-height to accommodate active +
 *     visible peek edges
 *
 * Single-regime projects bypass this entirely — they fall through to
 * the .constellation--single rules above and render as a quiet pill.
 */
.constellation--stack {
  position: relative;
  margin: 0 0 12px;
  /* Reserve space for the active card (~36px) + 2 peek edges at 8px each */
  min-height: 52px;
}

.constellation--stack .constellation__card {
  /* Override the inline-pill defaults: card is a full-width banner */
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: block;
  width: auto;
  padding: 9px 14px;
  font: 600 12.5px/1.3 var(--font-display, "Inter", system-ui, sans-serif);
  letter-spacing: 0.02em;
  border-radius: 8px;
  background: var(--pp-bg, #ffffff);
  border: 1px solid var(--pp-border, #d1d5db);
  color: var(--pp-ink-2, #4b5563);
  text-align: left;
  transition: transform 180ms ease-out, opacity 180ms ease-out,
              box-shadow 180ms ease-out;
}

/* D87.4.3 (K2) — Active card always on top, no offset, full opacity,
 * elevated by a subtle shadow that says "this is the foreground card". */
.constellation--stack .constellation__card--active {
  z-index: 5;
  transform: translate(0, 0);
  opacity: 1;
  background: var(--pp-ink, #1a1a1a);
  border-color: var(--pp-ink, #1a1a1a);
  color: var(--pp-bg, #ffffff);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
  cursor: default;
}

/* D87.4.3 — Peek cards offset down+right behind the active card.
 * Each subsequent peek steps further back (depth 1 = closest, etc.).
 * Opacity ramps down with depth so the back-most peek is quietest. */
.constellation--stack .constellation__card--peek[data-peek-depth="1"] {
  transform: translate(8px, 6px);
  z-index: 3;
  opacity: 0.7;
}
.constellation--stack .constellation__card--peek[data-peek-depth="2"] {
  transform: translate(16px, 12px);
  z-index: 2;
  opacity: 0.55;
}
.constellation--stack .constellation__card--peek[data-peek-depth="3"] {
  transform: translate(24px, 18px);
  z-index: 1;
  opacity: 0.45;
}
.constellation--stack .constellation__card--peek[data-peek-depth="4"] {
  transform: translate(32px, 24px);
  z-index: 0;
  opacity: 0.35;
}

/* Hover any peek: lift it slightly forward + raise opacity. Clicking
 * fires the regime-change handler (existing wire()) which swaps the
 * --active class onto the clicked card. */
.constellation--stack .constellation__card--peek:hover {
  opacity: 0.95;
  transform: translate(4px, 3px);
  z-index: 6;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  cursor: pointer;
}

.constellation--stack .constellation__card--peek:focus-visible {
  outline: 2px solid var(--pp-gold, #d4a84b);
  outline-offset: 2px;
}

/* Orphan variant: dimmed-and-visible per ADR §10.4. The label
 * 'Tracked, unclassified' tells the user we KNOW about this parcel
 * but don't have enough evidence to classify the regime. */
.constellation--orphan .constellation__dot--orphan {
  background: transparent;
  border-style: dashed;
  border-color: var(--pp-border, #d1d5db);
  color: var(--pp-ink-3, #9ca3af);
  cursor: default;
  font-style: italic;
}

.constellation--orphan .constellation__dot--orphan:hover {
  /* No hover treatment — informational, not interactive */
  border-color: var(--pp-border, #d1d5db);
  color: var(--pp-ink-3, #9ca3af);
}

/* ========== D84.G — Feedback chip + form ==================================
 * Inline <details> at the bottom of the panel. Closed state shows a quiet
 * link-style summary; open reveals the form. Submit posts to
 * /api/developments/projects/feedback.
 *
 * Visual: subordinate to the freshness footer above it. Reads as a
 * contributor affordance, not a complaint box.
 * ========================================================================== */
.project-panel__feedback {
  margin: 12px 0 0 0;
  padding: 0;
  border-top: 1px solid var(--pp-border, #d1d5db);
  padding-top: 12px;
}

.project-panel__feedback-summary {
  cursor: pointer;
  font: 500 12px/1.4 var(--font-display, "Inter", system-ui, sans-serif);
  color: var(--pp-ink-2, #4b5563);
  list-style: none;
  display: inline-block;
  padding: 4px 0;
  user-select: none;
}

.project-panel__feedback-summary:hover {
  color: var(--pp-ink, #1a1a1a);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.project-panel__feedback-summary::-webkit-details-marker {
  display: none;
}

.project-panel__feedback-summary::before {
  content: "+ ";
  color: var(--pp-ink-3, #9ca3af);
  font-weight: 600;
}

.project-panel__feedback[open] .project-panel__feedback-summary::before {
  content: "− ";
}

.project-panel__feedback-form {
  display: grid;
  gap: 10px;
  padding: 12px 0 0 0;
}

.project-panel__feedback-label {
  display: grid;
  gap: 4px;
}

.project-panel__feedback-field-label {
  font: 500 11px/1.4 var(--font-display, "Inter", system-ui, sans-serif);
  color: var(--pp-ink-2, #4b5563);
  letter-spacing: 0.02em;
}

.project-panel__feedback-select,
.project-panel__feedback-input,
.project-panel__feedback-textarea {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--pp-border, #d1d5db);
  border-radius: 6px;
  font: 400 13px/1.4 var(--font-display, "Inter", system-ui, sans-serif);
  background: var(--pp-bg, #ffffff);
  color: var(--pp-ink, #1a1a1a);
  box-sizing: border-box;
}

.project-panel__feedback-select:focus,
.project-panel__feedback-input:focus,
.project-panel__feedback-textarea:focus {
  outline: 2px solid var(--pp-gold, #d4a84b);
  outline-offset: 1px;
  border-color: transparent;
}

.project-panel__feedback-textarea {
  resize: vertical;
  min-height: 60px;
}

/* Honeypot — visually hidden but accessible to bots that parse the DOM */
.project-panel__feedback-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.project-panel__feedback-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
}

.project-panel__feedback-submit {
  appearance: none;
  background: var(--pp-ink, #1a1a1a);
  color: var(--pp-bg, #ffffff);
  border: 1px solid var(--pp-ink, #1a1a1a);
  border-radius: 6px;
  padding: 6px 14px;
  font: 600 12px/1.4 var(--font-display, "Inter", system-ui, sans-serif);
  cursor: pointer;
  letter-spacing: 0.02em;
}

.project-panel__feedback-submit:hover:not(:disabled) {
  background: #000;
}

.project-panel__feedback-submit:focus-visible {
  outline: 2px solid var(--pp-gold, #d4a84b);
  outline-offset: 2px;
}

.project-panel__feedback-submit:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.project-panel__feedback-status {
  font: 400 12px/1.4 var(--font-display, "Inter", system-ui, sans-serif);
  color: var(--pp-ink-2, #4b5563);
}

.project-panel__feedback-status.is-error {
  color: #c1361a;
}
