/*
 * components.css — the SEO surface's component styles and typographic rhythm.
 *
 * Pairs with templates/components/seo/. Every class here is styled by exactly
 * one macro, and every macro's classes are styled here. If a page needs a card,
 * callout or table that this file does not describe, the answer is a macro, not
 * a page-local <style> block: 35% of the SEO template surface was duplicated
 * markup precisely because "write another page" was easier than "write another
 * include".
 *
 * COLOUR: chippie-marketing.css :root owns the marketing palette. Nothing here
 * may introduce a raw hex value; the css_literals ratchet caps them per file
 * and this file starts at zero. Tints of a palette colour use colour-mix()
 * against the token rather than a hand-picked hex.
 *
 * The two spacing scales below are the whole reason the surface reads as one
 * system. Do not override them per page.
 */

:root {
    /* Landmark rhythm. Strictly tiered and identical on every page: the
       scanning pattern readers use depends on the gap before a heading being
       reliably bigger than the gap between paragraphs, so a page that tunes
       its own spacing breaks the pattern for every other page too. */
    --seo-gap-h2: 3.5em;
    --seo-gap-h3: 2.25em;
    --seo-gap-p: 1.5em;

    /* Reading measure. Long lines lose the eye on the return sweep; short ones
       force too many sweeps. */
    --seo-measure: 68ch;
}

/* ---------- Anchor navigation ---------- */

/* scroll-padding-top keeps a heading clear of the top bar when a jump link
   lands on it; without it the thing you navigated to sits under the chrome.
   No scroll-behavior here: public_base.html neutralises Bootstrap's smooth
   scroll with an inline `!important` because it slows Turbo navigation, so a
   rule here would be dead CSS that reads like a live setting. */
html {
    scroll-padding-top: 24px;
}

.prose :is(h2, h3),
.seo-section :is(h2, h3) {
    scroll-margin-top: 24px;
}

/* ---------- Breadcrumbs and article meta ---------- */

/* Migrated from static/css/blog/article.css: these are page furniture for the
   whole SEO surface, not blog-specific. chippie-mf6zu.3 removes the originals
   when the blog template moves onto templates/seo/article.html. */
.crumbs {
    font-family: "IBM Plex Mono", monospace;
    font-size: 12px;
    color: var(--text-2);
    list-style: none;
    padding: 0;
    margin: 0 0 14px;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.crumbs li::after {
    content: "/";
    margin-left: 8px;
    color: var(--border);
}

.crumbs li:last-child::after {
    content: "";
}

.crumbs a {
    color: var(--green);
    text-decoration: none;
}

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

.article-date {
    font-family: "IBM Plex Mono", monospace;
    font-size: 13px;
    color: var(--text-2);
    margin: 14px 0 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
}

.article-date i {
    margin-right: 5px;
}

.article-date .updated {
    color: var(--orange-deep);
}

.article-foot {
    margin-top: 48px;
    padding-top: 28px;
    border-top: 1px solid var(--border);
}

/* ---------- Author byline ---------- */

.author-card {
    display: flex;
    gap: 16px;
    align-items: flex-start;
}

.author-card .avatar,
.author-card .avatar-fallback {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    flex-shrink: 0;
}

.author-card .avatar {
    object-fit: cover;
    border: 2px solid var(--border);
}

.author-card .avatar-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--orange);
    color: var(--white);
    font-weight: 700;
    font-size: 22px;
    font-family: "Space Grotesk", sans-serif;
}

.author-card .author-name {
    font-weight: 700;
    font-size: 17px;
    margin: 0;
}

.author-card .author-role {
    font-family: "IBM Plex Mono", monospace;
    font-size: 12px;
    color: var(--text-2);
    margin: 2px 0 8px;
}

.author-card .author-bio {
    font-size: 15px;
    margin: 0;
}

/* ---------- Reading column and typographic rhythm ---------- */

.seo-body,
.seo-section .prose,
.prose {
    font-size: 18px;
    line-height: 1.6;
}

.prose > * {
    max-width: var(--seo-measure);
}

.prose p,
.seo-section p {
    margin: 0 0 var(--seo-gap-p);
}

.prose h2,
.seo-section h2 {
    font-size: 30px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.01em;
    color: var(--green);
    margin: var(--seo-gap-h2) 0 0.6em;
}

.prose h3,
.seo-section h3 {
    font-size: 1.15em;
    font-weight: 700;
    line-height: 1.3;
    color: var(--green);
    margin: var(--seo-gap-h3) 0 0.5em;
}

/* First heading in a section has the section's own padding above it. */
.seo-section > .wrap > :is(h2, h3):first-child,
.seo-section > .wrap-narrow > :is(h2, h3):first-child,
.prose > :is(h2, h3):first-child {
    margin-top: 0;
}

.prose ul,
.prose ol,
.seo-section ul,
.seo-section ol {
    margin: 0 0 var(--seo-gap-p);
    padding-left: 1.4em;
}

.prose li,
.seo-section li {
    margin-bottom: 0.5em;
}

/* Never justified: the uneven word spacing it produces creates vertical rivers
   that the eye follows down instead of along. */
.prose,
.seo-section {
    text-align: left;
}

.seo-body {
    background: var(--white);
    border-top: 1px solid var(--border);
    padding: 56px 0 0;
}

.seo-section {
    padding: 0 0 8px;
}

@media (max-width: 640px) {
    .seo-body,
    .prose {
        font-size: 17px;
    }

    .prose h2,
    .seo-section h2 {
        font-size: 25px;
    }
}

/* ---------- Anchor affordance ---------- */

/* Visible at low opacity rather than on hover alone. A hover-only control does
   not exist on a touchscreen, and this surface is read on phones as much as on
   laptops. */
.anchor-link {
    margin-left: 0.4em;
    font-weight: 400;
    text-decoration: none;
    color: var(--text-2);
    opacity: 0.35;
}

.anchor-link:hover,
.anchor-link:focus-visible {
    opacity: 1;
    color: var(--orange);
}

@media (prefers-reduced-motion: no-preference) {
    .anchor-link {
        transition: opacity 0.15s ease, color 0.15s ease;
    }
}

/* ---------- Table of contents ---------- */

/* Narrow first: a real disclosure in the content flow, open by default so the
   reader sees the shape of the page without having to act. The summary is
   worded, not an icon -- an icon alone says nothing about what tapping does,
   which is why mobile contents controls go unused. */
.toc-rail {
    margin: 0 0 var(--seo-gap-h3);
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--sandstone);
}

.toc-rail__summary {
    font-family: "IBM Plex Mono", monospace;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.04em;
    padding: 14px 20px;
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.toc-rail__summary::-webkit-details-marker {
    display: none;
}

.toc-rail__summary::after {
    content: "+";
    color: var(--orange);
    font-size: 20px;
    line-height: 1;
}

.toc-rail[open] > .toc-rail__summary::after {
    content: "\2212";
}

.toc-rail__label {
    display: none;
}

/* The number is drawn by a counter, not by the native list marker.

   A native <ol> marker sits outside the list's padding box, so on the wide
   layout it lands in the rail's border and is clipped by the overflow scroll
   container. At one digit nobody notices; the first contents list with ten
   entries renders "10." as "0." and every entry after it is wrong by a
   character. A counter in ::before is inside the box and can reserve its own
   width, so the number is as wide as it needs to be. */
.toc-rail__list {
    margin: 0;
    padding: 0 20px 18px 20px;
    list-style: none;
    counter-reset: toc-entry;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.toc-rail__list li {
    font-size: 15px;
    margin: 0;
    display: flex;
    gap: 8px;
    counter-increment: toc-entry;
}

/* tabular-nums so the entries line up once the count passes nine and the
   numbers stop being the same width. */
.toc-rail__list li::before {
    content: counter(toc-entry) ".";
    flex: 0 0 auto;
    min-width: 1.5em;
    color: var(--text-2);
    font-variant-numeric: tabular-nums;
}

/* Obvious link styling. An under-styled contents entry does not read as
   something you can click, and then nobody clicks it. */
.toc-rail__list a {
    color: var(--green);
    text-decoration: none;
}

.toc-rail__list a:hover {
    color: var(--orange);
    text-decoration: underline;
}

.toc-rail__list a.is-active {
    color: var(--orange-deep);
    font-weight: 600;
}

.toc-l3 {
    padding-left: 14px;
}

/* Wide: a sticky rail in its own grid column. Sticky is right for a side rail
   and wrong for one in the body, where it would compete with the page's own
   chrome for the same edge of the screen. */
@media (min-width: 1100px) {
    .toc-rail {
        position: sticky;
        top: 24px;
        background: transparent;
        border: none;
        border-left: 2px solid var(--border);
        border-radius: 0;
        padding: 0;
        max-height: calc(100vh - 48px);
        overflow-y: auto;
    }

    .toc-rail__summary {
        display: none;
    }

    /* Forced visible: a reader who collapsed it on a phone and then widened
       the window would otherwise get an empty column with no way to reopen it,
       because the summary above is gone. */
    .toc-rail > .toc-rail__inner {
        display: block;
    }

    .toc-rail__label {
        display: block;
        font-family: "IBM Plex Mono", monospace;
        font-size: 11px;
        font-weight: 600;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        color: var(--text-2);
        margin: 0 0 10px;
        padding-left: 18px;
    }

    .toc-rail__list {
        padding: 0 0 0 14px;
        gap: 10px;
    }

    .toc-rail__list li {
        font-size: 13.5px;
        line-height: 1.5;
    }

    .toc-rail__list a.is-active {
        box-shadow: -18px 0 0 -16px var(--orange);
    }
}

/* ---------- The tool slot ---------- */

/* The reference page type puts a tool above the rail at full width. This is
   the band it sits in, shared so that the calculator, the BAS calendar and the
   resource hub open at the same rhythm rather than each inventing a margin.

   It carries its own bottom border because the rail's body band starts with
   one, and without a rule here the tool and the first section run together
   into one undifferentiated column. */
/* No top padding: the hero band above already ends with its own generous
   space, and adding more here leaves the tool floating a long way from the
   headline that introduced it. */
.seo-tool {
    padding: 0 0 44px;
}

.seo-tool > h2 {
    margin-top: 0;
}

/* One line saying what the tool is for, between its heading and the tool
   itself. Sized down from body copy because it is an instruction, not part of
   the argument the page is making. */
.seo-tool__lede {
    max-width: var(--seo-measure);
    margin: 0 0 24px;
    font-size: 16px;
    color: var(--text-2);
}

/* ---------- Two-column body with a rail ---------- */

.seo-body--railed > .wrap-narrow,
.seo-body--railed > .seo-rail-grid {
    max-width: 1140px;
    margin: 0 auto;
    padding: 0 24px;
}

@media (min-width: 1100px) {
    .seo-rail-grid {
        display: grid;
        grid-template-columns: 220px minmax(0, 1fr);
        gap: 48px;
    }

    /* Deliberately NOT align-items: start. A sticky element can only travel
       inside its containing block, so an aside collapsed to its own content
       height gives the rail nowhere to stick and it scrolls away with the
       first section. The column has to span the full row for sticky to mean
       anything. */
    .seo-rail-aside {
        align-self: stretch;
    }

    /* The reading measure belongs to the prose, not to the column. Capping the
       column itself also caps everything in it that is not prose: a six-column
       market table or a grid of form controls then has to scroll sideways
       inside 68 characters while the page has room to spare. So the cap sits
       on the narrow wrapper, and section(narrow=False) is how a block says it
       is wider than the measure.

       margin-left: 0 keeps the prose flush with the rail's edge. Without it a
       measure-width block centres itself in a wider column and every section
       steps right, away from the contents list beside it. */
    .seo-rail-grid > .seo-rail-main > :not(.seo-section),
    .seo-rail-grid > .seo-rail-main .wrap-narrow {
        max-width: var(--seo-measure);
        margin-left: 0;
    }

    .seo-rail-grid > .seo-rail-main .wrap {
        max-width: none;
    }
}

/* ---------- Takeaways ---------- */

/* Tinted panel with a heavy left rule. Each landmark type gets a distinct
   treatment so the eye can tell them apart at a glance without reading them;
   variety is the point, not count. */
.takeaways {
    background: color-mix(in srgb, var(--orange) 7%, transparent);
    border-left: 4px solid var(--orange);
    border-radius: 0 12px 12px 0;
    padding: 22px 26px;
    margin: 0 0 var(--seo-gap-h3);
}

.takeaways__label {
    font-family: "IBM Plex Mono", monospace;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--orange-deep);
    margin: 0 0 10px;
}

.takeaways__list {
    margin: 0;
    padding-left: 1.2em;
}

.takeaways__list li {
    margin-bottom: 0.5em;
    font-size: 16.5px;
    line-height: 1.55;
}

.takeaways__list li:last-child {
    margin-bottom: 0;
}

/* ---------- Callouts ---------- */

/* Class names are shared with the blog editor's Callout node
   (application/utils/html_sanitizer.py). Renaming them here unstyles every
   callout an author has ever written. */
.callout {
    border-radius: 12px;
    border-left: 4px solid var(--border);
    background: var(--sandstone);
    padding: 18px 22px;
    margin: var(--seo-gap-p) 0;
}

.callout > :last-child {
    margin-bottom: 0;
}

.callout__title {
    font-weight: 700;
    margin: 0 0 6px;
}

/* The kind-to-colour mapping is inherited from static/css/blog/article.css so
   callouts in already-published posts keep meaning what their author meant.
   Only `info` moves: it was a raw blue that exists nowhere in the marketing
   palette, and an off-palette literal is exactly what the css_literals ratchet
   is there to stop. */
.callout-info {
    border-left-color: var(--green-deep);
    background: color-mix(in srgb, var(--green-deep) 6%, transparent);
}

.callout-tip {
    border-left-color: var(--green-paid);
    background: color-mix(in srgb, var(--green-paid) 8%, transparent);
}

.callout-warning {
    border-left-color: var(--yellow);
    background: color-mix(in srgb, var(--yellow) 12%, transparent);
}

/* ---------- Steps ---------- */

.steps {
    list-style: none;
    counter-reset: none;
    margin: var(--seo-gap-p) 0;
    padding: 0;
}

.steps__item {
    display: flex;
    gap: 16px;
    align-items: flex-start;
    padding: 16px 0;
    border-top: 1px solid var(--border);
}

.steps__item:first-child {
    border-top: none;
    padding-top: 0;
}

.steps__num {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border-radius: 999px;
    background: var(--green);
    color: var(--white);
    font-family: "IBM Plex Mono", monospace;
    font-size: 14px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
}

.steps__body > :last-child {
    margin-bottom: 0;
}

.steps__title {
    font-weight: 700;
    margin: 0 0 4px;
}

/* ---------- Tables ---------- */

.table-scroll {
    overflow-x: auto;
    margin: var(--seo-gap-p) 0;
    max-width: 100%;
    -webkit-overflow-scrolling: touch;
}

.table-scroll:focus-visible {
    outline: 2px solid var(--orange);
    outline-offset: 2px;
}

.compare-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 15.5px;
    min-width: 520px;
}

.compare-table caption {
    caption-side: top;
    text-align: left;
    font-size: 13px;
    color: var(--text-2);
    padding-bottom: 10px;
}

.compare-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--sandstone);
    text-align: left;
    font-size: 13px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-2);
    padding: 12px 14px;
    border-bottom: 2px solid var(--border);
}

.compare-table tbody th {
    text-align: left;
    font-weight: 600;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}

.compare-table td {
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}

/* Restack into labelled blocks below 640px. Never hides a column: a column
   hidden on a phone is a fact the reader came for and cannot reach. */
@media (max-width: 640px) {
    .compare-table {
        min-width: 0;
    }

    .compare-table thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .compare-table tbody th {
        display: block;
        border-bottom: none;
        padding-bottom: 4px;
        font-size: 16px;
    }

    .compare-table td {
        display: flex;
        gap: 12px;
        justify-content: space-between;
        padding: 8px 14px;
    }

    .compare-table td::before {
        content: attr(data-label);
        font-size: 13px;
        color: var(--text-2);
        flex: 0 0 40%;
    }

    .compare-table tbody tr {
        display: block;
        padding: 10px 0;
        border-bottom: 1px solid var(--border);
    }
}

/* ---------- Worked example ---------- */

.worked-example {
    margin: var(--seo-gap-p) 0;
    padding: 20px 24px;
    background: var(--sandstone);
    border: 1px solid var(--border);
    border-radius: 12px;
}

.worked-example__title {
    font-weight: 700;
    margin-bottom: 12px;
}

.worked-example__table {
    width: 100%;
    border-collapse: collapse;
    font-size: 15.5px;
}

.worked-example__table th {
    text-align: left;
    font-weight: 400;
    color: var(--text-2);
    padding: 7px 0;
}

.worked-example__table td {
    text-align: right;
    padding: 7px 0;
    white-space: nowrap;
}

.worked-example__total th,
.worked-example__total td {
    border-top: 2px solid var(--border);
    font-weight: 700;
    color: var(--black);
    padding-top: 12px;
}

.worked-example__note {
    font-size: 13px;
    color: var(--text-2);
    margin: 12px 0 0;
}

/* ---------- Figures and quotes ---------- */

.seo-figure {
    margin: var(--seo-gap-h3) 0;
}

.seo-figure img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 12px;
    border: 1px solid var(--border);
}

.seo-figure figcaption,
.seo-quote__by {
    font-size: 13.5px;
    color: var(--text-2);
    margin-top: 10px;
}

.seo-quote {
    margin: var(--seo-gap-h3) 0;
    padding-left: 22px;
    border-left: 3px solid var(--green-paid);
}

.seo-quote blockquote {
    margin: 0;
    font-size: 19px;
    line-height: 1.5;
    color: var(--black);
}

.seo-quote__by {
    display: flex;
    align-items: center;
    gap: 10px;
}

.seo-quote__avatar {
    border-radius: 999px;
}

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

.seo-faq {
    padding: 56px 0;
    background: var(--sandstone);
}

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

.faq-item > summary {
    cursor: pointer;
    list-style: none;
    padding: 18px 0;
    font-weight: 600;
    font-size: 17px;
    display: flex;
    justify-content: space-between;
    gap: 16px;
}

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

.faq-item > summary::after {
    content: "+";
    color: var(--orange);
    font-weight: 400;
    font-size: 22px;
    line-height: 1;
}

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

.faq-item__answer {
    padding: 0 0 18px;
    color: var(--text-2);
    max-width: var(--seo-measure);
}

.faq-item__answer > :last-child {
    margin-bottom: 0;
}

/* ---------- Related ---------- */

.seo-related {
    padding: 48px 0 8px;
}

.seo-related__title {
    font-size: 20px;
    color: var(--green);
    margin: 0 0 14px;
}

.seo-related__list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.seo-related__list li {
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
}

.seo-related__list li:last-child {
    border-bottom: none;
}

.seo-related__list a {
    color: var(--green);
    text-decoration: none;
    font-weight: 600;
}

.seo-related__list a:hover {
    color: var(--orange);
}

.seo-related__summary {
    display: block;
    font-size: 14.5px;
    color: var(--text-2);
    margin-top: 3px;
}

/* ---------- Hero note ---------- */

.hero-note {
    font-size: 13px;
    margin: 12px 0 0;
}

/* ---------- Coverage areas ---------- */

/* A location page's suburb lists. Auto-fit rather than a fixed column count so
   the grid reflows on its own between a phone and a laptop: the number of areas
   is page data, not a layout decision, and a page with three regions should not
   leave a hole where the fourth would be. */
.seo-areas {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 20px 28px;
    margin: 8px 0 0;
}

.seo-areas h3 {
    font-size: 16px;
    margin: 0 0 8px;
}

.seo-areas ul {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 14.5px;
    color: var(--text-2);
}

.seo-areas li {
    padding: 2px 0;
}

/* ---------- Source attribution ---------- */

/* The link under a jurisdiction section. It is the load-bearing part of the
   section, not a footnote: the claim above it is only as good as the authority
   it points at, so it stays at body size rather than shrinking into fine print. */
.seo-source {
    margin: 14px 0 0;
    font-size: 15px;
}

.seo-source a {
    color: var(--green);
    font-weight: 600;
}
