/* ═══════════════════════════════════════════════════════════════════════
   F2 Connections page — editorial cards layout (v2).

   Goal: useful on first paint. No "pick a node" gate, no empty rail.
   Default view is workspace cards (one per connected store) showing
   KPIs + inline product feed. Empty state shows the catalog inline so
   the user can connect their first store without a modal.

   Tokens: `var(--brand)` etc. from public/styles.css.
   Headings: system serif fallback (no webfont per BRAND.md §Typography).
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  --conn-cream: #fdfaf3;
  --conn-surf: #ffffff;
  --conn-surf-2: #f5ede0;
  --conn-olive: #4a4133;
  --conn-muted: #8a7b66;
  --conn-border: rgba(45, 38, 32, 0.10);
  --conn-border-mid: rgba(45, 38, 32, 0.16);
  --conn-text: #2d2620;
  --conn-radius: 14px;
  --font-heading: 'Iowan Old Style', 'Charter', 'Georgia', serif;
}

body:has(.conn-page) {
  background: var(--conn-cream);
}

/* On editorial pages, carry the cream surface into the outer shell
   (side-nav + slim top bar) so the editorial pages feel like one
   continuous theme, not "editorial column inside a white shell."
   Other pages (admin, editor) keep the flat white chrome. */
body:has(.conn-page) .side-nav {
  background: var(--conn-cream);
  border-right-color: var(--conn-border);
}
body:has(.conn-page) .app-header-slim {
  background: rgba(253, 250, 243, 0.92);
  border-bottom-color: var(--conn-border);
}

.conn-page {
  padding: 24px 32px 48px;
  max-width: 1240px;
  margin: 0 auto;
}

/* Back link — used on drill-in editorial pages (brand-kits, etc.) that
   are reached from the Connections cards. Matches the detail page's
   back affordance. */
.conn-back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: var(--conn-muted);
  text-decoration: none;
  margin-bottom: 16px;
  font-family: inherit;
  transition: color 160ms;
  cursor: pointer;
}
.conn-back:hover { color: var(--brand); }

/* ─── Page head ──────────────────────────────────────────────────────── */
.conn-page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
  margin-bottom: 24px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--conn-border);
  /* Override the legacy `.conn-page-head { text-align: center }` rule
     from public/styles.css. Without this, the H1 centers (no width cap)
     and the .conn-sub's max-width:640px container centers its text too —
     the two lines visibly disagree because they don't share a width. */
  text-align: left;
}
.conn-head-text { flex: 1; min-width: 0; }
.conn-h1 {
  font-family: var(--font-heading);
  font-size: 42px;
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.05;
  margin: 0 0 10px;
  color: var(--conn-text);
}
.conn-h1 i {
  font-style: italic;
  font-weight: 400;
  color: var(--brand);
}
.conn-sub {
  font-size: 15px;
  color: var(--conn-olive);
  margin: 0;
  max-width: 640px;
  line-height: 1.5;
}
.conn-head-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }

.conn-btn-honey {
  background: var(--brand);
  color: #fff;
  border: 0;
  border-radius: 99px;
  padding: 10px 20px;
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  font-family: inherit;
}
.conn-btn-honey:hover { background: var(--brand-deep); }

/* ─── Empty state — inline catalog ───────────────────────────────────── */
.conn-empty { padding: 16px 0; }
.conn-empty-card {
  background: var(--conn-surf);
  border: 1px solid var(--conn-border);
  border-radius: var(--conn-radius);
  padding: 36px 36px 32px;
  position: relative;
}
.conn-empty-h2 {
  font-family: var(--font-heading);
  font-size: 26px;
  font-weight: 400;
  letter-spacing: -0.01em;
  margin: 0 0 6px;
  color: var(--conn-text);
}
.conn-empty-sub {
  font-size: 14.5px;
  color: var(--conn-olive);
  margin: 0 0 24px;
  max-width: 560px;
  line-height: 1.5;
}

.conn-cat-tabs {
  display: flex;
  gap: 4px;
  background: var(--conn-surf-2);
  border-radius: 99px;
  padding: 4px;
  width: fit-content;
  margin-bottom: 20px;
}
.conn-cat-tab {
  background: transparent;
  border: 0;
  padding: 7px 16px;
  font-size: 13px;
  color: var(--conn-olive);
  border-radius: 99px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 500;
}
.conn-cat-tab.is-active {
  background: #fff;
  color: var(--conn-text);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(45,38,32,0.06);
}

.conn-cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}
.conn-cat-tile {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--conn-surf);
  border: 1px solid var(--conn-border);
  border-radius: 12px;
  padding: 14px 16px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: border-color 160ms, background 160ms, transform 160ms;
}
.conn-cat-tile:hover {
  border-color: var(--brand);
  background: var(--brand-soft);
  transform: translateY(-1px);
}
.conn-cat-tile[data-status="planned"] { opacity: 0.55; cursor: not-allowed; }
.conn-cat-tile[data-status="planned"]:hover { transform: none; border-color: var(--conn-border); background: var(--conn-surf); }

.conn-cat-tile-ic {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 17px;
  font-family: var(--font-heading);
  flex-shrink: 0;
}
.conn-cat-tile-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.conn-cat-tile-nm { font-size: 14px; font-weight: 600; color: var(--conn-text); }
.conn-cat-tile-sub { font-size: 11.5px; color: var(--conn-muted); }
.conn-cat-tile-sub b { color: var(--brand); font-weight: 600; }

/* Platform colors — match BRAND.md §Platform partners. Icons with a
   real local logo use background-image and hide the letter via
   `color: transparent`; the letter still sits in the markup so
   screen readers + the no-image fallback work. */
.ic-printify { background: #2eb872; }
.ic-shopify { background: #95bf47; color: #1a1a1a; }
.ic-tiktok_shop, .ic-tiktok { background: #161823; }
.ic-mailchimp { background: #ffe01b; color: #241c15; }
.ic-meta_ads, .ic-meta { background: #0866ff; }
.ic-google_ads, .ic-google { background: #4285f4; }
.ic-pinterest_ads, .ic-pinterest { background: #e60023; }
.ic-custom_webhook, .ic-webhook { background: var(--conn-olive); }
.ic-github { background: #1a1a1a; }
.ic-brand_kit { background: linear-gradient(135deg, #ec4899 0%, #a855f7 50%, var(--brand) 100%); }

/* Real-logo overlays. Compound selectors (.conn-card-ic.ic-*) raise
   specificity above the .conn-card-ic parent rule that comes later in
   this file — without that the parent's font-size: 22px + color: #fff
   win and the text letter bleeds through on top of the logo.
   Backgrounds are clean white for all logo-bearing tiles. */
.conn-card-ic.ic-everbee_research,
.conn-card-ic.ic-oposhop, .conn-card-ic.ic-opo,
.conn-card-ic.ic-etsy,
.conn-card-ic.ic-printful,
.conn-modal-tile-ic.ic-everbee_research,
.conn-modal-tile-ic.ic-oposhop, .conn-modal-tile-ic.ic-opo,
.conn-modal-tile-ic.ic-etsy,
.conn-modal-tile-ic.ic-printful,
.conn-cat-tile-ic.ic-everbee_research,
.conn-cat-tile-ic.ic-oposhop, .conn-cat-tile-ic.ic-opo,
.conn-cat-tile-ic.ic-etsy,
.conn-cat-tile-ic.ic-printful,
.conn-rail-ic.ic-everbee_research,
.conn-rail-ic.ic-oposhop, .conn-rail-ic.ic-opo,
.conn-rail-ic.ic-etsy,
.conn-rail-ic.ic-printful,
.conn-detail-ic.ic-everbee_research,
.conn-detail-ic.ic-oposhop, .conn-detail-ic.ic-opo,
.conn-detail-ic.ic-etsy,
.conn-detail-ic.ic-printful {
  font-size: 0;
  color: transparent;
  background-position: center;
  background-repeat: no-repeat;
}
/* Per-logo background image + bg color */
.conn-card-ic.ic-everbee_research,
.conn-modal-tile-ic.ic-everbee_research,
.conn-cat-tile-ic.ic-everbee_research,
.conn-rail-ic.ic-everbee_research,
.conn-detail-ic.ic-everbee_research {
  background-color: #ffffff;
  background-image: url("/assets/brand-logos/everbee-bee.svg");
  background-size: 72%;
}
.conn-card-ic.ic-oposhop, .conn-card-ic.ic-opo,
.conn-modal-tile-ic.ic-oposhop, .conn-modal-tile-ic.ic-opo,
.conn-cat-tile-ic.ic-oposhop, .conn-cat-tile-ic.ic-opo,
.conn-rail-ic.ic-oposhop, .conn-rail-ic.ic-opo,
.conn-detail-ic.ic-oposhop, .conn-detail-ic.ic-opo {
  background-color: #ffffff;
  background-image: url("/assets/brand-logos/oposhop-icon.png");
  background-size: 76%;
}
.conn-card-ic.ic-etsy,
.conn-modal-tile-ic.ic-etsy,
.conn-cat-tile-ic.ic-etsy,
.conn-rail-ic.ic-etsy,
.conn-detail-ic.ic-etsy {
  background-color: #ffffff;
  background-image: url("/assets/brand-logos/etsy-logo.svg");
  background-size: 80%;
}
.conn-card-ic.ic-printful,
.conn-modal-tile-ic.ic-printful,
.conn-cat-tile-ic.ic-printful,
.conn-rail-ic.ic-printful,
.conn-detail-ic.ic-printful {
  background-color: #ffffff;
  background-image: url("/assets/brand-logos/printful.svg");
  background-size: 80%;
}

/* Added connectors — real marks on white (printify, shopify, meta,
   pinterest, github). Hide the letter + center the logo. */
.conn-card-ic.ic-printify, .conn-modal-tile-ic.ic-printify, .conn-cat-tile-ic.ic-printify, .conn-rail-ic.ic-printify, .conn-detail-ic.ic-printify,
.conn-card-ic.ic-shopify, .conn-modal-tile-ic.ic-shopify, .conn-cat-tile-ic.ic-shopify, .conn-rail-ic.ic-shopify, .conn-detail-ic.ic-shopify,
.conn-card-ic.ic-meta_ads, .conn-modal-tile-ic.ic-meta_ads, .conn-cat-tile-ic.ic-meta_ads, .conn-rail-ic.ic-meta_ads, .conn-detail-ic.ic-meta_ads,
.conn-card-ic.ic-pinterest_ads, .conn-modal-tile-ic.ic-pinterest_ads, .conn-cat-tile-ic.ic-pinterest_ads, .conn-rail-ic.ic-pinterest_ads, .conn-detail-ic.ic-pinterest_ads,
.conn-card-ic.ic-github, .conn-modal-tile-ic.ic-github, .conn-cat-tile-ic.ic-github, .conn-rail-ic.ic-github, .conn-detail-ic.ic-github {
  font-size: 0;
  color: transparent;
  background-color: #ffffff;
  background-position: center;
  background-repeat: no-repeat;
}
.conn-card-ic.ic-printify, .conn-modal-tile-ic.ic-printify, .conn-cat-tile-ic.ic-printify, .conn-rail-ic.ic-printify, .conn-detail-ic.ic-printify {
  background-image: url("/assets/brand-logos/printify-icon.svg"); background-size: 62%;
}
.conn-card-ic.ic-shopify, .conn-modal-tile-ic.ic-shopify, .conn-cat-tile-ic.ic-shopify, .conn-rail-ic.ic-shopify, .conn-detail-ic.ic-shopify {
  background-image: url("/assets/brand-logos/shopify-icon.svg"); background-size: 58%;
}
.conn-card-ic.ic-meta_ads, .conn-modal-tile-ic.ic-meta_ads, .conn-cat-tile-ic.ic-meta_ads, .conn-rail-ic.ic-meta_ads, .conn-detail-ic.ic-meta_ads {
  background-image: url("/assets/brand-logos/meta-icon.svg"); background-size: 72%;
}
.conn-card-ic.ic-pinterest_ads, .conn-modal-tile-ic.ic-pinterest_ads, .conn-cat-tile-ic.ic-pinterest_ads, .conn-rail-ic.ic-pinterest_ads, .conn-detail-ic.ic-pinterest_ads {
  background-image: url("/assets/brand-logos/pinterest-icon.svg"); background-size: 60%;
}
.conn-card-ic.ic-github, .conn-modal-tile-ic.ic-github, .conn-cat-tile-ic.ic-github, .conn-rail-ic.ic-github, .conn-detail-ic.ic-github {
  background-image: url("/assets/brand-logos/github-icon.svg"); background-size: 60%;
}

/* POD providers from the Process & Push pipeline (shineon, hellocustom,
   completeful, anywherepod) — real marks on white. */
.conn-card-ic.ic-shineon, .conn-modal-tile-ic.ic-shineon, .conn-cat-tile-ic.ic-shineon, .conn-rail-ic.ic-shineon, .conn-detail-ic.ic-shineon,
.conn-card-ic.ic-hellocustom, .conn-modal-tile-ic.ic-hellocustom, .conn-cat-tile-ic.ic-hellocustom, .conn-rail-ic.ic-hellocustom, .conn-detail-ic.ic-hellocustom,
.conn-card-ic.ic-completeful, .conn-modal-tile-ic.ic-completeful, .conn-cat-tile-ic.ic-completeful, .conn-rail-ic.ic-completeful, .conn-detail-ic.ic-completeful,
.conn-card-ic.ic-anywherepod, .conn-modal-tile-ic.ic-anywherepod, .conn-cat-tile-ic.ic-anywherepod, .conn-rail-ic.ic-anywherepod, .conn-detail-ic.ic-anywherepod {
  font-size: 0;
  color: transparent;
  background-color: #ffffff;
  background-position: center;
  background-repeat: no-repeat;
}
.conn-card-ic.ic-shineon, .conn-modal-tile-ic.ic-shineon, .conn-cat-tile-ic.ic-shineon, .conn-rail-ic.ic-shineon, .conn-detail-ic.ic-shineon {
  background-image: url("/assets/brand-logos/shineon-icon.png"); background-size: 64%;
}
.conn-card-ic.ic-hellocustom, .conn-modal-tile-ic.ic-hellocustom, .conn-cat-tile-ic.ic-hellocustom, .conn-rail-ic.ic-hellocustom, .conn-detail-ic.ic-hellocustom {
  background-image: url("/assets/brand-logos/hellocustom-favicon.png"); background-size: 64%;
}
.conn-card-ic.ic-completeful, .conn-modal-tile-ic.ic-completeful, .conn-cat-tile-ic.ic-completeful, .conn-rail-ic.ic-completeful, .conn-detail-ic.ic-completeful {
  background-image: url("/assets/brand-logos/completeful-icon.png"); background-size: 70%;
}
.conn-card-ic.ic-anywherepod, .conn-modal-tile-ic.ic-anywherepod, .conn-cat-tile-ic.ic-anywherepod, .conn-rail-ic.ic-anywherepod, .conn-detail-ic.ic-anywherepod {
  background-image: url("/assets/brand-logos/anywherepod-icon.png"); background-size: 70%;
}

/* Default / platform-provisioned cards — slimmer treatment (no
   product feed, no KPIs). Same chrome, less density. */
.conn-card.is-default {
  background: linear-gradient(155deg, var(--conn-surf) 0%, var(--brand-soft) 140%);
}
.conn-card-default-blurb {
  font-size: 13.5px;
  color: var(--conn-olive);
  line-height: 1.55;
  margin: 0;
  padding: 14px 0;
  border-top: 1px dashed var(--conn-border-mid);
  border-bottom: 1px dashed var(--conn-border-mid);
  font-family: var(--font-heading);
  font-style: italic;
}

/* ─── Workspace cards — has-connections state ────────────────────────── */
.conn-cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
  gap: 20px;
}
.conn-card {
  background: var(--conn-surf);
  border: 1px solid var(--conn-border);
  border-radius: var(--conn-radius);
  padding: 22px 22px 18px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.conn-card:hover { border-color: var(--conn-border-mid); }

.conn-card-head {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 14px;
  align-items: start;
}
.conn-card-ic {
  width: 50px;
  height: 50px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 22px;
  font-family: var(--font-heading);
}
.conn-card-title .nm {
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 500;
  line-height: 1.1;
  margin: 0 0 4px;
  color: var(--conn-text);
}
.conn-card-title .nm i { font-style: italic; color: var(--brand); }
.conn-card-title .role {
  font-size: 11px;
  color: var(--conn-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
}
.conn-card-title .role .sep { padding: 0 6px; opacity: 0.5; }

/* Full-lockup variant of the card's visual mark — replaces the generic
   .conn-card-ic initial-circle for branded platforms (OpoShop, etc.).
   Sits in the grid's first column where the circle would normally go,
   sized roughly to its visual weight so the rest of the card layout
   doesn't reflow when the mark swaps in. */
.conn-card-mark-logo {
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
}
.conn-card-mark-logo img {
  height: 100%;
  width: auto;
  max-width: 180px;
  object-fit: contain;
  display: block;
}

/* Legacy role-line lockup. No longer rendered by renderWorkspaceCard()
   (the mark above carries the lockup now), but the class is kept in CSS
   in case any out-of-tree caller still uses it. */
.conn-card-role-logo {
  height: 30px;
  width: auto;
  vertical-align: middle;
  display: inline-block;
  margin-right: 10px;
  margin-top: 2px;
}
.conn-card-role-handle {
  font-size: 11px;
  color: var(--conn-muted);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
  vertical-align: middle;
}
.conn-card-role-handle::before {
  content: "·";
  margin-right: 8px;
  opacity: 0.5;
}

/* Branded title inside the Add-a-connection modal tile. Larger so the
   wordmark is the clear visual focus of the tile, not the description. */
.conn-modal-tile-nm-logo {
  height: 26px;
  width: auto;
  display: inline-block;
  align-self: start;
  margin: 2px 0 4px;
}

.conn-card-health {
  padding: 5px 10px;
  border-radius: 99px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.01em;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* Pulsing dot — slow, layered, gentle. Two concentric rings radiate
   outward on a 3.6s loop with a 1.8s phase offset, so the pulse never
   "ends" — one ring is always blooming while the other has just
   finished. The inner dot itself softly breathes a halo via box-shadow.
   Easing is gentle-out-cubic so each ring decelerates as it dissolves.
   Reduced-motion users see a solid dot with no animation
   (BRAND.md §Motion). */
.conn-health-pulse {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
  background: currentColor;
  position: relative;
  flex-shrink: 0;
  animation: conn-health-breathe 3.6s ease-in-out infinite;
}
.conn-health-pulse::before,
.conn-health-pulse::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: currentColor;
  pointer-events: none;
}
.conn-health-pulse::before {
  animation: conn-health-radiate 3.6s cubic-bezier(0.16, 1, 0.3, 1) infinite;
}
.conn-health-pulse::after {
  animation: conn-health-radiate 3.6s cubic-bezier(0.16, 1, 0.3, 1) infinite;
  animation-delay: 1.8s;
}
@keyframes conn-health-radiate {
  0%   { transform: scale(0.9); opacity: 0.42; }
  60%  { opacity: 0.06; }
  100% { transform: scale(3.6); opacity: 0; }
}
@keyframes conn-health-breathe {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50%      { box-shadow: 0 0 7px 0 currentColor; }
}
/* Only "alive" (ok / checking) statuses pulse — error / off / warn stay
   solid so a bad state doesn't read as friendly motion. */
.conn-card-health.is-err .conn-health-pulse,
.conn-card-health.is-warn .conn-health-pulse,
.conn-card-health.is-off .conn-health-pulse,
.conn-detail-head .conn-detail-health.is-err .conn-health-pulse,
.conn-detail-head .conn-detail-health.is-warn .conn-health-pulse,
.conn-detail-head .conn-detail-health.is-off .conn-health-pulse {
  animation: none;
  box-shadow: none;
}
.conn-card-health.is-err .conn-health-pulse::before,
.conn-card-health.is-err .conn-health-pulse::after,
.conn-card-health.is-warn .conn-health-pulse::before,
.conn-card-health.is-warn .conn-health-pulse::after,
.conn-card-health.is-off .conn-health-pulse::before,
.conn-card-health.is-off .conn-health-pulse::after,
.conn-detail-head .conn-detail-health.is-err .conn-health-pulse::before,
.conn-detail-head .conn-detail-health.is-err .conn-health-pulse::after,
.conn-detail-head .conn-detail-health.is-warn .conn-health-pulse::before,
.conn-detail-head .conn-detail-health.is-warn .conn-health-pulse::after,
.conn-detail-head .conn-detail-health.is-off .conn-health-pulse::before,
.conn-detail-head .conn-detail-health.is-off .conn-health-pulse::after {
  animation: none;
  opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
  .conn-health-pulse,
  .conn-health-pulse::before,
  .conn-health-pulse::after {
    animation: none;
    opacity: 1;
    box-shadow: none;
  }
  .conn-health-pulse::before,
  .conn-health-pulse::after { opacity: 0; }
}
.conn-card-health.is-ok { background: #d1fae5; color: #047857; }
.conn-card-health.is-warn { background: #fef3c7; color: #b45309; }
.conn-card-health.is-err { background: #fee2e2; color: #b91c1c; }
.conn-card-health.is-off { background: #f3f4f6; color: #6b7280; }
.conn-card-health.is-checking { background: #f3f4f6; color: #6b7280; font-weight: 500; }

/* KPIs */
.conn-card-kpis {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  padding: 14px 0;
  border-top: 1px dashed var(--conn-border-mid);
  border-bottom: 1px dashed var(--conn-border-mid);
}
.conn-kpi .v {
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 500;
  color: var(--conn-text);
  line-height: 1;
}
.conn-kpi .v b { color: var(--brand); font-weight: 500; }
.conn-kpi .l {
  font-size: 10px;
  color: var(--conn-muted);
  margin-top: 4px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-weight: 600;
}

/* Products section */
.conn-card-products {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.conn-card-products-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.conn-card-products-h h4 {
  font-family: var(--font-heading);
  font-size: 14px;
  font-style: italic;
  color: var(--conn-olive);
  margin: 0;
  font-weight: 500;
}
.conn-card-products-h a {
  color: var(--brand);
  font-size: 12px;
  text-decoration: none;
  font-weight: 600;
}
.conn-card-products-h a:hover { text-decoration: underline; }
.conn-pgrid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}
.conn-product { display: flex; flex-direction: column; gap: 4px; }
.conn-product .thumb {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 8px;
  background-color: var(--conn-surf-2);
  background-size: cover;
  background-position: center;
  border: 1px solid var(--conn-border);
  overflow: hidden;
  position: relative;
}
.conn-product .thumb .thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Fallback state — no image URL or image failed to load. Shows a
   stable per-product gradient with the product's initial letter,
   so the grid never has blank cream rectangles. */
.conn-product .thumb.is-fallback {
  background: var(--tint, linear-gradient(135deg, #fde68a, #f59e0b));
  display: flex;
  align-items: center;
  justify-content: center;
}
.conn-product .thumb.is-fallback::after {
  content: attr(data-initial);
  font-family: var(--font-heading);
  font-size: 28px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}
.conn-product .nm {
  font-size: 11.5px;
  color: var(--conn-text);
  font-weight: 500;
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.conn-product .meta { font-size: 10.5px; color: var(--conn-muted); }
.conn-product .meta b { color: var(--brand); font-weight: 600; }

.conn-products-loading,
.conn-products-empty,
.conn-products-err {
  font-size: 12.5px;
  color: var(--conn-muted);
  font-family: var(--font-heading);
  font-style: italic;
  padding: 14px 16px;
  background: var(--conn-cream);
  border-radius: 8px;
  text-align: center;
  line-height: 1.5;
  margin: 0;
}
.conn-products-err { color: #b91c1c; font-style: normal; }

/* In-card reconnect prompt — replaces the product grid when a
   connection's token is dead. Actionable: message + a real button. */
.conn-reconnect {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 18px;
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: 10px;
}
.conn-reconnect-msg {
  font-size: 13px;
  color: #92400e;
  line-height: 1.5;
}
.conn-reconnect-msg strong {
  display: block;
  color: #78350f;
  margin-bottom: 2px;
  font-size: 13.5px;
}
.conn-reconnect-btn {
  align-self: flex-start;
  background: var(--brand);
  color: #fff;
  border: 0;
  border-radius: 99px;
  padding: 9px 18px;
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: background 160ms;
}
.conn-reconnect-btn:hover { background: var(--brand-deep); }

/* Pill buttons — also defined in detail-b2.css, but the reconnect modal
   is created by connections.js on the /connections page, which only
   loads connections-b2.css. Without this the modal's buttons fall back
   to unstyled native chrome. */
.conn-pill {
  padding: 9px 16px;
  border: 1px solid var(--conn-border-mid);
  border-radius: 99px;
  background: transparent;
  color: var(--conn-olive);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background 160ms, border-color 160ms, color 160ms;
}
.conn-pill:hover { border-color: var(--brand); color: var(--brand); }
.conn-pill.is-honey {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
  font-weight: 600;
}
.conn-pill.is-honey:hover { background: var(--brand-deep); border-color: var(--brand-deep); color: #fff; }
.conn-pill.is-danger { color: #b91c1c; border-color: rgba(185, 28, 28, 0.32); }
.conn-pill.is-danger:hover { background: #fee2e2; border-color: #b91c1c; color: #b91c1c; }

/* Reconnect modal */
.reconnect-card {
  background: var(--conn-surf);
  border: 1px solid var(--conn-border);
  border-radius: var(--conn-radius);
  box-shadow: 0 24px 60px -20px rgba(45, 38, 32, 0.35);
  max-width: 480px;
  width: 90vw;
  padding: 0;
  overflow: hidden;
}
.reconnect-card .modal-head {
  padding: 20px 24px 16px;
  border-bottom: 1px solid var(--conn-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.reconnect-card .modal-head h2 {
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 400;
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--conn-text);
}
.reconnect-card .modal-close {
  width: 32px;
  height: 32px;
  border-radius: 99px;
  border: 1px solid var(--conn-border-mid);
  background: transparent;
  color: var(--conn-muted);
  font-size: 14px;
  cursor: pointer;
}
.reconnect-card .modal-close:hover { color: var(--conn-text); border-color: var(--conn-olive); }
.reconnect-body { padding: 22px 24px 24px; }
.reconnect-intro {
  font-size: 14px;
  color: var(--conn-olive);
  line-height: 1.55;
  margin: 0 0 18px;
}
.reconnect-external {
  display: inline-flex;
  margin-bottom: 8px;
}
.reconnect-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 18px 0 14px;
  font-size: 11.5px;
  color: var(--conn-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.reconnect-divider::before,
.reconnect-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--conn-border);
}
.reconnect-field-label {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--conn-muted);
  margin-bottom: 6px;
}
.reconnect-input {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--conn-border-mid);
  border-radius: 10px;
  background: var(--conn-cream);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 12px;
  line-height: 1.5;
  resize: vertical;
  color: var(--conn-text);
  box-sizing: border-box;
}
.reconnect-input:focus { outline: 2px solid var(--brand); outline-offset: -1px; border-color: var(--brand); }
.reconnect-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 14px;
  flex-wrap: wrap;
}
.reconnect-status {
  font-size: 12.5px;
  color: var(--conn-muted);
  font-family: var(--font-heading);
  font-style: italic;
}
.reconnect-status.is-ok { color: #047857; font-style: normal; }
.reconnect-status.is-err { color: #b91c1c; font-style: normal; }

/* Card footer */
.conn-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
.conn-card-meta {
  font-size: 11.5px;
  color: var(--conn-muted);
}
.conn-card-meta b { color: var(--conn-olive); font-weight: 600; }
.conn-card-actions { display: flex; gap: 6px; }
.conn-card-btn {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid var(--conn-border-mid);
  background: transparent;
  color: var(--conn-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-family: inherit;
  text-decoration: none;
}
.conn-card-btn:hover {
  color: var(--brand);
  border-color: var(--brand);
}

/* + Connect another tile at the end of the grid */
.conn-add-tile {
  border: 1px dashed var(--conn-border-mid);
  border-radius: var(--conn-radius);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  min-height: 280px;
  gap: 8px;
  color: var(--conn-muted);
  padding: 24px;
  cursor: pointer;
  background: transparent;
  font-family: inherit;
}
.conn-add-tile:hover {
  border-color: var(--brand);
  color: var(--brand);
  background: rgba(239, 125, 43, 0.03);
}
.conn-add-tile .plus { font-family: var(--font-heading); font-size: 42px; font-weight: 300; line-height: 1; }
.conn-add-tile .ttl { font-family: var(--font-heading); font-style: italic; font-size: 18px; }
.conn-add-tile .desc { font-size: 12.5px; text-align: center; max-width: 240px; line-height: 1.5; }

/* ─── Add-a-connection modal (editorial) ─────────────────────────────
   Restyles the legacy .modal-backdrop / .modal-card surfaces and adds
   conn-modal-tile / conn-modal-badge for the picker grid. Same visual
   language as the inline catalog tiles. */
.modal-backdrop {
  background: rgba(45, 38, 32, 0.40);
  backdrop-filter: blur(4px);
}
.modal-card.modal-card-wide {
  background: var(--conn-surf);
  border: 1px solid var(--conn-border);
  border-radius: var(--conn-radius);
  box-shadow: 0 24px 60px -20px rgba(45, 38, 32, 0.35);
  max-width: 760px;
  padding: 0;
  overflow: hidden;
}
.modal-card.modal-card-wide .modal-head {
  padding: 20px 24px 16px;
  border-bottom: 1px solid var(--conn-border);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.modal-card.modal-card-wide .modal-head h2 {
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 400;
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--conn-text);
}
.modal-card.modal-card-wide .modal-close {
  width: 32px;
  height: 32px;
  border-radius: 99px;
  border: 1px solid var(--conn-border-mid);
  background: transparent;
  color: var(--conn-muted);
  font-size: 14px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 160ms, border-color 160ms;
}
.modal-card.modal-card-wide .modal-close:hover {
  color: var(--conn-text);
  border-color: var(--conn-olive);
}
.modal-card.modal-card-wide .modal-body {
  padding: 22px 24px 26px;
  max-height: 70vh;
  overflow-y: auto;
}
.modal-card.modal-card-wide .catalog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}

.conn-modal-tile {
  display: grid;
  grid-template-columns: 40px 1fr;
  grid-template-rows: auto auto;
  gap: 4px 14px;
  background: var(--conn-surf);
  border: 1px solid var(--conn-border);
  border-radius: 12px;
  padding: 14px 14px 14px 16px;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  position: relative;
  transition: border-color 160ms, background 160ms, transform 160ms;
}
.conn-modal-tile:hover {
  border-color: var(--brand);
  background: var(--brand-soft);
  transform: translateY(-1px);
}
.conn-modal-tile.is-disabled {
  cursor: not-allowed;
  opacity: 0.62;
}
.conn-modal-tile.is-disabled:hover {
  border-color: var(--conn-border);
  background: var(--conn-surf);
  transform: none;
}
.conn-modal-tile-ic {
  grid-row: 1 / span 2;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 17px;
  font-family: var(--font-heading);
  align-self: start;
}
.conn-modal-tile-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; grid-column: 2; }
.conn-modal-tile-nm { font-size: 14px; font-weight: 600; color: var(--conn-text); }
.conn-modal-tile-desc {
  font-size: 12px;
  color: var(--conn-muted);
  line-height: 1.45;
}
.conn-modal-badge {
  align-self: end;
  justify-self: end;
  grid-column: 2;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 99px;
  margin-top: 4px;
}
.conn-modal-badge.is-go {
  background: var(--brand-soft);
  color: var(--brand-deep);
  border: 1px solid var(--brand-border);
}
.conn-modal-badge.is-soon {
  background: var(--conn-surf-2);
  color: var(--conn-muted);
  border: 1px solid var(--conn-border-mid);
}
.conn-modal-badge.is-connected {
  background: #d1fae5;
  color: #047857;
  border: 1px solid #a7f3cf;
}
.conn-modal-tile.is-connected { border-color: #a7f3cf; }
.conn-modal-tile.is-connected:hover { border-color: #047857; background: var(--conn-surf); }

/* Hide the graph view by default — kept around behind #view=web */
.conn-graph-hidden { display: none !important; }
.connections-graph:not(.conn-graph-hidden) {
  display: block;
  background: var(--conn-surf-2);
  border: 1px solid var(--conn-border);
  border-radius: var(--conn-radius);
  position: relative;
  min-height: 640px;
}
.connections-graph #connections-svg {
  width: 100%;
  height: 100%;
  display: block;
}
.connections-graph .graph-controls {
  position: absolute;
  top: 12px;
  right: 12px;
  display: flex;
  gap: 6px;
  z-index: 2;
}
.connections-graph .graph-controls button {
  background: var(--conn-surf);
  border: 1px solid var(--conn-border-mid);
  color: var(--conn-olive);
  font-size: 11.5px;
  padding: 5px 10px;
  border-radius: 99px;
  cursor: pointer;
  font-family: inherit;
}
.connections-graph .graph-controls button:hover {
  border-color: var(--brand);
  color: var(--brand);
}
