/* ==========================================================================
   SUREFIRE STUDIOS — shared interior-page stylesheet (STRIKE design language)

   Interior pages load: strike-blue.css (palette, type scale, shell, buttons,
   header, footer) -> strike-line.css (the flame) -> this file, which adds
   only what content pages need and the concept never had: long-form prose,
   article headers, breadcrumbs, and content grids.

   This replaces styles.css on every page it is applied to.
   ========================================================================== */

/* --------------------------------------------------------------------------
   LEGACY VARIABLE BRIDGE

   Interior pages carry inline <style> blocks written against styles.css's
   variables — --primary-color appears 121 times, --plan-border-color 103,
   --text-color 68. Replacing that sheet left every one of them undefined, so
   borders vanished, cards lost their backgrounds and text fell back to
   inherited colors. The printing page's product cards, for instance, still
   declare `border: 1px solid var(--plan-border-color)` and simply stopped
   drawing it.

   The originals were LIGHT-theme values (#000 ink on #f5f5f5), so these are
   mapped to their dark-theme equivalents rather than copied across.
   -------------------------------------------------------------------------- */
:root {
    /* strongest foreground: was #000 ink, reads as the bright end here.
       Serves both text and the hover borders that use it as an accent. */
    --primary-color: var(--paper);
    --text-color: var(--paper);
    --text-color-secondary: var(--ash);
    --gray-medium: var(--ash);
    --gray-400: var(--ash-dim);
    --gray-500: var(--ash-dim);

    --background-color: var(--night);
    --background-color-rgb: 5, 6, 10;
    --section-bg: var(--deep);
    --card-bg: rgba(255, 255, 255, 0.022);
    --nav-bg: rgba(5, 6, 10, 0.85);
    --input-bg: rgba(255, 255, 255, 0.03);

    /* the printing page's sticky category bar offsets itself by this so it
       parks under the fixed site header instead of behind it */
    --site-header-h: 86px;

    --plan-border-color: var(--line);
    --border-color: var(--line);
    --title-gradient: linear-gradient(180deg, var(--paper), var(--ash));
    --accent: var(--cyan);
}

/* ---------- the nav wordmark is now the logo ---------- */
.mark img {
    display: block;
    width: auto;
    height: clamp(38px, 4.2vw, 56px);
}

/* ---------- page header block ---------- */
.page-head {
    padding-block: calc(var(--gap) * 0.85) calc(var(--gap) * 0.5);
}

.page-head h1 {
    font-family: 'Manrope', sans-serif;
    font-weight: 200;
    font-size: var(--f4);
    line-height: 1.02;
    letter-spacing: -0.03em;
    max-width: 20ch;
}

.page-head .lede {
    margin-top: 1.4rem;
    max-width: 60ch;
    color: var(--ash);
    font-size: var(--f1);
    font-weight: 300;
    line-height: 1.5;
}

.crumbs {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.5rem;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.62rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ash-dim);
}

.crumbs a:hover {
    color: var(--cyan);
}

.crumbs span[aria-hidden] {
    opacity: 0.45;
}

/* ---------- long-form prose ----------
   Scoped to .prose so page-specific components are never caught by it. */
.prose {
    padding-bottom: var(--gap);
    max-width: 72ch;
    color: var(--ash);
    font-size: var(--f0);
    line-height: 1.75;
}

.prose > * + * {
    margin-top: 1.15rem;
}

.prose h2 {
    margin-top: 3rem;
    font-family: 'Manrope', sans-serif;
    font-weight: 200;
    font-size: var(--f3);
    line-height: 1.1;
    letter-spacing: -0.02em;
    color: var(--paper);
}

.prose h3 {
    margin-top: 2.25rem;
    font-size: var(--f1);
    font-weight: 400;
    color: var(--paper);
}

.prose h4 {
    margin-top: 1.75rem;
    font-size: var(--f0);
    font-weight: 500;
    color: var(--paper);
}

.prose a {
    color: var(--cyan);
    text-decoration: underline;
    text-underline-offset: 0.2em;
    text-decoration-thickness: 1px;
    text-decoration-color: rgba(92, 200, 255, 0.4);
    transition: text-decoration-color 0.3s var(--e);
}

.prose a:hover {
    text-decoration-color: var(--cyan);
}

.prose strong {
    color: var(--paper);
    font-weight: 500;
}

.prose ul,
.prose ol {
    padding-left: 1.3rem;
}

.prose li + li {
    margin-top: 0.5rem;
}

.prose li::marker {
    color: var(--cyan);
}

.prose img,
.prose video {
    width: 100%;
    height: auto;
    border-radius: 12px;
    border: 1px solid var(--line);
}

.prose blockquote {
    padding-left: 1.25rem;
    border-left: 2px solid var(--blue);
    color: var(--paper);
    font-weight: 300;
    font-size: var(--f1);
    line-height: 1.45;
}

.prose code {
    padding: 0.15em 0.4em;
    border-radius: 5px;
    background: rgba(45, 125, 255, 0.12);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.86em;
    color: var(--pale);
}

.prose pre {
    padding: 1.1rem 1.25rem;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.02);
    overflow-x: auto;
}

.prose pre code {
    padding: 0;
    background: none;
}

.prose hr {
    border: 0;
    border-top: 1px solid var(--line);
    margin-block: 2.5rem;
}

.prose table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--f-1);
}

.prose th,
.prose td {
    padding: 0.7rem 0.9rem;
    border-bottom: 1px solid var(--line);
    text-align: left;
}

.prose th {
    color: var(--paper);
    font-weight: 500;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.66rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

/* wide tables must scroll inside their own box, never the page */
.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* ---------- card grids (blog index, product lists, related links) ---------- */
.card-grid {
    padding-bottom: var(--gap);
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
    gap: clamp(1rem, 2.2vw, 1.75rem);
}

.card {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: clamp(1.2rem, 2.2vw, 1.7rem);
    border: 1px solid var(--line);
    border-radius: 14px;
    background: linear-gradient(180deg, rgba(45, 125, 255, 0.045), transparent 62%);
    transition: border-color 0.45s var(--e), transform 0.45s var(--e);
}

.card:hover {
    border-color: rgba(92, 200, 255, 0.42);
    transform: translateY(-3px);
}

.card h2,
.card h3 {
    font-size: var(--f1);
    font-weight: 300;
    color: var(--paper);
}

.card p {
    color: var(--ash);
    font-size: var(--f-1);
}

.card .tag {
    color: var(--cyan);
}

/* ---------- CTA strip ---------- */
.cta-strip {
    margin-block: var(--gap);
    padding: clamp(1.75rem, 4vw, 3rem);
    border: 1px solid var(--line);
    border-radius: 16px;
    background: linear-gradient(180deg, rgba(45, 125, 255, 0.1), transparent 70%);
    text-align: center;
}

.cta-strip h2 {
    font-family: 'Manrope', sans-serif;
    font-weight: 200;
    font-size: var(--f3);
    line-height: 1.08;
    letter-spacing: -0.02em;
    margin-bottom: 0.9rem;
}

.cta-strip p {
    max-width: 52ch;
    margin: 0 auto 1.6rem;
    color: var(--ash);
}

.cta-row {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    justify-content: center;
}

/* --------------------------------------------------------------------------
   ORPHANED COMPONENTS
   These used to be styled by styles.css. That sheet was replaced sitewide, so
   anything relying on it lost its rules and rendered raw — the mobile call bar
   appeared on desktop on all 82 pages, and client logos rendered at their
   natural pixel size. Restyled here in the STRIKE language.
   -------------------------------------------------------------------------- */

/* the call/email bar is a MOBILE affordance; styles.css defaulted it to
   display:none and only revealed it under 768px. Same contract here. */
.mobile-sticky-bar {
    display: none;
}

@media (max-width: 768px) {
    .mobile-sticky-bar {
        display: block;
        position: fixed;
        left: 0;
        bottom: 0;
        width: 100%;
        z-index: 60;
        padding: 0.7rem 1rem;
        padding-bottom: max(0.7rem, env(safe-area-inset-bottom));
        background: rgba(5, 6, 10, 0.92);
        backdrop-filter: blur(12px);
        border-top: 1px solid var(--line);
    }

    .mobile-sticky-bar .bar-content {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 1rem;
        max-width: 1200px;
        margin-inline: auto;
    }

    .mobile-sticky-bar a {
        display: inline-flex;
        align-items: center;
        gap: 0.4rem;
        color: var(--paper);
        font-size: 0.82rem;
        font-weight: 500;
    }

    .mobile-sticky-bar .get-quote-btn {
        padding: 0.5rem 1rem;
        border-radius: 999px;
        background: var(--blue);
        color: #04070E;
    }

    /* the bar sits over the page bottom — keep the footer clear of it */
    .site-foot {
        padding-bottom: 5.5rem;
    }
}

/* Client logo marquee. The logos rendered at natural pixel size once
   styles.css went — some are over 1000px wide, which is why they filled
   the screen. The track is a seamless loop: the markup duplicates the set,
   so translating by exactly -50% returns to an identical frame. */
.logo-scroll {
    width: 100%;
    display: flex;
    align-items: center;
    padding: 6px 0;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 12%, #000 88%, transparent 100%);
    mask-image: linear-gradient(to right, transparent 0, #000 12%, #000 88%, transparent 100%);
}

.logo-track {
    display: flex;
    align-items: center;
    gap: clamp(2.5rem, 6vw, 5rem);
    margin: 0;
    padding: 0;
    list-style: none;
    animation: logo-scroll 34s linear infinite;
    will-change: transform;
}

.logo-scroll:hover .logo-track {
    animation-play-state: paused;
}

@keyframes logo-scroll {
    from { transform: translate3d(0, 0, 0); }
    to { transform: translate3d(-50%, 0, 0); }
}

.client-logo {
    flex: 0 0 auto;
    list-style: none;
    display: grid;
    place-items: center;
}

.client-logo img {
    width: auto;
    /* the actual fix: cap by HEIGHT so wildly different logo aspect
       ratios all read at the same optical weight */
    height: clamp(26px, 3.4vw, 40px);
    max-width: 150px;
    object-fit: contain;
    opacity: 0.45;
    filter: grayscale(1);
    transition: opacity 0.5s var(--e), filter 0.5s var(--e);
}

.client-logo img:hover {
    opacity: 0.95;
    filter: grayscale(0);
}

@media (prefers-reduced-motion: reduce) {
    .logo-track {
        animation: none;
        flex-wrap: wrap;
        justify-content: center;
    }
}

/* ---------- shared footer social row ---------- */
.social {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    /* 6 icons at 34px + 5 gaps at 6.4px = 236px, which clears the ~255px
       footer column. At 36px/8px it came to 256px and wrapped the last
       icon onto its own line by a single pixel. */
}

.social a {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    flex: none;
    border: 1px solid var(--line);
    border-radius: 50%;
    color: var(--ash);
    transition: color 0.35s var(--e), border-color 0.35s var(--e), transform 0.35s var(--e);
}

.social a:hover {
    color: var(--core);
    border-color: rgba(92, 200, 255, 0.5);
    transform: translateY(-2px);
}

.social svg {
    width: 17px;
    height: 17px;
}

/* ---------- the shared footer ---------- */
.site-foot {
    position: relative;
    z-index: 2;
    border-top: 1px solid var(--line);
    padding-block: clamp(2.5rem, 6vw, 4rem) clamp(2rem, 4vw, 3rem);
}

.foot-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 170px), 1fr));
    gap: clamp(1.75rem, 4vw, 3rem);
}

.foot-grid h2 {
    margin-bottom: 0.9rem;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.62rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--ash-dim);
    font-weight: 400;
}

.foot-grid a {
    display: block;
    padding: 0.22rem 0;
    color: var(--ash);
    font-size: var(--f-1);
    transition: color 0.3s var(--e);
}

.foot-grid a:hover {
    color: var(--cyan);
}

.foot-base {
    margin-top: clamp(2rem, 5vw, 3rem);
    padding-top: 1.5rem;
    border-top: 1px solid var(--line);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1.5rem;
    flex-wrap: wrap;
    color: var(--ash-dim);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.62rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {

    .card,
    .social a,
    .foot-grid a {
        transition: none;
    }
}

/* --------------------------------------------------------------------------
   SOLID NAV
   The concept used a gradient that faded to transparent, so page content
   showed through the bar as it scrolled under. A fixed bar needs an opaque
   backdrop to stay legible over arbitrary content — and over the flame,
   which is bright.
   -------------------------------------------------------------------------- */
.top {
    background: var(--night);
    border-bottom: 1px solid var(--line);
}

/* the mobile overlay already sits on --night; keep its edge from
   double-drawing against the bar's new border */
@media (max-width: 900px) {
    .menu.is-open {
        border-top: 0;
    }
}

/* --------------------------------------------------------------------------
   BLOG INDEX
   Another styles.css casualty: .blog-grid and every .blog-card-* part lost
   their rules, so the index collapsed into an unstyled run of text with the
   cover images (background-image on an empty div) rendering at zero height.
   -------------------------------------------------------------------------- */
.blog-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
    gap: clamp(1rem, 2.2vw, 1.75rem);
    padding-bottom: var(--gap);
}

.blog-card {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: linear-gradient(180deg, rgba(45, 125, 255, 0.05), transparent 60%);
    transition: border-color 0.45s var(--e), transform 0.45s var(--e);
}

.blog-card:hover {
    border-color: rgba(92, 200, 255, 0.42);
    transform: translateY(-3px);
}

/* the cover is a background-image on an empty div, so it needs its own
   height or it collapses to nothing */
.blog-card-img {
    aspect-ratio: 16 / 9;
    background-color: var(--slate);
    background-size: cover;
    background-position: center;
    border-bottom: 1px solid var(--line);
}

.blog-card-content {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    padding: clamp(1.1rem, 2vw, 1.5rem);
    flex: 1;
}

.blog-card-date {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.62rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--cyan);
}

.blog-card-title {
    font-size: var(--f1);
    font-weight: 300;
    line-height: 1.22;
    color: var(--paper);
}

.blog-card-excerpt {
    color: var(--ash);
    font-size: var(--f-1);
    line-height: 1.6;
}

.blog-card-footer {
    margin-top: auto;
    padding-top: 0.9rem;
}

.blog-read-more {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.64rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--cyan);
}

.blog-card:hover .blog-read-more {
    color: var(--core);
}

/* the theme toggle belonged to the old sheet's light/dark switch, which
   this design does not have */
.theme-switch,
.theme-toggle {
    display: none;
}

@media (prefers-reduced-motion: reduce) {
    .blog-card {
        transition: none;
    }
}

/* blog controls: they inherit --input-bg from the bridge but their own
   inline CSS zeroes the border, leaving them edgeless on a dark page */
.blog-search,
.blog-sort {
    border: 1px solid var(--line) !important;
    border-radius: 10px;
    color: var(--paper);
}

.blog-search:focus,
.blog-sort:focus {
    outline: none;
    border-color: var(--blue) !important;
}

.blog-search::placeholder {
    color: rgba(152, 163, 181, 0.6);
}

/* --------------------------------------------------------------------------
   CLEAR THE FIXED HEADER
   The header is position:fixed, so it is out of flow and interior page
   content started underneath it — measured 21px of the h1 hidden behind the
   bar. The homepage never showed this because its hero carries its own top
   padding. Uses the height strike.js measures, with a fallback for first
   paint before the script runs.
   -------------------------------------------------------------------------- */
body:not(.home) {
    /* the homepage hero supplies its own top spacing, so it opts out via
       .home — that lets index.html share this stylesheet instead of keeping
       a duplicate copy of the footer rules that would drift */
    padding-top: var(--site-header-h, 86px);
}

/* in-page anchors must land below the bar too, not behind it */
html {
    scroll-padding-top: calc(var(--site-header-h, 86px) + 1rem);
}

/* the flame and its glow are fixed to the viewport, so they must not be
   pushed down by the body padding */
#flame,
.spill,
.grain {
    top: auto;
}

/* --------------------------------------------------------------------------
   PAGE TITLES
   73 interior pages carry an inline `font-size: 3.5rem` on their h1, a fixed
   size that cannot respond — on a 375px screen "Web Design & Development"
   broke across three lines. Inline styles can only be overridden with
   !important, hence the flag here. The clamp matches the display scale used
   everywhere else.
   -------------------------------------------------------------------------- */
.blog-post-title {
    font-size: clamp(2rem, 7vw, 3.5rem) !important;
    font-weight: 200;
    line-height: 1.06;
    letter-spacing: -0.03em;
    text-wrap: balance;
}

.blog-post-header {
    /* the inline style on these headers sets padding on all four sides; the
       !important is what beats it, but it must supply the container inset
       rather than zero it, or the title runs to the browser edge */
    padding-inline: var(--pad) !important;
    padding-bottom: clamp(1.5rem, 4vw, 2.5rem) !important;
}

/* These must align to the h1's left edge. margin-inline:auto centerd them
   at their own max-widths while the h1 stayed full-width, which staggered
   the eyebrow, title and subtitle each to a different left edge. */
.blog-post-header > p,
.blog-post-subtitle {
    max-width: 60ch;
    margin-inline: 0;
    color: var(--ash);
}

.blog-post-header .tag {
    margin-bottom: 0.9rem;
}

.blog-post-subtitle {
    margin-top: 1.1rem;
    font-size: var(--f1);
    font-weight: 300;
    line-height: 1.45;
}

/* ==========================================================================
   INTERIOR LAYOUT
   styles.css supplied the container that gave content its max-width and side
   padding. Nothing replaced it, so blog and article content ran edge to edge.
   Rather than patching each page, these are the top-level blocks the content
   pages actually use, given the same treatment as .shell.
   ========================================================================== */
.blog-controls,
.blog-results-count,
.blog-grid,
.blog-post-header,
.blog-post-content,
.faq-section,
.related-articles-section {
    width: 100%;
    max-width: 1400px;
    margin-inline: auto;
    padding-inline: var(--pad);
}

/* long-form article copy wants a reading measure, not the full 1400 */
.blog-post-content {
    /* was 76ch at body size, which rendered ~673px on a 1585px screen with
       456px of dead space each side. Widening alone would push past a
       comfortable line length, so the type grows with it: bigger text and a
       wider column keep the characters-per-line in range while filling more
       of the page. */
    max-width: min(88ch, 920px);
    color: var(--ash);
    font-size: clamp(1.05rem, 0.98rem + 0.35vw, 1.2rem);
    line-height: 1.72;
}

.blog-post-content > * + * {
    margin-top: 1.15rem;
}

.blog-post-content h2 {
    /* --f3 rendered at 57.6px against 17px body — 3.3x, which read as an
       oversized heading crowding a narrow column rather than a hierarchy */
    margin-top: 3rem;
    margin-bottom: 0.25rem;
    font-weight: 200;
    font-size: clamp(1.6rem, 1.3rem + 1.1vw, 2.4rem);
    line-height: 1.15;
    letter-spacing: -0.02em;
    color: var(--paper);
}

.blog-post-content h3 {
    margin-top: 2.25rem;
    margin-bottom: 0.15rem;
    font-size: clamp(1.15rem, 1.05rem + 0.4vw, 1.5rem);
    font-weight: 400;
    color: var(--paper);
}

.blog-post-content a {
    color: var(--cyan);
    text-decoration: underline;
    text-underline-offset: 0.2em;
}

.blog-post-content img {
    width: 100%;
    height: auto;
    border-radius: 12px;
    border: 1px solid var(--line);
}

.blog-post-content ul,
.blog-post-content ol {
    padding-left: 1.3rem;
}

.blog-post-content li + li {
    margin-top: 0.45rem;
}

.blog-post-content li::marker {
    color: var(--cyan);
}

/* the hero image is deliberately full bleed, so it opts out of the container */
.blog-post-hero-img {
    width: 100%;
    max-height: 60vh;
    overflow: hidden;
    margin-bottom: clamp(2rem, 5vw, 3.5rem);
}

.blog-post-hero-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* ---------- blog controls ---------- */
.blog-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
    padding-block: clamp(1.5rem, 4vw, 2.5rem);
}

.blog-search-wrapper {
    flex: 1 1 260px;
}

.blog-search {
    width: 100%;
    padding: 0.75rem 1rem;
}

.blog-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.blog-results-count {
    padding-bottom: 1rem;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.62rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ash-dim);
}

/* Native select popups are drawn by the OS. Without an explicit color the
   options render as dark-on-white regardless of the page, which is why the
   sort menu came out light. Both the control and its options need setting. */
.blog-sort {
    padding: 0.75rem 2.25rem 0.75rem 1rem;
    background-color: var(--slate);
    color: var(--paper);
    color-scheme: dark;
    appearance: none;
    -webkit-appearance: none;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--ash) 50%),
        linear-gradient(135deg, var(--ash) 50%, transparent 50%);
    background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
}

.blog-sort option {
    background-color: #10141D;
    color: var(--paper);
}

/* ---------- related articles ---------- */
.related-articles-section {
    /* the View All button sat flush against the footer */
    padding-block: clamp(2.5rem, 6vw, 4rem) clamp(3.5rem, 8vw, 6rem);
    border-top: 1px solid var(--line);
    margin-top: clamp(3rem, 7vw, 5rem);
}

.related-articles-section > h2 {
    margin-bottom: clamp(1.25rem, 3vw, 2rem);
    font-weight: 200 !important;
    font-size: var(--f2) !important;
    letter-spacing: -0.02em;
    color: var(--paper);
}

/* the cards carry grid-template-columns inline but styles.css held the
   `display: grid`, so without it the columns rule did nothing and every
   card stacked */
.related-articles-grid {
    display: grid;
    gap: clamp(1rem, 2.2vw, 1.5rem);
}

.related-article-card {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: clamp(1.1rem, 2.2vw, 1.6rem);
    border: 1px solid var(--line);
    border-radius: 14px;
    background: linear-gradient(180deg, rgba(45, 125, 255, 0.05), transparent 62%);
    transition: border-color 0.4s var(--e), transform 0.4s var(--e);
}

.related-article-card:hover {
    border-color: rgba(92, 200, 255, 0.42);
    transform: translateY(-3px);
}

.related-article-card h4 {
    font-weight: 300 !important;
    font-size: var(--f1) !important;
    line-height: 1.25;
    color: var(--paper);
}

.related-article-card .read-more {
    margin-top: auto !important;
    color: var(--cyan) !important;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.64rem !important;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

/* ---------- article FAQ blocks ---------- */
.faq-section {
    padding-block: clamp(2rem, 5vw, 3rem);
}

.faq-item {
    padding-block: 1rem;
    border-bottom: 1px solid var(--line);
}

.faq-answer {
    margin-top: 0.5rem;
    color: var(--ash);
    font-size: var(--f-1);
    line-height: 1.65;
}

@media (prefers-reduced-motion: reduce) {
    .related-article-card {
        transition: none;
    }
}

/* --------------------------------------------------------------------------
   CONTAINER SAFETY NET
   Pages whose markup does not use any of the blocks above (legal pages,
   locations, anything hand-built) had no container at all, so their copy ran
   to the browser edge. Rather than chase every class name, main itself
   becomes the container — but only when it does not already contain a block
   that supplies its own inset, which would otherwise double the padding.
   -------------------------------------------------------------------------- */
main:not(:has(.blog-post-content, .blog-post-header, .faq-section, .related-articles-section, .blog-grid, .shell, .print-jump)) {
    width: 100%;
    max-width: 1400px;
    margin-inline: auto;
    padding-inline: var(--pad);
}

/* fallback for engines without :has() — a slightly wider gutter is far
   better than text against the glass */
@supports not selector(:has(*)) {
    main {
        padding-inline: var(--pad);
    }
}

/* long unbroken strings (URLs in legal copy) must not force a scrollbar */
main p,
main li,
.blog-post-content p,
.blog-post-content li {
    overflow-wrap: break-word;
}

/* --------------------------------------------------------------------------
   SOCIAL ICONS — no chrome
   The circles made every difference in glyph proportion obvious: a ring is a
   perfect circle, so any icon that is not optically centerd or not the same
   visual weight reads as wrong. Without them the marks simply sit on the
   page and small differences in silhouette stop mattering.
   -------------------------------------------------------------------------- */
.social {
    display: flex;
    align-items: center;
    gap: 1.15rem;
    flex-wrap: wrap;
}

/* in the footer the row sits directly under the email link, which read as
   cramped — give it its own breathing space there only */
.foot-grid .social {
    margin-top: 1.1rem;
}

.social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: auto;
    height: auto;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    color: var(--ash-dim);
    transition: color 0.3s var(--e);
}

.social a:hover {
    color: var(--paper);
    transform: none;
    border-color: transparent;
}

.social svg {
    width: 19px;
    height: 19px;
    display: block;
}

/* --------------------------------------------------------------------------
   ION-ICONS
   The service pages use ionicons web components (50 checkmark bullets among
   them). They paint with currentColor and had no color of their own once
   styles.css went, so they rendered dark against a dark page. Feature and
   check marks take the accent; directional icons keep the color of the text
   they sit in.
   -------------------------------------------------------------------------- */
ion-icon {
    vertical-align: middle;
    flex: none;
}

/* Each of these carries an inline `color: var(--text-color)`, so a plain
   rule cannot win — inline styles are only beaten by !important. Check
   marks take the accent blue; before the variable bridge existed that
   inline value referred to an undefined variable, which is what made them
   render dark against the dark page. */
ion-icon[name*="checkmark"],
ion-icon[name*="check"] {
    color: var(--cyan) !important;
}

ion-icon[name*="arrow"],
ion-icon[name*="chevron"],
a ion-icon,
.btn ion-icon {
    color: currentColor;
}

/* the check bullets sit in lists that no longer need a marker */
li:has(> ion-icon[name*="checkmark"]) {
    list-style: none;
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
}

/* service page hero graphic: sits between the header and the copy, matching
   the container so it lines up with the title rather than going full bleed */
.svc-hero {
    width: 100%;
    max-width: 1400px;
    margin: 0 auto clamp(2rem, 5vw, 3.5rem);
    padding-inline: var(--pad);
}

.svc-hero img {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--slate);
}

/* location pages: the areas covered read as a grid, not a bullet list */
.area-list {
    list-style: none;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
    gap: 0.5rem 1.5rem;
}

.area-list {
    margin-bottom: clamp(3rem, 7vw, 5rem);
}

.area-list li {
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--line);
    color: var(--ash);
    font-size: var(--f-1);
}

.card-grid .card .go {
    margin-top: auto;
    color: var(--cyan);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.64rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}
