/* ============================================================================
   CRM SHOWCASE — the carousel of real app screenshots.
   Markup: templates/public/_crm_showcase.html.jinja2 · behaviour: js/crm_showcase.js

   🔴 THIS FILE EXISTS BECAUSE THE STYLES WERE TRAPPED IN ONE PAGE. They lived inline in
   `public/brokers.html.jinja2`'s head, so the showcase partial could only ever be included on
   that one page — include it anywhere else and you got unstyled figures in a vertical stack.
   Paul asked for the CRM carousel on the ROOT landing page (2026-08-18), which is what forced
   the extraction. Shared file, linked by both pages, one place to change.

   The base layer is a native scroll-snap strip: swipe on a phone, trackpad or shift-scroll on a
   desktop. Everything the JS adds — arrows, dots — is CHROME ON TOP. Without JS the strip still
   works, which is why the arrows ship `hidden` and are revealed by script rather than being
   drawn here and left dead.
   ============================================================================ */

.ms-gal-hint {
  display: flex; align-items: center; justify-content: center; gap: .4rem;
  font-size: .8rem; color: var(--bs-secondary-color, #6b7280); margin-bottom: .6rem;
}
.ms-gal {
  display: flex; gap: 1.1rem; overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; scroll-padding-inline: 1rem;
  padding: .5rem .35rem 1.2rem; margin-inline: -.35rem;
  -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.ms-gal:focus-visible { outline: 2px solid var(--pa-primary, #009A44); outline-offset: 4px; border-radius: 12px; }
.ms-gal::-webkit-scrollbar { height: 8px; }
.ms-gal::-webkit-scrollbar-thumb { background: #cfd4da; border-radius: 999px; }
.ms-shot { flex: 0 0 auto; width: min(300px, 82vw); margin: 0; scroll-snap-align: center; }
/* The POSTER: headline on the card, device angled into it and cropped by the card edge —
   the App Store product-shot convention (Paul sent the Salesforce listing as the reference).
   The card does the selling; the device is the evidence. */
.ms-poster {
  position: relative; height: 470px; overflow: hidden; border-radius: 20px;
  padding: 1.15rem 1rem 0; display: flex; flex-direction: column;
  background: linear-gradient(165deg, #ffffff 0%, var(--pa-primary-100, #E3F7EC) 100%);
  border: 1px solid #e3e7ea; box-shadow: 0 10px 30px rgba(16,24,40,.10);
}
.ms-poster__h {
  font-family: var(--pa-font-serif); font-size: 1.22rem; font-weight: 700; line-height: 1.2;
  letter-spacing: -.01em; color: #16241d; text-align: center;
  margin: 0 0 .85rem; flex: 0 0 auto;
  /* 🔴 RESERVE TWO LINES WHATEVER THE TITLE. The gallery is a horizontal row, so the eye reads
     the phone tops as one line — and a title that wraps ("The whole brief, one sentence")
     pushed its device down while its single-line neighbours stayed up, which reads as broken
     rather than as a longer title. Reserving 2 lines (2 x line-height 1.2) aligns every device
     to the same baseline and, unlike shortening the copy, keeps working when a future title
     wraps too. Centring the text inside the reserved box keeps a one-line title optically
     correct rather than stuck to the top of a tall box. */
  min-height: 2.4em;
  display: flex; align-items: center; justify-content: center;
}
/* 🔴 STRAIGHT, CENTRED, AND CROPPED ONLY AT THE FOOT.
   The first attempt tilted the device (rotate(-5deg)) and oversized it past both edges
   (width:116%; margin-inline:-8%). Three things went wrong and all three are visible in a
   screenshot: the left crop ate the start of every line, so the title read "y Day" and the
   avatar column was sliced; `margin-top:auto` pushed the device to the foot and left a dead
   void under the headline; and the tilt cost legibility on 10px UI text, which a photographed
   phone does not suffer because it has real perspective and scale.
   A flat CSS rotate of a small interface just reads as skew. So: no rotation, full width inside
   the padding, and `flex:1` so it FILLS the space rather than sitting at the bottom of it. The
   product-shot feel comes from the negative bottom margin alone — the screen runs off the card,
   which is the bit that actually sells it. */
.ms-device {
  flex: 1 1 auto; min-height: 0; width: 100%; margin: 0 0 -2.4rem;
  background: #f4f4f5; border-radius: 20px 20px 6px 6px; overflow: hidden;
  border: 7px solid #12151a; border-bottom: 0;
  box-shadow: 0 16px 38px rgba(16,24,40,.24);
  display: flex; flex-direction: column;
}
/* The screenshot is a tall phone capture (390x844 at 3x). It fills the device width and is
   cropped at the FOOT by the poster — object-position:top so the crop always takes the bottom,
   never the header. object-fit:cover would zoom; contain would letterbox. This is neither: the
   image is exactly the frame's width and simply runs past its bottom edge. */
.ms-device img {
  display: block; width: 100%; height: auto; border-radius: 13px 13px 0 0;
}
/* ---- Not-built-yet panel. Same poster, obviously NOT a screenshot: no device frame, no
   invented UI. If it looked like a screen it would be a lie about what ships today. ---- */
.ms-poster--soon {
  background: linear-gradient(165deg, #ffffff 0%, #f1f3f5 100%);
  border-style: dashed; border-color: #cfd6dd;
}
.ms-soon {
  flex: 1 1 auto; display: flex; flex-direction: column; align-items: center;
  justify-content: center; text-align: center; gap: .55rem; padding: 0 .4rem 2.2rem;
}
.ms-soon > i { font-size: 2.6rem; color: var(--pa-primary, #009A44); opacity: .85; }
.ms-soon__tag {
  font-size: .68rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
  color: var(--pa-primary-700, #007A35); background: var(--pa-primary-100, #E3F7EC);
  border: 1px solid rgba(0,154,68,.3); border-radius: 999px; padding: .22rem .7rem;
}
.ms-soon p { font-size: .86rem; line-height: 1.5; color: #4b5563; margin: 0; max-width: 17rem; }
.ms-shot figcaption { margin-top: .85rem; font-size: .84rem; line-height: 1.45; color: #4b5563; }
/* Alternate the tint so eight cards in a row do not read as one block. */
.ms-shot:nth-child(even) .ms-poster {
  background: linear-gradient(165deg, #ffffff 0%, #eaf0f7 100%);
}

/* ============================================================================
   CAROUSEL CHROME — arrows and dots, added for the root landing page.

   🔴 A SCROLL STRIP IS DISCOVERABLE ON A PHONE AND INVISIBLE ON A DESKTOP. Paul's ask was a
   "carousel of images" on the DESKTOP landing page, and the reason that wording matters is that
   swipe is a thumb gesture: a laptop visitor with a mouse sees four cards, no scrollbar worth
   noticing, and no reason to believe there is a fifth. Arrows say there is more. So the arrows
   are shown from the breakpoint where a pointer is likely and the strip stops being swiped.
   ============================================================================ */
.ms-carousel { position: relative; }
.ms-carousel__btn {
  position: absolute; top: calc((470px / 2) + .5rem); transform: translateY(-50%);
  z-index: 3; display: none;                 /* revealed by js/crm_showcase.js */
  width: 2.75rem; height: 2.75rem; border-radius: 999px;
  background: #fff; border: 1px solid #d8dee4; color: #16241d;
  box-shadow: 0 6px 18px rgba(16,24,40,.16);
  align-items: center; justify-content: center; font-size: 1.15rem; line-height: 1;
  cursor: pointer; transition: box-shadow .18s ease, transform .18s ease, opacity .18s ease;
}
.ms-carousel__btn:hover:not(:disabled) { box-shadow: 0 10px 26px rgba(16,24,40,.22); transform: translateY(-50%) scale(1.06); }
.ms-carousel__btn:focus-visible { outline: 2px solid var(--pa-primary, #009A44); outline-offset: 3px; }
/* 🔴 DISABLED, NOT REMOVED. At either end the arrow greys out and stays put — a control that
   vanishes shifts the other one sideways, and the visitor reads that as the page glitching. */
.ms-carousel__btn:disabled { opacity: .35; cursor: default; box-shadow: none; }
/* 🔴 LOGICAL, NOT left/right — the arrows have to swap sides in Arabic or "previous" points forwards.
   inset-inline-start/end follow `dir`, so one rule is correct in both. */
.ms-carousel__btn--prev { inset-inline-start: -.5rem; }
.ms-carousel__btn--next { inset-inline-end: -.5rem; }
/* 🔴 THE ROOM HAS TO BE MADE, NOT ASSUMED. The first version pulled the buttons to `left:-1.35rem`
   with a comment claiming they sat "outside the cards" — but `.ms-gal` fills its container, so from
   992px up each button overlapped the edge poster by ~22px and clipped the phone frame beneath it. On
   a page whose argument is "these are real screens", an arrow parked on top of one is the worst
   possible place to put it.

   So the carousel reserves its own gutters and the buttons sit IN them, flush to the padding edge. */
@media (min-width: 992px) {
  .ms-carousel--ready { padding-inline: 3.25rem; }
  .ms-carousel--ready .ms-carousel__btn { display: flex; }
  .ms-carousel--ready .ms-gal-hint { display: none; }   /* the arrows ARE the hint */
  .ms-carousel__btn--prev { inset-inline-start: 0; }
  .ms-carousel__btn--next { inset-inline-end: 0; }
}
.ms-carousel__dots {
  display: none; justify-content: center; align-items: center; gap: .4rem; margin-top: .1rem;
}
.ms-carousel--ready .ms-carousel__dots { display: flex; }
/* 🔴 AN 8px DOT IS A VISUAL, NOT A TAP TARGET. The dots have no breakpoint — unlike the arrows they
   show on phones, where mobile-friendly is a hard rule and a thumb needs ~44px. So the BUTTON is 44px
   and transparent, and the dot is drawn inside it with ::before. Ten cards then give ten reachable
   targets rather than ten near-misses. */
.ms-carousel__dot {
  width: 2.75rem; height: 2.75rem; padding: 0; border: 0; background: none;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.ms-carousel__dot::before {
  content: ""; display: block;
  width: .5rem; height: .5rem; border-radius: 999px; background: #cfd6dd;
  transition: background .18s ease, width .18s ease;
}
.ms-carousel__dot[aria-current="true"]::before {
  background: var(--pa-primary, #009A44); width: 1.4rem;
}
.ms-carousel__dot:focus-visible { outline: 2px solid var(--pa-primary, #009A44); outline-offset: -6px; border-radius: 999px; }
/* The 44px buttons would otherwise sit a finger apart. Overlap them; the visual gap is the dot's. */
.ms-carousel__dots { gap: 0; margin-top: -.35rem; }

/* ---- feature tiles under the strip ---- */
.ms-crm-feat {
  background: #fff; border: 1px solid var(--bs-border-color, #e5e7eb); border-radius: 14px;
  padding: 1.1rem 1.15rem; box-shadow: 0 1px 2px rgba(0,0,0,.04);
  transition: box-shadow .2s ease, transform .2s ease;
}
.ms-crm-feat:hover { box-shadow: 0 10px 30px rgba(0,0,0,.08); transform: translateY(-2px); }
.ms-crm-feat > i { font-size: 1.35rem; color: var(--pa-primary, #009A44); }
.ms-crm-feat h3 { font-size: 1rem; font-weight: 700; margin: .5rem 0 .3rem; color: #1f2a24; font-family: var(--pa-font-serif); }
.ms-crm-feat p { font-size: .88rem; line-height: 1.5; color: #4b5563; margin: 0; }

@media (prefers-reduced-motion: reduce) {
  .ms-gal { scroll-behavior: auto; }
  .ms-crm-feat, .ms-carousel__btn, .ms-carousel__dot::before { transition: none; }
  .ms-crm-feat:hover { transform: none; }
  .ms-carousel__btn:hover:not(:disabled) { transform: translateY(-50%); }
}
