/* 03-components.css: buttons, cards, banners, trust bar, chips, tables,
   gallery + lightbox, review cards, pricing tables, FAQ, stat band. */

/* ---------- buttons ---------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: var(--tap);
    padding: 12px 22px;
    border: 2px solid transparent;
    border-radius: var(--radius);
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: 0.98rem;
    font-weight: 600;
    line-height: 1.15;
    text-align: center;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}

.btn:hover {
    text-decoration: none;
}

.btn:disabled,
.btn[disabled] {
    background: var(--stone-300);
    border-color: var(--stone-300);
    color: var(--stone-600);
    cursor: not-allowed;
}

.btn-primary {
    background: var(--green-700);
    border-color: var(--green-700);
    color: var(--white);
}

.btn-primary:hover {
    background: var(--green-800);
    border-color: var(--green-800);
    color: var(--white);
}

.btn-outline {
    background: var(--white);
    border-color: var(--green-700);
    color: var(--green-800);
}

.btn-outline:hover {
    background: var(--green-100);
    color: var(--green-800);
}

.btn-outline-light {
    background: transparent;
    border-color: var(--white);
    color: var(--white);
}

.btn-outline-light:hover {
    background: var(--white);
    color: var(--ink-900);
}

.btn-danger {
    background: var(--danger);
    border-color: var(--danger);
    color: var(--white);
}

.btn-danger:hover {
    background: #8F1C13;
    border-color: #8F1C13;
    color: var(--white);
}

.btn-lg {
    padding: 15px 28px;
    font-size: 1.08rem;
}

.btn-full {
    width: 100%;
}

.btn-ghost {
    background: transparent;
    border-color: var(--stone-300);
    color: var(--ink-900);
}

.btn-ghost:hover {
    border-color: var(--green-700);
    color: var(--green-800);
}

/* Inline "Learn more" link with an arrow. */
.link-arrow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 600;
    color: var(--green-800);
    min-height: var(--tap);
}

.link-arrow::after {
    content: "\2192";
    transition: transform .15s ease;
}

.link-arrow:hover::after {
    transform: translateX(3px);
}

/* ---------- cards ---------- */

.card {
    background: var(--white);
    border: 1px solid var(--stone-200);
    border-radius: var(--radius);
    padding: 22px;
}

.card-pad-lg {
    padding: 26px;
}

.card-shadow {
    box-shadow: var(--shadow-card);
}

/* Service card: photo top (4:3), leaf rule, title, blurb, arrow link. */
.service-card {
    display: flex;
    flex-direction: column;
    background: var(--white);
    border: 1px solid var(--stone-200);
    border-radius: var(--radius);
    overflow: hidden;
    transition: box-shadow .18s ease, transform .18s ease;
}

.service-card:hover {
    box-shadow: var(--shadow-lift);
    transform: translateY(-2px);
}

.service-card-media {
    position: relative;
    aspect-ratio: 4 / 3;
    background: var(--off-white);
    border-bottom: 3px solid var(--leaf-500);
}

.service-card-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.service-card-body {
    padding: 18px 20px 22px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    flex: 1;
}

.service-card-title {
    font-size: 1.15rem;
    text-transform: none;
    letter-spacing: 0.01em;
}

.service-card-blurb {
    font-size: 0.95rem;
    color: var(--stone-700);
    flex: 1;
}

/* ---------- trust bar ---------- */

.trust-bar {
    background: var(--earth-100);
    border-top: 1px solid var(--stone-200);
    border-bottom: 1px solid var(--stone-200);
}

.trust-bar-inner {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 6px 20px;
    /* Sits on a .container element: never use a padding shorthand here or the
       container's horizontal gutter disappears on phones. */
    padding-top: 12px;
    padding-bottom: 12px;
}

.trust-item {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--stone-700);
}

/* The payment promise is the differentiator no competitor within 40 miles
   advertises, so it carries the accent colour while the rest stays quiet.
   Declared after .trust-item: same specificity, so order decides. */
.trust-item-promise {
    color: var(--green-800);
    font-weight: 600;
}

.trust-item svg {
    color: var(--bark-600);
    flex: 0 0 auto;
}

/* ---------- banners ---------- */

.banner {
    padding: 12px 0;
    font-size: 0.95rem;
}

.banner-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 14px;
}

.banner-oakwilt {
    background: var(--warning-bg);
    color: var(--ink-900);
    border-bottom: 1px solid #E7D9A2;
}

.banner-oakwilt a {
    color: var(--ink-900);
    text-decoration: underline;
}

.banner-storm {
    background: var(--danger);
    color: var(--white);
}

.banner-storm a {
    color: var(--white);
    text-decoration: underline;
}

/* The seasonal promotion bar. Green rather than the storm red or the oak-wilt
   amber, so the three are never mistaken for one another: red is an emergency,
   amber is a caution, green is an offer. White on --green-700 is 6.6:1.

   overflow-wrap on the two copy elements is load bearing, not tidiness. Every
   word in this bar was typed by the owner into a free-text field, so a pasted
   URL or a 40-character run with no space in it is a thing that can actually
   happen, and without this it would push the whole page sideways on a phone. */
.banner-promo {
    background: var(--green-700);
    color: var(--white);
}

.banner-promo a {
    color: var(--white);
    text-decoration: underline;
}

.banner-promo-headline,
.banner-promo-line {
    margin: 0;
    min-width: 0;
    overflow-wrap: anywhere;

    /* Not redundant with the white on .banner-promo, and removing it makes the
       bar unreadable. 01-foundation sets `p { color: var(--stone-700) }`, and a
       colour applied DIRECTLY to an element always beats one inherited from an
       ancestor, whatever the specificity. So the white on the bar never reached
       these paragraphs and the copy rendered at 1.68:1 on the green, which is
       barely visible. The storm and oak-wilt bars dodge it only because they
       use spans, which no global rule colours. Any future light-on-dark block
       built from paragraphs needs this line too. */
    color: var(--white);
}

.banner-promo-headline {
    font-family: var(--font-heading);
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}

.banner-label {
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-size: 0.78rem;
    font-weight: 600;
    padding: 3px 9px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .12);
    flex: 0 0 auto;
}

.banner-storm .banner-label {
    background: rgba(255, 255, 255, .22);
}

/* ---------- chips / filters ---------- */

.chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 22px;
}

.chip {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap);
    padding: 8px 16px;
    border: 1px solid var(--stone-300);
    border-radius: 999px;
    background: var(--white);
    color: var(--stone-700);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
}

.chip:hover {
    border-color: var(--green-700);
    color: var(--green-800);
    text-decoration: none;
}

.chip-active {
    background: var(--green-700);
    border-color: var(--green-700);
    color: var(--white);
}

.chip-active:hover {
    background: var(--green-800);
    color: var(--white);
}

/* ---------- lists ---------- */

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

.checklist li {
    position: relative;
    padding-left: 30px;
    color: var(--stone-700);
}

.checklist li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.52em;
    width: 11px;
    height: 6px;
    border-left: 2.5px solid var(--leaf-500);
    border-bottom: 2.5px solid var(--leaf-500);
    transform: rotate(-45deg);
}

.section-dark .checklist li,
.checklist-light li {
    color: var(--stone-200);
}

.steps {
    list-style: none;
    counter-reset: step;
    padding: 0;
    margin: 0;
    display: grid;
    gap: 18px;
}

.steps li {
    counter-increment: step;
    position: relative;
    padding-left: 54px;
}

.steps li::before {
    content: counter(step);
    position: absolute;
    left: 0;
    top: 0;
    width: 38px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--green-100);
    color: var(--green-800);
    font-family: var(--font-heading);
    font-size: 1.1rem;
    font-weight: 700;
}

.step-title {
    font-size: 1.05rem;
    text-transform: none;
    margin-bottom: 4px;
}

.pill-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.pill-list a {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap);
    padding: 8px 15px;
    border: 1px solid var(--stone-300);
    border-radius: 999px;
    background: var(--white);
    color: var(--stone-700);
    font-size: 0.92rem;
}

.pill-list a:hover {
    border-color: var(--green-700);
    color: var(--green-800);
    text-decoration: none;
}

/* ---------- callout ---------- */

/* The payment promise as a standalone block on a light page (pricing). Louder
   than a callout because on that page it is the argument, not an aside. */
.promise-block {
    background: var(--green-100);
    border: 1px solid var(--green-700);
    border-left: 6px solid var(--green-700);
    border-radius: var(--radius);
    padding: 20px 22px;
    margin-bottom: 24px;
}

.promise-block-kicker {
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.12em;
    font-size: 0.78rem;
    color: var(--bark-600);
    margin-bottom: 8px;
}

.promise-block-line {
    font-family: var(--font-heading);
    font-size: 1.24rem;
    line-height: 1.35;
    color: var(--ink-900);
    margin-bottom: 10px;
}

.promise-block-detail {
    color: var(--stone-700);
    margin-bottom: 10px;
}

/* The same promise as a single line inside a service page's prose. */
.service-promise {
    border-left: 4px solid var(--green-700);
    background: var(--green-100);
    border-radius: var(--radius-sm);
    padding: 12px 16px;
    font-weight: 600;
    color: var(--ink-900);
}

.callout {
    background: var(--earth-100);
    border-left: 4px solid var(--bark-600);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    padding: 18px 20px;
    margin: 24px 0;
}

.callout p + p,
.card p + p {
    margin-top: 12px;
}

.callout-title {
    font-size: 1rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--bark-600);
    margin-bottom: 8px;
}

.callout-green {
    background: var(--green-100);
    border-left-color: var(--green-700);
}

.callout-green .callout-title {
    color: var(--green-800);
}

.callout-danger {
    background: var(--danger-bg);
    border-left-color: var(--danger);
}

.callout-danger .callout-title {
    color: var(--danger);
}

/* ---------- tables ---------- */

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.96rem;
}

.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.data-table th,
.data-table td {
    text-align: left;
    padding: 12px 14px;
    border-bottom: 1px solid var(--stone-200);
    vertical-align: top;
}

.data-table thead th {
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.82rem;
    color: var(--ink-900);
    background: var(--off-white);
    border-bottom: 2px solid var(--bark-600);
    white-space: nowrap;
}

.data-table td.price-cell {
    font-family: var(--font-heading);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--green-800);
    white-space: nowrap;
}

/* Most price cells are a short range and nowrap keeps "$250 to $1,200"
   together. A few are a sentence ("25 to 50 percent above scheduled rates"),
   and on a phone nowrap made the storm table 382px wide inside a 350px column:
   the right-hand column ran off the screen behind a scrollbar with no
   affordance, and the job column collapsed to one word per line. Below the
   two-column breakpoint the price wraps instead. */
@media (max-width: 560px) {
    .data-table td.price-cell {
        white-space: normal;
    }
}

.data-table tbody tr:last-child td {
    border-bottom: none;
}

/* ---------- FAQ ---------- */

.faq-list {
    display: grid;
    gap: 10px;
}

.faq-item {
    border: 1px solid var(--stone-200);
    border-radius: var(--radius-sm);
    background: var(--white);
}

.faq-item summary {
    cursor: pointer;
    list-style: none;
    padding: 15px 46px 15px 18px;
    position: relative;
    min-height: var(--tap);
    font-family: var(--font-heading);
    font-size: 1.03rem;
    color: var(--ink-900);
    letter-spacing: 0.01em;
}

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

.faq-item summary::after {
    content: "+";
    position: absolute;
    right: 16px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 1.4rem;
    line-height: 1;
    color: var(--leaf-500);
}

.faq-item[open] summary::after {
    content: "\2013";
}

.faq-item[open] summary {
    border-bottom: 1px solid var(--stone-200);
}

.faq-answer {
    padding: 14px 18px 18px;
}

/* ---------- gallery + lightbox ---------- */

.gallery-grid {
    display: grid;
    gap: 14px;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

/* A single photo in a four-column grid leaves 75% of the row blank and reads
   as a failed load rather than a gallery. On its own it sits at a card's width,
   centred. */
.gallery-grid:has(> .gallery-item:only-child) {
    grid-template-columns: minmax(0, 420px);
    justify-content: center;
}

.gallery-item {
    margin: 0;
    border: 1px solid var(--stone-200);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--white);
}

.gallery-item .gallery-open,
.gallery-pair .gallery-open {
    display: block;
    cursor: zoom-in;
}

.gallery-item img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    background: var(--off-white);
}

.gallery-item figcaption {
    padding: 10px 12px;
    font-size: 0.88rem;
    color: var(--stone-600);
}

/* Before / after pair: two photos side by side inside one framed card. */
.gallery-pair {
    grid-column: span 2;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px;
    background: var(--stone-200);
    border: 1px solid var(--stone-200);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

@media (max-width: 560px) {
    .gallery-pair {
        grid-column: span 1;
    }
}

.gallery-pair figure {
    margin: 0;
    background: var(--white);
    position: relative;
}

.gallery-phase-tag {
    position: absolute;
    top: 8px;
    left: 8px;
    background: var(--ink-900);
    color: var(--white);
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.7rem;
    padding: 3px 8px;
    border-radius: 3px;
}

/* CSS-only lightbox. No JS, so it works before the circuit connects, and no
   navigation, so the interactive Blazor router cannot swallow the click the
   way it swallowed the old :target fragment link. The checkbox sits just
   before the photo's label and lightbox inside the same figure. */
.lightbox-toggle {
    /* Focusable for the keyboard, invisible and unclickable for the mouse.
       Never display:none: that would take it out of the tab order. */
    position: absolute;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
    pointer-events: none;
}

.lightbox-toggle:focus-visible ~ .gallery-open {
    outline: 3px solid var(--leaf-500);
    outline-offset: -3px;
}

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 120;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(10, 10, 10, .92);
}

.lightbox-toggle:checked ~ .lightbox {
    display: flex;
}

/* The dark surround is itself a close control. */
.lightbox-backdrop {
    position: absolute;
    inset: 0;
    cursor: zoom-out;
}

.lightbox-figure {
    /* Above the backdrop label, which is positioned and would otherwise paint
       over this static content. */
    position: relative;
    z-index: 1;
    margin: 0;
    max-width: min(1100px, 96vw);
    max-height: 92vh;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.lightbox-figure img {
    max-height: 78vh;
    width: auto;
    max-width: 100%;
    margin: 0 auto;
    object-fit: contain;
}

.lightbox-figure figcaption {
    color: var(--stone-200);
    text-align: center;
    font-size: 0.95rem;
}

.lightbox-close {
    position: absolute;
    cursor: pointer;
    top: 14px;
    right: 16px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--tap);
    min-height: var(--tap);
    border-radius: 50%;
    background: var(--white);
    color: var(--ink-900);
    font-size: 1.4rem;
    line-height: 1;
    z-index: 2;
}

.lightbox-close:hover {
    text-decoration: none;
    color: var(--ink-900);
}

/* ---------- review cards ---------- */

.review-card {
    background: var(--white);
    border: 1px solid var(--stone-200);
    border-radius: var(--radius);
    padding: 22px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    height: 100%;
}

.review-stars {
    color: var(--leaf-500);
    letter-spacing: 3px;
    font-size: 1.05rem;
}

.review-body {
    flex: 1;
    color: var(--stone-700);
}

.review-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    font-size: 0.9rem;
    color: var(--stone-600);
}

.review-author {
    font-weight: 700;
    color: var(--ink-900);
}

.source-badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 9px;
    border-radius: 999px;
    background: var(--off-white);
    border: 1px solid var(--stone-200);
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--stone-600);
}

/* ---------- stat band (dark) ---------- */

.stat-band {
    background: var(--ink-900);
    color: var(--white);
    padding: 34px 0;
}

.stat-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 22px;
    text-align: center;
}

@media (min-width: 860px) {
    .stat-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

.stat-value {
    font-family: var(--font-heading);
    font-variant-numeric: tabular-nums;
    font-size: 2rem;
    font-weight: 700;
    color: var(--leaf-500);
    line-height: 1.1;
}

.stat-label {
    font-size: 0.88rem;
    color: var(--stone-200);
    margin-top: 6px;
}

/* ---------- CTA band ---------- */

.cta-band {
    background: var(--ink-900);
    color: var(--white);
    padding: 40px 0;
}

.cta-band-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 22px;
}

.cta-band-title {
    color: var(--white);
    max-width: 22ch;
}

.cta-band-sub {
    color: var(--stone-200);
    margin-top: 8px;
    max-width: 58ch;
}

.cta-band-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.cta-band-danger {
    background: var(--danger);
}

.cta-band-danger .cta-band-sub {
    color: #FFE7E4;
}

.cta-band-danger .btn-primary {
    background: var(--white);
    border-color: var(--white);
    color: var(--danger);
}

.cta-band-danger .btn-primary:hover {
    background: var(--ink-900);
    border-color: var(--ink-900);
    color: var(--white);
}

/* ---------- empty states ---------- */

.empty-state {
    border: 1px dashed var(--stone-300);
    border-radius: var(--radius);
    background: var(--off-white);
    padding: 28px 22px;
    text-align: center;
}

.empty-state h3 {
    text-transform: none;
    margin-bottom: 8px;
}

/* ---------- auth card (staff login) ---------- */

.auth-page {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 56px 20px;
    background: var(--off-white);
    min-height: 70vh;
}

.auth-card {
    width: 100%;
    max-width: 420px;
    background: var(--white);
    border: 1px solid var(--stone-200);
    border-top: 6px solid var(--bark-800);
    border-radius: var(--radius);
    box-shadow: var(--shadow-card);
    padding: 30px;
}

.auth-header {
    text-align: center;
    margin-bottom: 22px;
}

.auth-header img {
    height: 54px;
    width: auto;
    margin: 0 auto 14px;
}

.auth-header p {
    color: var(--stone-600);
    font-size: 0.94rem;
}
