/* Boise porch: trim, door, enamel plaques, clapboard, brass figures. */

@font-face {
    font-family: "Literata";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/assets/literata-latin-f7659a86.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Literata";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/assets/literata-latin-ext-698a507a.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Literata";
    font-style: italic;
    font-weight: 400 700;
    font-display: swap;
    src: url("/assets/literata-latin-italic-14b52dde.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Literata";
    font-style: italic;
    font-weight: 400 700;
    font-display: swap;
    src: url("/assets/literata-latin-ext-italic-07d61b9f.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
    --trim-white: #f6f5f1;
    --trim-shade: #ebe9e2;
    --rule: #d8d4ca;
    --door-juniper: #1f4337;
    --door-deep: #163329;
    --on-door: #dfe6e1;
    --enamel-slate: #331620;
    --enamel-letter: #e4ebea;
    --brass: #d9b574;
    --clapboard-putty: #e3dcce;
    --clapboard-lap: #b9c2b6;
    --umber-ink: #2b2622;
    --umber-soft: #5a534c;
    --eave-shadow: #221e1b;
    /* A muted brick red, not a stock UI red, the one accent in the palette
       reserved for "something needs fixing." */
    --danger: #a3402c;
    --lamp: 226, 150, 52;
    --serif: "Literata", "Iowan Old Style", Georgia, serif;
    --gutter: clamp(20px, 4vw, 56px);
    --max-width: 1280px;
    --type-display: clamp(2.25rem, 1.2rem + 2.4vw, 3.25rem);
    --type-headline: clamp(1.75rem, 1.05rem + 1.4vw, 2.125rem);
    --type-title: 1.3125rem;
    --type-subhead: 1.125rem;
    --type-numeral: 1.625rem;
    --type-numeral-lg: 1.875rem;
    --type-lead: 1.125rem;
    --type-body: 1.0625rem;
    --type-ui: 0.9375rem;
    --type-label: 0.8125rem;
    --type-micro: 0.75rem;
    /* Drawn once, painted juniper through a mask. --list-mark is a filled
       house glyph: a triangle roof stacked on a square, wider than it is
       tall so it doesn't read as an up-arrow. --check is a tick (done:
       toasts, success plaques). --check-open is an empty box a tenant
       can print and tick. */
    --list-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 12'%3E%3Cpath fill-rule='evenodd' d='M0 4.4L7 .2 14 4.4H11V11.6H3V4.4H0zM6 7.8h2V11.6H6z'/%3E%3C/svg%3E");
    --check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 13 10'%3E%3Cpath d='M1.25 5.25 4.75 8.5 11.75 1.5' fill='none' stroke='%23000' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    --check-open: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect x='1.9' y='1.9' width='12.2' height='12.2' rx='1.8' fill='none' stroke='%23000' stroke-width='1.6' stroke-linejoin='round'/%3E%3C/svg%3E");
}

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

* {
    margin: 0;
    padding: 0;
}

html {
    font-size: 100%;
    scroll-padding-top: 96px;
}

body {
    background: var(--trim-white);
    color: var(--umber-ink);
    font-family: var(--serif);
    font-size: var(--type-body);
    font-weight: 400;
    line-height: 1.65;
    font-optical-sizing: auto;
    -webkit-font-smoothing: antialiased;
    caret-color: var(--umber-ink);
    accent-color: var(--door-juniper);
}

.utility-bar,
.site-footer,
.cta-band,
.front-door,
.home-cta,
.door-panel,
.plaque,
.city-numbers {
    -webkit-font-smoothing: auto;
}

::selection {
    background: rgba(var(--lamp), 0.35);
}

img,
svg {
    display: block;
    max-width: 100%;
    height: auto;
    -webkit-user-drag: none;
}

a {
    color: var(--door-juniper);
    text-decoration-thickness: 1px;
    text-underline-offset: 4px;
}

a:hover {
    color: var(--door-deep);
    text-decoration-thickness: 2px;
}

/* A phone number never breaks across lines. */
a[href^="tel:"] {
    white-space: nowrap;
}

h1,
h2,
h3,
h4 {
    font-weight: 500;
    line-height: 1.12;
    color: var(--umber-ink);
    text-wrap: balance;
    letter-spacing: -0.015em;
    font-variation-settings: "opsz" 60, "wght" 500;
}

h1 {
    font-size: var(--type-display);
    line-height: 1.08;
    letter-spacing: -0.02em;
    font-variation-settings: "opsz" 72, "wght" 500;
}

h2 {
    font-size: var(--type-headline);
}

h3 {
    font-size: var(--type-title);
    line-height: 1.3;
    letter-spacing: -0.01em;
    font-variation-settings: "opsz" 36, "wght" 500;
}

.service-block h2 {
    font-size: var(--type-title);
    line-height: 1.3;
    letter-spacing: -0.01em;
    font-variation-settings: "opsz" 36, "wght" 500;
}

p {
    text-wrap: pretty;
}

ul,
ol {
    padding-left: 1.25rem;
}

:focus-visible {
    outline: 2px solid var(--umber-ink);
    outline-offset: 3px;
}

.container {
    width: 100%;
    max-width: var(--max-width);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.narrow {
    max-width: 72ch;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 8px;
    z-index: 100;
    background: var(--umber-ink);
    color: var(--trim-white);
    padding: 8px 12px;
}

.skip-link:focus {
    left: 8px;
}

/* Utility transom */
.utility-bar {
    background: var(--umber-ink);
    color: var(--trim-shade);
    font-size: var(--type-label);
}

.utility-bar .container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    padding-block: 7px;
    flex-wrap: wrap;
}

.utility-bar nav {
    display: flex;
    gap: 18px;
    flex-wrap: wrap;
}

.utility-bar a {
    color: var(--trim-white);
    text-decoration: none;
}

.utility-bar a:hover {
    text-decoration: underline;
}

.u-narrow {
    display: none;
}

/* Header */
.site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--trim-white);
    border-bottom: 1px solid var(--rule);
}

.site-header .container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    min-height: 76px;
}

.brand {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    color: var(--umber-ink);
}

.brand img {
    width: 36px;
    height: 40px;
}

.brand-name {
    display: block;
    font-size: var(--type-title);
    font-weight: 500;
    line-height: 1.1;
}

.brand-name small {
    display: block;
    font-size: var(--type-label);
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--umber-soft);
}

.nav-toggle {
    display: none;
    background: none;
    border: 1px solid var(--umber-soft);
    border-radius: 3px;
    padding: 8px 14px;
    font: inherit;
    font-size: var(--type-ui);
    color: var(--umber-ink);
    cursor: pointer;
}

.main-nav > ul {
    display: flex;
    align-items: center;
    gap: 8px 26px;
    list-style: none;
    padding: 0;
}

.main-nav li {
    position: relative;
}

.main-nav > ul > li > a {
    display: block;
    padding: 8px 0;
    color: var(--umber-ink);
    text-decoration: none;
    font-size: var(--type-ui);
}

.main-nav > ul > li:not(.nav-cta) > a:hover,
.main-nav > ul > li > a[aria-current="page"] {
    color: var(--door-juniper);
    text-decoration: underline;
}

.submenu {
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 220px;
    list-style: none;
    padding: 0;
    background: var(--trim-white);
    border: 1px solid var(--rule);
    box-shadow: 0 10px 24px -12px rgba(43, 38, 34, 0.35);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(4px);
    transition: opacity 0.15s, transform 0.15s, visibility 0.15s;
    z-index: 20;
}

.main-nav li:hover > .submenu,
.main-nav li:focus-within > .submenu {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0);
}

.submenu li + li {
    border-top: 1px solid var(--rule);
}

.submenu a {
    display: block;
    padding: 11px 16px;
    color: var(--umber-ink);
    text-decoration: none;
    font-size: var(--type-ui);
}

.submenu a:hover {
    color: var(--door-juniper);
}

.nav-toggle,
.sub-toggle {
    display: none;
}

.main-nav .nav-cta {
    margin-left: 8px;
}

.main-nav > ul > li.nav-cta > a {
    padding: 9px 18px;
    background: var(--door-juniper);
    border-color: var(--door-juniper);
    color: var(--trim-white);
    text-decoration: none;
    box-shadow: none;
}

.main-nav > ul > li.nav-cta > a:hover {
    background: var(--door-deep);
    border-color: var(--door-deep);
    color: var(--trim-white);
}

/* Buttons: painted juniper, 3px corners. Plaques are square, slate, rimmed. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 14px 24px;
    border: 1px solid var(--door-juniper);
    border-radius: 3px;
    background: var(--door-juniper);
    color: var(--trim-white);
    font: 500 1rem/1.2 var(--serif);
    text-decoration: none;
    cursor: pointer;
    transition: background-color 180ms ease-out, box-shadow 500ms cubic-bezier(0.16, 1, 0.3, 1);
}

.btn:hover {
    background: var(--door-deep);
    color: var(--trim-white);
}

.btn-primary,
.btn-secondary {
    background: var(--door-juniper);
    border-color: var(--door-juniper);
    color: var(--trim-white);
}

.btn-primary:hover,
.btn-secondary:hover {
    background: var(--door-deep);
    color: var(--trim-white);
}

/* The porch lamp burns against a dark ground only: on trim white it is a smudge. */
.cta-band .btn-lit,
.front-door .btn-lit,
.home-cta .btn-lit,
.door-panel .btn-lit,
.door-hero .btn-lit,
.section-dark .btn-lit {
    box-shadow: 0 14px 34px -8px rgba(var(--lamp), 0.62), 0 5px 14px -5px rgba(var(--lamp), 0.5);
    animation: lamp-on 1600ms 600ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.cta-band .btn-lit:hover,
.front-door .btn-lit:hover,
.home-cta .btn-lit:hover,
.door-panel .btn-lit:hover,
.door-hero .btn-lit:hover,
.section-dark .btn-lit:hover {
    box-shadow: 0 20px 46px -8px rgba(var(--lamp), 0.85), 0 6px 16px -4px rgba(var(--lamp), 0.6);
}

@keyframes lamp-on {
    0% { box-shadow: 0 14px 34px -8px rgba(var(--lamp), 0), 0 5px 14px -5px rgba(var(--lamp), 0); }
    12% { box-shadow: 0 14px 34px -8px rgba(var(--lamp), 0.3), 0 5px 14px -5px rgba(var(--lamp), 0.2); }
    18% { box-shadow: 0 14px 34px -8px rgba(var(--lamp), 0.05), 0 5px 14px -5px rgba(var(--lamp), 0.05); }
    100% { box-shadow: 0 14px 34px -8px rgba(var(--lamp), 0.62), 0 5px 14px -5px rgba(var(--lamp), 0.5); }
}

.btn-outline {
    background: transparent;
    color: var(--door-juniper);
    border-color: var(--door-juniper);
    box-shadow: none;
    animation: none;
}

.btn-outline:hover {
    background: rgba(31, 67, 55, 0.07);
    color: var(--door-deep);
    box-shadow: none;
}

.btn:disabled {
    background: var(--trim-white);
    border-color: var(--rule);
    color: var(--umber-soft);
    cursor: not-allowed;
    box-shadow: none;
}

.btn:disabled:hover {
    background: var(--trim-white);
    color: var(--umber-soft);
}

/* The secondary action in a door band: an unlit outline, so the lamp stays on the one way in. */
.btn-on-dark {
    background: transparent;
    border-color: var(--trim-white);
    color: var(--trim-white);
    box-shadow: none;
    animation: none;
}

.btn-on-dark:hover {
    background: rgba(246, 245, 241, 0.1);
    color: var(--trim-white);
}

.btn-small {
    padding: 9px 18px;
    font-size: var(--type-ui);
}

.btn-row,
.hero-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px 24px;
}

.text-link {
    font-size: var(--type-ui);
}

/* House plaques */
.plaque {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 2px;
    padding: 10px 16px 11px;
    border-radius: 1px;
    background: var(--enamel-slate);
    box-shadow:
        inset 0 0 0 1px var(--brass),
        inset 0 0 0 4px var(--enamel-slate),
        inset 0 0 0 5px rgba(217, 181, 116, 0.4),
        0 4px 9px -3px rgba(0, 0, 0, 0.5);
    color: var(--enamel-letter);
}

.plaque-label {
    font-size: var(--type-label);
    line-height: 1.3;
    text-wrap: balance;
}

.figure {
    font-family: var(--serif);
    font-size: var(--type-numeral);
    font-weight: 500;
    line-height: 1.1;
    font-variant-numeric: lining-nums tabular-nums;
    color: var(--brass);
    white-space: nowrap;
    letter-spacing: -0.01em;
}

.figure small {
    font-size: var(--type-label);
}

.figure-inline {
    color: var(--brass);
    font-variant-numeric: lining-nums;
}

.roll {
    display: inline-block;
}

.roll.is-rolling {
    animation: roll 420ms cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes roll {
    0% { transform: translateY(55%); opacity: 0; }
    100% { transform: translateY(0); opacity: 1; }
}

.plaque-rent {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    gap: 16px;
}

.plaque-rent label {
    font-size: var(--type-label);
    line-height: 1.3;
}

.plaque-lead {
    grid-column: 1 / -1;
    flex-direction: row;
    align-items: center;
    gap: 16px;
}

.plaque-lead .figure { margin-left: auto; font-size: var(--type-numeral-lg); }

.rent-well {
    display: inline-flex;
    align-items: baseline;
    margin-left: auto;
    padding: 3px 10px 4px;
    border-radius: 2px;
    background: rgba(0, 0, 0, 0.32);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.55), 0 1px 0 rgba(255, 255, 255, 0.08);
    cursor: text;
}

.plaque input {
    font-family: var(--serif);
    font-size: var(--type-numeral);
    font-weight: 500;
    line-height: 1.1;
    font-variant-numeric: lining-nums tabular-nums;
    color: var(--brass);
    white-space: nowrap;
    letter-spacing: -0.01em;
    width: 6ch;
    min-width: 3ch;
    border: 0;
    background: transparent;
    caret-color: var(--brass);
}

/* Hug the typed rent where the browser can; 6ch fits "99,999" elsewhere. */
@supports (field-sizing: content) {
    .plaque input {
        width: auto;
        field-sizing: content;
    }
}

.plaque input:focus {
    outline: none;
}

.rent-well:focus-within {
    outline: 2px solid var(--brass);
    outline-offset: 3px;
}

.edge-caption {
    display: inline-block;
    padding: 4px 10px;
    border-radius: 1px;
    background: rgba(43, 38, 34, 0.74);
    color: var(--trim-white);
    font-size: var(--type-micro);
    line-height: 1.4;
}

/* Homepage porch hero */
.porch-hero {
    position: relative;
    aspect-ratio: 16 / 9;
    max-height: calc(100vh - 110px);
    min-height: 620px;
    width: 100%;
    overflow: hidden;
    background: var(--umber-ink);
}

.porch-hero .hero-photo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 42%;
}

.hero-inner {
    position: relative;
    height: 100%;
    max-width: 1440px;
    margin-inline: auto;
}

.porch-hero .hero-panel {
    position: absolute;
    left: clamp(20px, 4.2%, 64px);
    top: 50%;
    transform: translateY(-50%);
    width: min(40%, 540px);
    padding: clamp(28px, 3vw, 44px);
    background: var(--trim-white);
    border-radius: 1px;
    box-shadow:
        inset 0 0 0 9px var(--trim-white),
        inset 0 0 0 10px var(--rule),
        0 24px 48px -24px rgba(10, 14, 20, 0.6);
}

.porch-hero .hero-lead {
    margin-top: 16px;
    font-size: var(--type-lead);
    line-height: 1.5;
    color: var(--umber-soft);
}

.plaque-wall {
    position: absolute;
    right: clamp(20px, 4.2%, 64px);
    top: 50%;
    transform: translateY(-50%);
    width: clamp(360px, 28%, 400px);
}

.plaque-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}

.plaque-board {
    display: inline-block;
    margin-top: 12px;
    padding: 6px 12px;
    background: var(--trim-white);
    box-shadow: 0 3px 8px -3px rgba(0, 0, 0, 0.45);
    font-size: var(--type-label);
    color: var(--umber-ink);
}

.hero-caption {
    position: absolute;
    right: 16px;
    bottom: 14px;
}

/* Sections */
.section,
.band {
    padding-block: clamp(56px, 8vw, 104px);
}

.section-alt,
.clapboard {
    background-color: var(--clapboard-putty);
    background-image: repeating-linear-gradient(
        to bottom,
        rgba(43, 38, 34, 0.05) 0px,
        rgba(43, 38, 34, 0.05) 1px,
        transparent 1px,
        transparent 48px
    );
}

/* Siding is wall only: content in a siding band sits on a trim-white board. */
.section-alt > .container {
    background: var(--trim-white);
    padding-block: clamp(28px, 4vw, 56px);
    box-shadow: 0 10px 24px -14px rgba(43, 38, 34, 0.45);
}

.section-dark {
    background: var(--door-juniper);
    color: var(--trim-white);
}

.section-dark a:not(.btn) {
    color: var(--trim-white);
}

/* Dark bands: the global h1-h4 rule sets umber-ink, which overrides the
   inherited light color. Every heading inside a dark band needs its own
   override so nothing renders dark-on-dark. */
.front-door h1,
.front-door h2,
.front-door h3,
.front-door h4,
.door-panel h1,
.door-panel h2,
.door-panel h3,
.door-panel h4,
.section-dark h1,
.section-dark h2,
.section-dark h3,
.section-dark h4,
.door-hero h1,
.cta-band h1,
.cta-band h2,
.cta-band h3,
.cta-band h4,
.home-cta h1,
.home-cta h2,
.home-cta h3,
.home-cta h4,
.site-footer h1,
.site-footer h3,
.site-footer h4 {
    color: var(--trim-white);
}

.section-head {
    max-width: 56ch;
    margin-bottom: 40px;
}

/* The register plate is evidence for the claim above it, so it sits closer to
   that claim than to whatever follows. At an even 40px on both sides it read as
   floating between two groups rather than belonging to one. */
.section-head:has(+ .city-numbers) {
    margin-bottom: 28px;
}

.section-head.center {
    margin-inline: auto;
    text-align: center;
}

.section-head p,
.intro {
    margin-top: 12px;
    max-width: 56ch;
    font-size: var(--type-lead);
    line-height: 1.5;
    color: var(--umber-soft);
}

.clapboard .intro,
.clapboard .section-head p {
    color: var(--umber-ink);
}

.eyebrow {
    display: none;
}

.lead {
    font-size: var(--type-lead);
    line-height: 1.5;
    color: var(--umber-soft);
}

.page-hero {
    padding-block: clamp(40px, 6vw, 72px);
    background: var(--trim-white);
    border-bottom: 1px solid var(--rule);
}

.page-hero h1 {
    margin-bottom: 20px;
}

.page-hero .lead {
    max-width: 56ch;
}

.page-hero .btn-row {
    margin-top: 24px;
}

.about-hero-action {
    display: none;
}

.breadcrumbs {
    font-size: var(--type-label);
    color: var(--umber-soft);
    margin-bottom: 14px;
}

/* Tall tap target without moving the line. */
.breadcrumbs a {
    display: inline-block;
    padding-block: 12px;
    margin-block: -12px;
    color: var(--umber-soft);
}

/* Section layouts. Owner pages open on the painted door; tenant pages open on
   a board hung on the porch wall. Both then share the tab row and a closing door. */
.door-hero {
    padding-top: clamp(48px, 7vw, 96px);
    background: var(--door-deep);
    color: var(--on-door);
    box-shadow: inset 0 2px 0 rgba(0, 0, 0, 0.3);
}

/* The copy pads the bottom so the fanlight can sit on the lintel. */
.door-hero-inner {
    position: relative;
    padding-bottom: clamp(48px, 7vw, 96px);
}

.door-hero.has-aside .door-hero-inner {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: 40px clamp(32px, 6vw, 88px);
    align-items: end;
}

.door-hero-copy {
    position: relative;
    z-index: 1;
    max-width: 44rem;
}

.door-hero h1 {
    margin-bottom: 20px;
}

.door-hero .lead {
    max-width: 56ch;
    color: var(--on-door);
}

.door-hero a:not(.btn) {
    color: var(--trim-white);
}

.door-hero :focus-visible {
    outline-color: var(--trim-white);
}

.door-hero .btn-row {
    margin-top: 28px;
}

.door-hero .btn-primary {
    background: var(--trim-white);
    border-color: var(--trim-white);
    color: var(--door-juniper);
}

.door-hero .btn-primary:hover {
    background: var(--trim-shade);
    color: var(--door-deep);
}

.door-hero .plaque {
    box-shadow:
        inset 0 0 0 1px var(--brass),
        inset 0 0 0 4px var(--enamel-slate),
        inset 0 0 0 5px rgba(217, 181, 116, 0.4),
        0 6px 14px -4px rgba(0, 0, 0, 0.6);
}

.roofline {
    position: absolute;
    right: var(--gutter);
    bottom: 0;
    width: clamp(260px, 32vw, 440px);
    color: rgba(217, 181, 116, 0.3);
    pointer-events: none;
}

/* Tenants: the same section hero as the owner door and the city pages, on the
   siding. Owners open on the painted door and cities on enamel; a tenant already
   lives in the house, so their pages open on its wall, and the one question the
   page answers hangs there on a juniper board. */
.door-hero.tenant-hero {
    background-color: var(--clapboard-putty);
    background-image: repeating-linear-gradient(
        to bottom,
        rgba(43, 38, 34, 0.05) 0px,
        rgba(43, 38, 34, 0.05) 1px,
        transparent 1px,
        transparent 48px
    );
    color: var(--umber-ink);
    box-shadow: inset 0 1px 0 rgba(43, 38, 34, 0.08);
}

.door-hero.tenant-hero h1,
.tenant-hero .lead {
    color: var(--umber-ink);
}

.tenant-hero .door-hero-copy a:not(.btn) {
    color: var(--door-juniper);
}

.tenant-hero :focus-visible {
    outline-color: var(--umber-ink);
}

.tenant-hero .btn-primary {
    background: var(--door-juniper);
    border-color: var(--door-juniper);
    color: var(--trim-white);
}

.tenant-hero .btn-primary:hover {
    background: var(--door-deep);
    border-color: var(--door-deep);
    color: var(--trim-white);
}

.door-hero.tenant-hero.has-aside .door-hero-inner {
    align-items: center;
}

.tenant-hero .door-hero-aside {
    justify-self: end;
    width: min(100%, 24rem);
}

.wall-note {
    padding: 28px 30px 30px;
    background: var(--door-juniper);
    box-shadow:
        inset 0 2px 0 rgba(0, 0, 0, 0.3),
        inset 0 -1px 0 rgba(255, 255, 255, 0.07),
        inset 0 0 0 6px var(--door-deep),
        inset 0 0 0 7px rgba(0, 0, 0, 0.3),
        inset 0 0 0 8px rgba(255, 255, 255, 0.05),
        0 10px 24px -12px rgba(22, 51, 41, 0.6);
    color: var(--on-door);
}

.wall-note-q {
    color: var(--trim-white);
    margin-bottom: 8px;
    font-size: var(--type-subhead);
    font-weight: 500;
    line-height: 1.35;
    letter-spacing: -0.01em;
    text-wrap: balance;
}

.wall-note p + p {
    font-size: 1rem;
    line-height: 1.6;
    color: var(--on-door);
}

.wall-note a {
    color: var(--trim-white);
}

.wall-note :focus-visible {
    outline-color: var(--trim-white);
}


/* The tab row is the lintel under either hero: every sibling page, one line. */
.section-tabs {
    position: sticky;
    top: 77px;
    z-index: 40;
    background: var(--trim-white);
    border-bottom: 1px solid var(--rule);
}

.section-tabs .container {
    position: relative;
}

.section-tabs ul {
    display: flex;
    gap: clamp(20px, 2.6vw, 36px);
    padding: 0;
    list-style: none;
}

.section-tabs a {
    display: block;
    margin-bottom: -1px;
    padding-block: 15px 13px;
    border-bottom: 2px solid transparent;
    color: var(--umber-soft);
    font-size: var(--type-ui);
    line-height: 1.2;
    text-decoration: none;
    white-space: nowrap;
    transition: color 160ms ease-out, border-color 160ms ease-out;
}

.section-tabs a:hover {
    border-bottom-color: var(--rule);
    color: var(--umber-ink);
}

.section-tabs a[aria-current="page"] {
    border-bottom-color: var(--door-juniper);
    color: var(--umber-ink);
}

.section-tabs a:focus-visible {
    outline-offset: -2px;
}

html:has(.section-tabs) {
    scroll-padding-top: 148px;
}

.board {
    padding: clamp(28px, 4vw, 56px);
    border-radius: 1px;
    background: var(--trim-white);
    box-shadow: 0 10px 24px -14px rgba(43, 38, 34, 0.45);
}

.grid {
    display: grid;
    gap: 20px;
}

.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

/* Cards are hairline-ruled list items: no box, no fill, no shadow. */
.card {
    padding-block: 18px 22px;
    border-top: 1px solid var(--rule);
}

.card h3 {
    margin-bottom: 8px;
}

.card p {
    color: var(--umber-soft);
    font-size: var(--type-body);
}

.card .card-link {
    display: inline-block;
    margin-top: 14px;
    font-size: var(--type-ui);
}

a.card {
    display: block;
    color: inherit;
    text-decoration: none;
}

a.card:hover h3 {
    color: var(--door-juniper);
    text-decoration: underline;
}

.section-dark .card {
    border-color: rgba(255, 255, 255, 0.2);
    color: var(--trim-white);
}

.section-dark .card p {
    color: var(--on-door);
}

/* A city's reference figures as one engraved register plate.

   This was four separate plaques in a 20px-gap grid, each stretched to 1fr. The
   figures are unequal in length by nature ("8%" against "Application fee, per
   adult"), so equal boxes left every cell a different run of dead space on its
   right, and the row read as four objects that happened to land near each other.
   One frame, hairline rules between cells, and centred content: the space left
   over in each cell is now symmetric, which is what stops it looking arbitrary. */
.city-numbers {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    /* Clears the 5px of inset rules below, so no cell sits on the frame. */
    padding: 5px;
    background: var(--enamel-slate);
    border-radius: 1px;
    box-shadow:
        inset 0 0 0 1px var(--brass),
        inset 0 0 0 4px var(--enamel-slate),
        inset 0 0 0 5px rgba(217, 181, 116, 0.4),
        0 4px 9px -3px rgba(0, 0, 0, 0.5);
}

.city-number {
    /* A little more below than above: the numeral's optical weight sits high, so
       equal padding reads as bottom-light. */
    padding: 20px 22px 24px;
    text-align: center;
}

.city-number + .city-number {
    border-left: 1px solid rgba(217, 181, 116, 0.28);
}

.city-number strong {
    display: block;
    font-size: var(--type-numeral-lg);
    font-weight: 500;
    line-height: 1.1;
    color: var(--brass);
    font-variant-numeric: lining-nums tabular-nums;
}

.city-number span {
    display: block;
    margin-top: 6px;
    font-size: var(--type-label);
    line-height: 1.35;
    color: var(--enamel-letter);
}

/* Two by two rather than one 350px-wide cell holding two short lines. The rules
   reorient with the grid: cell 3 starts a row, so it drops its left rule and the
   bottom pair gains a top one. */
@media (max-width: 720px) {
    .city-numbers {
        grid-template-columns: repeat(2, 1fr);
    }

    .city-number {
        padding: 18px 14px 20px;
    }

    .city-number:nth-child(3) {
        border-left: 0;
    }

    .city-number:nth-child(n+3) {
        border-top: 1px solid rgba(217, 181, 116, 0.28);
    }
}

.fine-print {
    margin-top: 28px;
    padding-top: 10px;
    border-top: 1px solid var(--rule);
    max-width: 72ch;
    font-size: var(--type-label);
    font-style: italic;
    line-height: 1.4;
    color: var(--umber-soft);
}

.fine-print a {
    font-style: italic;
}

.section-dark .fine-print {
    color: var(--on-door);
    border-top-color: rgba(223, 230, 225, 0.28);
}

/* Steps */
.steps {
    counter-reset: step;
    list-style: none;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 32px;
}

.steps li {
    counter-increment: step;
    position: relative;
    padding-top: 0;
}

.steps li::before {
    content: counter(step);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    margin-bottom: 16px;
    padding: 10px 0 11px;
    border-radius: 1px;
    background: var(--enamel-slate);
    color: var(--brass);
    font-size: var(--type-numeral-lg);
    font-weight: 500;
    box-shadow:
        inset 0 0 0 1px var(--brass),
        inset 0 0 0 4px var(--enamel-slate),
        inset 0 0 0 5px rgba(217, 181, 116, 0.4),
        0 4px 9px -3px rgba(0, 0, 0, 0.5);
}

.steps h3 {
    font-size: var(--type-subhead);
    margin-bottom: 6px;
}

.steps p {
    font-size: var(--type-body);
    color: var(--umber-soft);
    max-width: 60ch;
}

.split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 56px;
    align-items: center;
}

.split.top {
    align-items: start;
}

.split > div > p {
    max-width: 56ch;
}

.split > div > p + p {
    margin-top: 14px;
}

.split h2 {
    margin-bottom: 16px;
}

.split h3 {
    margin-bottom: 18px;
}

.split h3 + .checklist {
    margin-top: 0;
}

.split .fine-print {
    max-width: 56ch;
}

/* Two owner-relevant exceptions, not a done-list: term at subhead so it
   cannot optically outrank the column title, hairline between facts. */
.rule-topics {
    display: grid;
}

.rule-topics > div + div {
    margin-top: 18px;
    padding-top: 18px;
    border-top: 1px solid var(--rule);
}

.rule-topics dt {
    font-size: var(--type-subhead);
    font-weight: 500;
    line-height: 1.35;
    letter-spacing: -0.01em;
    font-variation-settings: "opsz" 36, "wght" 500;
}

.rule-topics dd {
    margin: 4px 0 0;
    max-width: 56ch;
    font-variant-numeric: lining-nums tabular-nums;
}

.image-placeholder {
    aspect-ratio: 4 / 3;
    max-width: 100%;
    display: grid;
    place-items: center;
    border-radius: 1px;
    background: var(--trim-white);
    border: 1px dashed var(--umber-soft);
    color: var(--umber-soft);
    font-size: var(--type-label);
    text-align: center;
    padding: 20px;
}

.portal-shot {
    background: var(--trim-white);
    border: 1px solid var(--rule);
    border-radius: 1px;
    padding: 12px;
}

.portal-shot img {
    display: block;
    width: 100%;
    height: auto;
}

/* The owner mock ends well above its frame; crop the blank page below it. */
.portal-shot.is-cropped img {
    aspect-ratio: 16 / 9;
    object-fit: cover;
    object-position: top left;
}

.portal-split {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
}

/* /portals has no login to paint, so the phone number is the page's hardware:
   the house-number plaque, with the figure itself as the tel: link. Brass has
   to survive the hover and focus a plain link would repaint, since the sitewide
   hover color (door-deep) is unreadable on enamel. */
.desk-plaque {
    gap: 8px;
    padding: 14px 18px 15px;
    /* Stacked under the copy it would stretch the full board and read as a
       banner; a plaque is hung, not painted across the wall. */
    justify-self: start;
}

.desk-plaque .figure {
    align-self: start;
    font-size: var(--type-numeral-lg);
    text-decoration: underline;
    text-decoration-color: rgba(217, 181, 116, 0.45);
}

/* Balanced wrapping splits the hours mid-range ("9am-" / "5pm"). The number
   already sets the plaque's width, so let the caption fill it. */
.desk-plaque .plaque-label {
    text-wrap: wrap;
}

.desk-plaque .figure:hover,
.desk-plaque .figure:focus-visible {
    color: var(--brass);
    text-decoration-color: var(--brass);
}

.desk-plaque .figure:focus-visible {
    outline: 2px solid var(--brass);
    outline-offset: 3px;
}

/* About: story and a shared line on the left, the two operators on the right.
   DOM order is story, people, contact so narrow screens meet the people first. */
.hiring {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    grid-template-rows: auto 1fr;
    grid-template-areas:
        "story people"
        "contact people";
    column-gap: clamp(40px, 5vw, 72px);
    align-items: start;
}

.hiring-story { grid-area: story; }
.hiring-people { grid-area: people; }
.hiring-contact { grid-area: contact; }

.hiring-story p {
    margin-top: 16px;
    max-width: 44ch;
    font-size: var(--type-lead);
    line-height: 1.5;
    color: var(--umber-soft);
}

.hiring-people {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: clamp(24px, 3vw, 40px);
}

/* Portrait, nameplate, and bio share rows across the pair, so the nameplates
   match in height even when one role wraps. */
.operator {
    display: grid;
    grid-row: span 3;
    grid-template-rows: subgrid;
    align-content: start;
}

/* A framed portrait with an enamel nameplate screwed to the bottom of the mat. */
.portrait {
    position: relative;
    padding: 10px;
    background: var(--trim-white);
    box-shadow:
        inset 0 0 0 1px var(--rule),
        0 10px 24px -14px rgba(43, 38, 34, 0.45);
    border-radius: 1px;
}

.portrait img {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    border-radius: 1px;
}

.portrait .edge-caption {
    position: absolute;
    top: 20px;
    left: 20px;
    margin-right: 20px;
}

.nameplate {
    position: relative;
    z-index: 1;
    width: fit-content;
    min-width: min(15rem, calc(100% - 40px));
    max-width: calc(100% - 40px);
    margin: -30px 0 0 20px;
    padding: 11px 18px 12px;
    gap: 1px;
    justify-content: flex-start;
}

.nameplate h3 {
    font-size: var(--type-title);
    line-height: 1.2;
    color: var(--brass);
}

.nameplate p {
    font-size: var(--type-label);
    letter-spacing: 0.01em;
    color: var(--enamel-letter);
}

.operator > p {
    margin-top: 16px;
    max-width: 44ch;
    line-height: 1.55;
    color: var(--umber-soft);
}

.hiring-contact {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    margin-top: 32px;
    font-size: var(--type-ui);
}

.hiring-contact h3 {
    margin-bottom: 8px;
    font-size: var(--type-subhead);
}

.hiring-phone {
    font-size: var(--type-title);
    font-weight: 500;
    font-variant-numeric: lining-nums tabular-nums;
    line-height: 1.3;
}

.hiring-hours {
    margin-top: 4px;
    color: var(--umber-soft);
}

@media (max-width: 960px) {
    .hiring {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: none;
        grid-template-areas: "story" "people" "contact";
    }

    .hiring-people {
        margin-top: 36px;
    }

    .hiring-contact {
        margin-top: 36px;
    }
}

/* Phones: square crops keep both faces close to the top of the section. */
@media (max-width: 600px) {
    .hiring-people {
        grid-template-columns: minmax(0, 1fr);
        row-gap: 0;
    }

    .operator + .operator {
        margin-top: 40px;
    }

    .portrait {
        padding: 8px;
    }

    .portrait img {
        aspect-ratio: 1 / 1;
        object-position: 50% 22%;
    }

    .portrait .edge-caption {
        top: 16px;
        left: 16px;
    }

    .nameplate {
        margin: -26px 0 0 16px;
    }
}

.photo-frame {
    position: relative;
}

.photo-frame img {
    width: 100%;
    object-fit: cover;
    border-radius: 3px;
}

.photo-frame .edge-caption {
    position: absolute;
    left: 12px;
    bottom: 12px;
    margin-right: 12px;
}

.checklist {
    list-style: none;
    padding: 0;
    display: grid;
    gap: 10px;
    margin-top: 18px;
}

.checklist li {
    position: relative;
    padding-left: 24px;
}

.checklist-open li {
    padding-left: 26px;
}

.checklist li::before {
    content: "";
    position: absolute;
    left: 0;
    /* Middle of the first line. 0.5lh is the line-box center; translateY
       centers the mark on it. */
    top: 0.5lh;
    width: 14px;
    height: 12px;
    transform: translateY(-50%);
    background: var(--door-juniper);
    -webkit-mask: var(--list-mark) center / contain no-repeat;
    mask: var(--list-mark) center / contain no-repeat;
}

/* Empty box for lists a tenant might print and tick: move-in, move-out,
   documents to gather. Item lists use the house glyph; a tick means done. */
.checklist-open li::before {
    width: 16px;
    height: 16px;
    -webkit-mask: var(--check-open) center / contain no-repeat;
    mask: var(--check-open) center / contain no-repeat;
}

.prose h2 {
    font-size: var(--type-headline);
    margin-top: 44px;
    margin-bottom: 12px;
}

.prose h3 {
    margin-top: 28px;
    margin-bottom: 8px;
}

.prose p,
.prose ul,
.prose ol {
    margin-bottom: 14px;
    color: var(--umber-soft);
}

.prose li + li {
    margin-top: 6px;
}

.prose > :first-child {
    margin-top: 0;
}

.service-block {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 40px;
    padding-block: 40px;
    border-top: 1px solid var(--rule);
}

.service-block:first-child {
    border-top: 0;
    padding-top: 0;
}

.service-block p {
    color: var(--umber-soft);
    max-width: 64ch;
}

.service-block .checklist {
    grid-template-columns: 1fr 1fr;
}

/* A FAQ group on the services rule: the block rules stand in for the first
   and last questions' rules, and the first question lines up with the group
   heading. */
.faq-block .faq details:first-child {
    border-top: 0;
}

.faq-block .faq details:last-child {
    border-bottom: 0;
}

.faq-block .faq details:first-child summary {
    padding-top: 0;
}

.faq-block .faq details:first-child summary::after {
    top: calc(-0.75px + 0.7em);
}

.faq-block .faq details:first-child:not([open]) summary::before {
    top: calc(-8px + 0.7em);
}

/* Rental criteria on the services rule: plain bullets, since a criterion is a
   standard to meet, not a checked-off item. */
.criteria-block ul {
    max-width: 64ch;
    color: var(--umber-soft);
}

.criteria-block li + li {
    margin-top: 6px;
}

/* A two-up set that opens its section right under a section rule or the section
   tabs. That edge already separates it, so the top row drops its rules; stacked
   on a phone, only the first card does. */
.grid-open > .card:first-child {
    padding-top: 0;
    border-top: 0;
}

@media (min-width: 601px) {
    .grid-open > .card:nth-child(2) {
        padding-top: 0;
        border-top: 0;
    }
}


/* A board on siding holds a heading block and its actions side by side. Without
   this the copy keeps its 56ch measure and leaves two-thirds of the board empty. */
.band-split {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: clamp(28px, 4vw, 56px);
    align-items: center;
}

.band-split .section-head {
    margin-bottom: 0;
}

@media (max-width: 960px) {
    .band-split {
        grid-template-columns: 1fr;
        align-items: start;
    }
}

/* Areas: the section is hardware, not the painted door. Owner pages open on
   door-deep and tenant pages on siding; a city page opens on enamel, because a
   map is wayfinding and wayfinding on this house is brass engraved on slate. */
.door-hero.area-hero {
    background: var(--enamel-slate);
    color: var(--enamel-letter);
    /* The map is a tall shape, Ada County's cities run north to south, so this
       hero carries less padding than the owner door, or it towers over it. */
    padding-top: clamp(44px, 6vw, 80px);
}

.area-hero .door-hero-inner {
    padding-bottom: clamp(44px, 6vw, 80px);
}

.area-hero .lead {
    color: var(--enamel-letter);
}

.area-hero .btn-primary {
    background: var(--brass);
    border-color: var(--brass);
    color: var(--eave-shadow);
}

.area-hero .btn-primary:hover {
    background: var(--trim-white);
    border-color: var(--trim-white);
    color: var(--eave-shadow);
}

.door-hero.area-hero.has-aside .door-hero-inner {
    align-items: center;
}

.area-map {
    margin: 0;
}

.area-map svg {
    display: block;
    width: auto;
    height: clamp(230px, 30vw, 380px);
    margin-inline: auto;
    /* No clipping. This used to be overflow:hidden to cut off the Ada County
       path, which ran ~990 units past the bottom of the viewBox. That path is no
       longer drawn, every city fits the frame (Kuna reaches y=1098 of 1140), and
       clipping now would only cut the focus ring off the map's own links. */
    overflow: visible;
}

/* These outlines are the only thing identifying four link targets, so they are
   held to WCAG 1.4.11 (3:1 for non-text UI). The old 0.5-alpha stroke measured
   2.38:1 on enamel slate and the 0.08 fill about 1.2:1, a table of contents you
   had to already know was there. 0.78 alpha measures ~3.6:1. */
.map-city path {
    fill: rgba(217, 181, 116, 0.16);
    stroke: rgba(217, 181, 116, 0.78);
    stroke-width: 2.5;
    stroke-linejoin: round;
    transition: fill 160ms ease-out, stroke 160ms ease-out;
}

.map-city text {
    font-family: var(--serif);
    font-size: 46px;
    fill: var(--enamel-letter);
    fill-opacity: 0.72;
    text-anchor: middle;
    dominant-baseline: middle;
    /* A slate halo so a label stays legible over a jagged boundary. */
    paint-order: stroke fill;
    stroke: var(--enamel-slate);
    stroke-width: 7;
    stroke-linejoin: round;
}

/* Raised from 0.26 when the resting fill went 0.08 -> 0.16 for contrast: the
   old value left only 0.10 of separation, and "you are here" has to stay obvious
   now that every other shape is a link too. */
.map-city.is-current path {
    fill: rgba(217, 181, 116, 0.36);
    stroke: var(--brass);
    stroke-width: 4;
}

/* The current city is the one label that must win. Brass on its own brass fill
   disappears, so it goes trim-white and keeps the slate halo. */
.map-city.is-current text {
    fill: var(--trim-white);
    fill-opacity: 1;
    stroke-width: 8;
}

/* On the index the map is the section's table of contents. */
.area-map.is-linked .map-city a {
    cursor: pointer;
}

.area-map.is-linked .map-city:hover path,
.area-map.is-linked .map-city a:focus-visible path {
    fill: rgba(217, 181, 116, 0.24);
    stroke: var(--brass);
    stroke-width: 4;
}

.area-map.is-linked .map-city:hover text,
.area-map.is-linked .map-city a:focus-visible text {
    fill: var(--trim-white);
    fill-opacity: 1;
}

/* A paint change alone cannot carry focus here: fill moved 1.33:1 and stroke
   2.09:1 between states, both under the 3:1 that WCAG 2.2 SC 2.4.11 wants. A
   real ring is also the only focus cue that survives the shapes being small. */
.area-map.is-linked .map-city a:focus-visible {
    outline: 2px solid var(--brass);
    outline-offset: 2px;
}

/* Home base. The map exists to prove "five cities, one drive", which is a claim
   about distance from somewhere, so the somewhere has to be on the drawing. */
.map-home circle {
    fill: none;
    stroke: var(--trim-white);
    stroke-width: 3;
}

.map-home .map-home-pip {
    fill: var(--trim-white);
    stroke: none;
}

.map-home text {
    font-family: var(--sans);
    font-size: 40px;
    font-weight: 600;
    letter-spacing: 0.06em;
    fill: var(--trim-white);
    text-anchor: middle;
    paint-order: stroke fill;
    stroke: var(--enamel-slate);
    stroke-width: 7;
    stroke-linejoin: round;
}

/* The current city stays legible as "you are here" even though every shape is
   now a link: its brass is solid where the others are 0.78, and the rest-state
   rule below never outranks it because .is-current adds a class. */

/* The map gets smaller on a phone, and SVG text scales with it, at the stacked
   size a 46-unit label renders around 8px. Sizes here are viewBox units, so the
   labels grow as the drawing shrinks and end up about the same on screen. */
@media (max-width: 960px) {
    .map-city text {
        font-size: 74px;
        stroke-width: 11;
    }

    .map-city.is-current text {
        stroke-width: 12;
    }

    /* The labels grow as the drawing shrinks, which reopens the collision with
       Boise's label that the 60-unit lift clears on desktop. Another 40 user
       units of separation buys ~7px at this size. */
    .map-home text {
        font-size: 62px;
        stroke-width: 11;
        transform: translateY(-40px);
    }

    .map-home circle {
        stroke-width: 5;
    }
}

@media (prefers-reduced-motion: reduce) {
    .map-city path {
        transition: none;
    }
}

/* The city's population, in the label column beside its description. */
.area-figures {
    margin-top: 6px;
    font-size: var(--type-label);
    font-variant-numeric: lining-nums tabular-nums;
    color: var(--umber-soft);
}

/* Pricing: fee plaques on the owner door, then a first-year ledger on enamel. */
.pricing-plaques .plaque-grid {
    gap: 12px;
}

.pricing-plaques .figure {
    font-size: var(--type-numeral-lg);
}

.plaque-caption {
    margin-top: 14px;
    font-size: var(--type-label);
    color: var(--umber-soft);
}

.door-hero .plaque-caption {
    color: var(--on-door);
}

.first-year-ledger {
    max-width: 34rem;
}

.ledger {
    gap: 0;
    padding: 20px 24px 6px;
}

.ledger-rent {
    display: flex;
    align-items: center;
    gap: 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid rgba(217, 181, 116, 0.4);
}

.ledger-rent label {
    font-size: var(--type-ui);
}

.ledger dl > div {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 20px;
    padding-block: 14px;
    border-bottom: 1px solid rgba(228, 235, 234, 0.14);
}

.ledger dl > div:last-child {
    border-bottom: 0;
}

.ledger dt {
    font-size: var(--type-ui);
    line-height: 1.35;
}

.ledger dt small {
    display: block;
    margin-top: 2px;
    font-size: var(--type-label);
    color: rgba(228, 235, 234, 0.78);
}

.ledger dd {
    font-size: var(--type-numeral);
    font-weight: 500;
    line-height: 1.1;
    font-variant-numeric: lining-nums tabular-nums;
    color: var(--brass);
    white-space: nowrap;
}

.ledger .ledger-total,
.ledger dl > div:has(+ .ledger-total) {
    border-bottom-color: rgba(217, 181, 116, 0.4);
}

.ledger-total dt {
    font-weight: 500;
    color: var(--trim-white);
}

.ledger-total dd {
    font-size: var(--type-numeral-lg);
}

.fee-line {
    margin-top: 4px;
    font-size: var(--type-ui);
    font-variant-numeric: lining-nums tabular-nums;
}

@media (max-width: 600px) {
    .ledger {
        padding-inline: 16px;
    }

    .ledger dl > div {
        gap: 12px;
    }

    .ledger-total dd {
        font-size: var(--type-numeral);
    }
}

/* The two compared columns get equal width; the fee name stays narrow. */
@media (min-width: 601px) {
    .fee-table table {
        table-layout: fixed;
    }

    .fee-table th:first-child {
        width: 24%;
    }
}

/* Our column is the painted door: a light juniper wash running the full height
   of the table, door-deep figures, hairline juniper rims. The "typical" column
   stays plain trim white, so the comparison lands before a single number is
   read. Column 2 is ours, the fee name is the row header, so the positional
   selector matches the width rule above.

   Juniper on trim white is the outline button's own hover wash, used here at
   column scale; color-mix keeps it tied to the door token instead of adding a
   palette entry. Deliberately not the enamel plaque: a full-height slab of
   slate reads as a black bar beside two near-white columns, and brass stops
   being legible long before the wash is light enough to sit calmly next to
   them. The plaque stays what it is elsewhere, a small tile, not a column. */
.fee-table thead th:nth-child(2),
.fee-table tbody td:nth-child(2) {
    background: color-mix(in srgb, var(--door-juniper) 12%, var(--trim-white));
    color: var(--door-deep);
    font-weight: 500;
    font-variant-numeric: lining-nums tabular-nums;
    border-bottom-color: color-mix(in srgb, var(--door-juniper) 28%, transparent);
    box-shadow:
        inset 1px 0 0 var(--door-juniper),
        inset -1px 0 0 var(--door-juniper);
}

/* The column's top edge. */
.fee-table thead th:nth-child(2) {
    background: color-mix(in srgb, var(--door-juniper) 20%, var(--trim-white));
    box-shadow:
        inset 1px 0 0 var(--door-juniper),
        inset -1px 0 0 var(--door-juniper),
        inset 0 1px 0 var(--door-juniper);
}

/* The column's bottom edge. */
.fee-table tbody tr:last-child td:nth-child(2) {
    box-shadow:
        inset 1px 0 0 var(--door-juniper),
        inset -1px 0 0 var(--door-juniper),
        inset 0 -1px 0 var(--door-juniper);
}

@media (max-width: 600px) {
    /* Stacked rows have no columns left, so our figure carries the wash with
       it: a painted panel per fee, hairline juniper rim, with the stacked
       layout's generated label above it in juniper. */
    .fee-table.table-stack tbody td:nth-child(2) {
        margin: 9px 0 3px;
        padding: 10px 15px 11px;
        background: color-mix(in srgb, var(--door-juniper) 12%, var(--trim-white));
        color: var(--door-deep);
        font-weight: 500;
        font-variant-numeric: lining-nums tabular-nums;
        box-shadow: inset 0 0 0 1px var(--door-juniper);
    }

    .fee-table.table-stack tbody td:nth-child(2)::before {
        color: var(--door-juniper);
    }
}

.badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 1px;
    background: var(--clapboard-putty);
    color: var(--door-deep);
    font-size: var(--type-micro);
    font-weight: 500;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.badge-clay {
    background: var(--enamel-slate);
    color: var(--brass);
}

.table-wrap {
    overflow-x: auto;
    border: 1px solid var(--rule);
    border-radius: 1px;
    background: var(--trim-white);
}

table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--type-body);
}

th,
td {
    padding: 14px 18px;
    text-align: left;
    border-bottom: 1px solid var(--rule);
    vertical-align: top;
}

thead th {
    background: var(--trim-shade);
    font-weight: 500;
}

/* Row headers read like the cells beside them; the stacked layout gives them weight. */
tbody th {
    font-weight: 400;
}

tbody tr:last-child th,
tbody tr:last-child td {
    border-bottom: 0;
}

/* Tables with 3+ columns clip on narrow screens: .table-stack renders each
   row as a labeled, stacked block instead. thead stays in the DOM (and
   readable to assistive tech) but is visually hidden. */
@media (max-width: 600px) {
    .table-stack table,
    .table-stack tbody,
    .table-stack tr,
    .table-stack tbody th,
    .table-stack td {
        display: block;
        width: 100%;
    }

    .table-stack thead th {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }

    .table-stack tbody tr {
        padding: 16px 18px;
        border-bottom: 1px solid var(--rule);
    }

    .table-stack tbody tr:last-child {
        border-bottom: 0;
    }

    .table-stack tbody th,
    .table-stack td {
        padding: 3px 0;
        border-bottom: 0;
    }

    .table-stack tbody th,
    .table-stack td:first-child {
        margin-bottom: 6px;
        font-size: var(--type-lead);
        font-weight: 500;
        color: var(--umber-ink);
    }

    .table-stack td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: var(--type-micro);
        color: var(--umber-soft);
    }
}

.lead-details {
    max-width: 360px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pagination {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-block-start: 16px;
}

.pagination-disabled {
    color: var(--umber-soft);
}

/* FAQ */
.faq {
    display: grid;
    gap: 0;
}

.faq details,
.qa {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--rule);
    border-radius: 0;
    padding: 0;
}

.faq details:first-child,
.qa:first-child {
    border-top: 1px solid var(--rule);
}

.faq summary,
.qa summary {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 20px;
    gap: 20px;
    cursor: pointer;
    list-style: none;
    padding: 18px 0;
    position: relative;
    font-weight: 500;
    font-size: var(--type-subhead);
    line-height: 1.4;
}

.faq summary::-webkit-details-marker,
.qa summary::-webkit-details-marker {
    display: none;
}

.faq summary::after {
    content: "";
    position: absolute;
    right: 0;
    top: calc(17.25px + 0.7em);
    width: 16px;
    height: 1.5px;
    background: var(--door-juniper);
    box-shadow: 0 0 0 0 var(--door-juniper);
}

.faq details:not([open]) summary::after {
    box-shadow: 0 0 0 0 currentColor;
}

.faq details:not([open]) summary::before {
    content: "";
    position: absolute;
    right: 7.25px;
    top: calc(10px + 0.7em);
    width: 1.5px;
    height: 16px;
    background: var(--door-juniper);
}

.faq summary:hover,
.qa summary:hover {
    color: var(--door-juniper);
}

.faq details > div,
.qa .answer {
    padding: 0 40px 20px 0;
    max-width: 64ch;
    color: var(--umber-soft);
}

.notice {
    padding: 18px 22px;
    border-radius: 1px;
    background: var(--trim-white);
    border: 1px solid var(--rule);
    border-left: 3px solid var(--door-juniper);
    box-shadow: 0 10px 24px -14px rgba(43, 38, 34, 0.45);
    color: var(--umber-ink);
}

.notice-warn {
    border-left-color: var(--umber-soft);
}

.notice-danger {
    border-left-color: var(--danger);
}

.notice strong {
    display: block;
    margin-bottom: 4px;
}

/* The way out when the way in is broken. A step down from the notice's own
   copy, and given room, so it reads as the second option rather than a
   run-on of the first. */
.notice-aside {
    margin: 10px 0 0;
    font-size: var(--type-label);
    color: var(--umber-soft);
}

/* Fixed regardless of where in the DOM it's rendered (see layouts/_toast),
   it's a stack of cards floating over the page, not part of its flow.
   Top, not bottom: bottom-right went unnoticed and collided with the
   footer's own links once a visitor scrolled that far. 96px clears the
   sticky header (76px + rule) the same way `scroll-padding-top` already
   does for anchors, reusing that number rather than inventing a new one. */
.toast-stack {
    position: fixed;
    top: 96px;
    right: 20px;
    z-index: 100;
    display: grid;
    gap: 12px;
    width: min(380px, calc(100vw - 32px));
}

/* The front-door treatment (.cta-band, .door-panel) turned up for a moment
   that deserves the same confidence: Door Deep fill, trim-white type, the
   same layered inset highlight as the door bands. A flat trim-white card
   with a hairline rule read as one more piece of page furniture; this reads
   as the porch light coming on to say the message landed. */
.toast {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 18px 44px 18px 22px;
    background: var(--door-deep);
    color: var(--trim-white);
    border-radius: 1px;
    cursor: pointer;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        0 24px 48px -18px rgba(22, 51, 41, 0.6);
    font-size: var(--type-ui);
    font-weight: 500;
    line-height: 1.5;
    /* Drops from above the header it now sits under, the toast's own entry
       point, and settles with a touch of weight (a board landing, not a
       toy sliding). 420ms is deliberately in the overlay range, not routine
       feedback: this is the payoff of the one thing every lead form exists
       to do, and it was going unnoticed at the old position. */
    animation: toast-in 420ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* The sitewide checklist mark (.checklist li::before), not a new icon: a
   completed lead form is exactly the kind of thing that mark already means.
   It lands a beat after the card, its own small confirmation inside the
   larger one. */
.toast::before {
    content: "";
    flex-shrink: 0;
    width: 14px;
    height: 11px;
    margin-top: 0.3em;
    background: var(--trim-white);
    -webkit-mask: var(--check) center / contain no-repeat;
    mask: var(--check) center / contain no-repeat;
    animation: toast-mark-in 260ms 180ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.toast p {
    flex: 1;
}

/* Danger is already the site's one alarm color (required marks, inline
   field errors); the toast just wears it as a full fill instead of a
   hairline, the same amplification the notice got. No checkmark here,
   that mark means "done," not "something needs attention." */
.toast-alert {
    background: var(--danger);
}

.toast-alert::before {
    content: none;
}

.toast-close {
    position: absolute;
    top: 14px;
    right: 14px;
    flex-shrink: 0;
    border: 0;
    background: none;
    padding: 4px;
    line-height: 1;
    font-size: 1.25rem;
    color: var(--trim-white);
    opacity: 0.7;
    cursor: pointer;
}

.toast-close:hover {
    opacity: 1;
}

/* Exits back the way it came, and faster than it arrived, retreating
   toward the header rather than falling away from it. `animation: none`
   releases opacity/transform from the entrance keyframes' `both` fill,
   without it the transition below never gets a turn at those properties,
   `transitionend` never fires, and the toast (auto-dismiss or the close
   button, both call the same JS) never actually leaves. */
.toast-leaving {
    animation: none;
    transition: opacity 180ms ease-in, transform 180ms ease-in;
    opacity: 0;
    transform: translateY(-16px);
    /* Stops it intercepting clicks meant for whatever's underneath the
       instant it starts leaving, regardless of how long the fade (or its
       removal from the DOM) actually takes. */
    pointer-events: none;
}

@keyframes toast-in {
    from { opacity: 0; transform: translateY(-28px) scale(0.97); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes toast-mark-in {
    from { opacity: 0; transform: scale(0.4); }
    to { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .toast,
    .toast::before {
        animation: none;
    }

    .toast-leaving {
        transition: none;
        opacity: 0;
    }
}

@media only screen and (max-width: 620px) {
    .toast-stack {
        top: 88px;
        right: 12px;
        left: 12px;
        width: auto;
    }
}

/* Front door CTA */
.cta-band,
.home-cta,
.front-door {
    background: var(--door-juniper);
    color: var(--trim-white);
}

.cta-band {
    border-radius: 1px;
    padding: clamp(36px, 5vw, 68px);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 32px;
    flex-wrap: wrap;
    box-shadow:
        inset 0 2px 0 rgba(0, 0, 0, 0.35),
        inset 0 -1px 0 rgba(255, 255, 255, 0.08),
        inset 0 0 0 14px var(--door-deep),
        inset 0 0 0 15px rgba(0, 0, 0, 0.3),
        inset 0 0 0 16px rgba(255, 255, 255, 0.06);
    background: var(--door-deep);
}

.cta-band h2,
.home-cta h2,
.front-door h2 {
    margin-bottom: 8px;
}

.cta-band p,
.home-cta p,
.front-door .intro {
    color: var(--on-door);
    max-width: 56ch;
    line-height: 1.7;
}

.cta-band .btn-primary,
.cta-band .btn-lit,
.front-door .btn-lit,
.front-door .btn-primary,
.home-cta .btn-primary {
    background: var(--trim-white);
    border-color: var(--trim-white);
    color: var(--door-juniper);
}

.cta-band .btn-primary:hover,
.cta-band .btn-lit:hover,
.front-door .btn-lit:hover,
.front-door .btn-primary:hover,
.home-cta .btn-primary:hover {
    background: var(--trim-shade);
    color: var(--door-deep);
}

.cta-band a:not(.btn),
.front-door a:not(.btn),
.home-cta a:not(.btn) {
    color: var(--trim-white);
}

.cta-band :focus-visible,
.front-door :focus-visible,
.home-cta :focus-visible {
    outline-color: var(--trim-white);
}

.door-panel {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: 32px clamp(32px, 6vw, 88px);
    align-items: center;
    padding: clamp(36px, 5vw, 68px);
    border-radius: 1px;
    background: var(--door-deep);
    box-shadow:
        inset 0 2px 0 rgba(0, 0, 0, 0.35),
        inset 0 -1px 0 rgba(255, 255, 255, 0.08),
        inset 0 0 0 14px var(--door-deep),
        inset 0 0 0 15px rgba(0, 0, 0, 0.3),
        inset 0 0 0 16px rgba(255, 255, 255, 0.06);
}

.listing-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 28px;
}

.listing {
    background: var(--trim-white);
    border: 1px solid var(--rule);
    border-radius: 1px;
    overflow: hidden;
}

.listing .image-placeholder {
    border-radius: 0;
    aspect-ratio: 16 / 10;
}

.listing-body {
    padding: 20px;
}

.listing-price {
    display: inline-block;
    margin-bottom: 4px;
}

.listing-price .figure {
    font-size: var(--type-numeral);
}

.listing-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    margin-block: 6px 14px;
    font-size: var(--type-label);
    color: var(--umber-soft);
}

.form {
    display: grid;
    gap: 16px;
    background: var(--trim-white);
    border: 1px solid var(--rule);
    border-radius: 1px;
    padding: clamp(22px, 4vw, 34px);
}

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

/* The comp diagram: one more enamel plaque, holding a drawing where the fee
   plaques hold a figure. Brass is the subject house and the distance rings,
   hardware, per The Brass Is For Doors Rule, and the rentals it is priced
   against are set in enamel lettering so the centre stays the point. */
.comp-plaque .plaque {
    padding: clamp(20px, 3vw, 30px);
    color: var(--brass);
}

.comp-plaque svg {
    display: block;
    width: 100%;
    height: auto;
}

.comp-rings {
    stroke-width: 1;
    opacity: 0.42;
}

.comp-links {
    stroke-width: 1;
    opacity: 0.3;
}

.comp-others {
    fill: var(--enamel-letter);
    opacity: 0.7;
}

.comp-subject {
    fill: var(--brass);
}

/* The one label on the drawing, and the reason the rings read as distance
   from somewhere rather than as decoration. */
.comp-subject text {
    fill: var(--enamel-letter);
    font-family: var(--serif);
    font-size: 15px;
    text-anchor: middle;
}

/* Paired fields line up on their inputs, not their labels: a label that wraps
   to two lines would otherwise drop its own input a line below its neighbour's.
   Bottom-aligning the contents fixes it for any label, at any width. */
/* Paired fields share one set of rows: labels, controls, messages. A label
   that wraps to two lines grows row one for both halves instead of pushing
   its own control down, and an inline error hangs in row three instead of
   lifting its control above the field beside it. */
.form-row {
    grid-template-rows: auto auto auto;
    row-gap: 6px;
}

.form-row > .field {
    grid-row: span 3;
    grid-template-rows: subgrid;
    gap: 0;
}

.form-row > .field > .field-label {
    align-self: end;
}

/* Street and ZIP are one address: the street gets the room, the ZIP gets five
   characters' worth. They stay paired at every width, a lone ZIP on its own
   row reads as a second question rather than the end of the first. */
.form-row.is-address {
    grid-template-columns: minmax(0, 1fr) 7.5rem;
}

.field {
    display: grid;
    gap: 6px;
}

.field label,
.field legend {
    font-size: var(--type-ui);
    font-weight: 500;
}

.field input,
.field select,
.field textarea {
    width: 100%;
    padding: 11px 13px;
    border: 1px solid var(--umber-soft);
    border-radius: 2px;
    background: var(--trim-white);
    font: inherit;
    font-size: var(--type-body);
    color: var(--umber-ink);
}

.field-check {
    grid-template-columns: 1.15em 1fr;
    gap: 10px 12px;
    align-items: start;
}

.field-check input[type="checkbox"] {
    appearance: none;
    flex: none;
    width: 1.15em;
    height: 1.15em;
    margin: 0.2em 0 0;
    padding: 0;
    border: 1.5px solid var(--umber-soft);
    border-radius: 2px;
    background: var(--trim-white) center / 100% no-repeat;
}

/* Drawn, not native, so the box is the same size and shape in every state. */
.field-check input[type="checkbox"]:checked {
    border-color: var(--door-juniper);
    background-color: var(--door-juniper);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.field-check label {
    font-weight: 400;
    font-size: var(--type-label);
    color: var(--umber-soft);
    line-height: 1.5;
}

/* The disclosure the checkbox points at with aria-describedby. It is no longer
   inside the <label>, so it needs its own place in the two-column grid. */
/* Rails wraps an invalid checkbox and its label in div.field_with_errors. As
   the lone grid item it took the checkbox's column and left the label an
   inline box, so the label's lines inherited the wrapper's taller strut.
   Let the checkbox and label be the grid items again. */
.field-check .field_with_errors {
    display: contents;
}

/* The checkmark is a background image, which forced-colors mode drops, so a
   ticked box would look empty. Hand the box back to the system there. */
@media (forced-colors: active) {
    .field-check input[type="checkbox"] {
        appearance: auto;
    }
}

/* An unticked required box in error is red: border, a pale red fill, and the
   whole consent, links and disclosure included. Ticking it clears the state. */
.field-check.field-invalid:not(:has(input:checked)) input[type="checkbox"] {
    border-color: var(--danger);
    background-color: color-mix(in srgb, var(--danger) 14%, var(--trim-white));
}

.field-check.field-invalid:not(:has(input:checked)) .consent-text,
.field-check.field-invalid:not(:has(input:checked)) .consent-text a,
.field-check.field-invalid:not(:has(input:checked)) .consent-detail,
.field-check.field-invalid:not(:has(input:checked)) label {
    color: var(--danger);
}

.field-check.field-invalid:has(input:checked) .field-error {
    display: none;
}

.field-check .consent-text,
.field-check .consent-detail,
.field-check .field-error,
.field-check .hint {
    grid-column: 2;
}

.field-check .consent-text {
    margin: 0;
    font-size: var(--type-label);
    line-height: 1.5;
}

.field-check .consent-detail {
    margin: 0;
    font-size: var(--type-label);
    line-height: 1.5;
    color: var(--umber-soft);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
    outline: 2px solid var(--umber-ink);
    outline-offset: 0;
    border-color: var(--umber-ink);
}

.field textarea {
    min-height: 120px;
    resize: vertical;
}

.field .hint {
    font-size: var(--type-label);
    color: var(--umber-soft);
}

.required-mark {
    color: var(--danger);
    margin-left: 2px;
}

.field-invalid input,
.field-invalid select,
.field-invalid textarea {
    border-color: var(--danger);
}

.field-invalid input:focus,
.field-invalid select:focus,
.field-invalid textarea:focus {
    outline-color: var(--danger);
    border-color: var(--danger);
}

/* The message can echo what was typed, and what was typed can be a 200-
   character string with no spaces in it. Break it rather than let it push the
   field's column past the form. */
.field-error {
    font-size: var(--type-label);
    color: var(--danger);
    overflow-wrap: anywhere;
}

/* The form's grid of fields dissolves into this, a plaque, not a paragraph,
   because the moment a lead form exists to reach deserves the site's own
   "something earned" object, not a bare confirmation line. Settles in a beat
   after the toast lands (see toast-in), so the two read as one sequence
   instead of two unrelated notifications firing at once. */
.form-success {
    display: flex;
    align-items: center;
    gap: 18px;
    min-height: 120px;
    color: var(--umber-ink);
    animation: form-success-in 380ms 80ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.form-success p {
    max-width: 48ch;
}

/* The enamel plaque (.plaque), sized down to hold one figure: same brass
   rim, same slate body, same signature, just wearing the checklist mark
   (--check) instead of a fee or a stat this time.

   The submit button that got them here already carries the site's one
   reserved lamp effect (.btn-lit, "reserved for the main conversion"), this
   is that promise arriving. Sequence: the panel settles, the plaque and its
   check appear (0–460ms), then the lamp actually catches (460ms+), reusing
   .btn-lit's own lamp-on rhythm, a quick flicker, a dip, then a steady
   hold, because that's the one lamp behavior this site has already
   authored and it shouldn't invent a second one. */
.success-plaque {
    position: relative;
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 52px;
    height: 52px;
    border-radius: 1px;
    background: var(--enamel-slate);
    animation: plaque-lamp-on 800ms 460ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

/* The glow spilling out around the plaque as the lamp catches: sized past
   the plaque and stacked behind it (z-index) so it reads as light in the
   air, not a painted shape. */
.success-plaque::after {
    content: "";
    position: absolute;
    inset: -22px;
    z-index: -1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(var(--lamp), 0.5) 0%, rgba(var(--lamp), 0.14) 45%, transparent 72%);
    animation: plaque-bloom-in 800ms 460ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

.success-plaque::before {
    content: "";
    width: 20px;
    height: 15px;
    background: var(--brass);
    -webkit-mask: var(--check) center / contain no-repeat;
    mask: var(--check) center / contain no-repeat;
    animation:
        toast-mark-in 260ms 200ms cubic-bezier(0.16, 1, 0.3, 1) both,
        mark-catch-light 800ms 460ms cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes form-success-in {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

/* Matches .btn-lit's own lamp-on keyframe shape (12% catch, 18% dip, 100%
   hold), same fixture, same behavior, just glowing around a plaque instead
   of under a button. */
@keyframes plaque-lamp-on {
    0% {
        box-shadow:
            inset 0 0 0 1px var(--brass),
            inset 0 0 0 4px var(--enamel-slate),
            inset 0 0 0 5px rgba(217, 181, 116, 0.4),
            0 4px 9px -3px rgba(0, 0, 0, 0.5),
            0 0 0 0 rgba(var(--lamp), 0);
    }
    12% {
        box-shadow:
            inset 0 0 0 1px var(--brass),
            inset 0 0 0 4px var(--enamel-slate),
            inset 0 0 0 5px rgba(217, 181, 116, 0.4),
            0 4px 9px -3px rgba(0, 0, 0, 0.5),
            0 0 14px 2px rgba(var(--lamp), 0.45);
    }
    18% {
        box-shadow:
            inset 0 0 0 1px var(--brass),
            inset 0 0 0 4px var(--enamel-slate),
            inset 0 0 0 5px rgba(217, 181, 116, 0.4),
            0 4px 9px -3px rgba(0, 0, 0, 0.5),
            0 0 3px 0 rgba(var(--lamp), 0.08);
    }
    100% {
        box-shadow:
            inset 0 0 0 1px var(--brass),
            inset 0 0 0 4px var(--enamel-slate),
            inset 0 0 0 5px rgba(217, 181, 116, 0.4),
            0 4px 9px -3px rgba(0, 0, 0, 0.5),
            0 0 16px 2px rgba(var(--lamp), 0.55);
    }
}

@keyframes plaque-bloom-in {
    0% { opacity: 0; transform: scale(0.7); }
    12% { opacity: 0.85; transform: scale(1.05); }
    18% { opacity: 0.15; transform: scale(0.92); }
    100% { opacity: 1; transform: scale(1); }
}

@keyframes mark-catch-light {
    0%, 100% { filter: drop-shadow(0 0 0 rgba(var(--lamp), 0)); }
    15% { filter: drop-shadow(0 0 5px rgba(var(--lamp), 0.9)); }
}

@media (prefers-reduced-motion: reduce) {
    .form-success,
    .success-plaque,
    .success-plaque::before,
    .success-plaque::after {
        animation: none;
    }

    /* Reduced motion loses the ignition sequence, not the lamp itself,
       the payoff still shows, just without the flicker performing it. */
    .success-plaque {
        box-shadow:
            inset 0 0 0 1px var(--brass),
            inset 0 0 0 4px var(--enamel-slate),
            inset 0 0 0 5px rgba(217, 181, 116, 0.4),
            0 4px 9px -3px rgba(0, 0, 0, 0.5),
            0 0 16px 2px rgba(var(--lamp), 0.55);
    }

    .success-plaque::after {
        opacity: 1;
    }
}

.form-status {
    font-size: var(--type-ui);
    padding: 12px 14px;
    border-radius: 1px;
    background: var(--clapboard-putty);
}

.calc {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: 28px clamp(32px, 5vw, 72px);
    align-items: start;
}

/* The fields sit on the page or the board they belong to; the result ledger is
   the only raised object in a calculator. */
.calc .form {
    padding: 0;
    border: 0;
    background: none;
}

/* A hint under one field must not stretch its neighbour's input. */
.calc .form-row {
    align-items: start;
}

/* A lone number field doesn't need the full column. */
.calc .form > .field {
    max-width: 30rem;
}

.calc-asterisk a {
    color: inherit;
    text-decoration: none;
    margin-left: 2px;
    line-height: 1;
}

.area-list {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    list-style: none;
    padding: 0;
}

.area-list a,
.area-list span {
    display: inline-block;
    padding: 8px 16px;
    border-radius: 1px;
    border: 1px solid var(--rule);
    background: var(--trim-white);
    color: var(--umber-ink);
    text-decoration: none;
    font-size: var(--type-ui);
}

.area-list a:hover {
    border-color: var(--door-juniper);
    color: var(--door-deep);
}

.site-footer {
    background: var(--eave-shadow);
    color: var(--trim-shade);
    font-size: var(--type-label);
    padding-top: 56px;
}

.footer-grid {
    display: grid;
    /* fit-content, not a minmax track: the info plate's own two columns are
       already capped by .footer-brand/.footer-contact's max-width, so the
       track should hug that content instead of reserving a fixed width the
       divider then floats inside of, leaving dead space before it. */
    grid-template-columns: fit-content(29rem) minmax(0, 1fr);
    column-gap: clamp(48px, 6vw, 96px);
    align-items: start;
    padding-bottom: 48px;
}

/* Branding left, contact/hours right: two content-sized columns, not a
   stretchy 1fr, so they sit close together instead of spreading across
   the full stacked-width at the 1100px breakpoint. */
.footer-info {
    display: grid;
    grid-template-columns: auto auto;
    justify-content: start;
    column-gap: 12px;
    padding-right: clamp(8px, 1.5vw, 28px);
    border-right: 1px solid rgba(246, 245, 241, 0.12);
}

.footer-brand {
    max-width: 230px;
}

.footer-info p {
    max-width: 42ch;
    margin-top: 4px;
    font-size: var(--type-ui);
    line-height: 1.55;
    letter-spacing: 0.01em;
}

/* The brand line, not a sentence of copy: set at subhead size. */
.footer-slogan {
    margin-top: 10px;
    font-size: var(--type-subhead);
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: -0.01em;
}

.footer-nav {
    display: grid;
}

/* Each category is a ruled row, label beside a horizontally wrapped link
   list, echoing the .service-block label-column idiom instead of stacking
   every link one per line. */
.footer-category {
    display: grid;
    grid-template-columns: 128px 1fr;
    column-gap: 24px;
    padding-block: 18px;
    border-top: 1px solid rgba(246, 245, 241, 0.12);
}

.footer-category:first-child {
    border-top: 0;
    padding-top: 0;
}

.footer-category:last-child {
    padding-bottom: 0;
}

.site-footer h2 {
    font-size: var(--type-ui);
    font-weight: 500;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--trim-white);
}

.footer-category ul {
    list-style: none;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 8px 22px;
}

/* Screen width alone doesn't tell you the input method: a landscape phone
   or small tablet lands well above the 600px stacking breakpoint but is
   still a thumb, not a cursor. Loosen the wrap's pitch there without
   restructuring it, full block rows are reserved for the width the wrap
   itself can no longer use (max-width: 600px, below). */
@media (pointer: coarse) {
    .footer-category ul {
        gap: 16px 26px;
    }

    .footer-category ul a {
        display: inline-block;
        padding-block: 6px;
    }

    .footer-contact {
        gap: 14px;
    }
}

.site-footer a {
    color: var(--trim-white);
    text-decoration: none;
}

.site-footer a:hover {
    text-decoration: underline;
}

.site-footer .brand {
    color: var(--trim-white);
    margin-bottom: 16px;
}

.site-footer .brand:hover {
    text-decoration: none;
}

.site-footer .brand-name small {
    color: var(--trim-shade);
}

.footer-contact {
    display: grid;
    gap: 6px;
    max-width: 170px;
    padding-left: 14px;
    border-left: 1px solid rgba(246, 245, 241, 0.12);
    font-size: var(--type-label);
    line-height: 1.45;
    letter-spacing: 0.01em;
}

.footer-bottom {
    border-top: 1px solid rgba(246, 245, 241, 0.12);
    padding-block: 22px;
    display: flex;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    font-size: var(--type-label);
}

.footer-bottom nav {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}

.eho {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.error-page main {
    min-height: 60vh;
    display: grid;
    place-items: center;
    text-align: center;
}

.error-code {
    font-size: clamp(5rem, 14vw, 9rem);
    line-height: 1;
    color: var(--clapboard-putty);
}

.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 12px; }
.mt-2 { margin-top: 24px; }
.mt-3 { margin-top: 40px; }
.mt-4 { margin-top: 56px; }
.center { text-align: center; }
.muted { color: var(--umber-soft); }

.center .btn-row {
    justify-content: center;
}

.services,
.band.faq,
.section-ruled {
    border-top: 1px solid var(--rule);
}

.section:has(> .container > .cta-band) {
    background: var(--door-juniper);
}

.hero-actions {
    margin-top: 26px;
}

/* Homepage bands */
.terms-grid,
.why-grid,
.services-grid,
.faq-grid {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
    gap: clamp(28px, 5vw, 72px);
    align-items: start;
}

.why-grid {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    align-items: center;
}

.services-grid {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    margin-top: 36px;
}

.terms-note {
    margin-top: 32px;
    padding-top: 16px;
    border-top: 1px solid var(--rule);
    max-width: 60ch;
    font-size: var(--type-ui);
    color: var(--umber-soft);
}

.why-next {
    margin-top: 22px;
}

.points,
.service-list,
.faq-links,
.terms-list {
    list-style: none;
    padding: 0;
}

.points {
    margin-top: 28px;
}

.points li {
    padding-block: 20px;
    border-top: 1px solid var(--rule);
}

.points p,
.service p {
    margin-top: 4px;
    max-width: 60ch;
    color: var(--umber-soft);
}

.points a {
    display: inline-block;
    margin-top: 6px;
    font-size: var(--type-ui);
}

/* "What you get" on the rental report page: heading over a two-column grid of
   the four deliverables, instead of the 4fr/8fr side heading whose left
   column held one title and nothing else. */
.report-contents-head {
    max-width: 60ch;
}

.report-contents-head .intro {
    margin-top: 8px;
}

.report-contents-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: clamp(28px, 5vw, 72px);
}

.report-contents-list li {
    padding-block: 24px 28px;
}

@media (max-width: 720px) {
    .report-contents-list {
        grid-template-columns: 1fr;
    }
}

.manager-slot {
    display: block;
    width: fit-content;
    margin-top: 8px;
    padding: 3px 10px;
    border: 1px dashed var(--umber-soft);
    font-size: var(--type-label);
    color: var(--umber-soft);
}

.service-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 36px;
}

.service {
    padding-block: 18px 22px;
    border-top: 1px solid var(--rule);
}

.service h3 {
    font-size: var(--type-subhead);
}

.service h3 a {
    color: var(--umber-ink);
    text-decoration: none;
}

.service h3 a:hover {
    color: var(--door-juniper);
    text-decoration: underline;
}

.covered {
    display: block;
    margin-top: 8px;
    font-size: var(--type-label);
    color: var(--umber-soft);
}

.services-photo img {
    aspect-ratio: 4 / 3;
}

.porch-steps {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 32px;
    margin-top: 32px;
    list-style: none;
    padding: 0;
}

.porch-steps .plaque {
    display: inline-flex;
    align-items: center;
    width: 3.5rem;
    margin-bottom: 16px;
    padding: 10px 0 11px;
}

.porch-steps .figure {
    font-size: var(--type-numeral-lg);
}

.porch-steps p {
    margin-top: 6px;
}

.terms-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 28px 36px;
}

/* Every commitment gets the same plaque, whatever its figure, so the four
   read as a set rather than boxes sized to their contents. */
.terms-list .plaque {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 11rem;
    padding: 12px 16px 13px;
}

.terms-list .figure {
    font-size: var(--type-numeral-lg);
    white-space: nowrap;
}

.terms-list p {
    margin-top: 12px;
    max-width: 32ch;
    text-wrap: pretty;
}

/* The four things that stop being the owner's job. The section's argument is
   its anaphora, so the structure says it too: each sentence opens with "Never",
   in juniper, and the rest of it stays in ink at the same size. Set apart at a
   bigger size, the repeated word outweighed the four things that differ, and a
   skimmer read "Never Never Never Never". One line per promise keeps the noun as
   loud as the word. This band has no figures, so no plaque: enamel is for fees,
   stats, and step numerals, and the hero's fee wall sits 56px above this on a
   phone.

   The board keeps the page's 4fr/8fr side heading (terms-grid, why-grid and
   faq-grid all use it), so the four items read as a two-up beside the heading
   rather than a full-width run. */
.outcomes-board {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
    gap: clamp(28px, 5vw, 72px);
    align-items: start;
}

.outcomes-head .intro {
    margin-top: 10px;
}

.outcomes-more {
    margin-top: 18px;
}

.outcomes {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(26px, 3vw, 44px) clamp(28px, 4vw, 64px);
    list-style: none;
    padding: 0;
}

/* The divider is the system's hairline rule, tinted toward juniper so the four
   items read as a set without the rule competing with the word above it. */
.outcomes li {
    padding-top: 18px;
    border-top: 1px solid color-mix(in srgb, var(--door-juniper) 55%, var(--trim-white));
}

.outcomes h3 {
    margin-bottom: 10px;
    font-size: var(--type-numeral);
    line-height: 1.2;
    letter-spacing: -0.01em;
    text-wrap: balance;
}

.outcomes .never { color: var(--door-juniper); }

.outcomes p {
    color: var(--umber-soft);
}

@media (max-width: 720px) {
    /* One column before the two-up measure drops under about 40 characters. */
    .outcomes {
        grid-template-columns: 1fr;
    }
}

/* Owners: the road from first message to first payout. The painted door ground
   of the owner hero, house-number plaques, and a brass rail between them drawn
   at the roofline's strength, the one stretch of the page that moves. */
.journey {
    --journey-gap: clamp(24px, 3vw, 48px);
    --journey-plaque: 4.5rem;
    --journey-rail: rgba(217, 181, 116, 0.6);
    background: var(--door-deep);
    color: var(--on-door);
    box-shadow: inset 0 2px 0 rgba(0, 0, 0, 0.3);
}

/* Tenant steps: the same journey, hung as a panel on the page rather than a
   full-bleed band, so it doesn't butt against the section tabs. */
.journey-panel {
    padding: clamp(28px, 5vw, 56px);
    border-radius: 1px;
    box-shadow: 0 18px 36px -24px rgba(34, 30, 27, 0.6);
}

.journey h2,
.journey h3 {
    color: var(--trim-white);
}

.journey .section-head {
    margin-bottom: clamp(40px, 5vw, 64px);
}

.steps.journey-steps {
    gap: 40px var(--journey-gap);
}

.steps.journey-steps li::before {
    width: var(--journey-plaque);
    height: var(--journey-plaque);
    margin-bottom: 24px;
    padding: 0;
    font-size: var(--type-headline);
}

/* Rail: from this plaque's right edge to the next plaque's left edge. */
.steps.journey-steps li:not(:last-child)::after {
    content: "";
    position: absolute;
    top: calc(var(--journey-plaque) / 2);
    left: calc(var(--journey-plaque) + 12px);
    right: calc(-1 * var(--journey-gap) + 12px);
    height: 1px;
    background: var(--journey-rail);
}

.steps.journey-steps h3 {
    margin-bottom: 8px;
    font-size: var(--type-title);
}

.steps.journey-steps p {
    max-width: 30ch;
    color: var(--on-door);
}

.journey :focus-visible {
    outline-color: var(--trim-white);
}

@media (max-width: 960px) {
    /* Two to a row: the rail only runs between neighbours on the same row. */
    .steps.journey-steps li:nth-child(2n)::after {
        content: none;
    }
}

@media (max-width: 600px) {
    .journey {
        --journey-plaque: 3.5rem;
    }

    .steps.journey-steps {
        gap: 32px;
    }

    .steps.journey-steps li {
        grid-template-columns: var(--journey-plaque) minmax(0, 1fr);
        column-gap: 18px;
    }

    .steps.journey-steps li::before {
        margin-bottom: 0;
        font-size: var(--type-numeral-lg);
    }

    /* One column: the rail drops straight down the plaque column. */
    .steps.journey-steps li:not(:last-child)::after {
        content: "";
        top: calc(var(--journey-plaque) + 10px);
        bottom: -22px;
        left: calc(var(--journey-plaque) / 2);
        right: auto;
        width: 1px;
        height: auto;
    }
}

/* Owners: the fees run as a ledger, one plaque per ruled row, so three items
   don't leave a hole in the two-column terms grid. */
.fee-terms {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
}

.fee-terms li {
    display: grid;
    grid-template-columns: 13rem minmax(0, 1fr);
    align-items: center;
    gap: 0 28px;
    padding-block: 20px;
    border-top: 1px solid var(--rule);
}

.fee-terms li:first-child {
    padding-top: 0;
    border-top: 0;
}

.fee-terms .plaque {
    width: 100%;
}

.fee-terms p {
    margin-top: 0;
    max-width: 48ch;
}

/* Owner types: a ruled list beside the heading, name then description. */
.owner-types .card {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    gap: 4px 32px;
}

.owner-types .card:first-child {
    padding-top: 0;
    border-top: 0;
}

.owner-types .card h3 {
    margin-bottom: 0;
    font-size: var(--type-subhead);
}

.faq-links {
    display: grid;
    gap: 6px;
    margin-top: 18px;
}

.areas h3 {
    font-size: var(--type-subhead);
}

.areas p {
    margin-top: 4px;
    color: var(--on-door);
}

.areas ul {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 22px;
    margin-top: 14px;
    list-style: none;
    font-size: var(--type-lead);
    padding: 0;
}

/* The rental report: the form rides in the owner hero's aside, a trim board
   standing on the painted door. Everything the dark hero recolors, the text,
   the white button, the white links, the white focus ring, has to come back
   to its on-trim value inside the board, or it disappears into it. */
.owner-hero.has-aside:has(.report-well) .door-hero-inner {
    align-items: start;
}

/* Set in the trim the rest of the copy column wears; the house mark's juniper
   would disappear against the door. */
.hero-support-note {
    margin-top: 22px;
    font-size: var(--type-ui);
    color: var(--on-door);
    text-wrap: pretty;
}

/* The invitation, the number, and the hours used to be four sentences at one
   size, separated by full stops. They are three different jobs: an offer, the
   thing a hand acts on, and metadata about when. So three roles, 15/18/13,
   400/500/400, full/full/dimmed, with the number in the middle, because it
   is the only line here anyone acts on. Sentence case and no tracking on the
   first line: it is a question addressed to the reader, not an eyebrow. */
.hero-contact {
    display: grid;
    justify-items: start;
    margin-top: 24px;
}

.hero-contact-invite {
    margin: 0;
    font-size: var(--type-ui);
    line-height: 1.5;
    color: color-mix(in srgb, var(--on-door) 84%, transparent);
}

/* Lining tabular figures, per The Serif Counts Rule, a phone number is a
   figure, and tabular keeps the three groups evenly set. The brass hairline is
   the link affordance: hardware under a figure, not a fill. */
.hero-contact-number {
    margin-top: 2px;
    font-size: var(--type-subhead);
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: -0.01em;
    font-variant-numeric: lining-nums tabular-nums;
    text-decoration-line: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 5px;
    text-decoration-color: color-mix(in srgb, var(--brass) 70%, transparent);
}

.hero-contact-number:hover {
    text-decoration-color: var(--brass);
}

.hero-contact-hours {
    margin: 8px 0 0;
    font-size: var(--type-label);
    line-height: 1.5;
    color: color-mix(in srgb, var(--on-door) 72%, transparent);
}

/* On the report page the form is the hero's whole job on a phone, so the copy
   column's support gives up its room. Scoped to a hero that has an aside,
   because the thank-you page's support note, which inbox to watch, is the
   most useful line on it. */
@media (max-width: 600px) {
    .door-hero.has-aside .hero-contact,
    .door-hero.has-aside .hero-support-note {
        display: none;
    }
}

.door-hero .report-form {
    color: var(--umber-ink);
}

.report-form a:not(.btn) {
    color: var(--door-juniper);
}

.report-form :focus-visible {
    outline-color: var(--umber-ink);
}

.door-hero .report-form .btn-primary {
    background: var(--door-juniper);
    border-color: var(--door-juniper);
    color: var(--trim-white);
}

.door-hero .report-form .btn-primary:hover {
    background: var(--door-deep);
    color: var(--trim-white);
}

/* The lamp burns against the door, not against the board standing on it. The
   conversion keeps .btn-lit so the class still names it; the halo stays out. */
.door-hero .report-form .btn-lit {
    box-shadow: none;
    animation: none;
}

/* Turbo disables the button while the submit is in flight, but the rule above
   is more specific than .btn:disabled, so nothing changed on screen and the
   visitor pressed it again. */
.door-hero .report-form .btn-primary:disabled,
.door-hero .report-form .btn-primary:disabled:hover {
    background: var(--trim-shade);
    border-color: var(--rule);
    color: var(--umber-soft);
    cursor: progress;
}

/* Both CTAs that point at the form land it clear of the sticky header. The
   well is a scroll target that takes focus, not an interactive element, so it
   does not draw a ring of its own, the field the visitor tabs to next does. */
.report-well {
    scroll-margin-top: 96px;
}

.report-well:focus {
    outline: none;
}

.form-note {
    margin-top: -6px;
    font-size: var(--type-label);
    color: var(--umber-soft);
    text-wrap: pretty;
}

/* The note under the report form's submit reads as fine print: one block of
   italic micro type, the way .fine-print sets type. */
.report-form .form-note {
    font-size: var(--type-micro);
    font-style: italic;
    line-height: 1.4;
}

/* The report form is the page's whole job, so it is tuned for height: one
   screen on a laptop, and as little scrolling as the fields allow on a phone.
   Three moves, in order of what they are worth:

   1. The SMS consent, 148px of required legal type, waits for a number to
      consent about (sms_consent_controller). It ships visible and JS hides it.
   2. Rhythm instead of a flat gap: fields sit tight inside the form, and the
      things that end it get air above them. Fewer pixels and better grouping.
   3. Rails' hidden inputs are grid children and were each eating a gap. */
.report-form {
    gap: 12px;
    padding: clamp(20px, 3vw, 26px);
}

.report-form > input[type="hidden"] {
    display: none;
}

.report-form .form-more {
    margin-top: 6px;
}

.report-form [type="submit"] {
    margin-top: 6px;
}

.field-check[hidden] {
    display: none;
}

/* The four fields most owners skip, folded away rather than dropped: a summary
   on the form's own hairline, opening the same field grid underneath it. */
.form-more {
    border-top: 1px solid var(--rule);
    padding-top: 16px;
}

.form-more summary {
    display: inline-flex;
    /* The label wraps to two lines on a phone; the marker belongs on the first
       one, not floating between them. */
    align-items: start;
    gap: 10px;
    list-style: none;
    cursor: pointer;
    font-size: var(--type-ui);
    font-weight: 500;
    color: var(--door-juniper);
}

.form-more summary::-webkit-details-marker {
    display: none;
}

/* The FAQ's 1.5px juniper plus and minus, at field scale. */
.form-more summary::before {
    content: "";
    flex: none;
    margin-top: 2px;
    width: 14px;
    height: 14px;
    background:
        linear-gradient(var(--door-juniper), var(--door-juniper)) center / 14px 1.5px no-repeat,
        linear-gradient(var(--door-juniper), var(--door-juniper)) center / 1.5px 14px no-repeat;
}

.form-more[open] summary::before {
    background:
        linear-gradient(var(--door-juniper), var(--door-juniper)) center / 14px 1.5px no-repeat;
}

.form-more summary:hover {
    color: var(--door-deep);
}

.form-more-fields {
    display: grid;
    gap: 16px;
    margin-top: 16px;
}

/* A grouped set of money boxes inside the disclosure: a legend and one note
   covering all four, so each field's own label can stay short. */
.form-group {
    display: grid;
    gap: 12px;
    margin: 0;
    padding: 16px 0 0;
    border: 0;
    border-top: 1px solid var(--rule);
}

.form-group legend {
    padding: 0;
    font-size: var(--type-ui);
    font-weight: 500;
    color: var(--umber-ink);
}

.form-group-note {
    font-size: var(--type-label);
    line-height: 1.5;
    color: var(--umber-soft);
    text-wrap: pretty;
}

@media (max-width: 1200px) {
    .main-nav > ul {
        gap: 6px 16px;
    }
}

@media (max-width: 1100px) {
    .footer-grid {
        grid-template-columns: 1fr;
        row-gap: 40px;
    }

    .footer-info {
        padding-right: 0;
        border-right: none;
        padding-bottom: 32px;
        border-bottom: 1px solid rgba(246, 245, 241, 0.12);
    }
}

@media (max-width: 960px) {
    .about-hero-action {
        display: flex;
    }

    /* One-line utility bar at tablet width too: drop the "Serving..." span. */
    .utility-bar .container > span {
        display: none;
    }

    .nav-toggle {
        display: inline-block;
    }

    .main-nav {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        max-height: calc(100vh - 76px);
        overflow-y: auto;
        background: var(--trim-white);
        border-bottom: 1px solid var(--rule);
        padding: 12px var(--gutter) 24px;
    }

    .site-header.nav-open .main-nav {
        display: block;
    }

    .main-nav > ul {
        flex-direction: column;
        align-items: stretch;
        gap: 0;
    }

    .main-nav > ul > li > a {
        display: flex;
        align-items: center;
        min-height: 44px;
        padding-block: 10px;
    }

    .main-nav > ul > li:has(> .submenu) {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 44px;
        align-items: center;
        column-gap: 8px;
    }

    .sub-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        position: relative;
        grid-column: 2;
        grid-row: 1;
        width: 44px;
        height: 44px;
        padding: 0;
        border: 1px solid var(--umber-soft);
        border-radius: 3px;
        background: none;
        font: inherit;
        cursor: pointer;
    }

    .sub-toggle::before,
    .sub-toggle::after {
        content: "";
        position: absolute;
        background: var(--door-juniper);
    }

    .sub-toggle::before {
        width: 10px;
        height: 1.5px;
    }

    .sub-toggle::after {
        width: 1.5px;
        height: 10px;
    }

    .main-nav li.is-open > .sub-toggle::after {
        display: none;
    }

    .submenu {
        display: none;
        position: static;
        grid-column: 1 / -1;
        opacity: 1;
        visibility: visible;
        transform: none;
        box-shadow: none;
        border: 0;
        padding: 0 0 8px 4px;
    }

    .main-nav li.is-open > .submenu {
        display: block;
    }

    .submenu li + li {
        border-top: 0;
    }

    .main-nav .nav-cta {
        order: -1;
        margin: 0 0 8px;
        padding-bottom: 12px;
        border-bottom: 1px solid var(--rule);
    }

    .main-nav > ul > li.nav-cta > a {
        display: inline-flex;
        width: auto;
        min-height: 0;
        padding: 9px 18px;
    }

    .submenu a {
        display: flex;
        align-items: center;
        min-height: 44px;
    }

    .porch-hero {
        aspect-ratio: auto;
        max-height: none;
        min-height: 0;
        overflow: visible;
        background: var(--trim-white);
    }

    .hero-inner {
        position: static;
        height: auto;
    }

    .porch-hero .hero-photo {
        position: relative;
        aspect-ratio: 4 / 3;
        object-position: 52% 50%;
    }

    .hero-caption {
        top: 12px;
        bottom: auto;
        right: 12px;
    }

    .porch-hero .hero-panel {
        position: relative;
        left: auto;
        top: auto;
        transform: none;
        width: auto;
        margin: -40px var(--gutter) 0;
        box-shadow: inset 0 0 0 9px var(--trim-white), inset 0 0 0 10px var(--rule);
    }

    .plaque-wall {
        position: static;
        transform: none;
        width: auto;
        margin-top: 28px;
        padding: 24px var(--gutter) 28px;
        background: var(--umber-ink) url("/assets/porch-e207e146.webp") 22% 40% / 280% auto no-repeat;
    }

    .plaque-grid {
        max-width: 480px;
    }

    .terms-grid,
    .outcomes-board,
    .why-grid,
    .services-grid,
    .faq-grid,
    .door-panel,
    .split,
    .calc,
    .service-block,
    .door-hero.has-aside .door-hero-inner,
    .hero-grid {
        grid-template-columns: 1fr;
        gap: 28px;
    }

    .grid-3,
    .grid-4,
    .stats,
    .steps,
    .porch-steps {
        grid-template-columns: 1fr 1fr;
    }

    /* Two sticky bars eat a phone screen: the tab row scrolls with the page,
       and sideways when the tabs outrun the width. */
    .section-tabs {
        position: static;
    }

    html:has(.section-tabs) {
        scroll-padding-top: 96px;
    }

    .section-tabs .container {
        overflow-x: auto;
        scrollbar-width: none;
        scroll-padding-inline: 28px;
        -webkit-mask-image: linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent);
        mask-image: linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent);
    }

    .section-tabs .container::-webkit-scrollbar {
        display: none;
    }

    .section-tabs ul {
        width: max-content;
        padding-inline: 28px;
    }

    .roofline {
        width: 240px;
    }

    .tenant-hero .door-hero-aside {
        justify-self: stretch;
        width: auto;
    }

}

@media (max-width: 600px) {
    /* The horizontal wrap is a width play that only pays off once there's
       width to spend; below 600px it packs links close enough that
       adjacent taps land on the wrong one. Falls back to one link per row,
       each a full tap target with its own hairline, same idiom the FAQ and
       ruled lists already use. */
    .footer-category {
        grid-template-columns: 1fr;
        row-gap: 8px;
    }

    .footer-category ul {
        display: block;
    }

    .footer-category li {
        border-top: 1px solid rgba(246, 245, 241, 0.08);
    }

    .footer-category li:first-child {
        border-top: 0;
    }

    .footer-category ul a {
        display: block;
        padding-block: 13px;
    }

    .footer-info {
        grid-template-columns: 1fr;
        row-gap: 20px;
    }

    .footer-brand,
    .footer-contact {
        max-width: none;
    }

    .footer-contact {
        gap: 0;
        padding-left: 0;
        border-left: 0;
    }

    .footer-contact > * {
        border-top: 1px solid rgba(246, 245, 241, 0.08);
        padding-block: 13px;
    }

    .footer-contact > *:first-child {
        border-top: 0;
        padding-top: 0;
    }

    .footer-bottom {
        flex-direction: column;
        align-items: stretch;
    }

    .footer-bottom nav {
        flex-direction: column;
        gap: 0;
    }

    .footer-bottom nav a {
        display: block;
        padding-block: 13px;
        border-top: 1px solid rgba(246, 245, 241, 0.08);
    }

    body {
        font-size: 1rem;
    }

    /* Utility bar: one row, every link visible, no side-scroll. Dual
       labels (see .u-wide/.u-narrow) swap to short text so it all fits.
       Links keep a tall tap target. */
    .utility-bar .container {
        padding-block: 0;
        gap: 0;
        flex-wrap: nowrap;
        justify-content: flex-start;
    }

    .utility-bar nav {
        flex-wrap: nowrap;
        gap: 4px;
        width: 100%;
    }

    .utility-bar a {
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        padding: 13px 10px;
        white-space: nowrap;
    }

    .utility-bar .u-wide {
        display: none;
    }

    .utility-bar .u-narrow {
        display: inline;
    }

    .porch-hero .hero-panel {
        margin-inline: 12px;
        padding: 26px 22px;
    }

    h1 {
        font-size: 2.125rem;
    }

    h2 {
        font-size: 1.75rem;
    }

    .grid-2,
    .grid-3,
    .grid-4,
    .stats,
    .steps,
    .form-row,
    .service-block .checklist,
    .terms-list,
    .service-list,
    .porch-steps {
        grid-template-columns: 1fr;
    }

    /* ...except the address, which stays one line with its ZIP. */
    .form-row.is-address {
        grid-template-columns: minmax(0, 1fr) 5.5rem;
        gap: 12px;
    }

    /* Terms and steps: plaque in a fixed-width left column, text beside
       it, instead of a full-width plaque stacked above the text. */
    .board {
        padding-inline: 22px;
    }

    .terms-list li {
        display: grid;
        grid-template-columns: 6.25rem 1fr;
        align-items: start;
        gap: 0 14px;
    }

    /* Tall enough for a figure with its unit underneath, so single-line
       figures ("24/7", "$0") get the same plaque as "60–90 days". */
    .terms-list .plaque {
        width: 100%;
        min-height: 4.25rem;
        padding: 10px 8px 11px;
    }

    /* A unit ("days", "repair") drops under its figure so the plaque
       column stays narrow. */
    .terms-list .figure {
        display: flex;
        flex-direction: column;
        align-items: center;
        font-size: var(--type-numeral);
        line-height: 1.1;
        text-align: center;
    }

    .terms-list p {
        margin-top: 0;
    }


    .fee-terms li {
        align-items: start;
        padding-block: 16px;
    }

    /* "repair markup" is wider than the plaque column; let the unit wrap. */
    .fee-terms .figure small {
        white-space: normal;
        line-height: 1.2;
    }

    .owner-types .card {
        grid-template-columns: minmax(0, 1fr);
    }

    .steps li {
        display: grid;
        grid-template-columns: 3.5rem minmax(0, 1fr);
        grid-template-rows: auto 1fr;
        column-gap: 16px;
    }

    .steps li::before {
        grid-row: span 2;
        align-self: start;
        margin-bottom: 0;
    }

    .steps li > * {
        grid-column: 2;
    }

    .porch-steps li {
        display: grid;
        grid-template-columns: 3.5rem minmax(0, 1fr);
        grid-template-areas: "plaque h3" "plaque p";
        align-items: start;
        gap: 0 16px;
    }

    .porch-steps li .plaque {
        grid-area: plaque;
    }

    .porch-steps li h3 {
        grid-area: h3;
    }

    .porch-steps li p {
        grid-area: p;
    }

    .porch-steps .plaque {
        margin-bottom: 0;
    }

    /* Footer: brand block full width, link groups in a 2-column grid
       (inherits the 2-column rule from the 1100px breakpoint), links
       given a taller tap target. */
    .footer-grid ul a,
    .footer-contact > *,
    .footer-bottom nav a {
        display: inline-block;
        padding-block: 9px;
    }

    .door-panel {
        padding: 36px 26px;
    }

    /* The roofline would sit under the buttons on a phone. */
    .roofline {
        display: none;
    }

}

/* A media query adds no specificity, so a bare `.btn-lit` (0,1,0) here never beat
   the `.door-hero .btn-lit` (0,2,0) that sets the lamp animation, the porch lamp
   kept firing for every visitor who asked for less motion. `:where()` contributes
   zero specificity, so `:where(...) .btn-lit` still scores (0,1,0) while matching
   the same places; `!important` on the reset would work too, but this keeps the
   cascade honest and reads as the deliberate override it is. */
@media (prefers-reduced-motion: reduce) {
    .btn-lit,
    :where(.cta-band, .front-door, .home-cta, .door-panel, .door-hero, .section-dark) .btn-lit,
    .roll.is-rolling {
        animation: none;
    }

    /* Every transition on the site, rather than a list that drifts out of date:
       the section tabs and the map paths were each missed by the old enumeration. */
    *,
    *::before,
    *::after {
        transition-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
}

/* ---------------------------------------------------------------------------
   Touch target floor

   WCAG 2.5.5 (AAA) wants 44px. The footer links sat at 39.4px and the area
   card-links at 24px, close enough to look fine and miss often, one-handed.
   Prose links are deliberately excluded: an inline link inside a sentence is
   exempt under 2.5.8, and padding one out would wreck the line box.
   --------------------------------------------------------------------------- */
@media (max-width: 960px) {
    .site-footer nav a,
    .footer-bottom nav a,
    .footer-contact > a,
    .hiring-contact > a,
    .card-link,
    .section-tabs li > a {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
    }

    .nav-toggle {
        min-height: 44px;
    }
}

/* ---------------------------------------------------------------------------
   Print

   The utility tables are the most printed thing on this site, a tenant
   setting up power and water at a new address wants them on paper or in a PDF.
   Printed as-designed they arrive behind a full-bleed slate hero and a dark
   footer, so this strips the furniture and keeps the table.
   --------------------------------------------------------------------------- */
@media print {
    *,
    *::before,
    *::after {
        background: transparent !important;
        color: #000 !important;
        box-shadow: none !important;
        text-shadow: none !important;
    }

    .site-header,
    .utility-bar,
    .section-tabs,
    .site-footer,
    .cta-band,
    .area-map,
    .skip-link,
    .nav-toggle,
    .flash {
        display: none !important;
    }

    .section {
        padding: 12pt 0 !important;
    }

    /* A printed link is useless unless it says where it goes. Tel and mailto
       already read as their own text, so only http(s) gets the treatment. */
    a[href^="http"]::after {
        content: " (" attr(href) ")";
        font-size: 9pt;
        word-break: break-all;
    }

    table {
        border-collapse: collapse;
        page-break-inside: auto;
    }

    tr,
    .faq details {
        page-break-inside: avoid;
    }

    th,
    td {
        border: 1px solid #999 !important;
        padding: 4pt 6pt !important;
    }

    /* The print reset strips every background, so our column loses its juniper
       wash on paper. It keeps the emphasis in ink instead: a heavier rule down
       both sides and bold figures, so an owner reading the printed comparison
       still sees which column is ours. */
    .fee-table thead th:nth-child(2),
    .fee-table tbody td:nth-child(2) {
        border-left: 1.5pt solid #000 !important;
        border-right: 1.5pt solid #000 !important;
        font-weight: 700;
    }

    /* Collapsed answers print as nothing at all otherwise. */
    .faq details > div {
        display: block !important;
    }

    /* Masks and background-images do not print (the reset zeros backgrounds,
       and Chrome skips CSS masks). Real borders always ink. */
    .checklist li::before {
        -webkit-mask: none !important;
        mask: none !important;
        background: #000 !important;
        width: 7.5pt !important;
        height: 6.5pt !important;
        border: 0 !important;
        clip-path: polygon(50% 0, 100% 37%, 79% 37%, 79% 100%, 21% 100%, 21% 37%, 0 37%);
    }

    .checklist-open li::before {
        background: none !important;
        -webkit-mask: none !important;
        mask: none !important;
        border: 1.35pt solid #000 !important;
        border-left-width: 1.35pt !important;
        border-right-width: 1.35pt !important;
        border-bottom-width: 1.35pt !important;
        border-radius: 2pt;
        width: 11pt !important;
        height: 11pt !important;
    }
}

/* Owners hero: the house is the page's first image, so it rises larger and
   brighter than on the city pages, and a line under the buttons says what the
   click costs. */
.owner-hero .roofline {
    width: clamp(300px, 44vw, 600px);
    color: rgba(217, 181, 116, 0.45);
}

.hero-reassurance {
    margin-top: 14px;
    max-width: 44ch;
    font-size: var(--type-ui);
    color: var(--on-door);
    text-wrap: pretty;
}

/* Owners objections: the headings are the owner's own questions, so a scan
   finds the one that worries them. */
.points p a {
    display: inline;
    margin-top: 0;
    font-size: inherit;
}

.objections h3 {
    font-size: var(--type-subhead);
    text-wrap: balance;
}

/* Tenant landing: the hero plaque carries the emergency rules, 911 first. */
.wall-note .wall-note-911 {
    margin-bottom: 10px;
    color: var(--trim-white);
    font-size: var(--type-subhead);
    font-weight: 700;
    line-height: 1.35;
}

.wall-note a[href^="tel:"] {
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
    white-space: nowrap;
}

/* Four everyday tasks as one ruled two-up list, then a single line for the FAQ. */
.tenant-tasks {
    margin-top: 28px;
    gap: 0 clamp(24px, 3vw, 40px);
}

.tenant-tasks .card p {
    max-width: 48ch;
}

.tenant-tasks .card h3 {
    font-size: var(--type-title);
}

.tenant-more {
    margin-top: 24px;
    padding-top: 18px;
    border-top: 1px solid var(--rule);
    color: var(--umber-soft);
}

/* The mock leads and the checklist reads as its caption. */
.tenant-pitch {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
}

.tenant-pitch .portal-shot.is-cropped img {
    aspect-ratio: 16 / 7;
}

/* One rhythm: the pitch follows the tasks without a second full section pad,
   and the CTA band sits closer to the content it closes. */
.section-ruled.tenant-pitch-section {
    padding-block: clamp(40px, 5vw, 64px);
}

.section:has(> .container > .cta-band) {
    padding-block: clamp(40px, 5vw, 72px);
}

@media (max-width: 720px) {
    .tenant-pitch {
        grid-template-columns: minmax(0, 1fr);
    }

    .tenant-pitch .portal-shot.is-cropped {
        overflow: hidden;
    }

    .tenant-pitch .portal-shot.is-cropped img {
        width: 190%;
        max-width: none;
        aspect-ratio: 16 / 5.4;
    }

    .section-tabs a {
        min-width: 44px;
        padding-inline: 4px;
        text-align: center;
    }
}

/* Apply hero plaque: the short list of what to have ready. */
.wall-note-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.wall-note-list li {
    padding-block: 6px;
    border-top: 1px solid rgba(255, 255, 255, 0.14);
    color: var(--on-door);
    font-size: 1rem;
    line-height: 1.45;
}

.wall-note-list li:first-child {
    border-top: 0;
}

/* Maintenance "Try this first": a ruled problem / fix list instead of cards. */
.fix-list {
    margin: 0;
    max-width: 62rem;
}

.fix-list > div {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    gap: 8px 32px;
    padding-block: 16px;
    border-top: 1px solid var(--rule);
}

.fix-list > div:last-child {
    border-bottom: 1px solid var(--rule);
}

.fix-list dt {
    font-weight: 700;
}

.fix-list dd {
    margin: 0;
}

@media (max-width: 720px) {
    .fix-list > div {
        grid-template-columns: 1fr;
    }
}

#urgency-title {
    margin-bottom: 24px;
}

/* Move-in timeline: three columns on the page background, each headed by a
   heavy rule, with its own checklist. Not .steps, whose li rules would leak
   into the nested checklists. */
.timeline {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(28px, 4vw, 56px);
}

.timeline > li {
    padding-top: 20px;
    border-top: 3px solid var(--door-juniper);
}

.timeline h3 {
    margin-bottom: 4px;
    font-size: var(--type-headline);
}

.timeline .checklist {
    margin-top: 16px;
    gap: 14px;
}

@media (max-width: 720px) {
    .timeline {
        grid-template-columns: 1fr;
    }
}

.timeline.timeline-4 {
    grid-template-columns: repeat(4, 1fr);
}

.timeline p {
    margin: 0;
}

@media (max-width: 960px) {
    .timeline.timeline-4 {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 720px) {
    .timeline.timeline-4 {
        grid-template-columns: 1fr;
    }
}

.timeline-4 h3 {
    margin-bottom: 8px;
    font-size: var(--type-subhead);
}

/* Stacked split columns (move-out): keep a gap between the two blocks. */
@media (max-width: 720px) {
    .split.top {
        row-gap: 40px;
    }
}

/* Below 960px the section-tab row stops being sticky, so nothing on ~6,900px
   of page leads back to the form in the hero. This bar does, in the thumb
   zone, and only while the form is off screen (report_recall_controller). It
   sits under the toast stack, which has to be able to speak over it. */
.report-recall {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 45;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 14px;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
    background: var(--door-deep);
    color: var(--on-door);
    border-top: 1px solid color-mix(in srgb, var(--brass) 40%, transparent);
}

.report-recall p {
    margin: 0;
    font-size: var(--type-label);
    line-height: 1.35;
    color: var(--on-door);
    text-wrap: pretty;
}

.report-recall .btn {
    white-space: nowrap;
}

.report-recall[hidden] {
    display: none;
}

@media (min-width: 961px) {
    .report-recall {
        display: none;
    }
}
