/* ============================================================
   Container — shared responsive layout constraint
   Provides 1024px max content width with responsive side padding.
   Import this in any component that uses the .container class.
   ============================================================ */

.container {
  position:   relative;
  width:      100%;
  max-width:  calc(1024px + 160px); /* 1024px content + 80px × 2 */
  padding:    0 80px;
  margin:     0 auto;
  box-sizing: border-box;
}

/* Tablet (≤991px): 60px sides */
@media (max-width: 991px) {
  .container {
    padding: 0 60px;
  }
}

/* Landscape mobile (≤767px): 2rem sides */
@media (max-width: 767px) {
  .container {
    padding: 0 2rem;
  }
}



/* ============================================================
   Wide container — 1360px content + 48px side padding
   Used for full-bleed section content blocks (slider, big cards)
   that need to be wider than the standard 1024px text container.
   ============================================================ */

.container-wide {
  width:      100%;
  max-width:  calc(1384px + 96px);   /* 1384px content + 48px × 2 */
  padding:    0 3rem;                /* 48px sides */
  margin:     0 auto;
  box-sizing: border-box;
}

/* Tablet (≤991px): 16px less than .container (60px → 44px) */
@media (max-width: 991px) {
  .container-wide {
    padding: 0 44px;
  }
}

/* Landscape mobile (≤767px): 16px less than .container (2rem → 1rem) */
@media (max-width: 767px) {
  .container-wide {
    padding: 0 1rem;
  }
}


/* ============================================================
   CaseStudies — Section styles.
   Card (slide) styles live in the CaseStudySlide primitive
   (primitives/CaseStudySlide/CaseStudySlide.css).
   Carousel mechanics live in Carousel/Carousel.css.
   Design tokens are defined in src/styles/tokens.css.
   ============================================================ */

.case-studies {
  background-color: var(--background);
  box-sizing:       border-box;
  display:          flex;
  flex-direction:   column;
  font-family:      var(--font-family-default);
  gap:              4rem;   /* 64px */
  padding:          6rem 0; /* 96px */
  width:            100%;
}

.case-studies[data-spacing="expanded"] {
  padding: 8rem 0; /* 128px */
}

.case-studies[data-variant="partner"] {
  gap: 0;
  padding: 4rem 0;
}

.case-studies__content {
  display:        flex;
  flex-direction: column;
  gap:            4rem; /* 64px */
  width:          100%;
}

/* Bound the sticky rail to the heading instead of the whole section, so the
   badge stops before the full-width carousel begins. This wrapper starts at
   the container's content edge, hence the simpler 100% rail offset. */
.case-studies__header-wrap {
  position: relative;
  width:    100%;
}

.case-studies__header-wrap > .hp-rail {
  right: 100%;
}

@media (min-width: 1480px) {
  .case-studies__header-wrap[data-hp-rail-overflow] > .hp-rail {
    visibility: hidden;
  }

  .case-studies__header-wrap[data-hp-rail-overflow] .hp-badge--inline {
    display: inline-flex;
  }
}

.case-studies__content > .carousel {
  margin-left: calc(50% - 50vw);
  width:       100vw;
}

/* `layout="grid"` — a static row of cards on the container instead of the
   full-bleed carousel track. Two-up, equal heights. Only the ClioCon LP uses
   it (no live page does).

   On phones it becomes a swipe row, as the ClioCon mobile frame draws it: a
   CSS scroll-snap strip with no arrows, the first card on the 16px media
   inset, the next one peeking in from the right edge. The strip bleeds out
   of `.container`'s 2rem mobile padding to BOTH screen edges and pads 16px
   back in (see the ≤767 rule), so cards rest on the 16px inset and scroll
   off the real edge; the last card snaps back to a 16px margin. */
.case-studies__grid {
  display:               grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap:                   var(--spacing-4);   /* 16px */
  align-items:           stretch;
}

@media (max-width: 767px) {
  /* The scroller runs EDGE TO EDGE (the container's 32px cancelled on both
     sides) with 16px of padding, so the cards rest 16px in but scroll off
     the real screen edge. With the scroller starting 16px in, a swiped-past
     card was clipped by a hard line inside the screen (owner, 2026-10-20).
     `scroll-padding` makes the snap land on that same 16px inset. */
  .case-studies__grid {
    display:             flex;
    margin-inline:       -2rem;
    padding-inline:      1rem;
    scroll-padding-inline: 1rem;
    overflow-x:          auto;
    scroll-snap-type:    x mandatory;
    overscroll-behavior-x: contain;
    scrollbar-width:     none;
  }

  .case-studies__grid::-webkit-scrollbar {
    display: none;
  }

  /* Two classes: CaseStudySlide's own `.case-study-card { flex: 1 }` has the
     same single-class weight and can load after this sheet. */
  /* Capped at 400 so a clear part of the NEXT card always shows — the
     usual cue that a row swipes. Full-bleed cards (100% - 2rem) left only a
     32px sliver of it on 600–767 screens (owner, 2026-10-20). At 402 the
     cap doesn't bite: 338, as the mobile frame. */
  .case-studies .case-studies__grid > * {
    flex:              0 0 min(calc(100% - 2rem), 400px);
    scroll-snap-align: start;
  }
}

.case-studies__partner-header {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--spacing-9);
}

.case-studies__partner-header .eyebrow {
  height: 38px;
  padding-block: 1px;
  font-weight: var(--font-weight-medium);
}

/* ============================================================
   Title — bespoke: `title` is a flexible ReactNode (any heading tag,
   not always <h2>), so it can't just be `.hp-heading` on the element
   itself like other sections. This wrapper targets whatever heading
   child is passed and matches .hp-heading's type styles exactly.
   Sits inside `.section-header__text` (see docs/conventions.md →
   "Section header + sticky badge convention"); description uses the
   shared `.hp-body` directly since it's always a plain string.
   ============================================================ */

.case-studies__title > :is(h1, h2, h3, h4, h5, h6, p) {
  color:       var(--foreground);
  display:     block;
  font-size:   2.25rem;     /* 36px */
  font-weight: var(--font-weight-regular);
  line-height: 2.5rem;      /* 40px */
  margin:      0;
}

.case-studies__title > h2 {
  font-weight: var(--font-weight-regular);
}


/* ============================================================
   Mobile landscape (≤767px)
   ============================================================ */

@media (max-width: 767px) {
  .case-studies {
    padding: 4rem 0;
  }

  .case-studies__content {
    gap: 2.25rem; /* 36px — heading group to carousel */
  }

  .case-studies[data-spacing="expanded"] {
    padding: 5rem 0;
  }

  .case-studies[data-variant="partner"] {
    padding: 3rem 0;
  }

  .case-studies__partner-header {
    gap: var(--spacing-6);
  }

  .case-studies__title > :is(h1, h2, h3, h4, h5, h6, p) {
    font-size:   1.875rem;  /* 30px */
    line-height: 2.25rem;   /* 36px */
  }
}

@media (max-width: 479px) {
  .case-studies[data-spacing="expanded"] {
    padding: 4rem 0;
  }
}


/* ============================================================
   Variant: redesign — the new design language
   (docs/redesign-design-language.md). The About page and the ClioCon LP.
   Moved here from AboutCaseStudiesSection.css (2026-10-27, now archived), rules and values
   unchanged; only the scope moved from that page's class to the variant.
   Figma: About v3 7214:10049. Every rule is under
   `.case-studies[data-variant="redesign"]`, so no other variant is touched.
   The slide, carousel and ratings sheets can load after this one, so every
   rule carries at least one more class than the rule it overrides.
   ============================================================ */


/* ---- Section --------------------------------------------- */

/* White ground — the redesign's inversion. `spacing="expanded"` gives Figma's
   128px padding; the cream badge (`.hp-badge--cream`) comes with the variant. */
.case-studies[data-variant="redesign"] {
  background-color: var(--background-white);
}

/* `.case-studies__title > h2` sets 400; the redesign heading is Rowan Light.
   Size (36/40, 30/36 at ≤767) already matches `.hp-heading--serif`. */
.case-studies[data-variant="redesign"] .case-studies__title > h2 {
  font-weight: var(--font-weight-light);
}


/* ---- Carousel on white ----------------------------------- */

/* The carousel's edge fades and nav buttons are painted in `--background`
   (cream) — right on every cream page, a cream strip on this one. */
.case-studies[data-variant="redesign"] .carousel .carousel__overlay:not(.carousel__overlay--left) {
  background: linear-gradient(to right, transparent 0%, var(--background-white) 60%);
}

.case-studies[data-variant="redesign"] .carousel .carousel__overlay--left {
  background: linear-gradient(to left, transparent 0%, var(--background-white) 60%);
}

.case-studies[data-variant="redesign"] .carousel .carousel__nav-btn,
.case-studies[data-variant="redesign"] .carousel .carousel__nav-btn:hover:not(:disabled) {
  background-color: var(--background-white);
}

/* The track's 8px bottom padding is room for card shadows; these cards have
   none, and it pushed the ratings row 8px below Figma's. */
.case-studies[data-variant="redesign"] .carousel .carousel__track {
  padding-bottom: 0;
}

@media (max-width: 767px) {
  .case-studies[data-variant="redesign"] .carousel .carousel__overlay:not(.carousel__overlay--left) {
    background: linear-gradient(to right, transparent 0%, var(--background-white) 50%);
  }

  .case-studies[data-variant="redesign"] .carousel .carousel__overlay--left {
    background: linear-gradient(to left, transparent 0%, var(--background-white) 50%);
  }
}


/* ---- Slides (6947:10260) ---------------------------------- */

/* White on white needs the hairline; Figma's padding is 36 / 32 / 36 / 36. */
.case-studies[data-variant="redesign"] .case-study-card {
  border:  0.5px solid var(--opacity-neutral-40);
  padding: 2.25rem 2rem 2.25rem 2.25rem;
}

/* Button area → quote: 24 here, 32 in the stock slide. */
.case-studies[data-variant="redesign"] .case-study-card .case-study-card__top {
  padding-bottom: 1.5rem;
}

/* Figma sets the mark in Rowan Medium; the hosted faces are Light and
   Semibold, so Semibold is the nearest real weight. 36 tall, level with the
   36px button (the stock mark's 38 made the row 2px taller than Figma's). */
.case-studies[data-variant="redesign"] .case-study-card .case-study-card__quote-mark {
  font-family: var(--font-family-serif);
  font-weight: 600;
  height:      36px;
}

/* The redesign's quote-card text: Rowan Light 24/32 (the stock slide is the
   sans at the same size and weight). Figma's card is `justify-between` with
   the quote sitting directly on the author block, so the free space goes
   ABOVE the quote — the stock slide centres it instead. */
.case-studies[data-variant="redesign"] .case-study-card .case-study-card__quote {
  font-family:   var(--font-family-serif);
  font-weight:   var(--font-weight-light);
  align-content: flex-end;
}

@media (max-width: 767px) {
  .case-studies[data-variant="redesign"] .case-study-card {
    padding: 1.5rem 2rem 2.25rem 2.25rem;
  }
}


/* ---- Ratings row (6947:10295) ----------------------------- */

/* Bare, as LegalHubSocialProofSection strips them: no chip fill, border or
   padding, logo box hugging the mark, 16px logo → stars, Figma's 76.8px
   stars — the LOOK, at every width. */
.case-studies[data-variant="redesign"] .ratings-bar .ratings-bar__item {
  justify-content: flex-start;
  padding:         0;
  gap:             var(--spacing-4);               /* 16px */
  background:      none;
  border:          0;
  border-radius:   0;
}

.case-studies[data-variant="redesign"] .ratings-bar .ratings-bar__meta {
  flex: 0 0 auto;
}

/* Figma's five stars: 12.8px with 3.2px gaps = 76.8px. */
.case-studies[data-variant="redesign"] .ratings-bar .ratings-bar__stars {
  flex:      0 0 auto;
  width:     76.8px;
  max-width: none;
}

/* The LAYOUT, desktop (≥992): Figma's single row, the four groups 64px
   apart, 12px in from the container edge. Below 992 the stock RatingsBar's
   layout applies — two equal columns filling the width, logo over stars at
   ≤479 — with only its gaps opened up for bare marks (owner, 2026-10-20:
   "copy the layout, not the styles"). */
@media (min-width: 992px) {
  .case-studies[data-variant="redesign"] .ratings-bar.ratings-bar {
    grid-template-columns: repeat(4, max-content);
    justify-content:       start;
    gap:                   4rem;                   /* 64px */
    padding-inline:        0.75rem;                /* 12px */
    /* Figma's row is a 16px box (6947:10295) that the 30px marks overflow
       evenly — so the section's 64 / 128 spacing is measured to THAT box. */
    grid-auto-rows:        1rem;
    align-items:           center;
  }

  /* Logo box hugging the mark. Below 992 the stock 64px box stays, so the
     stars line up down each column. */
  .case-studies[data-variant="redesign"] .ratings-bar .ratings-bar__logo {
    width: auto;
  }
}

@media (max-width: 991px) {
  .case-studies[data-variant="redesign"] .ratings-bar.ratings-bar {
    gap: var(--spacing-8) var(--spacing-6);        /* 32px rows / 24px columns */
  }

  /* Each rating centred in its column (owner, 2026-10-20). They are all one
     width — the stock 64px logo box + the 76.8px stars + the score — so
     centring keeps the logos and stars aligned down each column. */
  .case-studies[data-variant="redesign"] .ratings-bar .ratings-bar__item {
    justify-self: center;
  }

  /* …and each mark centred in its 64px box, so the logos stacked in a
     column share one centre line. */
  .case-studies[data-variant="redesign"] .ratings-bar .ratings-bar__logo {
    justify-content: center;
  }
}

/* Portrait phones (≤479): like Figma's mobile row (ClioCon 7399:13876) —
   ONE column, each rating on one line (logo hugging the mark, 16, stars),
   each row centred on its own, rows 20 apart. Deliberately NOT Figma's
   16px row boxes or its larger 16px stars: the owner preferred this look
   (2026-10-20). The stock ≤479 logo-over-stars stack is undone. */
@media (max-width: 479px) {
  .case-studies[data-variant="redesign"] .ratings-bar.ratings-bar {
    grid-template-columns: max-content;
    justify-content:       center;
    gap:                   20px;                   /* Figma; no 20px token */
  }

  .case-studies[data-variant="redesign"] .ratings-bar .ratings-bar__item {
    flex-direction: row;
    align-items:    center;
    padding-bottom: 0;
  }

  .case-studies[data-variant="redesign"] .ratings-bar .ratings-bar__logo {
    flex-grow: 0;
    width:     auto;
  }
}

/* ============================================================
   Carousel — Draggable horizontal scroll carousel
   with accessible nav controls and smooth snap-on-release.

   CSS custom properties (set on .carousel or any ancestor):
     --carousel-gutter   Left padding & overlay width.
                         Default: matches the 1024px container breakpoints.
     --carousel-trail    Right padding — trailing scroll space that lets
                         the last card scroll to the snap start position.
                         Computed dynamically by Carousel.tsx.
   ============================================================ */

.carousel {
  --carousel-gutter: max(80px, calc((100% - 1024px) / 2));
  --carousel-trail:  0px;
  position: relative;
  width:    100%;
}


/* ============================================================
   Scrollable track
   ============================================================ */

@media (pointer: fine) {
  .carousel__track { cursor: grab; }
}

.carousel__track {
  display:             flex;
  gap:                 1rem;    /* 16px — must match CARD_GAP constant in Carousel.tsx */
  overflow-x:          auto;
  padding-bottom:      0.5rem;  /* breathing room so box-shadows aren't clipped */
  padding-left:        var(--carousel-gutter);
  scroll-padding-left: var(--carousel-gutter);
  padding-right:       var(--carousel-trail);
  scroll-snap-type:    x mandatory;
  scrollbar-width:     none;    /* Firefox */
}

.carousel__track::-webkit-scrollbar {
  display: none;                /* Chrome / Safari */
}


/* ---- Slide sizing -----------------------------------------
   Slide width + snap are a carousel concern, so they live here, not on the
   card. Targeted via a descendant selector (not `> *`) because compiled
   Webflow wraps each slide in a `display:contents` code-island element, which
   is not a layout box — only the card itself reliably sizes/snaps in both
   React and Webflow. The card stays width-flexible when used standalone. */
.carousel__track .case-study-card {
  flex:              0 0 36.375rem;   /* 582px */
  scroll-snap-align: start;
}
@media (max-width: 767px) {
  .carousel__track .case-study-card {
    width:100%;
    flex: 0 0 100%;
  }
}


/* ============================================================
   Navigation overlays — sit in the gutter on each side so
   they never cover the container content area.
   ============================================================ */

.carousel__overlay {
  align-items: center;
  bottom:      0;
  display:     flex;
  overflow:    hidden;
  position:    absolute;
  top:         0;
  box-sizing: border-box;
  width:       var(--carousel-gutter);
}

/* Right side — gradient fades left; button centered in gutter */
.carousel__overlay:not(.carousel__overlay--left) {
  background:      linear-gradient(to right, transparent 0%, var(--background) 60%);
  justify-content: center;
  right:           0;
}

/* Left side — gradient fades right; button centered in gutter */
.carousel__overlay--left {
  background:      linear-gradient(to left, transparent 0%, var(--background) 60%);
  justify-content: center;
  left:            0;
}

/* When gutter > 2rem + 40px + 1rem (88px), position button 2rem from the edge */
@media (min-width: 1201px) {
  .carousel__overlay:not(.carousel__overlay--left) {
    justify-content: flex-end;
    padding-right:   2rem;
  }

  .carousel__overlay--left {
    justify-content: flex-start;
    padding-left:    2rem;
  }
}


/* ============================================================
   Nav buttons
   ============================================================ */

.carousel__nav-btn {
  align-items:      center;
  background-color: var(--background);
  border:           1px solid var(--primary);
  border-radius:    var(--radius-full);
  color:            var(--primary);
  cursor:           pointer;
  display:          flex;
  flex-shrink:      0;
  height:           2.5rem;   /* 40px */
  justify-content:  center;
  transform:        translateX(0);
  transition:       border-color     120ms ease,
                    color            120ms ease,
                    opacity          200ms ease,
                    transform        200ms ease;
  width:            2.5rem;
}

.carousel__nav-btn:hover:not(:disabled) {
  background-color: var(--background);
  border-color: color-mix(in srgb, var(--primary) 80%, #282825 20%);
  color:        color-mix(in srgb, var(--primary) 80%, #282825 20%);
}

/* Left button slides out to the left when at the start */
.carousel__overlay--left .carousel__nav-btn:disabled {
  opacity:   0;
  transform: translateX(-100%);
}

/* Right button slides out to the right when at the end */
.carousel__overlay:not(.carousel__overlay--left) .carousel__nav-btn:disabled {
  opacity:   0;
  transform: translateX(100%);
}

.carousel__nav-btn svg {
  display: block;
  height:  1rem;
  width:   1rem;
}


/* ============================================================
   Visually hidden — accessible to screen readers only
   ============================================================ */

.sr-only {
  clip:        rect(0 0 0 0);
  clip-path:   inset(50%);
  height:      1px;
  overflow:    hidden;
  position:    absolute;
  white-space: nowrap;
  width:       1px;
}


/* ============================================================
   Responsive gutter overrides — mirror container.css breakpoints
   ============================================================ */

@media (max-width: 991px) {
  .carousel { --carousel-gutter: 60px; }

}

@media (max-width: 767px) {
  .carousel { --carousel-gutter: 48px; }

  .carousel__track { padding-right: var(--carousel-gutter); }

  .carousel__nav-btn {
    height: 2rem;
    width:  2rem;
  }

  /* Gradient spans 24px — 50% of the 48px gutter */
  .carousel__overlay:not(.carousel__overlay--left) {
    background: linear-gradient(to right, transparent 0%, var(--background) 50%);
  }

  .carousel__overlay--left {
    background: linear-gradient(to left, transparent 0%, var(--background) 50%);
  }
}

@media (max-width: 479px) {
  .carousel { --carousel-gutter: 48px; }
}

/* ============================================================
   IconBadge — Small circular icon container
   ============================================================ */

.icon-badge {
  display:         flex;
  align-items:     center;
  justify-content: center;
  width:           1.625rem;  /* 26px */
  height:          1.625rem;
  border-radius:   var(--radius-full);
  flex-shrink:     0;
  color:           var(--foreground);
}

/* ---- Size ------------------------------------------------- */

.icon-badge[data-size="md"] { width: 2rem; height: 2rem; }  /* 32px */

@media (max-width: 767px) {
  .icon-badge[data-mobile-size="sm"] { width: 1.625rem; height: 1.625rem; }
}


/* ---- Typography ------------------------------------------- */

.icon-badge[data-typography="label"] {
  font-size:   var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-xs);
}


/* ---- Color variants --------------------------------------- */

.icon-badge[data-variant="card"]        { background: var(--card); }
.icon-badge[data-variant="bg"]          { background: var(--background); }
.icon-badge[data-variant="teal"]        { background: color-mix(in srgb, var(--color-brand-blue-400) 40%, transparent); }
.icon-badge[data-variant="teal-active"] { background: color-mix(in srgb, var(--color-brand-blue-400) 60%, var(--background)); }

/* ============================================================
   Eyebrow — icon + label kicker. See Eyebrow.tsx.
   ============================================================ */

.eyebrow {
  display:      inline-flex;
  align-items:  center;
  gap:          0.5rem;            /* 8px */
  height:       36px;
  padding:      5px 0;
  width:        fit-content;       /* never stretch in a column-flex parent */
  font-size:    var(--font-size-sm);
  line-height:  var(--line-height-sm);
  font-weight:  var(--font-weight-regular);
  color:        var(--muted-foreground);
  white-space:  nowrap;
  box-sizing:   border-box;
}

.eyebrow[data-variant="active"] {
  color:       var(--foreground);
  font-weight: var(--font-weight-medium);
}

/* ============================================================
   RatingsBar — internal shared rating pills strip
   ============================================================ */

.ratings-bar {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 1fr;
  gap: 12px;
}

.ratings-bar--grid-2-col {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.ratings-bar__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-3);
  min-width: 0;
  padding: 1.5rem;
  background: var(--secondary);
  border: 0.5px solid var(--border);
  border-radius: 1.5rem;
  box-sizing: border-box;
}

.ratings-bar__logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  width: 64px;
}

.ratings-bar__meta {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--spacing-2);
  flex: 1 1 0;
  min-width: 0;
}

.ratings-bar__stars {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  align-items: center;
  gap: 4.16%;
  color: var(--primary);
  flex: 1 1 0;
  max-width: 96px;
}

.ratings-bar__star {
  display: block;
  min-width: 0;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
}

.ratings-bar__score {
  width: 1.25rem;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-xs);
  color: var(--muted-foreground);
  text-align: center;
}

.ratings-bar__brand-img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: 100%;
  object-fit: contain;
}

@media (max-width: 991px) {
  .ratings-bar--strip {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 479px) {
  .ratings-bar__item {
    flex-direction: column;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--spacing-4);
    height: auto;
    padding-bottom: 2rem;
  }

  .ratings-bar__logo {
    flex-grow: 1;
  }

  .ratings-bar__meta {
    justify-content: flex-start;
    flex: unset;
  }
}

/* ============================================================
   Button — Component Styles
   Scheme-aware: inherits data-scheme from a parent element.
   All color tokens flip automatically in dark context.
   ============================================================ */

.btn {
  /* Layout */
  align-items:      center;
  border:           1px solid transparent;
  box-sizing:       border-box;
  cursor:           pointer;
  display:          inline-flex;
  flex-shrink:      0;
  justify-content:  center;
  overflow:         hidden;
  text-decoration:  none;
  user-select:      none;
  white-space:      nowrap;
  background-clip:  padding-box;

  /* Typography */
  font-family: var(--font-family-default);
  font-weight: var(--font-weight-medium);

  /* Transition */
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease, opacity 120ms ease;
}


/* ============================================================
   Sizes
   Heights: xs=26px  sm=32px  md=36px  lg=40px
   All use font-size-sm (14px) except xs which uses font-size-xs (12px).
   ============================================================ */

.btn[data-size="xs"] {
  font-size:   var(--font-size-xs);      /* 12px */
  line-height: var(--line-height-xs);    /* 16px */
  gap:         0.25rem;                  /* 4px  */
  padding:     0.3125rem 0.75rem;        /* 5px 12px → height 26px */
  --btn-gap:   0.25rem;
}

.btn[data-size="sm"] {
  font-size:   var(--font-size-sm);      /* 14px */
  line-height: var(--line-height-sm);    /* 20px */
  gap:         0.375rem;                 /* 6px  */
  padding:     0.375rem 1rem;            /* 6px 16px → height 32px */
  --btn-gap:   0.375rem;
}

.btn[data-size="md"] {
  font-size:   var(--font-size-sm);      /* 14px */
  line-height: var(--line-height-sm);    /* 20px */
  gap:         0.375rem;                 /* 6px  */
  padding:     0.5rem 1rem;              /* 8px 16px → height 36px */
  --btn-gap:   0.375rem;
}

.btn[data-size="lg"] {
  font-size:   var(--font-size-sm);      /* 14px */
  line-height: var(--line-height-sm);    /* 20px */
  gap:         0.5rem;                   /* 8px  */
  padding:     0.625rem 1.5rem;          /* 10px 24px → height 40px */
  --btn-gap:   0.5rem;
}

.btn[data-icon-only="true"] {
  padding: 0;
}

.btn[data-size="xs"][data-icon-only="true"] {
  width:  1.625rem; /* 26px */
  height: 1.625rem;
}

.btn[data-size="sm"][data-icon-only="true"] {
  width:  2rem; /* 32px */
  height: 2rem;
}

.btn[data-size="md"][data-icon-only="true"] {
  width:  2.25rem; /* 36px */
  height: 2.25rem;
}

.btn[data-size="lg"][data-icon-only="true"] {
  width:  2.5rem; /* 40px */
  height: 2.5rem;
}


/* ============================================================
   Shapes
   ============================================================ */

.btn[data-shape="rounded"] { border-radius: var(--radius-sm);   } /* 8px  */
.btn[data-shape="round"]   { border-radius: var(--radius-full); } /* pill */


/* ============================================================
   Variants
   ============================================================ */

.btn[data-variant="primary"][data-tone="default"] {
  background-color: var(--primary);
  border-color:     var(--primary);
  color:            var(--primary-foreground);
}

.btn[data-variant="secondary"][data-tone="default"] {
  background-color: transparent;
  border-color:     var(--primary);
  color:            var(--primary);
}

.btn[data-variant="primary"][data-tone="accent"] {
  background-color: var(--accent);
  border-color:     var(--accent);
  color:            var(--foreground);
}

.btn[data-variant="secondary"][data-tone="accent"] {
  background-color: transparent;
  border-color:     var(--accent);
  color:            var(--accent);
}


.btn[data-variant="info"] {
  background-color: var(--info);
  border-color:     var(--info);
  color:            var(--info-foreground);
}

.btn[data-variant="success"] {
  background-color: var(--success);
  border-color:     var(--success);
  color:            var(--success-foreground);
}

.btn[data-variant="warning"] {
  background-color: var(--warning);
  border-color:     var(--warning);
  color:            var(--warning-foreground);
}

.btn[data-variant="destructive"] {
  background-color: var(--destructive);
  border-color:     var(--destructive);
  color:            var(--destructive-foreground);
}


/* ============================================================
   States
   ============================================================ */

/* Primary hover — 20% dark overlay on background, full opacity */
.btn[data-variant="primary"][data-tone="default"]:hover:not(:disabled):not([aria-disabled="true"]) {
  background-color: color-mix(in srgb, var(--primary) 80%, #282825 20%);
  border-color:     color-mix(in srgb, var(--primary) 80%, #282825 20%);
  opacity:          1;
}

.btn[data-variant="primary"][data-tone="accent"]:hover:not(:disabled):not([aria-disabled="true"]) {
  background-color: color-mix(in srgb, var(--accent) 80%, transparent);
  border-color:     color-mix(in srgb, var(--accent) 80%, transparent);
  opacity:          1;
}

/* Secondary hover — darker primary border + text, no fill */
.btn[data-variant="secondary"][data-tone="default"]:hover:not(:disabled):not([aria-disabled="true"]) {
  border-color: color-mix(in srgb, var(--primary) 80%, #282825 20%);
  color:        color-mix(in srgb, var(--primary) 80%, #282825 20%);
  opacity:      1;
}

.btn[data-variant="secondary"][data-tone="accent"]:hover:not(:disabled):not([aria-disabled="true"]) {
  border-color: color-mix(in srgb, var(--accent) 80%, transparent);
  color:        color-mix(in srgb, var(--accent) 80%, transparent);
  opacity:      1;
}

.btn[data-variant="info"]:hover:not(:disabled):not([aria-disabled="true"]) {
  background-color: color-mix(in srgb, var(--info) 80%, #282825 20%);
  border-color:     color-mix(in srgb, var(--info) 80%, #282825 20%);
  color:            var(--info-foreground);
  opacity:          1;
}

.btn[data-variant="success"]:hover:not(:disabled):not([aria-disabled="true"]) {
  background-color: color-mix(in srgb, var(--success) 80%, #282825 20%);
  border-color:     color-mix(in srgb, var(--success) 80%, #282825 20%);
  color:            var(--success-foreground);
  opacity:          1;
}

.btn[data-variant="warning"]:hover:not(:disabled):not([aria-disabled="true"]) {
  background-color: color-mix(in srgb, var(--warning) 80%, #282825 20%);
  border-color:     color-mix(in srgb, var(--warning) 80%, #282825 20%);
  color:            var(--warning-foreground);
  opacity:          1;
}

.btn[data-variant="destructive"]:hover:not(:disabled):not([aria-disabled="true"]) {
  background-color: color-mix(in srgb, var(--destructive) 80%, #282825 20%);
  border-color:     color-mix(in srgb, var(--destructive) 80%, #282825 20%);
  color:            var(--destructive-foreground);
  opacity:          1;
}

/* Active / pressed */
.btn:active:not(:disabled):not([aria-disabled="true"]) {
  opacity: 0.76;
}

/* Focus */
.btn:focus-visible {
  outline:        2px solid var(--ring);
  outline-offset: 2px;
}

/* Disabled */
.btn:disabled,
.btn[aria-disabled="true"] {
  cursor:         not-allowed;
  opacity:        0.4;
  pointer-events: none;
}


/* ============================================================
   Icon slot
   ============================================================ */

.btn__icon {
  align-items:     center;
  display:         inline-flex;
  flex-shrink:     0;
  justify-content: center;
}

.btn[data-size="xs"] .btn__icon:not(.btn__icon--hover-only) { height: 0.75rem; width: 0.75rem; } /* 12px */
.btn[data-size="sm"] .btn__icon:not(.btn__icon--hover-only),
.btn[data-size="md"] .btn__icon:not(.btn__icon--hover-only),
.btn[data-size="lg"] .btn__icon:not(.btn__icon--hover-only) { height: 1rem;    width: 1rem;    } /* 16px */

.btn__icon svg {
  display: block;
  height:  100%;
  width:   100%;
}


/* ============================================================
   Hover-only icon — hidden by default, slides/fades in on :hover.
   Negative margin-right cancels the flex gap when collapsed so
   the label stays flush with the padding edge.
   ============================================================ */

/* Must come after the .btn[data-size] .btn__icon rules to win specificity tie */
.btn .btn__icon--hover-only {
  min-width:    0;        /* override flex min-width: auto so item can truly collapse */
  width:        0;
  overflow:     hidden;
  opacity:      0;
  margin-right: calc(-1 * var(--btn-gap, 0.5rem));
  transition:   width 0.2s ease, opacity 0.15s ease, margin-right 0.2s ease;
}

.btn:hover:not(:disabled):not([aria-disabled="true"]) .btn__icon--hover-only {
  width:        1rem; /* sm / md / lg */
  height:       1rem;
  opacity:      1;
  margin-right: 0;
}

.btn[data-size="xs"]:hover:not(:disabled):not([aria-disabled="true"]) .btn__icon--hover-only {
  width:  0.75rem;
  height: 0.75rem;
}


/* ============================================================
   Badge slot — optional count pill inside the button
   ============================================================ */

.btn__badge {
  align-items:      center;
  background-color: var(--primary);
  border-radius:    var(--radius-full);
  color:            var(--primary-foreground);
  display:          inline-flex;
  font-size:        var(--font-size-xs);   /* 12px */
  font-weight:      var(--font-weight-medium);
  justify-content:  center;
  line-height:      var(--line-height-xs); /* 16px */
  min-width:        1.25rem;               /* 20px */
  padding:          0.125rem 0.375rem;     /* 2px 6px */
}

/* ============================================================
   CaseStudySlide — Individual testimonial card styles.
   Used inside the Carousel primitive.
   ============================================================ */

.case-study-card {
  background-color: var(--card);
  border-radius:    var(--radius-lg);   /* 24px */
  box-sizing:       border-box;
  display:          flex;
  flex:             1;   /* expand to fill its flex track by default; height follows content */
  flex-direction:   column;
  justify-content:  space-between;
  overflow:         hidden;
  padding:          2.25rem;
}
/* Slide width + scroll-snap are a carousel concern — applied by Carousel.css
   (`.carousel__track .case-study-card`, which overrides the flex above).
   Standalone cards stay flexible. */


/* ---- Top row: quote mark + CTA ---- */
.case-study-card__top {
  align-items:     flex-start;
  display:         flex;
  justify-content: space-between;
  padding-bottom:  2rem;      /* 32px */
  width:           100%;
}
/* No quote-mark → keep the CTA right-aligned. */
.case-study-card--no-quote-mark .case-study-card__top {
  justify-content: flex-end;
}


/* ---- Optional result / stat line ---- */
.case-study-card__result {
  margin:      0;
  font-size:   var(--font-size-xl);
  line-height: var(--line-height-xl);
  color:       var(--popover-foreground);
}

/* With a result line, the card uses the Figma stack rhythm: 24px between
   button-area / result / quote, and a slightly tighter right padding.
   (Carousel cards have no result and keep the space-between layout.) */
.case-study-card--with-result {
  gap:           1.5rem;   /* 24px */
}
/* Top-align the quote text (default variant centers it within the flex-grown
   paragraph). */
.case-study-card--with-result .case-study-card__quote {
  align-content: flex-start;
}

.case-study-card__quote-mark {
  color:       var(--border);           /* #D6CFC2 — extra-muted-foreground */
  font-size:   3rem;                    /* 48px */
  font-weight: var(--font-weight-bold);
  line-height: 1;
  height:      38px;
}


/* ---- Body: quote + author ---- */
.case-study-card__body {
  display:        flex;
  flex-direction: column;
  gap:            2.25rem;    /* 36px */
  flex: 1 0 0;
}

.case-study-card__quote {
  color:       var(--foreground);
  font-size:   1.5rem;        /* 24px */
  font-weight: 300;           /* Light — no token exists yet */
  line-height: 2rem;          /* 32px */
  margin:      0;
  flex: 1 0 0;
  display: flex;
  align-content: center;
  flex-wrap: wrap;
}

.case-study-card__author-group {
  align-items: center;
  display:     flex;
  gap:         0.75rem;       /* 12px */
}

.case-study-card__avatar {
  background-color: var(--opacity-primary-20);
  border-radius:    var(--radius-full);
  flex-shrink:      0;
  height:           3rem;     /* 48px */
  overflow:         hidden;
  width:            3rem;
}

.case-study-card__avatar img {
  display:    block;
  height:     100%;
  object-fit: cover;
  width:      100%;
}

.case-study-card__author-meta {
  display:        flex;
  flex-direction: column;
  gap:            0;
}

.case-study-card__author-name {
  color:       var(--foreground);
  font-size:   var(--font-size-base);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-base);
  white-space: nowrap;
}

.case-study-card__author-role {
  color:       var(--muted-foreground);
  font-size:   var(--font-size-base);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-base);
}


/* ---- Size variant: lg (bigger avatar, smaller author type) ---- */
.case-study-card--lg .case-study-card__avatar {
  width:  60px;
  height: 60px;
}
.case-study-card--lg .case-study-card__author-name,
.case-study-card--lg .case-study-card__author-role {
  font-size:   var(--font-size-sm);
  line-height: var(--line-height-sm);
}


/* ============================================================
   Mobile landscape (≤767px)
   ============================================================ */

@media (max-width: 767px) {
  .case-study-card {
    padding: 1.5rem 2.25rem 2.25rem 2.25rem;
  }

  .case-study-card__quote {
    font-size:   1.25rem;   /* 20px */
    line-height: 1.75rem;   /* 28px */
  }

  .case-study-card__author-name,
  .case-study-card__author-role {
    font-size:   0.75rem;   /* 12px */
    line-height: 1rem;      /* 16px */
  }
}


/* ---- Optional author-row chip (`tag`) ----------------------
   Added for the Legal Hub case-study carousel, where each quote carries the
   attorney's practice area. Absent by default, so every existing consumer
   renders byte-identically. Pushed to the end of the row so it sits opposite
   the author no matter how long the name/firm run. */
.case-study-card__tag {
  display:         inline-flex;
  align-items:     center;
  gap:             var(--spacing-2);
  margin-left:     auto;
  flex-shrink:     0;
  padding:         var(--spacing-2) var(--spacing-3);
  background:      var(--secondary);
  border-radius:   var(--radius-full);
  font-size:       var(--font-size-sm);
  line-height:     var(--line-height-sm);
  font-weight:     var(--font-weight-regular);
  color:           var(--muted-foreground);
  white-space:     nowrap;
}

@media (max-width: 767px) {
  /* The chip is `nowrap` + `flex-shrink: 0` (its label must never break
     mid-word), so in a narrow card it ran past the card's edge and got
     clipped. Below 768 it moves to its own line under the author.

     Deliberately a BREAKPOINT rule, not `flex-wrap: wrap` on its own: with
     plain wrapping each slide would decide for itself, so a short label
     ("Family law") stayed inline while a long one ("Criminal defense") dropped
     — and in a carousel the author row has to sit at the same place on every
     slide. `flex-basis: 100%` forces the break for all of them, and
     `margin-left: 0` overrides the desktop `auto` that would otherwise strand
     the chip against the right edge on its own line.

     Scoped with `:has()` so only consumers that pass a `tag` gain wrapping;
     every other card keeps its existing single-line row. */
  .case-study-card__author-group:has(.case-study-card__tag) {
    display:               grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap:            0.75rem;   /* 12px — the flex row's gap */
    row-gap:               0.75rem;
    align-items:           center;
  }

  .case-study-card__author-group:has(.case-study-card__tag) .case-study-card__tag {
    grid-column:  1 / -1;
    /* Hugs its label instead of stretching across the card. */
    justify-self: start;
    /* Cancels the desktop `auto`, which on its own row would strand the chip
       against the right edge. */
    margin-left:  0;
  }
}

