/* Find A Surveyor design system.

   SCOPED under .directory-hub, for the same reason tools.css is scoped under
   .tools-hub: this sheet carries .container, .btn, .hero and .field, all of
   which the shared header and footer also use. Nothing here may leak out.

   Tokens come from cine.css (--gold, --ink, --line, --head, --body). The few
   defined below are ones cine.css does not carry, derived from the same palette. */

.directory-hub{
  --card:#ffffff; --field:#ffffff; --line-strong:#D8D7D2;
  --accent-bg:#FFFBEF; --accent-line:#F3DFA0;
  --good:#2A6249; --good-bg:#EAF2ED;
  --bad:#B4342A;
  --radius:14px;
  --shadow-row:0 14px 34px -20px rgba(20,24,28,.30);

  /* The topbar is fixed, so this page's hero has to clear it, same as tools. */
  .hero .inner{padding-top:calc(var(--head-h, 76px) + 34px);padding-bottom:8px}
  /* Wide enough for the longest title the directory generates, which is
     "Licensed land surveyors in North Carolina" at 41 characters. At 18ch even
     the hub's own heading broke across two lines on a screen with room for
     four of it. It still wraps on a phone, where it has to, and balance keeps
     that break even rather than leaving one word alone on the second line. */
  .hero h1{max-width:44ch;text-wrap:balance}
  .hero .sub{max-width:56ch}

  .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
           clip:rect(0 0 0 0);white-space:nowrap;border:0}

  /* ---- search ---- */
  .searchrow{display:flex;gap:10px;flex-wrap:wrap;max-width:640px;margin-top:26px}

  /* The state page's one number. It was an unstyled <ul>, so it rendered as a
     bulleted list with the count welded to its label: "179licensed firms".
     A count is a sentence, not a list of one. */
  .count{margin:18px 0 0;font-family:var(--body);color:var(--ink2);font-size:1rem}
  .count b{font-family:var(--head);font-weight:700;font-size:1.35rem;color:var(--ink);
    margin-right:.3em;letter-spacing:.01em}
  .field{flex:1 1 240px;display:flex;align-items:center;gap:10px;background:var(--field);
         border:1px solid var(--line);border-radius:10px;padding:0 14px;height:54px}
  .field-type{flex:0 1 232px}
  .field svg{width:18px;height:18px;color:var(--ink3);flex:none}
  .field input,.field select{border:0;outline:0;font:inherit;font-size:1rem;color:var(--ink);
                             background:transparent;width:100%;height:100%}
  .field input::placeholder{color:var(--ink3)}
  .field:focus-within{border-color:var(--ink)}

  .filters{display:flex;gap:8px;flex-wrap:wrap;margin-top:18px}
  .chip{font-family:var(--body);font-size:.9rem;font-weight:500;padding:7px 14px;border-radius:999px;
        border:1px solid var(--line);background:var(--bg);color:var(--ink2);cursor:pointer}
  .chip[aria-pressed="true"]{background:var(--ink);color:#fff;border-color:var(--ink)}
  .chip:hover[aria-pressed="false"]{border-color:var(--ink3)}

  /* ---- results: a listing, not a grid of cards ---- */
  .results-band{padding-block:26px 56px}
  .resulthead{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:10px}
  .resultcount{font-size:.9rem;color:var(--ink3);margin:0;flex:1 1 auto}
  .results{border-top:1px solid var(--line)}

  /* ---- list / split / map ----
     One results list, one map, and a data-view on the wrapper deciding which is
     on screen. The map is never rebuilt, only resized, so switching views keeps
     the pan and zoom the visitor set. */
  .viewtoggle{display:inline-flex;border:1px solid var(--line);border-radius:999px;
              background:var(--bg);padding:3px;gap:2px}
  .viewtoggle button{font-family:var(--body);font-size:.82rem;font-weight:600;letter-spacing:.02em;
                     padding:6px 15px;border:0;border-radius:999px;background:transparent;
                     color:var(--ink2);cursor:pointer}
  .viewtoggle button[aria-pressed="true"]{background:var(--ink);color:#fff}
  .viewtoggle button:hover[aria-pressed="false"]{color:var(--ink)}

  /* Basemap switch, inside the map's own top-right corner. Same pill language as
     .viewtoggle so the map does not introduce a second button style, with a
     shadow because it sits on tiles rather than on the page. */
  .basemapswitch{display:inline-flex;border:1px solid var(--line);border-radius:999px;
                 background:var(--bg);padding:3px;gap:2px;
                 box-shadow:0 1px 4px rgba(20,24,28,.18)}
  .basemapswitch button{font-family:var(--body);font-size:.74rem;font-weight:600;letter-spacing:.02em;
                        padding:5px 12px;border:0;border-radius:999px;background:transparent;
                        color:var(--ink2);cursor:pointer}
  .basemapswitch button[aria-pressed="true"]{background:var(--ink);color:#fff}
  .basemapswitch button:hover[aria-pressed="false"]{color:var(--ink)}

  .results-layout{display:grid;grid-template-columns:1fr;gap:22px;align-items:start}
  .mappanel{display:none}
  #firmMap{height:min(72vh,640px);border-radius:var(--radius);border:1px solid var(--line);
           background:var(--alt);overflow:hidden}

  /* Map pins: gold for a firm running ZiaMap, ink for the rest. */
  /* ---- filters and paging ---- */
  .filterrow{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:0 0 18px}
  .chip{display:inline-flex;align-items:center;gap:6px;padding:7px 14px;border-radius:999px;
        font-size:.9rem;font-weight:600;text-decoration:none;color:var(--ink2);
        background:var(--bg);box-shadow:inset 0 0 0 1.5px var(--line);
        transition:background .12s ease,color .12s ease,box-shadow .12s ease}
  .chip:hover{color:var(--ink);box-shadow:inset 0 0 0 1.5px var(--ink3)}
  .chip span{font-variant-numeric:tabular-nums;color:var(--ink3);font-weight:500}
  .chip.on{background:var(--ink);color:#fff;box-shadow:none}
  .chip.on span{color:rgb(255 255 255 / .7)}

  /* The state map has no list beside it, so it takes the full width and a
     height that reads as a map rather than a strip. */
  .mappanel.is-standalone{display:block;margin:0 0 34px}
  .mappanel.is-standalone #firmMap{height:min(58vh,520px);border-radius:var(--radius)}

  .outnote{font-size:.9rem;color:var(--ink3);margin:6px 0 0;max-width:62ch}

  .pager{display:flex;gap:14px;align-items:center;justify-content:center;margin:26px 0 0}
  .pagerat{font-size:.9rem;color:var(--ink3);font-variant-numeric:tabular-nums}

  /* ---- map markers: the v1-marker family from Interface Redesign 6.0 ----
     Shapes carried across so the directory map and the app's Journal map read
     as one product. The colors are re-meant: gold is a claimed listing here,
     not a QuickNote with photos.
     
     Two colors on this map, and only one of them is loud. Unclaimed is ink,
     the same near-black as the body text, so a hundred of them recede into the
     basemap. Gold is claimed, and it is the only saturated thing on the page,
     which is the whole visual payoff of claiming a listing.
     
     The blue that used to be here, #1d4ed8, came across from Interface
     Redesign 6.0 where it meant something else. It was the only non-brand
     color on the page, and while nothing is claimed yet it made the map a
     field of blue with nothing for gold to be louder than. */
  /* The datum is gold, verified or not. It was ink for unverified and gold for
     verified, which made the map read as a field of black pins: nothing is
     verified yet, so nobody had ever seen the gold one. Gold is the brand's
     colour and the mark is ZiaMap's own datum, so it is gold by default.

     The verified/unverified distinction survives in the EDGE rather than the
     fill: a verified datum is ringed in ink, an unverified one in white. That
     keeps the map one colour without losing the thing colour used to carry,
     which matters on the day the first firm verifies. */
  --mk-claimed:#f0b100; --mk-claimed-edge:#14181c; --mk-claimed-ink:#18181b;
  --mk-open:#f0b100;    --mk-open-edge:#b8860b;    --mk-open-ink:#14181c;

  /* The whole 56x48 box is the tap target, which is the 48px the field spec
     asks for. The badge inside is what you see. */
  .v1-marker{display:flex;align-items:center;justify-content:center;
             background:none;border:0;cursor:pointer;
             transition:transform .14s cubic-bezier(.2,.8,.2,1)}
  .v1-marker>b{position:relative;display:inline-flex;align-items:center;justify-content:center;
               font-variant-numeric:tabular-nums;line-height:1;font-weight:700;
               font-family:var(--head);letter-spacing:.01em}

  /* A single is always a pill, never a circle, even at one character: min-width
     is well clear of the height so it cannot be mistaken for a group. */
  /* A single firm is the ZiaMap mark. The apex is the coordinate, so the box
     hangs above the point rather than straddling it, and flex-end puts the
     glyph on the bottom edge where the anchor expects it. */
  .v1-marker.is-single{align-items:flex-end}
  .v1-marker.is-single>b{width:1.9rem;height:1.6rem;display:block}
  .v1-marker.is-single>b svg{display:block;width:100%;height:100%;overflow:visible}

  /* The white stroke is what lifts the mark off a busy topo basemap. Painted
     behind the fill rather than over it, so the triangle keeps its corners. */
  .v1-marker.is-single.is-claimed .dm-body{stroke:var(--mk-claimed-edge)}
  .v1-marker.is-single .dm-body{stroke:#fff;stroke-width:6;stroke-linejoin:round;
                                paint-order:stroke fill}
  .v1-marker.is-single .dm-dot{stroke:none}

  .v1-marker.is-single.is-claimed .dm-body{fill:var(--mk-claimed)}
  .v1-marker.is-single.is-claimed .dm-dot{fill:var(--mk-claimed-ink)}
  .v1-marker.is-single.is-open .dm-body{fill:var(--mk-open)}
  .v1-marker.is-single.is-open .dm-dot{fill:var(--mk-open-ink)}

  /* Placed at a ZIP centroid rather than the door. Hollow, so the map never
     claims a precision the data does not have. */
  .v1-marker.is-single.is-approx .dm-body{fill:#fff;stroke-width:2.6;stroke-dasharray:5 3.5}
  .v1-marker.is-single.is-approx.is-claimed .dm-body{stroke:var(--mk-claimed)}
  .v1-marker.is-single.is-approx.is-claimed .dm-dot{fill:var(--mk-claimed-edge)}
  .v1-marker.is-single.is-approx.is-open .dm-body{stroke:var(--mk-open)}
  .v1-marker.is-single.is-approx.is-open .dm-dot{fill:var(--mk-open)}

  /* A group is a black circle carrying its count, ringed in the color of what
     is inside. The ring names the kinds present, not the proportion. */
  /* The ring is a box-shadow, not a pseudo-element.
     
     It was a ::before at inset -5px with z-index -1, on a b that also carried
     isolation:isolate. Those two cancel: isolate makes the b its own stacking
     context, and inside one the element's own background paints before any
     negative z-index child, so the larger ring painted OVER the fill. The
     circle was never dark and the count was white on white. With a blue ring
     it read as a deliberate blue disc, which is how it survived this long. */
  .v1-marker.is-group>b{width:2.6rem;height:2.6rem;border-radius:50%;
                        background:var(--ink);color:#fff;font-size:.82rem;
                        box-shadow:0 0 0 5px #fff,0 2px 6px rgb(0 0 0 / .3)}
  .v1-marker.is-group.is-big>b{width:3rem;height:3rem;font-size:.88rem}

  /* What a cluster is made of, as a ring around what it counts. The gold arc is
     the firm share, the rest ink. --firm-share is set per marker in groupHtml. */
  .v1-marker.is-group>b{
    background:
      conic-gradient(var(--gold) 0 var(--firm-share,0%), var(--ink) var(--firm-share,0%) 100%)
      border-box;
    box-shadow:0 0 0 5px #fff,0 2px 6px rgb(0 0 0 / .3)}
  .v1-marker.is-group>b::after{content:"";position:absolute;inset:5px;border-radius:50%;
                               background:var(--ink);z-index:0}
  .v1-marker.is-group>b{position:relative;isolation:isolate}
  .v1-marker.is-group>b>i{position:relative;z-index:1;font-style:normal;
                          font-family:inherit;font-size:inherit;color:#fff}

  /* An individual licensee: a ring on its coordinate, not a monument above it.
     Smaller than the datum on purpose, since a person is not an office. */
  .v1-marker.is-single.is-person>b{width:1.5rem;height:1.5rem}
  .v1-marker.is-single.is-person{align-items:center}
  .v1-marker.is-single.is-person .dm-body{fill:var(--ink);stroke:#fff;stroke-width:5}
  .v1-marker.is-single.is-person .dm-dot{fill:var(--gold)}
  .v1-marker.is-single.is-person.is-approx .dm-body{fill:#fff;stroke:var(--ink);stroke-width:3.5;
                                                    stroke-dasharray:5 3.5}
  .v1-marker.is-single.is-person.is-approx .dm-dot{fill:var(--ink)}

  /* Coverage circles, drawn instead of pins below BUBBLE_MAX_ZOOM. Sized by
     count, split by kind: gold arc for firms, ink for individual licensees. A
     state with no firms therefore reads as a solid ink ring, which is the
     honest picture of California and the whole argument for the CLSA ask. */
  .state-bubble{display:flex;align-items:center;justify-content:center;
                background:none;border:0;cursor:pointer}
  .state-bubble>b{position:relative;display:flex;align-items:center;justify-content:center;
                  border-radius:50%;
                  background:conic-gradient(var(--gold) 0 var(--firm-share,0%),
                                            var(--ink) var(--firm-share,0%) 100%);
                  box-shadow:0 2px 10px rgb(20 24 28 / .28);
                  transform:translate(-50%,-50%);
                  transition:filter .14s ease}
  .state-bubble>b::after{content:"";position:absolute;inset:7px;border-radius:50%;
                         background:var(--card)}
  .state-bubble>b>i{position:relative;z-index:1;font-style:normal;font-family:var(--head);
                    font-weight:600;font-size:.82rem;color:var(--ink);letter-spacing:.01em}
  .state-bubble:hover>b{filter:brightness(1.06)}
  /* The ring stays white on every cluster, deliberately, for now.
     
     It used to go gold when anything inside was claimed. With one claimed firm
     in 3,160 that lit a whole region gold at national zoom, which says far more
     than one claim earns. Gold still means claimed on a single mark, where it
     points at one firm and is honest about it.
     
     The is-claimed class is still on the element, so turning this back on is
     one rule. Worth doing once enough firms have claimed that a gold cluster
     means a cluster of them rather than one. */

  /* Selected lifts. It does not gain a dark ring, because a ring reads as a
     group and the two must never be confusable. */
  .v1-marker.is-hot{transform:translateY(-3px) scale(1.08);z-index:900}

  @media (prefers-reduced-motion:reduce){
    .v1-marker{transition:none}
    .v1-marker.is-hot{transform:none;filter:drop-shadow(0 0 0 3px rgb(0 0 0 / .35))}
  }

  /* The list a group opens when zooming can never split it. */
  .pop-list{margin:8px 0 0;padding-left:18px;font-size:.9rem}
  .pop-list li{margin:2px 0}
  .leaflet-popup-content{font-family:var(--body);font-size:.88rem;line-height:1.45}
  .leaflet-popup-content strong{font-family:var(--head);font-size:1rem;color:var(--ink)}
  .leaflet-popup-content .pop-approx{color:var(--gold-text);font-size:.78rem}
  .leaflet-popup-content .pop-addr{color:var(--ink);font-size:.86rem}
  .leaflet-popup-content .pop-call{font-family:var(--head);font-weight:600}

  /* What a hover shows: the name, where it is, and the number to call.
     A tooltip rather than the popup, because a popup opens on click, takes
     focus and will not close while the pointer crosses a crowded town. */
  /* width:max-content is load bearing. Leaflet's tooltip is absolutely
     positioned with white-space:nowrap; overriding the wrap without giving it a
     width collapses the box to its narrowest possible column, one word per
     line, which is what the first version did. */
  .leaflet-tooltip.pin-tip{background:var(--ink);color:#fff;border:0;border-radius:9px;
    padding:8px 11px;box-shadow:0 10px 26px rgb(0 0 0 / .28);font-family:var(--body);
    font-size:.82rem;line-height:1.4;white-space:normal;
    width:max-content;max-width:16rem}
  .leaflet-tooltip.pin-tip b{display:block;font-family:var(--head);font-size:.92rem;
    letter-spacing:.01em}
  .leaflet-tooltip.pin-tip span{display:block;color:#cfd4da}
  .leaflet-tooltip.pin-tip i{display:block;margin-top:3px;font-style:normal;
    font-size:.74rem;color:var(--gold)}
  /* direction:auto flips the tooltip to whichever side has room, so the arrow
     can be on any edge. */
  .leaflet-tooltip.pin-tip.leaflet-tooltip-top::before{border-top-color:var(--ink)}
  .leaflet-tooltip.pin-tip.leaflet-tooltip-bottom::before{border-bottom-color:var(--ink)}
  .leaflet-tooltip.pin-tip.leaflet-tooltip-left::before{border-left-color:var(--ink)}
  .leaflet-tooltip.pin-tip.leaflet-tooltip-right::before{border-right-color:var(--ink)}
  .leaflet-popup-content .pop-meta{color:var(--ink3);font-size:.8rem}
  .leaflet-popup-content a{color:var(--gold-link);font-weight:600}

  /* A row lit from its pin, and the reverse. */
  .res.is-hot{background:var(--accent-bg)}
  .res{transition:background .16s ease}
  .res{display:grid;grid-template-columns:auto 1fr auto;gap:20px;padding:24px 0;
       border-bottom:1px solid var(--line);align-items:start;position:relative}

  /* THE WHOLE ROW IS THE LINK.
     The firm's own <a> is stretched over the card rather than the card being
     given a click handler, so it stays a real link: keyboard reachable, middle
     clickable, openable in a new tab, and it still works with JS off. Only one
     link may do this per card, which is why it is the heading's.
     Everything else interactive has to be lifted above it or the stretch eats
     the click: the website link and the Call button both go somewhere else. */
  .res > *{position:relative}
  .res h2 a::after{content:"";position:absolute;inset:0;z-index:1}
  .res .weblink a,
  .res .side .btn{position:relative;z-index:2}

  /* A row that is entirely clickable has to look it. */
  .res:hover{background:var(--accent-bg)}
  .res:hover h2 a{text-decoration:underline;text-underline-offset:3px}
  .res:has(h2 a:focus-visible){background:var(--accent-bg)}
  .res h2 a:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:3px}
  .res .avatar{width:54px;height:54px;border-radius:11px;background:var(--alt);
               border:1px solid var(--line);display:grid;place-items:center;
               font-family:var(--head);font-weight:700;color:var(--ink3);font-size:1.18rem}
  /* A claimed firm shows its own mark here instead of its initials. */
  .res .avatar.has-mark{overflow:hidden;padding:0}
  .res .avatar.has-mark img{width:100%;height:100%;object-fit:contain;display:block}
  .res h2{font-family:var(--head);font-weight:600;font-size:1.25rem;line-height:1.25;
          margin:0 0 3px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
  .res h2 a{color:var(--ink);text-decoration:none}
  .res h2 a:hover{text-decoration:underline;text-underline-offset:3px}
  .res .meta{font-size:.9rem;color:var(--ink3);margin:0 0 9px}
  .res .meta b{color:var(--ink2);font-weight:600}
  .svc{display:flex;gap:6px;flex-wrap:wrap;margin:0;padding:0;list-style:none}
  .svc li{font-size:.82rem;color:var(--ink2);background:var(--alt);border-radius:6px;padding:3px 9px}

  /* Website on claimed listings. No email address anywhere on this page: a
     roster of published addresses is a harvesting target, which is the exact
     defect the site audit flags on other people's sites. Phone and the quote
     form carry contact instead. rel=nofollow so a listing is not a link farm. */
  .weblink{margin:9px 0 0;font-size:.85rem}
  .weblink a{display:inline-flex;align-items:center;gap:6px;color:var(--gold-link);
             font-weight:600;text-decoration:none}
  .weblink a:hover{text-decoration:underline;text-underline-offset:3px}
  .weblink svg{width:14px;height:14px;color:var(--ink3);flex:none}

  .res .side{display:flex;flex-direction:column;gap:9px;align-items:flex-end;text-align:right}
  .res .side p{margin:0}
  .verified{display:inline-flex;align-items:center;gap:5px;font-size:.82rem;
            color:var(--good);font-weight:600;white-space:nowrap}
  .verified svg{width:14px;height:14px}
  .btn.sm{font-size:.9rem;padding:10px 18px}
  .btn.ghost{background:transparent;color:var(--ink);box-shadow:inset 0 0 0 1.5px var(--line)}
  .btn.ghost:hover{background:var(--bg);box-shadow:inset 0 0 0 1.5px var(--ink3)}

  /* ---- premium row ----
     The lift comes from content only ZiaMap holds, not a louder badge: one real
     shadow with offset and blur, one gold hairline. Every other row stays flat. */
  .res.pro{position:relative;background:var(--card);border:1px solid var(--line);
           border-radius:16px;padding:24px;margin:24px 0;box-shadow:var(--shadow-row)}
  .res.pro::before{content:"";position:absolute;inset:0 0 auto;height:2px;border-radius:16px 16px 0 0;
                   background:linear-gradient(90deg,var(--gold),transparent 62%)}
  .membermark{display:inline-flex;align-items:center;gap:6px;font-family:var(--body);
              font-size:.7rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
              color:var(--gold-text);background:var(--accent-bg);border:1px solid var(--accent-line);
              border-radius:999px;padding:4px 11px;white-space:nowrap}
  .membermark svg{width:13px;height:13px}

  /* Uses ZiaMap. Solid gold against the verified badge's tinted outline, because
     they sit side by side and two tinted pills would read as one label. The mark
     inside is the datum, filled ink so it stays legible on gold. */
  .ziamark{display:inline-flex;align-items:center;gap:6px;font-family:var(--body);
           font-size:.7rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
           color:var(--ink);background:var(--gold);border:1px solid var(--gold);
           border-radius:999px;padding:4px 11px;white-space:nowrap}
  .ziamark svg{width:14px;height:14px;overflow:visible}
  .ziamark .dm-body{fill:var(--ink);stroke:none}
  .ziamark .dm-dot{fill:var(--gold)}

  /* The pack. A band, not a styled row: the point is that a reader can see where
     the promoted listings stop and the roster starts. */
  .ziapack{border:1px solid var(--accent-line);background:var(--accent-bg);
           border-radius:var(--radius);padding:16px 16px 4px;margin:0 0 22px}
  .ziapack-head{margin:0 0 4px;padding:0 4px}
  .ziapack-head h2{font-family:var(--head);font-size:1.02rem;font-weight:600;color:var(--ink);
                   margin:0 0 4px;display:flex;align-items:center;gap:8px}
  .ziapack-head h2::before{content:"";width:10px;height:10px;border-radius:50%;
                           background:var(--gold);flex:none}
  .ziapack-head p{font-size:.82rem;color:var(--ink2);margin:0 0 10px;max-width:60ch}
  .ziapack .res{background:var(--card)}

  /* License not confirmed. Quieter than the verified line rather than alarming:
     an unchecked licence is a gap in what we know, not a warning about the
     firm, and styling it as a warning would defame a business for our own
     coverage problem. Same shape as .verified so they read as one field
     answering one question two ways. */
  .unverified{display:inline-flex;align-items:center;gap:7px;font-size:.82rem;
              color:var(--ink2);margin:0}
  .unverified svg{width:15px;height:15px;flex:none;color:var(--ink2);opacity:.75}
  .firm-id .unverified{font-size:.9rem}
  /* On the detail page the badge sits inside the h1, so it needs to stop
     inheriting the heading's size and baseline. */
  .firm-id h1 .ziamark{vertical-align:middle;margin-left:10px;position:relative;top:-2px}

  /* Lead tile carries the weight, three follow. Photos are the one thing in this
     row a competing directory cannot produce, so they get room to say so. */
  .shots{display:grid;grid-template-columns:1.35fr 1fr 1fr 1fr;gap:10px;margin-top:18px;max-width:680px}
  /* Only the lead tile carries the aspect ratio; it sets the row height and the
     rest stretch to match. Giving every tile 4/3 leaves the narrower three short
     and the strip reads ragged. */
  .shot{border-radius:10px;background:var(--alt);border:1px solid var(--line);
        display:grid;place-items:center;overflow:hidden}
  .shot:first-child{aspect-ratio:4/3}
  .shot svg{width:26px;height:26px;color:#B9BEC3}
  .shot.more{background:var(--ink);border-color:var(--ink);color:#fff;
             font-family:var(--head);font-weight:700;font-size:1.25rem;line-height:1.05;text-align:center}
  .shot.more small{display:block;font-family:var(--body);font-weight:500;font-size:.66rem;
                   letter-spacing:.07em;text-transform:uppercase;color:var(--panel-dim);margin-top:2px}
  .shotcap{font-size:.82rem;color:var(--ink3);margin:10px 0 0}

  .signals{display:flex;gap:18px;flex-wrap:wrap;margin:16px 0 0;padding:0;list-style:none}
  .signals li{font-size:.88rem;color:var(--ink2);display:flex;align-items:center;gap:7px}
  .signals svg{width:15px;height:15px;color:var(--gold-text);flex:none}
  .signals b{color:var(--ink);font-weight:600}

  .quickquote{display:flex;gap:8px;flex-wrap:wrap;margin-top:18px;max-width:470px}
  .quickquote .field{height:46px;flex:1 1 190px}

  /* ---- claim strip and datum ---- */
  .claimstrip{background:var(--alt);border:1px solid var(--line);border-radius:var(--radius);
              padding:20px 22px;margin-top:34px;display:flex;gap:18px;align-items:center;flex-wrap:wrap}
  .claimstrip p{margin:0;font-size:.96rem;flex:1 1 330px}
  .claimstrip b{font-family:var(--head);color:var(--ink);font-size:1.06rem;display:block;margin-bottom:2px}

  .datum{display:flex;gap:11px;align-items:flex-start;border-top:1px solid var(--line);
         padding-top:16px;margin-top:38px;max-width:52ch}
  .datum svg{width:17px;height:17px;color:var(--gold);flex:none;margin-top:4px}
  .datum b{font-family:var(--head);font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;
           color:var(--gold-text);display:block}
  .datum span{font-family:var(--head);font-weight:600;color:var(--ink);font-size:1.03rem}

  /* ---- tiers ---- */
  .claim{background:var(--alt);padding-block:56px;border-top:1px solid var(--line)}
  .claim .eyebrow{margin-bottom:12px}
  .claimlede{font-size:1.06rem;max-width:62ch;margin-bottom:0}
  .tiers{display:grid;grid-template-columns:repeat(3,1fr);border:1px solid var(--line);
         border-radius:16px;overflow:hidden;background:var(--card);margin-top:26px}
  .tier{padding:26px 22px;border-right:1px solid var(--line)}
  .tier:last-child{border-right:0}
  .tier.is-pro{background:var(--accent-bg)}
  .tier h3{font-family:var(--head);font-weight:600;font-size:1.18rem;color:var(--ink);
           margin:0 0 2px;display:flex;align-items:center;gap:9px;flex-wrap:wrap}
  .tier .who{font-size:.82rem;color:var(--ink3);margin:0 0 16px}
  .tier ul{list-style:none;padding:0;margin:0;font-size:.9rem}
  .tier li{position:relative;padding:7px 0 7px 24px;color:var(--ink2)}
  .tier li b{color:var(--ink);font-weight:600}
  .tier li::before{position:absolute;left:0;top:7px;font-weight:700;font-size:.95rem;line-height:1.5}
  .tier li.yes::before{content:"\2713";color:var(--good)}
  .tier li.no{color:var(--ink3)}
  .tier li.no::before{content:"\00d7";color:#B9BEC3}

  .microcta{margin-top:26px;font-size:.96rem}
  .microcta a{color:var(--gold-link);font-weight:600}

  /* ---- firm page ---- */
  .firm-band{padding-top:calc(var(--head-h, 76px) + 30px);padding-bottom:56px}
  .crumbs{font-size:.84rem;color:var(--ink3);margin-bottom:20px}
  .crumbs a{color:var(--gold-link);text-decoration:none;font-weight:600}
  .crumbs span{margin:0 6px;color:var(--line-strong)}

  .firm-head{display:grid;grid-template-columns:auto 1fr auto;gap:26px;align-items:start;
             padding-bottom:26px;border-bottom:1px solid var(--line)}
  /* The mark sits on its own tile. A firm's icon is usually artwork on a solid
     ground, not a transparent glyph, so it needs that ground rather than the
     page's white. Object-fit contains it so a non square mark is not cropped. */
  .firmmark{width:84px;height:84px;border-radius:16px;overflow:hidden;border:1px solid var(--line);
            background:var(--alt);flex:none}
  .firmmark img{width:100%;height:100%;object-fit:contain;display:block}
  .firm-id h1{font-family:var(--head);font-weight:700;font-size:clamp(1.7rem,3.6vw,2.4rem);
              color:var(--ink);line-height:1.1;margin:0 0 5px;letter-spacing:-.01em}
  .firm-sub{font-size:1rem;color:var(--ink3);margin:0 0 9px}
  .firm-id .verified{margin:0 0 12px}
  /* Licensed in one state, based in another. A quiet fact, not a warning. */
  .firm-note{font-size:.82rem;color:var(--ink3);margin:-6px 0 12px}
  .firm-act{display:flex;flex-direction:column;gap:10px;align-items:stretch;min-width:212px}
  .firm-act .btn{text-align:center}
  .firm-act .weblink{margin-top:2px;text-align:center}

  .cols{display:grid;grid-template-columns:1.55fr 1fr;gap:44px;margin-top:34px;align-items:start}
  .firm-main h2{font-family:var(--head);font-weight:700;font-size:1.4rem;color:var(--ink);
                margin:32px 0 10px}
  .firm-main h2:first-child{margin-top:0}
  .facts{list-style:none;padding:0;margin:0;font-size:.96rem}
  .facts li{display:grid;grid-template-columns:110px 1fr;gap:12px;padding:10px 0;
            border-bottom:1px solid var(--line)}
  .facts li:last-child{border-bottom:0}
  .facts .k{color:var(--ink3);font-size:.7rem;letter-spacing:.06em;text-transform:uppercase;
            font-family:var(--head);font-weight:700;padding-top:3px}
  .facts .v{color:var(--ink)}
  .facts .v a{color:var(--gold-link);font-weight:600;text-decoration:none}

  .bignumbers{display:flex;gap:12px;flex-wrap:wrap;margin:14px 0 0}
  /* The second group on a city or county page: firms that cover the place
     without being based in it. Set apart so the distinction is readable. */
  .alsocovers{font-family:var(--head);font-weight:600;font-size:1.15rem;color:var(--ink);
    margin:34px 0 2px;padding-top:26px;border-top:1px solid var(--line)}
  .alsocoverslede{font-size:.92rem;color:var(--ink3);margin:0 0 4px}

  .quotelede{font-size:.92rem;color:var(--ink3)}
  .quoteform{display:grid;gap:10px;max-width:520px}
  .fieldpair{display:grid;grid-template-columns:1fr 1fr;gap:10px}
  .field-tall{height:auto;align-items:flex-start;padding-top:12px;padding-bottom:12px}
  .field-tall textarea{border:0;outline:0;font:inherit;font-size:1rem;color:var(--ink);
                       background:transparent;width:100%;resize:vertical;line-height:1.5}
  .quotenote{font-size:.85rem;color:var(--ink3);margin:4px 0 0;max-width:52ch}
  .quotenote a{color:var(--gold-link);font-weight:600}
  .matchlist{list-style:none;padding:0;margin:20px 0 0;border-top:1px solid var(--line)}
  .matchlist li{display:flex;gap:16px;align-items:center;justify-content:space-between;
                padding:14px 0;border-bottom:1px solid var(--line)}
  .matchlist b{display:block;font-family:var(--head);font-weight:600;color:var(--ink);font-size:1.05rem}
  .matchlist span{font-size:.85rem;color:var(--ink3)}
  .alreadyclaimed{font-size:.8rem;color:var(--ink3);font-style:italic;white-space:nowrap}
  @media (max-width:560px){ .matchlist li{flex-direction:column;align-items:flex-start;gap:8px} }
  .formerrors{background:#FBEFED;border:1px solid #B4342A;border-radius:10px;padding:12px 16px}
  .formerrors p{margin:0;font-size:.9rem;color:#8E1C12}
  @media (max-width:520px){ .fieldpair{grid-template-columns:1fr} }

  /* Add-your-firm. A wrapping grid rather than fixed columns, because the row
     is address, city, state, ZIP, phone and website, and forcing those into
     equal halves puts a two-character state field next to a website. */
  .addform{max-width:640px}
  .addform .fieldgrid{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 10px}
  .addform .field-sm{flex:0 1 120px}
  .addform .field-tall{width:100%}
  .addform .formerrors{margin:0 0 18px}
  .addform button[type=submit]{margin-top:14px}

  /* Pick what you do, do not type it. A wrapping set of chips rather than a
     column of checkboxes: seven options in a list reads as a form to fill in,
     and as chips it reads as a question with seven answers. */
  .svcpick{border:0;padding:0;margin:0 0 6px}
  .svcpick legend{font-size:.9rem;color:var(--ink2);padding:0;margin:0 0 8px}
  .svcbox{display:inline-flex;align-items:center;gap:8px;margin:0 8px 8px 0;
          padding:9px 14px;border:1px solid var(--line);border-radius:999px;
          background:var(--bg);font-size:.88rem;cursor:pointer}
  .svcbox:has(input:checked){background:var(--accent-bg);border-color:var(--accent-line);
                             color:var(--gold-text);font-weight:600}
  .svcbox input{accent-color:var(--gold);width:15px;height:15px;cursor:pointer}
  .svcbox:focus-within{outline:2px solid var(--gold);outline-offset:2px}

  /* Coverage areas. Chips above the box rather than inside it: a firm covering
     fourteen counties should not be typing into a field that has shrunk to
     forty pixels. */
  .placepick{position:relative;margin:0 0 6px}
  .placechips{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 10px}
  .placechips:empty{display:none}
  .placechip{display:inline-flex;align-items:center;gap:8px;padding:7px 10px 7px 14px;
             border-radius:999px;background:var(--accent-bg);border:1px solid var(--accent-line);
             color:var(--gold-text);font-size:.86rem;font-weight:600}
  .placechip button{border:0;background:transparent;color:var(--gold-text);cursor:pointer;
                    font-size:1.05rem;line-height:1;padding:0 2px}
  .placechip button:hover{color:var(--ink)}
  .placehits{position:absolute;left:0;right:0;z-index:20;background:var(--card);
             border:1px solid var(--line);border-radius:12px;overflow:hidden;
             box-shadow:0 10px 30px rgb(20 24 28 / .14)}
  .placehits:empty{display:none}
  .placehits .placehit{display:block;width:100%;text-align:left;padding:11px 16px;border:0;
                       background:transparent;font-family:var(--body);font-size:.9rem;
                       color:var(--ink);cursor:pointer}
  .placehits .placehit:hover,.placehits .placehit:focus{background:var(--alt);outline:none}
  .quoteform .field{height:50px}
  /* The textarea is the one field that is not one line tall. This has to beat
     the rule above it, which was setting every field in the form to 50px and
     crushing a three row box into a single line. */
  .quoteform .field-tall{height:auto;min-height:98px}
  .quoteform .btn{justify-self:start}

  /* ONE MEASURE FOR THE BLOCK. The heading and the lede wrapped at 550px while
     the fields stopped at 520, so three elements stacked vertically had three
     different right edges and only the left one agreed. The note keeps its own
     narrower 52ch: that is a reading measure and it is meant to be shorter. */
  #quote,
  .quotelede{max-width:520px}

  .firm-side{display:grid;gap:16px}
  .sidebox{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:20px}
  .sidebox.is-own{background:var(--accent-bg);border-color:var(--accent-line)}

  /* The one-firm map in the sidebar. Square, because a single pin has no spread
     to show and the hub's 640px-tall panel would be mostly empty ground.
     aspect-ratio rather than a fixed height so it stays square at every sidebar
     width; the map controller already waits for a settled box before building,
     which is what makes a height derived from width safe here. */
  .sidebox.is-map{padding:16px}
  .firmmap{margin:0 0 10px}
  /* .firm-page sits on the SAME element as .directory-hub, so a descendant
     selector never matches it. .firmmap only exists on the firm page anyway. */
  .firmmap #firmMap{height:auto;width:100%;aspect-ratio:1/1;
                    border-radius:calc(var(--radius) - 6px)}
  .maploc{font-size:.84rem;color:var(--ink2);margin:0}
  .sidebox h3{font-family:var(--head);font-weight:600;font-size:1.06rem;color:var(--ink);margin:0 0 8px}
  .sidebox p{font-size:.9rem;margin-bottom:.7em}
  .sidebox p:last-child{margin-bottom:0}

  @media (max-width:860px){
    .firm-head{grid-template-columns:auto 1fr}
    .firm-act{grid-column:1 / -1;flex-direction:row;flex-wrap:wrap;min-width:0}
    .firm-act .weblink{text-align:left;width:100%}
    .cols{grid-template-columns:1fr;gap:30px}
  }
  @media (max-width:560px){
    .firmmark{width:64px;height:64px;border-radius:13px}
    .facts li{grid-template-columns:1fr;gap:2px}
  }

  /* ---- guides: reading, not operating ---- */
  &.guide .guide-band{padding-top:calc(var(--head-h, 76px) + 34px);padding-bottom:64px}
  .guide h1{max-width:20ch}
  .guide-lede{font-size:1.2rem;line-height:1.5;color:var(--ink2);max-width:60ch;margin:0 0 8px}
  .guide-body{margin-top:34px}
  .guide-body p{font-size:1.06rem;line-height:1.65;max-width:68ch}
  .guide-body h2{font-family:var(--head);font-weight:700;font-size:1.55rem;color:var(--ink);
                 margin:38px 0 10px;max-width:30ch}
  .guide-body h3{font-family:var(--head);font-weight:600;font-size:1.18rem;color:var(--ink);margin:26px 0 6px}
  .guide-body ul{margin:0 0 1em;padding-left:20px;max-width:68ch}
  .guide-body li{font-size:1.04rem;line-height:1.6;margin-bottom:.4em}
  .guide-body a{color:var(--gold-link);font-weight:600}

  .callout{background:var(--alt);border:1px solid var(--line);border-radius:var(--radius);
           padding:22px 24px;margin:32px 0 0}
  .callout h3{margin-top:0}
  .callout p:last-child{margin-bottom:0}
  .callout-todo{background:var(--accent-bg);border-color:var(--accent-line)}

  .guide-more{margin-top:44px;padding-top:22px;border-top:1px solid var(--line)}
  .guide-more h2{font-family:var(--head);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;
                 color:var(--ink3);font-weight:700;margin:0 0 12px}
  .guide-more ul,.guide-list{list-style:none;padding:0;margin:0}
  .guide-more li{padding:12px 0;border-bottom:1px solid var(--line)}
  .guide-more li:last-child{border-bottom:0}
  .guide-more a{color:var(--ink);font-family:var(--head);font-weight:600;text-decoration:none}
  .guide-more a:hover{text-decoration:underline;text-underline-offset:3px}
  .guide-more span{display:block;font-size:.88rem;color:var(--ink3);margin-top:2px}

  .guide-list li{padding:20px 0;border-bottom:1px solid var(--line)}
  .guide-list li:last-child{border-bottom:0}
  .guide-list h2{font-family:var(--head);font-weight:600;font-size:1.3rem;margin:0 0 4px}
  .guide-list h2 a{color:var(--ink);text-decoration:none}
  .guide-list h2 a:hover{text-decoration:underline;text-underline-offset:3px}
  .guide-list p{font-size:.98rem;color:var(--ink3);margin:0}

  /* ---- state index ---- */
  .citiesh{font-family:var(--head);font-weight:700;font-size:1.6rem;color:var(--ink);margin:0 0 6px}
  .citygrid{list-style:none;padding:0;margin:18px 0 0;display:grid;
            grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:10px}
  .citygrid a{display:flex;align-items:baseline;gap:10px;background:var(--card);
              border:1px solid var(--line);border-radius:12px;padding:14px 16px;text-decoration:none;
              transition:border-color .16s ease,transform .16s cubic-bezier(.2,.8,.2,1)}
  .citygrid a:hover{border-color:var(--ink3);transform:translateY(-1px)}
  .citygrid b{font-family:var(--head);font-weight:600;color:var(--ink);font-size:1rem}
  .citygrid i{font-style:normal;margin-left:auto;color:var(--ink3);font-size:.85rem;
              font-variant-numeric:tabular-nums}

  /* ---- the firm's own side ---- */
  &.portal .firm-band{padding-top:calc(var(--head-h, 76px) + 26px)}
  .portalnav{display:flex;gap:20px;align-items:center;flex-wrap:wrap;font-size:.92rem;
             padding-bottom:16px;margin-bottom:26px;border-bottom:1px solid var(--line)}
  .portalnav a{color:var(--ink2);text-decoration:none;font-weight:500}
  .portalnav a.on{color:var(--ink);font-weight:700}
  .portalnav a:hover{color:var(--ink)}
  .portalnav-sep{flex:1}

  /* ---- ask for reviews ---- */
  .askh{font-family:var(--head);font-weight:700;font-size:1.05rem;margin:0 0 6px}
  /* The messages are meant to be read, edited and copied, so they wrap like
     prose rather than scrolling sideways the way a code block would. */
  .askbox{white-space:pre-wrap;word-break:break-word;font:inherit;
          background:var(--bg);border:1px solid var(--line);border-radius:10px;
          padding:14px 16px;margin:0 0 10px;font-size:.95rem;line-height:1.5}

  /* The card the crew leaves behind. Sized so the printed version lands near a
     business card rather than filling a sheet. */
  .askcard{max-width:340px;margin:18px 0 0;padding:24px 22px;text-align:center;
           background:var(--bg);border:1px solid var(--line);border-radius:14px}
  .askcard-h{font-family:var(--head);font-weight:700;font-size:1.25rem;margin:0 0 8px}
  .askcard-b{font-size:.92rem;color:var(--ink2);margin:0 0 16px}
  .askcard-qr{min-height:132px;display:flex;align-items:center;justify-content:center}
  .askcard-qr img{width:132px;height:132px;display:block;image-rendering:pixelated}
  .askcard-f{font-size:.85rem;color:var(--ink3);margin:14px 0 0}

  .alertstrip{display:flex;gap:18px;align-items:center;flex-wrap:wrap;
              background:var(--accent-bg);border:1px solid var(--accent-line);
              border-radius:var(--radius);padding:16px 20px;margin:22px 0 0}
  .alertstrip p{margin:0;flex:1 1 320px;font-size:.96rem}

  .checklist li.done b{color:var(--good)}
  .checklist li.todo::before{content:"\00b7";color:var(--ink3)}
  .checklist li b{display:inline-block;min-width:96px;font-weight:600;color:var(--ink)}
  .checklist li span{color:var(--ink3);font-size:.9rem}

  .portalform{max-width:none}
  .fieldblock{display:block;margin-bottom:20px}
  .fieldblock .fl{display:block;font-family:var(--head);font-weight:700;font-size:.72rem;
                  letter-spacing:.1em;text-transform:uppercase;color:var(--ink2);margin-bottom:4px}
  .fieldblock .fh{display:block;font-size:.85rem;color:var(--ink3);margin-bottom:8px;max-width:60ch}
  .fieldblock input,.fieldblock textarea{width:100%;font:inherit;font-size:1rem;color:var(--ink);
              background:var(--field);border:1px solid var(--line);border-radius:10px;padding:12px 14px;
              resize:vertical;line-height:1.5}
  .fieldblock input:focus,.fieldblock textarea:focus{outline:0;border-color:var(--ink)}

  .quotecard{border:1px solid var(--line);border-radius:var(--radius);background:var(--card);
             padding:22px 24px;margin-bottom:14px}
  .quotecard header{display:flex;gap:14px;align-items:baseline;justify-content:space-between;flex-wrap:wrap}
  .quotecard h2{font-family:var(--head);font-weight:600;font-size:1.15rem;color:var(--ink);margin:0}
  .qwhen{font-size:.82rem;color:var(--ink3);white-space:nowrap}
  .qtype{font-size:.88rem;color:var(--gold-text);font-weight:600;margin:6px 0 0}
  .qdetail{font-size:.94rem;margin:10px 0 0}
  .qfrom{font-size:.92rem;margin:12px 0 0;padding-top:12px;border-top:1px solid var(--line)}
  .qfrom a{color:var(--gold-link);font-weight:600}

  /* ---- claim page ---- */
  &.claim-page .hero h1{max-width:22ch}
  .claimnote{font-size:.9rem;color:var(--ink3);margin-top:-8px}

  .steps-band{padding-block:44px 8px}
  .steps{list-style:none;counter-reset:none;padding:0;margin:0;display:grid;gap:34px;max-width:70ch}
  .steps li{position:relative;padding-left:52px}
  .stepnum{position:absolute;left:0;top:0;width:34px;height:34px;border-radius:50%;
           display:grid;place-items:center;background:var(--ink);color:#fff;
           font-family:var(--head);font-weight:700;font-size:1rem}
  .steps h2{font-family:var(--head);font-weight:600;font-size:1.3rem;color:var(--ink);margin:2px 0 6px}
  .steps p{font-size:.98rem;margin-bottom:.6em}
  .steps .searchrow{margin-top:14px}
  .verifiedline{display:inline-flex;align-items:center;gap:8px;background:var(--good-bg);
                color:var(--good);font-weight:600;font-size:.92rem;
                border-radius:999px;padding:8px 16px;margin:4px 0 0}
  .verifiedline svg{width:16px;height:16px;flex:none}

  /* ---- the scorecard ---- */
  .card-band{padding-block:44px 56px}
  .scorecard{border:1px solid var(--line);border-radius:18px;background:var(--card);
             box-shadow:var(--shadow-row);overflow:hidden;max-width:920px}
  .sc-head{display:grid;grid-template-columns:1fr auto;gap:24px;align-items:end;
           padding:26px 28px;border-bottom:1px solid var(--line)}
  .sc-kicker{font-family:var(--head);font-size:.7rem;letter-spacing:.12em;text-transform:uppercase;
             color:var(--gold-text);font-weight:700;margin:0 0 6px}
  .sc-head h2{font-family:var(--head);font-weight:700;font-size:1.6rem;color:var(--ink);margin:0}
  .sc-sub{font-size:.9rem;color:var(--ink3);margin:3px 0 0}
  .sc-score{text-align:right}
  .sc-score .n{font-family:var(--head);font-weight:700;font-size:3.1rem;line-height:.9;
               color:var(--bad);font-variant-numeric:tabular-nums;display:block}
  .sc-score .n em{font-style:normal;font-size:.36em;color:var(--ink3)}
  .sc-score .lab{font-family:var(--head);font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;
                 color:var(--ink3);font-weight:700;display:block;margin-top:5px}

  /* Six facts, not six cards: one grid, hairlines between, severity carried by a
     1px rule under the value rather than a tinted box per item. */
  .sc-grid{display:grid;grid-template-columns:repeat(3,1fr)}
  .sc-item{padding:20px 24px;border-right:1px solid var(--line);border-bottom:1px solid var(--line)}
  .sc-item:nth-child(3n){border-right:0}
  .sc-item:nth-last-child(-n+3){border-bottom:0}
  .sc-item .k{font-family:var(--head);font-size:.68rem;letter-spacing:.11em;text-transform:uppercase;
              color:var(--ink3);font-weight:700;margin:0 0 5px}
  .sc-item .v{font-family:var(--head);font-weight:600;font-size:1.12rem;color:var(--ink);
              margin:0 0 8px;padding-bottom:8px;border-bottom:2px solid var(--line)}
  .sc-item.bad .v{border-bottom-color:var(--bad)}
  .sc-item.warn .v{border-bottom-color:var(--gold)}
  .sc-item .a{font-size:.86rem;color:var(--ink2);margin:0;line-height:1.5}

  .sc-foot{padding:22px 28px;background:var(--alt);border-top:1px solid var(--line)}
  .sc-foot p{margin:0;font-size:.96rem;max-width:66ch}
  .sc-foot b{font-family:var(--head);color:var(--ink)}
  .sc-priv{margin-top:10px !important;font-size:.82rem !important;color:var(--ink3)}

  .afterwrap{display:grid;grid-template-columns:1.3fr 1fr;gap:40px;align-items:start;margin-top:22px}
  .afterside{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:22px}
  .afterside h3,.afterwrap h3{font-family:var(--head);font-weight:600;font-size:1.15rem;color:var(--ink);margin:0 0 10px}
  .afterside p{font-size:.92rem}
  .fixlist{list-style:none;padding:0;margin:0;font-size:.96rem}
  .fixlist li{position:relative;padding:8px 0 8px 26px;border-bottom:1px solid var(--line);color:var(--ink2)}
  .fixlist li:last-child{border-bottom:0}
  .fixlist li::before{content:"\2713";position:absolute;left:0;top:8px;color:var(--good);font-weight:700}

  @media (max-width:860px){
    .sc-grid{grid-template-columns:1fr 1fr}
    .sc-item:nth-child(3n){border-right:1px solid var(--line)}
    .sc-item:nth-child(2n){border-right:0}
    .sc-item:nth-last-child(-n+3){border-bottom:1px solid var(--line)}
    .sc-item:nth-last-child(-n+2){border-bottom:0}
    .afterwrap{grid-template-columns:1fr;gap:28px}
  }
  @media (max-width:560px){
    .sc-head{grid-template-columns:1fr;align-items:start}
    .sc-score{text-align:left}
    .sc-grid{grid-template-columns:1fr}
    .sc-item{border-right:0 !important;border-bottom:1px solid var(--line) !important}
    .sc-item:last-child{border-bottom:0 !important}
  }

  /* Unclaimed firms have no mark, so the monogram is the normal case rather
     than the fallback. Square, same slot, so the row never shifts. */
  .firmmark--mono{display:grid;place-items:center;background:var(--alt);
                  font-family:var(--head);font-weight:700;font-size:1.5rem;color:var(--ink3)}

  .emptystate{padding:44px 0 8px;max-width:60ch}
  .emptystate h2{font-family:var(--head);font-weight:600;font-size:1.5rem;color:var(--ink);margin:0 0 10px}
  .emptystate p{font-size:.96rem}

  .rosternote{margin-top:30px;font-size:.85rem;color:var(--ink3);max-width:70ch}
  .rosternote a{color:var(--gold-link);font-weight:600}
  .container.narrow{max-width:780px}

  /* ---- view states ----
     Split only exists where there is room for two readable columns. Below that
     the toggle still offers list and map, one at a time. */
  &[data-view="map"] .results-panel{display:none}
  &[data-view="map"] .mappanel{display:block}
  @media (min-width:1000px){
    &[data-view="split"] .results-layout{grid-template-columns:minmax(0,1.25fr) minmax(0,1fr)}
    &[data-view="split"] .mappanel{display:block;position:sticky;top:calc(var(--head-h,76px) + 18px)}
    /* The premium row loses its photo strip in split: the column is too narrow
       for four tiles to read, and a cramped strip is worse than none. */
    &[data-view="split"] .shots,
    &[data-view="split"] .quickquote{display:none}
    &[data-view="split"] .res{grid-template-columns:auto 1fr}
    &[data-view="split"] .res .side{grid-column:2;align-items:flex-start;text-align:left;
                                    flex-direction:row;flex-wrap:wrap;gap:12px;align-items:center}
  }
  @media (max-width:999px){
    .viewtoggle button[data-view="split"]{display:none}
  }

  /* ---- narrow ---- */
  @media (max-width:860px){
    .tiers{grid-template-columns:1fr}
    .tier{border-right:0;border-bottom:1px solid var(--line)}
    .tier:last-child{border-bottom:0}
  }
  @media (max-width:760px){
    .res{grid-template-columns:auto 1fr}
    .res .side{grid-column:2;align-items:flex-start;text-align:left;
               flex-direction:row;flex-wrap:wrap;gap:14px;align-items:center}
  }
  @media (max-width:640px){
    /* Two up: every tile takes the aspect ratio back, since no single tile leads. */
    .shots{grid-template-columns:1fr 1fr;max-width:none}
    .shot,.shot:first-child{aspect-ratio:4/3}
    .shot svg{width:22px;height:22px}
    .res.pro{padding:20px}
  }
}

/* Printing just the review card.
   Set on <body> by the review-ask controller for the duration of window.print.

   Hiding by visibility rather than display, because the card sits several
   levels inside a .scorecard and display:none on an ancestor cannot be undone
   by a descendant, while visibility:hidden can. The card is then lifted to the
   top of the sheet so it does not print on page four where it happens to sit. */
@media print {
  body.printing-card * {
    visibility: hidden;
  }

  body.printing-card .askcard,
  body.printing-card .askcard * {
    visibility: visible;
  }

  body.printing-card .askcard {
    position: absolute;
    top: 0;
    left: 0;
    width: 3.5in;
    margin: 0;
    border: 1px solid #14181C;
    break-inside: avoid;
  }

  /* The QR is the point of the card, so it must not be dropped as a background
     or shrunk by a print scale. */
  body.printing-card .askcard-qr img {
    width: 1.4in;
    height: 1.4in;
  }
}
