/* SERVICE-CARD LAYOUTS — the reusable Services module, shared by the design lab
   (/service-cards/), the dashboard picker, and the public vendor page. Every
   style renders the SAME markup and differs only in CSS, so a block swaps look
   by its `.sc-*` class alone — the same discipline as faq_layouts.css /
   pricing_layouts.css.

   Markup: .services.sc-* > .service-list > .service >
           .service-img + .service-index + .service-body >
           (.service-eyebrow + .service-name + .service-desc)

   Every color/font is driven through the vendor's theme via the --sc-* palette
   variables, set on the .services element by Agent.offerings_style on the public
   page (mirrors Agent.faq_style). Service cards carry NO price — just an eyebrow,
   a name, a description, and an optional scheme-recoloring image block.

   ---------------------------------------------------------------------------
   TYPE: Zulli Typography Kit v1.0. Three rules from the kit decide everything
   below, and they are the reason this file was retuned:

   1. Card type is FIXED px, not cqi. --type-h3 / --type-body-sm / --type-label
      are fixed steps in the kit. Sizing them in cqi off .services meant every
      step pinned to the top of its clamp the moment the section broke out to
      1024px on desktop — the whole block rendered a size too large. Only
      display-level type (see .sc-editorial) stays fluid.
   2. The card name takes the --type-h3 SIZE (18px) but keeps the vendor's
      display face. The kit's "display stops at level two" rule is about
      Fraunces inside Zulli's own product UI; on the vendor page --sc-hf is the
      vendor's own brand face, and stripping it out of the services block is not
      what that rule is for. .sc-editorial goes further and scales, because its
      heading is a genuine display moment.
   3. Eyebrows, badges and indices are mono (--sc-mf), never bold sans.

   SPACING: the kit's --space-* tokens are not (yet) defined on the public
   vendor page, so each is referenced with its own kit value as the fallback.
   When the tokens do land globally they win automatically, with no edit here.

   RADIUS: --sc-radius carries the vendor's corner_style (2px sharp / 14px
   rounded), the same way --he-radius does for the hero. This file used to
   hardcode 14px, i.e. every vendor got rounded corners whether they picked them
   or not. The 6px fallback is the kit's --radius-lg, for the lab and the
   dashboard picker where no vendor theme is emitted. */

.services {
  /* The card type is fixed px and no longer reads this container. It stays for
     .sc-editorial, the one style whose heading is display type and therefore
     still scales — without it that clamp's cqi has no container to resolve
     against and silently falls back to the viewport. */
  container-type: inline-size;
  font-family: var(--sc-bf, 'Inter', system-ui, sans-serif);
  color: var(--sc-ink, #1a1a1f);

  --sc-r: var(--sc-radius, 6px);
  --sc-gap: var(--space-md, clamp(16px, 2vw, 24px));
  --sc-pad: var(--space-md, clamp(16px, 2vw, 24px));
  --sc-row: var(--space-sm, clamp(12px, 1.4vw, 16px));
  --sc-eb-gap: var(--stack-eb-gap-sm, clamp(6px, .8vw, 9px));
  --sc-hairline: color-mix(in srgb, var(--sc-ink) 12%, transparent);
  --sc-border: color-mix(in srgb, var(--sc-ink) 14%, transparent);
  --sc-fill: color-mix(in srgb, var(--sc-ink) 2%, var(--sc-bg));
}
.service-list { display: grid; gap: var(--sc-gap); }

.service { color: var(--sc-ink, #1a1a1f); min-width: 0; }

/* --type-label */
.service-eyebrow { display: block; font-family: var(--sc-mf, ui-monospace, monospace);
  font-size: 12px; line-height: 1.2; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--sc-primary-text, var(--sc-primary, currentColor)); }
/* --type-h3 size, vendor's display face. The size was the bug (22px in a 3-up
   desktop grid); the face is not. The kit's "display stops at level two, floor
   of 24px" rule is a fact about Fraunces' optical-size axis inside Zulli's own
   three-face product UI — but --sc-hf here is whichever of 58 display faces the
   vendor's pairing chose, and this is the vendor's marketing page, where that
   face is the brand. font-optical-sizing is left at its `auto` default, so a
   variable face matches its opsz to 18px rather than rendering a large-optical
   cut small, which is what actually causes muddy small display type. */
.service-name { font-family: var(--sc-hf, 'Fraunces', serif); font-weight: var(--sc-tw, 600);
  font-size: 18px; line-height: 1.36; letter-spacing: -0.008em;
  margin: var(--sc-eb-gap) 0 5px; }
/* --type-body-sm — card copy is the small register, and gets a measure */
.service-desc { font-family: var(--sc-bf, 'Inter', sans-serif); font-size: 13px;
  line-height: 1.55; margin: 0; max-width: 46ch;
  color: color-mix(in srgb, var(--sc-ink, #1a1a1f) 76%, transparent); }

/* Image block shows the offering's uploaded photo; with no photo it falls back
   to a scheme-recoloring gradient so the image styles still read. Hidden unless
   a style opts in. The gradient is set on the element; a photo overrides it via
   an inline background-image (see offerings.html). */
.service-img { display: none; border-radius: var(--sc-r); aspect-ratio: 16 / 10;
  background-size: cover; background-position: center;
  background-image:
    radial-gradient(120% 120% at 15% 15%, color-mix(in srgb, #fff 22%, transparent), transparent 55%),
    linear-gradient(135deg, var(--sc-primary, currentColor), var(--sc-accent, var(--sc-primary, currentColor))); }
.service-index { display: none; }

/* --- Minimal List: hairline-separated rows, no image --- */
.sc-minimal .service-list { gap: 0; }
.sc-minimal .service { padding: var(--sc-row) 0; border-top: 1px solid var(--sc-hairline); }
.sc-minimal .service:first-child { border-top: 0; padding-top: 0; }

/* --- Boxed: bordered cards in a responsive grid.
   minmax was 180px, which auto-fit five columns into a 1024px desktop row —
   190px cards. The floor is now sized so a row tops out at three. --- */
.sc-boxed .service-list { grid-template-columns: repeat(auto-fit, minmax(min(100%, 224px), 1fr)); }
.sc-boxed .service { padding: var(--sc-pad); border-radius: var(--sc-r);
  border: 1px solid var(--sc-border);
  background: var(--sc-fill); }

/* --- Image Top: photo banner over the copy --- */
.sc-image-top .service-list { grid-template-columns: repeat(auto-fit, minmax(min(100%, 264px), 1fr)); }
.sc-image-top .service { border-radius: var(--sc-r); overflow: hidden;
  border: 1px solid var(--sc-border);
  background: var(--sc-fill); }
.sc-image-top .service-img { display: block; border-radius: 0; aspect-ratio: 16 / 9; }
.sc-image-top .service-body { padding: var(--sc-pad); }

/* --- Image Side: square thumbnail beside the copy --- */
.sc-image-side .service { display: grid; grid-template-columns: 80px 1fr;
  gap: var(--sc-row); align-items: center; padding: var(--sc-row) 0;
  border-bottom: 1px solid color-mix(in srgb, var(--sc-ink) 10%, transparent); }
.sc-image-side .service:last-child { border-bottom: 0; }
/* width:100% pins the thumbnail to its grid track. Without it, `align-self:
   stretch` sets the height from the row and `aspect-ratio: 1` then derives the
   WIDTH from that height — so any row taller than the track (four lines of copy
   on a phone) grew the image past its column and slid it under the text. The
   ratio still governs when the row is shorter than the track. */
.sc-image-side .service-img { display: block; width: 100%; aspect-ratio: 1;
  border-radius: var(--sc-r); align-self: stretch; }

/* --- Image Overlay: copy sits over a full-bleed photo. The scrim is always
   dark, so this style's text is fixed light rather than theme ink. --- */
.sc-overlay .service-list { grid-template-columns: repeat(auto-fit, minmax(min(100%, 264px), 1fr)); }
.sc-overlay .service { position: relative; min-height: 180px; border-radius: var(--sc-r);
  overflow: hidden; display: flex; align-items: flex-end; }
.sc-overlay .service-img { display: block; position: absolute; inset: 0;
  aspect-ratio: auto; border-radius: 0; }
/* The scrim spans the whole CARD, not just the copy block.
   It used to live on .service-body as `to top, .72 → .15 at 70% → transparent`,
   which ramps across the body's own height — and the body's height is however
   tall the copy happens to be. The eyebrow sits on the body's FIRST line, i.e.
   at the top of that ramp, so it landed on ~0.15 alpha or less and became
   unreadable over anything but a dark photo. Spanning the card instead means
   the ramp is measured against a known box, and the 0.34 floor at the top
   guarantees every line has something behind it whatever the copy length. */
.sc-overlay .service::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(0,0,0,0.90), rgba(0,0,0,0.68) 42%, rgba(0,0,0,0.34) 100%);
}
.sc-overlay .service-body { position: relative; z-index: 1; width: 100%; padding: var(--sc-pad); }
/* Pill, like .sc-badge — a chip is a shape, not a step on the radius scale, so
   it doesn't follow --sc-radius. Filled rather than outlined: this chip is the
   one element that sits highest in the card, where the scrim is thinnest, and
   a hairline outline gave its label nothing of its own to sit on. */
.sc-overlay .service-eyebrow { display: inline-block; margin-bottom: 10px; padding: 4px 10px;
  background: rgba(0,0,0,0.45);
  border: 1px solid rgba(255,255,255,0.42); border-radius: 999px; color: #fff; }
.sc-overlay .service-name { color: #fff; }
.sc-overlay .service-desc { color: rgba(255,255,255,0.88); }

/* --- Numbered: the index leads each row. It was Fraunces at 34px; an index is
   data, not display, so it is now --type-data and sits on the first line
   rather than towering over it. --- */
.sc-numbered .service { display: grid; grid-template-columns: auto 1fr;
  gap: var(--sc-row); align-items: baseline; padding: var(--sc-row) 0;
  border-top: 1px solid var(--sc-hairline); }
.sc-numbered .service:first-child { border-top: 0; padding-top: 0; }
.sc-numbered .service-index { display: block; font-family: var(--sc-mf, ui-monospace, monospace);
  font-weight: 500; font-size: 13px; line-height: 1.4; letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums; color: var(--sc-primary); }

/* --- Accent Rail: a colored bar leads each row --- */
.sc-rail .service-list { gap: var(--space-lg, clamp(22px, 3vw, 36px)); }
.sc-rail .service { border-left: 3px solid var(--sc-primary); padding: 4px 0 4px var(--sc-row); }

/* --- Tinted: primary-tinted blocks --- */
.sc-tint .service-list { grid-template-columns: repeat(auto-fit, minmax(min(100%, 224px), 1fr)); }
.sc-tint .service { padding: var(--sc-pad); border-radius: var(--sc-r);
  background: color-mix(in srgb, var(--sc-primary) 10%, var(--sc-bg));
  border: 1px solid color-mix(in srgb, var(--sc-primary) 22%, transparent); }

/* --- Badge Eyebrow: eyebrow becomes a filled pill --- */
.sc-badge .service-list { grid-template-columns: repeat(auto-fit, minmax(min(100%, 232px), 1fr)); }
.sc-badge .service { padding: var(--sc-pad); border-radius: var(--sc-r);
  border: 1px solid var(--sc-border); }
.sc-badge .service-eyebrow { display: inline-block; margin-bottom: 10px; padding: 4px 10px;
  border-radius: 999px;
  background: var(--sc-primary-fill, var(--sc-primary)); color: var(--sc-on-primary); }

/* --- Centered Stack: everything centered. The measure has to be released or
   the centered copy sits off-axis inside its own 46ch box. --- */
.sc-stack .service-list { grid-template-columns: repeat(auto-fit, minmax(min(100%, 224px), 1fr)); }
.sc-stack .service { text-align: center; padding: var(--sc-pad) var(--sc-row); }
.sc-stack .service-eyebrow { color: var(--sc-accent); }
.sc-stack .service-name { margin-top: var(--sc-eb-gap); }
.sc-stack .service-desc { max-width: 46ch; margin-inline: auto; }

/* --- Image Right: bordered card, copy left, photo flush-right --- */
.sc-image-right .service { display: grid; grid-template-columns: 1fr 96px; border-radius: var(--sc-r);
  overflow: hidden; border: 1px solid var(--sc-border);
  background: var(--sc-fill); }
.sc-image-right .service-body { order: 1; padding: var(--sc-pad); }
.sc-image-right .service-img { order: 2; display: block; aspect-ratio: auto; border-radius: 0;
  align-self: stretch; }

/* --- Polaroid: a fixed white photo-paper frame, photo, caption below. The frame
   is always light (like the overlay is always dark), so its text uses a fixed
   dark ink rather than the theme ink — otherwise a dark theme's light ink would
   vanish on the white frame. The eyebrow keeps the brand colour. The frame's own
   radii are deliberately fixed: a photo print's corners are a property of the
   print, not of the vendor's corner_style. --- */
.sc-polaroid .service-list { grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }
.sc-polaroid .service { padding: 10px 10px 0; border-radius: 6px;
  background: #FBFAF7; border: 1px solid rgba(17,25,23,0.10);
  box-shadow: 0 2px 10px rgba(0,0,0,0.10); }
.sc-polaroid .service-img { display: block; aspect-ratio: 5 / 4; border-radius: 3px; }
.sc-polaroid .service-body { padding: 12px 6px 16px; }
.sc-polaroid .service-name { color: #1F1D1B; }
.sc-polaroid .service-desc { color: #5B554D; }
.sc-polaroid .service-eyebrow { color: var(--sc-primary-text, var(--sc-primary)); }

/* --- Stamp: a rotated, outlined eyebrow like an inked stamp; no image --- */
.sc-stamp .service { padding: var(--sc-pad); border-radius: var(--sc-r);
  border: 1px solid var(--sc-hairline);
  background: var(--sc-fill); }
.sc-stamp .service-eyebrow { display: inline-block; margin-bottom: 14px; transform: rotate(-2deg);
  padding: 4px 9px; border: 1.5px solid var(--sc-primary); border-radius: 3px;
  color: var(--sc-primary-text, var(--sc-primary)); letter-spacing: 0.16em; }

/* --- Editorial: a full-width magazine feature — one per row, an inset photo,
   and a centered, oversized serif-forward heading over a soft brand tint. Reads
   distinctly from Image Top (bordered, edge-to-edge photo, left-aligned, multi-
   column).

   This is the one style whose heading is display type: it clears the kit's 24px
   Fraunces floor, so it keeps the display face, the display weight and a fluid
   clamp — the exception rule 2 above exists for. --- */
.sc-editorial .service-list { grid-template-columns: 1fr; gap: var(--space-lg, clamp(22px, 3vw, 36px)); }
.sc-editorial .service { border-radius: var(--sc-r); padding: 14px 14px 4px;
  background: color-mix(in srgb, var(--sc-primary) 9%, var(--sc-bg)); }
.sc-editorial .service-img { display: block; aspect-ratio: 16 / 9; border-radius: var(--sc-r);
  margin-bottom: 14px; }
/* Editorial is one card per row, so past this width a 16/9 photo runs 500px+
   tall and three offerings become 1600px of photography with nothing else on
   screen. Swap the ratio for a fixed height and let background-size:cover crop.
   Capping with max-height instead would shrink the photo's WIDTH to preserve
   the ratio, which is not the same thing at all. */
@container (min-width: 700px) {
  .sc-editorial .service-img { aspect-ratio: auto; height: clamp(280px, 34cqi, 400px); }
}
.sc-editorial .service-body { padding: 2px 14px 16px; text-align: center; }
.sc-editorial .service-eyebrow { letter-spacing: 0.14em; }
.sc-editorial .service-name { font-family: var(--sc-hf, 'Fraunces', serif);
  font-weight: var(--sc-tw, 600); font-size: clamp(24px, 4.4cqi, 32px); line-height: 1.18;
  letter-spacing: -0.016em; margin: var(--sc-eb-gap) 0 8px; }
.sc-editorial .service-desc { max-width: 52ch; margin: 0 auto; }
