/* components part 12 of 13 — split for the host's 16KB FTP ceiling.
   Generated by split_for_ftp.py; edit the prototype, not this. */

.pf-count{font-size:11.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
          color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.pf-count b{color:var(--ink)}

/* The hero's two columns were an even split, but the copy is capped at --measure and
   stops well short of its half, so the page opened on ~150px of nothing down the
   middle. Give the map the width the text was never using. Scoped to .pf-hero: the
   service pages want the even split, because their right column is a photograph that
   fills it. */
/* fit-content, not a fraction. At .88fr the copy column grew with the viewport while the
   copy itself did not — the H1 needs about 660px and stops there, so on a 2000px screen
   the column was ~870px holding 430px of text and the map started 440px later than it had
   to. fit-content sizes the track to the copy (capped at the measure) and hands every
   remaining pixel to the map, which both closes the gap and makes the map bigger. */
/* The copy column is capped at the measure, so on an ultra-wide display every extra
   pixel went to the map alone and it grew to a size no map needs to be. The wall and
   the filter rail below stay full-bleed on purpose — they are a grid of images and
   they use the room. This cap applies to the hero only. */
.pf-hero .hero-row{grid-template-columns:fit-content(calc(var(--measure) + var(--edge-vp))) minmax(0,1fr);
                   gap:clamp(12px,1.4vw,22px);max-width:2500px}
/* The hero copy used to start at var(--edge-vp) — the inset that aligns text with the
   site's centred 1560px column. On every other page that is right. Here it is not: this
   page has no centred column. The wall runs to both edges and starts at the .pf gutter,
   so at 1920px the H1 began 252px in while the first frame began 34px in, and the hero
   read as a different, narrower page bolted above the work. Same gutter as .pf, so the
   headline and the first frame share a left edge. */
.pf-hero .hero-txt{padding-left:clamp(16px,2.2vw,34px);
                   padding-top:clamp(26px,3vw,48px);
                   padding-bottom:0}
/* The map runs flush to the top of the hero, the way the photograph does in the right
   column of a service page — only the copy column carries a top inset.
   The bottom cannot also be flush, and the arithmetic says why: at this column width
   the map is 422px tall while the copy column's CONTENT alone is 426px, so the row is
   always at least as tall as the copy, and the leftover under the map is exactly
   4px + the copy's vertical padding. Zero padding would put the breadcrumb hard against
   the sticky header. So the top inset moved off the map entirely and the bottom padding
   went to 0, which is as close to flush as the proportions allow. */
.pf-hero .hero-map{align-self:start}@media(max-width:1100px){
  .pf-hero .hero-row{display:flex;flex-direction:column;gap:0;
                     grid-template-columns:none;
                     padding-inline:clamp(16px,2.2vw,34px)}
  .pf-hero .hero-txt{display:contents}
  /* Only the map needs a rule. The prototype ALREADY dissolves .hero-txt here and
     numbers its children (.eyebrow 2, h1 3, .hero-sub 4, .checks 5, .hero-btns 6,
     .hero-scarce 7) — so the map just needs a slot in that sequence, and 5 puts it
     after the subtext and before the buttons. This page has no .checks, so 5 is free.
     Do NOT try to renumber the text via `.hero-row > .crumb` and friends: the child
     combinator walks the DOM, and display:contents does not reparent anything, so
     those selectors match nothing at all — the elements are still children of
     .hero-txt. Only .hero-map is a real child of .hero-row. */
  /* Map directly under the H1 and above the subtext: "251 frames across these markets"
     is part of the claim the headline is making, so it should land before the prose
     that qualifies it, not after. The shared numbering gives .hero-sub 4, so the map
     takes 4 and the subtext moves to 5 — free here, since .checks does not exist on
     this page. Descendant selectors, not child: .hero-txt is display:contents at this
     width, which dissolves the box but does NOT reparent, so `.hero-row > .hero-sub`
     would match nothing. */
  /* The shared prototype numbers these children at 1040, not 1100, so between the two
     widths the stack was unordered — every item at order 0 — and the map fell to the
     bottom behind the buttons. Restate the whole sequence here, scoped to .pf-hero at
     (0,3,0) so it outranks the prototype's (0,2,0) in both directions and the order is
     identical on either side of 1040. */
  .pf-hero .hero-txt>.eyebrow{order:2}
  .pf-hero .hero-txt>h1{order:3}
  .pf-hero .hero-map{order:4;margin:6px 0 20px;align-self:stretch}
  .pf-hero .hero-sub{order:5}
  .pf-hero .hero-txt>.hero-btns{order:6}}

/* The map is the market filter and it lives in the hero, running to the edge. */
.hero-map{align-self:center;padding:0;min-width:0}
.mp{width:100%;height:auto;display:block}
/* the compact build's three panels: a tinted window each, a hairline frame, a label */
.mp-sea{fill:#faf9f7;pointer-events:none}
.mp-frame{fill:none;stroke:var(--hair);stroke-width:1;vector-effect:non-scaling-stroke;
          pointer-events:none}
.mp-label{fill:var(--faint);font-family:var(--sans);font-size:11px;font-weight:700;
          letter-spacing:.13em;text-transform:uppercase}
.mp-bg path{fill:var(--hair);stroke:var(--white);stroke-width:1;vector-effect:non-scaling-stroke}
/* No markers. A dot sized to carry a count was wider than Estonia, Latvia and
   Austria put together, so the country fill is the whole display and the whole
   control; an invisible circle from make_map.py supplies a finger-sized hit area. */
/* The country FILL is the hit target, plus the invisible circle for the small ones.
   This used to be pointer-events:none, which left the circle as the only way to click
   anything: the USA renders 329x151px on a 1600px screen and its entire clickable area
   was a 25x25px disc — 0.6% of the country. Three probes inside the USA all missed it.
   Estonia is 15x7px, so the circle still earns its place; it just should not be the
   ONLY target. */
.mp-live path{fill:var(--accent);stroke:var(--white);stroke-width:.7;
              transition:fill .18s;vector-effect:non-scaling-stroke;pointer-events:auto}
.mp-pin{cursor:pointer}
.mp-hit{fill:transparent}
/* Hover and selected must not look the same. Both were var(--ink), so hovering a country
   was indistinguishable from having chosen it. Hover is now a mid tone between the resting
   accent and the selected ink; .mp-pin.on keeps the full ink below. */
.mp-pin:hover path,.mp-pin:focus-visible path{fill:#8a6b41}
.mp-pin.on path{fill:var(--ink)}
/* :focus, NOT :focus-visible — this one word is the whole fix for the ring on click.
   The ring was never ours. Clicking a `<g role="button" tabindex="0">` gives :focus but
   NOT :focus-visible, so the old `.mp-pin:focus-visible{outline:none}` never fired on a
   mouse click and the browser drew its own `-webkit-focus-ring-color auto 5px` — the OS
   accent, blue on a default Mac. Worse, an outline on a <g> is drawn round the group's
   bounding box, so clicking the USA boxed everything from Alaska to Maine. hello-elementor's
   reset already handles this for real buttons (`button:focus:not(:focus-visible)`), but a
   <g> is not a button. :focus is a superset, so this kills the UA ring on click AND on Tab,
   while the accent stroke below still marks keyboard focus. */
.mp-pin:focus{outline:none}
.mp-pin:focus-visible path{fill:var(--ink);stroke:var(--accent);stroke-width:3}
.mp-pin.dead{cursor:default;pointer-events:none}
.mp-pin.dead path{fill:var(--hair);pointer-events:none}

/* ---------------------------------------------------- browse by service (strip)
   The cards used to carry a photograph each, on a page that is already 233
   photographs. Icons say "this is a category" instead of competing with the work,
   and a card without an image is short enough that six fit in one scrolling row.

   pfs-*, NOT svc-*. This component is private to the portfolio, and it used to reuse
   .svc-strip / .svc-card / .svc-more / .svc-head / .svc-ico -- names that already belong
   to the shared design system in interior-ref.html, where .svc-strip is a six-card GRID
   of photographs rather than a horizontal flex scroller. That was invisible until
   build_interior.py started splicing this stylesheet into /services/interior-rendering/,
   which appends it AFTER that page's own <style>: at equal specificity the scroller won,
   and the top half of the service page collapsed. RULE 0 -- the shared component keeps
   the name, the private one gets its own. */
.pfs-head{display:flex;align-items:flex-end;justify-content:space-between;gap:28px}
.pfs-head > div{min-width:0}
.strip-arrows{display:flex;gap:8px;flex:0 0 auto;padding-bottom:4px}
.strip-arrow{width:42px;height:42px;border-radius:50%;border:1px solid var(--hair);
             background:var(--white);color:var(--ink);cursor:pointer;
             display:inline-flex;align-items:center;justify-content:center;
             transition:border-color .16s,color .16s,opacity .16s}
.strip-arrow svg{width:15px;height:15px}
.strip-arrow:hover,.strip-arrow:focus{background:rgba(20,19,16,.05)}
.strip-arrow:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.strip-arrow:disabled{opacity:.32;cursor:default;color:var(--ink);
                      border-color:var(--hair);background:var(--white)}

/* Full bleed, but the first card lines up with the H2 above it — that alignment is
   what stops a bleeding strip from looking like it slid out of the layout. */
.pfs-strip{display:flex;gap:14px;margin-top:clamp(24px,3vw,38px);
           overflow-x:auto;overscroll-behavior-x:contain;
           scroll-snap-type:x proximity;scrollbar-width:none;
           padding:4px var(--edge-vp) 8px;scroll-padding-inline:var(--edge-vp)}
.pfs-strip::-webkit-scrollbar{display:none}
.pfs-strip:focus-visible{outline:2px solid var(--accent);outline-offset:3px}@media(prefers-reduced-motion:no-preference){ .pfs-strip{scroll-behavior:smooth}}

.pfs-card{flex:0 0 clamp(238px,74vw,296px);scroll-snap-align:start;
          display:flex;flex-direction:column;gap:9px;min-width:0;
          padding:22px 22px 20px;background:var(--white);
          border:1px solid var(--hair);border-radius:12px;
          text-decoration:none;color:var(--body);
          transition:border-color .18s,transform .18s}
.pfs-card:hover{border-color:var(--faint);transform:translateY(-2px)}