/**
 * Section: Service detail blocks (service-blocks)
 *
 * Ported from _mockups/services.html `.sv-blocks` / `.sv-block` /
 * `.sv-block-head` / `.sv-what` / `.sv-note` / `.sv-cols` / `.sv-list` /
 * `.sv-more` / `.sv-foot` / `.sv-from` / `.sv-btns`. One page, no drift to
 * resolve.
 *
 * WHAT IS NOT HERE, because it is shared and lives in a globally loaded file:
 *
 *   .card             components.css. The paper ground, the hairline, the
 *                     radius and the resting shadow.
 *   .alert-info       components.css. The blue panel `.sv-note` is. BLUE, not
 *                     amber: the note's whole job is stopping "Direct Hire"
 *                     being read as the self-managed direct hiring route, and
 *                     a warning tone would make the agency's own service read
 *                     as the thing to be careful of.
 *   .pasia-icon-tile  components.css. This file sets the two size custom
 *                     properties and re-declares no part of the treatment.
 *   .pasia-ticklist   components.css. The ticked inclusions list, `.sv-list`.
 *                     Only its top margin is overridden here, which is the one
 *                     line that component's own comment sanctions: it is
 *                     written for a list under a heading, and here it sits
 *                     under a small label that already carries the space.
 *   .tag / .tag--new  tokens.css. The "Starts from HK$X,XXX" price pill, for
 *                     the ground, the ink, the weight and the radius. THE
 *                     PRIMITIVE IS NOT THE WHOLE PILL HERE, and the claim that
 *                     used to stand in this slot was simply wrong: it said
 *                     `.sv-from` is the same pill as index.html's `.c-path
 *                     .from` and byte-identical to `.tag.tag--new`. It is not.
 *                     `.c-path .from` (index.html:113) is --text-xs at
 *                     .42em 1em; `.sv-from` (services.html:162) is --text-sm at
 *                     .5em 1.1em. Rendered, that was 13px / 5.46px 13px against
 *                     the signed-off 15px / 7.5px 16.5px, so the pill on this
 *                     page came out a size small. The two declarations that
 *                     differ are added below as `.service-block-from`; the rest
 *                     of the primitive still carries it, and path-cards.css's
 *                     hand-written copy is still not joined by a third.
 *                     services.html also sets `display: inline-flex; gap: .35em`
 *                     on it. Those are inert for this content and are not
 *                     reproduced: the pill holds one contiguous run of inline
 *                     content, which flex layout wraps in a SINGLE anonymous
 *                     item, so there is no second item for a gap to sit between.
 *   .note             components.css. `.sv-more`, the quiet line under the
 *                     list. Only its colour differs, which is the one
 *                     declaration below.
 *   .btn, .btn-ghost, .btn-primary, .eyebrow, .head, .head h2 em, .section.tint
 *                     tokens.css and base.css.
 *
 * BAND: `.section.tint`, which is --paper, per the inventory entry. The blocks
 * are --paper as well and are told apart from the band by the --line hairline
 * and --shadow-s, exactly as services.html has them.
 *
 * CONTRAST, measured on the PASIA palette rather than assumed, and measured AS
 * COMPOSITED wherever a fill is translucent:
 *
 *   service name      --ink       #14231f  on --paper #ffffff   16.28:1
 *   lead paragraph    --ink-soft  #45524d  on --paper #ffffff    8.18:1
 *   "Core service"    --gold-deep #7e622e  on --paper #ffffff    5.72:1
 *   column labels     --gold-deep #7e622e  on --paper #ffffff    5.72:1
 *   who it is for     --ink-soft  #45524d  on --paper #ffffff    8.18:1
 *   inclusions        --ink-soft  #45524d  on --paper #ffffff    8.18:1
 *   the tick          --gold-deep #7e622e  on --paper #ffffff    5.72:1
 *   note under list   --ink-faint #5f6b66  on --paper #ffffff    5.55:1
 *   the blue panel    --info-ink  #2a5f88  on --info-bg #e4eef5  5.77:1
 *   the price pill    --price     #1c6b4a  on --price-bg #e6f4ec 5.69:1
 *   the icon glyph    --forest    #0e4038  on --forest-tint-10
 *                                          over --paper          9.73:1
 *   .ph-badge         --gold-deep #7e622e  through its own
 *                                          --gold-tint-10 stripe
 *                                          on its own pinned
 *                                          --paper base          5.17:1
 *
 * All clear WCAG AA for normal text. The badge figure is the composited one
 * from components.css, not --gold-deep on a bare token: the badge paints a
 * translucent stripe over a base it pins itself, so the bare figure would not
 * be a measurement of the component.
 *
 * --gold on the hover border is 2.56:1 and --line on the resting border is
 * 1.32:1. Both are decorative edges, not text, and neither is a control's only
 * affordance: the block is not a control at all, and the two buttons inside it
 * carry their own labels and the global --gold-deep focus ring from tokens.css.
 * There is therefore no pressed or selected state in this section that could
 * outrank a hover rule.
 *
 * The watermark numeral is --watermark, which is 1.09:1 on --paper. It is
 * decoration and it says so twice over: the renderer emits it as a real element
 * with aria-hidden rather than as `content: attr(data-num)`, because generated
 * content cannot be hidden from a screen reader and would have read an
 * invisible "01" before every service name, and the colour is a token NAMED as
 * decoration rather than a tint.
 *
 * It used to be --forest-tint-05, which AGENTS.md §1.7 forbids as a text colour
 * with no exception offered for decoration, and the exception was already
 * spreading to a second file. --watermark is that tint flattened on --paper,
 * 243,245,245, so the pixels are identical (the arithmetic, including why it
 * holds for antialiased edges, is in tokens.css) and the mechanism is no longer
 * a surface fill sitting in a `color` declaration where the next person to read
 * it will "fix" the contrast.
 *
 * Tokens for every colour, size, radius, shadow and duration. The pixel value
 * that remains is the icon tile's dimension, which has no token, and the
 * spacing clamps are composed from the spacing scale rather than from
 * literals.
 *
 * JavaScript: none. Two links in a footer and nothing else.
 */

/* ---------------------------------------------------------------------------
 * The stack.
 * ------------------------------------------------------------------------ */
.service-blocks-list {
  display: grid;
  gap: var(--s-5);
}

/* ---------------------------------------------------------------------------
 * The block. `.card` supplies the surface; this is the delta.
 *
 * The padding clamp is the mock-up's own, composed from the spacing scale:
 * --s-4 is 1.5rem and --s-6 is 3rem, which are exactly its two ends.
 * ------------------------------------------------------------------------ */
.service-block {
  position: relative;
  overflow: hidden;
  padding: clamp(var(--s-4), 4vw, var(--s-6));
  /* The footer's Services column deep-links to #direct-hire and friends, so a
     block is a scroll target and must clear the sticky header. --header-h is
     the reference for that, never a hardcoded 72px (AGENTS.md §6). */
  scroll-margin-top: calc(var(--header-h) + var(--s-4));
  transition: border-color var(--dur-normal) ease,
              box-shadow var(--dur-normal) ease;
}

.service-block:hover {
  border-color: var(--gold);
  box-shadow: var(--shadow-m);
}

/* ---------------------------------------------------------------------------
 * The watermark numeral.
 *
 * Derived from the block's position in the client's own running order, never
 * from a field. `overflow: hidden` on the block is what crops it, which is the
 * mock-up's effect.
 *
 * THE SIZE IS NOW A TOKEN, and this file no longer asks for the decision it was
 * asking for. It was `calc(var(--text-hero) * 1.4)`, which lands on exactly
 * 7rem at the top and 3.5rem at the bottom against the mock-up's 4rem, because
 * --text-hero's clamp floor and the numeral's are not in the same ratio as
 * their ceilings. Measured 57.9px against 64px at 375px, 12.5% small, on the
 * width where the numeral is largest relative to the block it is cropped by.
 * --text-watermark in tokens.css is services.html's own clamp(4rem, 9vw, 7rem),
 * so the numeral matches the signed-off design at both ends of the range and
 * this file still holds no literal size.
 * ------------------------------------------------------------------------ */
.service-block-num {
  position: absolute;
  top: -.14em;
  inset-inline-end: var(--s-1);
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--text-watermark);
  line-height: 1;
  color: var(--watermark);
  pointer-events: none;
  user-select: none;
}

/* ---------------------------------------------------------------------------
 * The head: tile, eyebrow, service name.
 *
 * Lifted above the numeral, which is the one place the mock-up raises anything:
 * the numeral is absolutely positioned and would otherwise paint over the name.
 * ------------------------------------------------------------------------ */
.service-block-head {
  position: relative;
  z-index: var(--z-raised);
  display: flex;
  align-items: center;
  gap: var(--s-4);
  margin-bottom: var(--s-4);
}

/* Only the size, on the shared tile's own custom properties. */
.service-block-ico {
  --pasia-tile: 54px;
  --pasia-tile-glyph: 28px;
}

/* min-width guards a long unbroken service name from pushing the flex row
   wider than the card at 320px. */
.service-block-name {
  min-width: 0;
}

.service-block-title {
  margin-top: .2em;
  font-size: var(--text-2xl);
}

/* ---------------------------------------------------------------------------
 * The lead paragraph. This is the service's own short description, the same
 * `blurb` the services grid prints, so the two pages cannot disagree.
 * ------------------------------------------------------------------------ */
.service-block-what {
  position: relative;
  z-index: var(--z-raised);
  max-width: 58ch;
  margin-bottom: var(--s-4);
  font-size: var(--text-lg);
  color: var(--ink-soft);
}

.service-block-what a,
.service-block-cols a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* The blue clarification panel. `.alert.alert-info` carries the treatment. */
.service-block-note {
  position: relative;
  z-index: var(--z-raised);
  margin-bottom: var(--s-4);
}

/* ---------------------------------------------------------------------------
 * The two columns: who it is for, and what is included.
 * ------------------------------------------------------------------------ */
.service-block-cols {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: var(--s-5);
  border-top: 1px solid var(--line);
  padding-top: var(--s-4);
}

.service-block-col {
  min-width: 0;
}

/* A service with only one of the two filled in gets the full width rather than
   an empty track beside it. Derived from the content, in one line of CSS. */
.service-block-col:only-child {
  grid-column: 1 / -1;
}

/* The small uppercase label above each column. A heading element, so the page
   keeps its outline; the sans face and the size are the design's. */
.service-block-label {
  margin-bottom: var(--s-2);
  font-family: var(--sans);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

/* A CLASS, NOT `.service-block-cols p`.
 *
 * The element form is the trap, and it was caught in the browser rather than by
 * eye: `.service-block-cols p` is 0,1,1 and outranks `.service-block-more` at
 * 0,1,0, so the quiet note under the list came out at --ink-soft with the
 * source reading as though it were --ink-faint. Two classes at equal
 * specificity cannot do that to each other. */
.service-block-who {
  color: var(--ink-soft);
}

/* The shared ticked list is written for a list under a heading and carries a
   top margin for it. Here the label above already owns that space. */
.service-block-list {
  margin-top: 0;
}

/* `.note` in components.css supplies the size; only the colour differs, and
   this file loads after components.css so an equal-specificity class wins. */
.service-block-more {
  margin-top: var(--s-2);
  color: var(--ink-faint);
}

/* ---------------------------------------------------------------------------
 * The foot: the published range, and the two buttons.
 * ------------------------------------------------------------------------ */
.service-block-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  border-top: 1px solid var(--line);
  margin-top: var(--s-4);
  padding-top: var(--s-4);
}

/* THE DELTA ON THE PRICE PILL, which the file header used to deny existed.
   `.tag.tag--new` is index.html's small pill; services.html's `.sv-from` is the
   same colours one step up, --text-sm at .5em 1.1em against --text-xs at
   .42em 1em. Two declarations, at one class against the primitive's one class,
   and this file loads after tokens.css, so it wins on load order at equal
   specificity exactly as `.service-block-more` does over `.note`. */
.service-block-from {
  font-size: var(--text-sm);
  padding: .5em 1.1em;
}

.service-block-btns {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}

/* ---------------------------------------------------------------------------
 * Breakpoints. Canonical set: 1024 / 860 / 620 / 560.
 * ------------------------------------------------------------------------ */
@media (max-width: 860px) {
  .service-block-cols {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 620px) {
  .service-block-foot {
    flex-direction: column;
    align-items: stretch;
  }

  .service-block-btns {
    flex-direction: column;
  }

  .service-block-btns .btn {
    justify-content: center;
  }
}
