/* =============================================================================
   47th.llc — Azora style
   -----------------------------------------------------------------------------
   The same design system built for labs.llc, carried onto the directory. Only
   two things change: the accent is a muted antique gold rather than a burnt
   orange, and the register is doing considerably more work -- fourteen hundred
   listings rather than forty-six properties -- so it carries a search field, a
   market filter and batched rendering.

   Everything else is the system as written:
   -----------------------------------------------------------------------------
   white paper, one ink, a great deal of air, and type doing the work that
   colour used to do.

   The whole system is five decisions:

     ink      #1E262B   near-black with the blue left in, never pure #000
     paper    #FFFFFF
     deep     #11161C   the dark band, one step colder than the ink
     line     a 10% ink hairline; there are no heavy borders anywhere
     measure  1265px

   Type is DM Sans at four weights. Display sizes run LIGHT (200-300) with
   tight negative tracking, which is what makes a large heading read as calm
   rather than loud; small text runs 500-700 and positive-tracked. That
   inversion -- big text light, small text heavy -- is the single most load-
   bearing rule in the sheet.
   ========================================================================== */

:root {
    --ink:        #1E262B;
    --ink-77:     rgba(30, 38, 43, .77);
    --ink-55:     rgba(30, 38, 43, .55);
    --paper:      #ffffff;
    --deep:       #11161C;
    --deep-soft:  #171E26;
    --line:       rgba(30, 38, 43, .12);
    --line-soft:  rgba(30, 38, 43, .07);
    --line-dark:  rgba(255, 255, 255, .13);
    --muted:      #878787;

    /* One restrained accent, used for rules and indicators only -- never for
       large fills. The previous build's orange, taken down to an antique gold
       that reads as the trade rather than as a warning label. */
    --accent:     #A67C3D;

    --measure:    1265px;
    --gutter:     clamp(20px, 5vw, 56px);

    /* A section's vertical rhythm. Everything is a multiple of this so bands
       stack without anyone having to think about it. */
    --band:       clamp(64px, 9vw, 128px);

    --ease:       cubic-bezier(.22, .61, .36, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
    margin: 0;
    background: var(--paper);
    color: var(--ink-77);
    font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
    font-size: 17px;
    line-height: 1.62;
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 { color: var(--ink); margin: 0; font-weight: 600; }

/* Display sizes. Light weight, tight tracking, short leading -- the three
   together are the house voice. */
.d1 {
    font-size: clamp(2.1rem, 5.2vw, 3.9rem);
    font-weight: 200; letter-spacing: -.035em; line-height: 1.09;
}
.d2 {
    font-size: clamp(1.75rem, 3.5vw, 2.77rem);
    font-weight: 600; letter-spacing: -.04em; line-height: 1.06;
}
.d3 {
    font-size: clamp(1.25rem, 2vw, 1.6rem);
    font-weight: 300; letter-spacing: -.028em; line-height: 1.22;
}

/* The eyebrow. Every band opens with one; it is the only place small-caps
   tracking appears, so it reads as a system label rather than as text. */
.eyebrow {
    display: flex; align-items: center; gap: .7rem;
    font-size: .688rem; font-weight: 700;
    letter-spacing: .19em; text-transform: uppercase;
    color: var(--ink-55);
    margin: 0 0 1.6rem;
}
.eyebrow::before {
    content: ''; width: 26px; height: 1px; background: var(--accent); flex: 0 0 auto;
}
.eyebrow.on-deep { color: rgba(255,255,255,.62); }

.lede {
    font-size: clamp(1.02rem, 1.35vw, 1.19rem);
    line-height: 1.6; font-weight: 300; color: var(--ink-77);
    max-width: 62ch;
}

a { color: inherit; }

.wrap { max-width: var(--measure); margin: 0 auto; padding-inline: var(--gutter); }
.band { padding-block: var(--band); }
.band--deep { background: var(--deep); color: rgba(255,255,255,.72); }
.band--deep h1, .band--deep h2, .band--deep h3, .band--deep h4 { color: #fff; }
.band--tint { background: #FAFAFA; }
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }

/* =============================================================================
   NAV
   ========================================================================== */

.nav {
    position: sticky; top: 0; z-index: 60;
    background: rgba(255,255,255,.86);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid var(--line-soft);
}
.nav__in {
    max-width: var(--measure); margin: 0 auto; padding: 0 var(--gutter);
    height: 74px; display: flex; align-items: center; gap: 1.5rem;
}
.nav__mark { display: flex; align-items: center; gap: .8rem; text-decoration: none; margin-right: auto; }
.nav__mark img { display: block; width: 78px; height: 33px; }
.nav__mark span {
    font-size: .6rem; font-weight: 700; letter-spacing: .32em;
    text-transform: uppercase; color: var(--ink-55);
    padding-left: .8rem; border-left: 1px solid var(--line);
}
@media (max-width: 900px) { .nav__mark span { display: none; } }

.nav__links { display: flex; align-items: center; gap: 1.9rem; }
@media (max-width: 1040px) { .nav__links { display: none; } }
.nav__links a {
    text-decoration: none; font-size: .875rem; font-weight: 500;
    color: var(--ink-77); letter-spacing: -.01em; position: relative; padding-block: .4rem;
}
.nav__links a::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0;
    height: 1px; background: var(--ink); transform: scaleX(0); transform-origin: left;
    transition: transform .32s var(--ease);
}
.nav__links a:hover::after, .nav__links a[aria-current]::after { transform: scaleX(1); }
.nav__links a[aria-current] { color: var(--ink); }

/* The cross-link to the previous build at /site2. Sized to sit between the
   nav links and the Contact button without competing with either: hairline
   box, no fill, label at the eyebrow's size and tracking. It is the only
   outbound thing in the header, so it carries the live dot and an arrow —
   the two marks used everywhere else on the page for "this leaves here".

   Below 1040 it folds down to the dot and the arrow, then disappears entirely
   at the drawer breakpoint, where the drawer repeats it in full. */
.nav__alt {
    display: inline-flex; align-items: center; gap: .5rem;
    padding: .42rem .8rem; border-radius: 999px;
    border: 1px solid var(--line); text-decoration: none;
    /* Set as a nav link, not as an eyebrow. It was .655rem/700 with .15em
       tracking in caps, which is the label voice used on the band headings --
       beside Insights and What We Believe it read as a different kind of
       object entirely. These four values are lifted from `.nav__links a`. */
    font-size: .875rem; font-weight: 500; letter-spacing: -.01em; text-transform: none;
    color: var(--ink-77); white-space: nowrap;
    transition: border-color .25s var(--ease), color .25s var(--ease), background .25s var(--ease);
}
.nav__alt:hover { border-color: var(--ink); color: var(--ink); background: #FAFAFA; }
.nav__alt .live-dot { margin-right: 0; }
/* The label now carries nav-sized type, so the pill is wider and folds to its
   dot and arrow a little earlier than it used to. */
@media (max-width: 1250px) { .nav__alt .nav__alt-l { display: none; } }
@media (max-width: 1040px) { .nav__alt { display: none; } }

/* The drawer's copy of the same link, set as its own neighbours are for the
   same reason the pill is. The rule it separates itself with stays -- it is
   still the one destination in the list that leaves this site. */
.nav__drawer-alt {
    display: flex; align-items: center; gap: .55rem;
    margin-top: .35rem; padding-top: .85rem !important;
    border-top: 1px solid var(--line); border-bottom: 0 !important;
    letter-spacing: -.01em; text-transform: none;
}

/* The burger, and the drawer it opens. Two rules rather than a component:
   below the breakpoint the link row goes and this arrives, and there is never
   a width where both are showing. */
.nav__burger {
    display: none; width: 40px; height: 40px; padding: 0;
    background: transparent; border: 1px solid var(--line); border-radius: 8px;
    cursor: pointer; align-items: center; justify-content: center; flex-direction: column; gap: 5px;
}
.nav__burger span { display: block; width: 16px; height: 1.5px; background: var(--ink);
                    transition: transform .28s var(--ease), opacity .28s var(--ease); }
.nav__burger[aria-expanded="true"] span:first-child { transform: translateY(3.25px) rotate(45deg); }
.nav__burger[aria-expanded="true"] span:last-child  { transform: translateY(-3.25px) rotate(-45deg); }
@media (max-width: 1040px) { .nav__burger { display: flex; } }

.nav__drawer {
    display: none; flex-direction: column;
    border-top: 1px solid var(--line-soft); background: var(--paper);
    padding: .5rem var(--gutter) 1.1rem;
}
.nav__drawer:not([hidden]) { display: flex; }
.nav__drawer a {
    text-decoration: none; color: var(--ink-77); font-size: .95rem; font-weight: 500;
    padding: .78rem 0; border-bottom: 1px solid var(--line-soft);
}
.nav__drawer a:last-child { border-bottom: 0; }
.nav__drawer a:hover { color: var(--ink); }
@media (min-width: 1041px) { .nav__drawer { display: none !important; } }

/* =============================================================================
   BUTTONS
   ========================================================================== */

.btn {
    display: inline-flex; align-items: center; gap: .6rem;
    font: inherit; font-size: .82rem; font-weight: 600; letter-spacing: .02em;
    padding: .72rem 1.15rem; border-radius: 8px;
    border: 1px solid transparent; background: var(--ink); color: #fff;
    text-decoration: none; cursor: pointer;
    transition: background .25s var(--ease), color .25s var(--ease),
                border-color .25s var(--ease), transform .25s var(--ease);
}
.btn:hover { background: #000; transform: translateY(-1px); }
.btn:active { transform: none; }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn--ghost:hover { background: var(--ink); color: #fff; border-color: var(--ink); }

/* The hero's call to action: uppercase, hairline box, arrow that steps out on
   hover. Deliberately not the filled button -- over a photographic field a
   solid block reads as a banner ad. */
.btn--outline {
    background: transparent; color: #fff; border-color: rgba(255,255,255,.45);
    text-transform: uppercase; font-size: .72rem; letter-spacing: .13em; font-weight: 600;
    padding: .82rem 1.35rem;
}
.btn--outline:hover { background: #fff; color: var(--ink); border-color: #fff; }
.btn i { transition: transform .25s var(--ease); }
.btn:hover i { transform: translateX(3px); }

/* =============================================================================
   HERO
   ========================================================================== */

.hero { position: relative; min-height: min(84vh, 720px); display: flex; align-items: flex-end;
        background: var(--deep); overflow: hidden; }
/* The reference site opens on an aerial photograph. There is no photograph to
   use here, and borrowing theirs was never an option, so the field is drawn:
   a slow horizon of fine verticals on a cold charcoal ground, painted to a
   canvas. It carries the same weight as a photo -- something quiet happening
   behind the words -- without pretending to be one. */
.hero__field { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* The scrim exists to protect the headline, and it was doing considerably more
   than that: at 94/72/30 it covered the whole width, so the field behind it
   was washed out everywhere rather than only under the type. Now it is heavy
   where the words are and clears quickly across, and the bottom pass stops
   short of the figures instead of climbing into the middle of the frame. */
.hero__scrim {
    position: absolute; inset: 0;
    background:
        linear-gradient(90deg, rgba(17,22,28,.92) 0%, rgba(17,22,28,.86) 26%,
                               rgba(17,22,28,.42) 62%, rgba(17,22,28,.06) 100%),
        linear-gradient(0deg,  rgba(17,22,28,.80) 0%, rgba(17,22,28,0) 38%);
}
.hero__in { position: relative; width: 100%; padding-block: clamp(56px, 11vw, 118px); }
.hero h1 { color: #fff; max-width: 20ch; }
.hero p { color: rgba(255,255,255,.74); max-width: 52ch; margin: 1.5rem 0 2.2rem; font-weight: 300; }

/* The live strip along the bottom of the hero — the one place the old build's
   pulse survives, reduced to a line of figures. */
.hero__ticker {
    position: relative; z-index: 2;
    border-top: 1px solid var(--line-dark);
    display: flex; flex-wrap: wrap; gap: 0;
}
.hero__stat {
    flex: 1 1 190px; padding: 1.15rem 0 1.25rem;
    border-right: 1px solid var(--line-dark);
}
.hero__stat:last-child { border-right: 0; }
.hero__stat b {
    display: block; font-size: 1.55rem; font-weight: 300; letter-spacing: -.03em; color: #fff;
    font-variant-numeric: tabular-nums;
}
/* Direct child only. As `.hero__stat span` this also caught the counter's own
   span inside the <b>, which shrank the figure to label size -- the number and
   its caption rendered at the same 10px. */
.hero__stat > span {
    display: block; margin-top: .15rem;
    font-size: .625rem; font-weight: 600; letter-spacing: .17em; text-transform: uppercase;
    color: rgba(255,255,255,.5);
}
/* Two up rather than four down on a phone. At a 190px basis each figure took a
   full row, which pushed the last one most of a screen below the headline and
   turned a four-figure summary into a scroll. */
@media (max-width: 640px) {
    .hero__stat { flex: 1 1 42%; padding: .95rem 0 1rem; }
    .hero__stat:nth-child(2n) { border-right: 0; padding-left: 1.1rem; }
    .hero__stat:nth-child(n+3) { border-top: 1px solid var(--line-dark); }
    .hero__stat b { font-size: 1.32rem; }
}

.live-dot {
    display: inline-block; width: 6px; height: 6px; border-radius: 50%;
    background: var(--accent); margin-right: .5rem; vertical-align: middle;
    animation: pulse 2.6s ease-in-out infinite;
}
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .live-dot { animation: none; } }

/* =============================================================================
   SPLIT — the two-column band the reference uses for every prose section
   ========================================================================== */

.split { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(2rem, 5vw, 5.5rem); }
@media (max-width: 860px) { .split { grid-template-columns: 1fr; gap: 2rem; } }
.split--even { grid-template-columns: 1fr 1fr; }
@media (max-width: 860px) { .split--even { grid-template-columns: 1fr; } }

/* The counter. One oversized figure per cell, hairline-separated. */
.figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1px;
           background: var(--line); border-block: 1px solid var(--line); margin-top: clamp(2rem,4vw,3.4rem); }
.figures > div { background: var(--paper); padding: 1.6rem 1.4rem 1.5rem; }
.band--deep .figures { background: var(--line-dark); border-color: var(--line-dark); }
.band--deep .figures > div { background: var(--deep); }
.figure__n {
    font-size: clamp(2.1rem, 4vw, 3.05rem); font-weight: 200; letter-spacing: -.04em;
    line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums;
}
.band--deep .figure__n { color: #fff; }
.figure__l {
    margin-top: .6rem; font-size: .64rem; font-weight: 700; letter-spacing: .17em;
    text-transform: uppercase; color: var(--ink-55);
}
.band--deep .figure__l { color: rgba(255,255,255,.5); }
.figure__d { margin-top: .5rem; font-size: .855rem; line-height: 1.5; color: var(--ink-55); }
.band--deep .figure__d { color: rgba(255,255,255,.55); }

/* =============================================================================
   PRACTICES
   ========================================================================== */

.practices { display: grid; grid-template-columns: repeat(auto-fit, minmax(255px, 1fr)); gap: 1px;
             background: var(--line); border: 1px solid var(--line); margin-top: clamp(2rem,4vw,3.2rem); }
.practice {
    background: var(--paper); padding: clamp(1.6rem, 2.4vw, 2.2rem);
    display: flex; flex-direction: column; min-height: 268px;
    text-decoration: none; transition: background .3s var(--ease);
}
.practice:hover { background: #FAFAFA; }
.practice__i {
    width: 34px; height: 34px; display: grid; place-items: center;
    border: 1px solid var(--line); border-radius: 50%; color: var(--ink);
    font-size: .78rem; margin-bottom: 1.4rem;
    transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.practice:hover .practice__i { background: var(--ink); color: #fff; border-color: var(--ink); }
.practice h3 { font-size: 1.16rem; font-weight: 600; letter-spacing: -.025em; }
.practice p { margin: .7rem 0 0; font-size: .9rem; line-height: 1.56; color: var(--ink-55); }
.practice__n {
    margin-top: auto; padding-top: 1.3rem;
    font-size: .64rem; font-weight: 700; letter-spacing: .17em; text-transform: uppercase;
    color: var(--ink-55);
}

/* =============================================================================
   PORTFOLIO INDEX
   -----------------------------------------------------------------------------
   A register, not a card wall. Forty-six properties on cards would be a grid of
   noise; as hairline-ruled rows they read the way a holdings table reads, which
   is the point of the whole restyle.
   ========================================================================== */

.filters { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 2.2rem; }
.filter {
    font: inherit; font-size: .755rem; font-weight: 600; letter-spacing: .02em;
    padding: .5rem .95rem; border-radius: 999px;
    border: 1px solid var(--line); background: transparent; color: var(--ink-77);
    cursor: pointer; transition: all .24s var(--ease);
}
.filter:hover { border-color: var(--ink-55); color: var(--ink); }
.filter[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: #fff; }
.filter span { opacity: .55; font-variant-numeric: tabular-nums; margin-left: .3rem; }

.register { margin-top: 2.2rem; border-top: 1px solid var(--line); }
.entry {
    display: grid; grid-template-columns: 2.3fr 3.6fr 1.5fr auto;
    align-items: baseline; gap: 1.6rem;
    padding: 1.15rem .4rem 1.2rem;
    border-bottom: 1px solid var(--line-soft);
    text-decoration: none; color: inherit;
    transition: background .22s var(--ease), padding-left .22s var(--ease);
}
.entry:hover { background: #FAFAFA; padding-left: 1rem; }
.entry__name { font-size: 1.02rem; font-weight: 600; letter-spacing: -.022em; color: var(--ink); }
.entry__sum  { font-size: .85rem; line-height: 1.5; color: var(--ink-55); }
.entry__sec  { font-size: .64rem; font-weight: 700; letter-spacing: .15em;
               text-transform: uppercase; color: var(--ink-55); }
.entry__go   { font-size: .8rem; color: var(--ink-55); transition: transform .22s var(--ease), color .22s var(--ease); }
.entry:hover .entry__go { transform: translateX(4px); color: var(--ink); }
.entry__host { display: block; margin-top: .2rem; font-size: .7rem; color: var(--muted); font-weight: 400;
               letter-spacing: 0; }
@media (max-width: 900px) {
    .entry { grid-template-columns: 1fr auto; gap: .5rem 1rem; }
    .entry__sum { grid-column: 1 / -1; }
    .entry__sec { grid-column: 1; }
}
.register__empty { padding: 3rem .4rem; color: var(--ink-55); font-size: .92rem; }

/* =============================================================================
   INSIGHTS
   ========================================================================== */

.insights { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
            gap: clamp(1.4rem, 2.4vw, 2.2rem); margin-top: clamp(2rem,4vw,3.2rem); }
.insight { display: flex; flex-direction: column; text-decoration: none; }
.insight__t {
    aspect-ratio: 16 / 10; border-radius: 10px; overflow: hidden;
    background: var(--deep-soft); position: relative;
}
.insight__t canvas { width: 100%; height: 100%; display: block; }
.insight__k {
    margin: 1.1rem 0 .5rem; font-size: .625rem; font-weight: 700; letter-spacing: .17em;
    text-transform: uppercase; color: var(--ink-55);
}
.insight h3 { font-size: 1.06rem; font-weight: 600; letter-spacing: -.024em; line-height: 1.32; }
.insight p { margin: .55rem 0 0; font-size: .875rem; line-height: 1.55; color: var(--ink-55); }
.insight:hover h3 { text-decoration: underline; text-underline-offset: 3px; }

/* =============================================================================
   CONTACT + FOOTER
   ========================================================================== */

.offices { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
           gap: clamp(1.6rem, 3vw, 2.6rem); margin-top: 2.6rem; }
.office h3 { font-size: 1.16rem; font-weight: 700; letter-spacing: -.025em; }
.office p  { margin: .5rem 0 0; font-size: .875rem; line-height: 1.55; color: rgba(255,255,255,.55); }
.office a  { color: #fff; text-decoration: none; border-bottom: 1px solid var(--line-dark); }
.office a:hover { border-color: #fff; }

.form { display: grid; gap: .8rem; margin-top: 1.8rem; max-width: 460px; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; }
@media (max-width: 560px) { .form__row { grid-template-columns: 1fr; } }
.field {
    font: inherit; font-size: .9rem; width: 100%;
    padding: .78rem .9rem; border-radius: 8px; color: #fff;
    background: rgba(255,255,255,.045); border: 1px solid var(--line-dark);
    transition: border-color .24s var(--ease), background .24s var(--ease);
}
.field::placeholder { color: rgba(255,255,255,.38); }
.field:focus { outline: none; border-color: rgba(255,255,255,.5); background: rgba(255,255,255,.08); }
textarea.field { resize: vertical; min-height: 104px; }
/* The native select needs its own arrow once the platform chrome is removed,
   and color-scheme so the dropped-open list is dark too -- without it the
   options render as black-on-white over a dark form. */
select.field {
    appearance: none; -webkit-appearance: none;
    color-scheme: dark; cursor: pointer;
    padding-right: 2.4rem;
    background-image: linear-gradient(45deg, transparent 50%, rgba(255,255,255,.55) 50%),
                      linear-gradient(135deg, rgba(255,255,255,.55) 50%, transparent 50%);
    background-position: calc(100% - 18px) 51%, calc(100% - 13px) 51%;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
}
select.field:invalid { color: rgba(255,255,255,.38); }
.form .btn { background: #fff; color: var(--ink); justify-content: center; }
.form .btn:hover { background: rgba(255,255,255,.86); }
.form__note { font-size: .74rem; color: rgba(255,255,255,.45); margin: 0; }
.form__status { font-size: .82rem; margin: 0; min-height: 1.2em; }
.form__status[data-state="ok"]  { color: #6EE7B7; }
.form__status[data-state="err"] { color: #FCA5A5; }

.foot { border-top: 1px solid var(--line-dark); background: var(--deep); color: rgba(255,255,255,.5); }
.foot__in { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 2rem; padding-block: 2.2rem; }
.foot__in p { margin: 0; font-size: .78rem; }
.foot__links { display: flex; flex-wrap: wrap; gap: 1.4rem; margin-left: auto; }
.foot__links a { font-size: .78rem; text-decoration: none; color: rgba(255,255,255,.5); }
.foot__links a:hover { color: #fff; }

/* =============================================================================
   REVEAL
   -----------------------------------------------------------------------------
   Held to a short rise with no scale and no stagger beyond a beat. The house
   voice is calm; anything springier undoes the type.
   ========================================================================== */
.rise { opacity: 0; transform: translateY(14px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.rise.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
    .rise { opacity: 1; transform: none; transition: none; }
    .entry, .btn, .practice, .filter { transition: none; }
}

/* Focus, once, for everything. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }

/* Visually hidden, still announced. The previous build got this from Tailwind;
   this system has no framework under it, so without the rule the "Search the
   directory" and "Filter by market" labels simply printed on the page. */
.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;
}

.skip {
    position: absolute; left: -9999px; top: 0; z-index: 100;
    background: var(--ink); color: #fff; padding: .8rem 1.2rem; text-decoration: none;
}
.skip:focus { left: 0; }

/* =============================================================================
   THE DIRECTORY
   -----------------------------------------------------------------------------
   The labs build's register carried forty-six rows and could simply be printed.
   This one carries fourteen hundred, which changes three things: it needs a
   search field, it needs a second axis of filtering (market as well as
   department), and it cannot render the whole set at once — so rows arrive in
   batches behind a "show more".

   The row itself is the same object: hairline-ruled, no card, no border. Only
   the columns differ.
   ========================================================================== */

.finder { display: grid; gap: 1rem; margin-top: 2.4rem; }
.finder__search { position: relative; }
.finder__search input {
    font: inherit; font-size: 1rem; width: 100%;
    padding: .9rem 2.6rem .9rem 1rem;
    border: 0; border-bottom: 1px solid var(--ink);
    background: transparent; color: var(--ink);
    border-radius: 0;
}
.finder__search input::placeholder { color: var(--ink-55); }
.finder__search input:focus { outline: none; border-bottom-width: 2px; padding-bottom: calc(.9rem - 1px); }
.finder__search::after {
    content: '⌕'; position: absolute; right: .6rem; top: 50%; transform: translateY(-55%);
    font-size: 1.15rem; color: var(--ink-55); pointer-events: none;
}
.finder__rows { display: flex; flex-wrap: wrap; gap: .75rem 1.4rem; align-items: center; }
.finder__market {
    font: inherit; font-size: .8rem; font-weight: 500; color: var(--ink);
    padding: .5rem 2.2rem .5rem .9rem; border: 1px solid var(--line); border-radius: 999px;
    background-color: transparent; cursor: pointer;
    appearance: none; -webkit-appearance: none;
    background-image: linear-gradient(45deg, transparent 50%, var(--ink-55) 50%),
                      linear-gradient(135deg, var(--ink-55) 50%, transparent 50%);
    background-position: calc(100% - 17px) 52%, calc(100% - 12px) 52%;
    background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.finder__count {
    margin-left: auto; font-size: .64rem; font-weight: 700; letter-spacing: .17em;
    text-transform: uppercase; color: var(--ink-55); font-variant-numeric: tabular-nums;
}

/* A listing row. Four columns on a desktop: who, where, what, and the way to
   reach them. The whole row is not a link — a listing has two destinations
   (site and phone) and making the row itself clickable would have to pick one. */
.listing {
    display: grid; grid-template-columns: 2.6fr 3fr 1.4fr auto;
    gap: 1.4rem; align-items: baseline;
    padding: 1.05rem .4rem 1.1rem;
    border-bottom: 1px solid var(--line-soft);
}
.listing:first-child { border-top: 1px solid var(--line); }
.listing:hover { background: #FAFAFA; }
.listing__name { font-size: 1rem; font-weight: 600; letter-spacing: -.022em; color: var(--ink); }
.listing__name a { text-decoration: none; }
.listing__name a:hover { text-decoration: underline; text-underline-offset: 3px; }
.listing__note { display: block; margin-top: .25rem; font-size: .78rem; line-height: 1.45; color: var(--ink-55); }
.listing__addr { font-size: .85rem; line-height: 1.5; color: var(--ink-55); }
.listing__cat  { font-size: .64rem; font-weight: 700; letter-spacing: .15em;
                 text-transform: uppercase; color: var(--ink-55); }
.listing__cat span { display: block; margin-top: .3rem; letter-spacing: .1em; color: var(--muted); }
.listing__act { display: flex; gap: .5rem; align-items: center; white-space: nowrap; }
.listing__act a {
    display: inline-grid; place-items: center; width: 32px; height: 32px;
    border: 1px solid var(--line); border-radius: 50%; text-decoration: none;
    font-size: .78rem; color: var(--ink-55);
    transition: background .24s var(--ease), color .24s var(--ease), border-color .24s var(--ease);
}
.listing__act a:hover { background: var(--ink); color: #fff; border-color: var(--ink); }
@media (max-width: 980px) {
    .listing { grid-template-columns: 1fr auto; gap: .45rem 1rem; }
    .listing__addr { grid-column: 1 / -1; }
    .listing__cat  { grid-column: 1; }
    .listing__act  { grid-row: 1; grid-column: 2; }
}

.more { display: flex; justify-content: center; margin-top: 2.4rem; }
.register__empty { padding: 3rem .4rem; color: var(--ink-55); font-size: .92rem; }

/* =============================================================================
   HERO — photographic
   -----------------------------------------------------------------------------
   The labs build drew its hero because there was nothing to photograph. This
   site has twenty diamond plates of its own, so the reference's actual move —
   a full-bleed photograph under a directional scrim — is available here, and
   one is drawn at random per load the way the previous build did it.
   ========================================================================== */
.hero__photo {
    position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; object-position: center 42%;
    opacity: 0; transition: opacity .9s var(--ease);
}
.hero__photo.is-in { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .hero__photo { transition: none; } }

.hero__cap {
    position: absolute; right: var(--gutter); bottom: 1.1rem; z-index: 2;
    font-size: .6rem; font-weight: 600; letter-spacing: .17em; text-transform: uppercase;
    color: rgba(255,255,255,.42);
}
@media (max-width: 860px) { .hero__cap { display: none; } }

/* =============================================================================
   THE STRIPS
   -----------------------------------------------------------------------------
   Carried over from the previous build's ticker and re-set in this system.
   There it was two rows of chips crawling over a dark ground, lit in the accent.
   Here it sits on paper between the hero and the first band, held by a hairline
   top and bottom like every other division on the page.

   Two rows rather than one, running opposite ways at slightly different speeds,
   so they never march in lockstep and read as a single block. Each house gets
   an enclosed chip rather than a run of text between dots: at crawl speed a
   bare "name · market" string reads as one continuous smear.

   Speed is not set here. The script measures the laid-out run and writes
   animation-duration, so the strip always crawls at a fixed pixels-per-second
   whatever ended up in it.
   ========================================================================== */
.strips {
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    background: #FCFCFC;
    overflow: hidden;
    padding: calc(1.1rem - 3px) 0;
}
.strip-row {
    display: flex; overflow: hidden;
    /* Three pixels of slack inside the clip. A row is as tall as one chip and a
       chip works out to a fractional height, so without this the clip rounds
       down and shaves the bottom line of pixels off every chip in the top row —
       which reads as the two rows overlapping rather than as one being cut. */
    padding: 3px 0;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
}
.strip-row + .strip-row { margin-top: calc(.7rem - 6px); }

.strip-track {
    display: flex; align-items: center; flex: 0 0 auto;
    gap: .7rem;
    /* Matches `gap` exactly. Without it the track is one gap short of twice a
       run, so the -50% keyframe lands half a gap off and the loop visibly
       hitches once per pass. */
    padding-right: .7rem;
    white-space: nowrap;
    animation: strip-run 120s linear infinite;
    will-change: transform; backface-visibility: hidden;
}
/* The crawl deliberately does not pause on hover: a chip is a control, and
   stopping the row the moment the pointer arrives made every click stop the
   strip dead. */

.s-chip {
    display: inline-flex; align-items: center; gap: .6rem;
    flex: 0 0 auto;
    padding: .42rem .9rem;
    border: 1px solid var(--line); border-radius: 999px;
    background: var(--paper);
    font: inherit; text-align: left; cursor: pointer;
    transition: border-color .22s var(--ease), background .22s var(--ease);
}
.s-chip:hover { border-color: var(--ink); background: #fff; }
.s-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.s-chip::before {
    content: '◆'; color: var(--accent); font-size: .58rem; line-height: 1; flex: 0 0 auto;
}
.s-name {
    font-size: .82rem; font-weight: 600; letter-spacing: -.018em; color: var(--ink);
}
.s-meta {
    font-size: .58rem; font-weight: 700; letter-spacing: .15em; text-transform: uppercase;
    color: var(--ink-55);
    padding-left: .6rem; border-left: 1px solid var(--line);
}

@keyframes strip-run {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
}
@media (prefers-reduced-motion: reduce) { .strip-track { animation: none; } }

@media (max-width: 640px) {
    .strips { padding: calc(.8rem - 3px) 0; }
    .strip-row + .strip-row { margin-top: calc(.5rem - 6px); }
    .s-chip { gap: .45rem; padding: .36rem .7rem; }
    .s-name { font-size: .76rem; }
    .s-meta { font-size: .53rem; padding-left: .45rem; }
}
