/* city-pages.css
 *
 * Styling for /tankstations and /tankstations/<plaats>.
 * Built entirely on the tokens already defined in colors.css — no new palette,
 * no new type scale, no new spacing system.
 */

/* The site-wide .container is display:flex. Its children default to
 * min-width:auto, which lets the wide station table push the whole page wider
 * than the viewport on mobile. Stack the sections and let them shrink. */
.city-container {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    /* The shared .container is a centred, wrapping flex row with a 1em gap.
     * As a column that layout adds stray space between sections, so reset the
     * inherited row behaviour and let the section margins do the spacing. */
    flex-wrap: nowrap;
    justify-content: flex-start;
    gap: 0;
    margin-top: 6.5em;
    padding-bottom: 3rem;
    max-width: 1100px;
}

.city-container > * {
    min-width: 0;
    max-width: 100%;
}

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

.city-hero {
    margin-bottom: 2rem;
}

.city-hero h1 {
    margin-bottom: 0.75rem;
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    line-height: 1.15;
}

.city-lead {
    font-size: 1.05rem;
    line-height: 1.65;
    max-width: 68ch;
    margin-bottom: 0.75rem;
}

.city-context {
    color: var(--color-muted);
    line-height: 1.65;
    max-width: 68ch;
}


/* --------------------------------------------------------------------------
 * Fuel selector — mirrors the control on the map page
 * -------------------------------------------------------------------------- */

.city-fuel-selector {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin: 0;
}

.city-fuel-label {
    font-size: 0.9rem;
    font-weight: 500;
    color: #374151;
}

.city-fuel-options {
    display: flex;
    gap: 0.5em;
    flex-wrap: nowrap;
    width: 100%;
}

.city-fuel-option {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5em;
    flex: 1 1 0;
    min-width: 0;
    height: var(--city-control-h, auto);
    padding: 0.55em 0.6em;
    font-size: 0.9rem;
    border: 1px solid #e5e7eb;
    border-radius: var(--border-radius-3);
    background: transparent;
    color: inherit;
    cursor: pointer;
    font: inherit;
    transition: border-color 0.2s ease, background-color 0.2s ease;
}

.city-fuel-option:hover {
    border-color: var(--color-primary);
}

.city-fuel-option.is-active {
    border-color: var(--color-primary);
    background-color: rgba(var(--rgb-primary), 0.08);
    font-weight: 600;
}

/* The active fuel is signalled by border, weight and aria-checked, not by the
 * swatch colour alone. */
.city-fuel-swatch {
    display: block;
    /* Without this the flex row squeezes the swatch of the longest label
     * ("Diesel") down to a dot while the short ones keep their dash. */
    flex-shrink: 0;
    width: 1.25em;
    height: 3px;
    border-radius: 2px;
}

/* --------------------------------------------------------------------------
 * Sections
 * -------------------------------------------------------------------------- */

.city-section {
    margin-bottom: 2.75rem;
}

.city-section h2 {
    font-size: clamp(1.25rem, 2.5vw, 1.6rem);
    margin-bottom: 0.75rem;
}

.city-section p {
    line-height: 1.7;
    max-width: 72ch;
    margin-bottom: 0.9rem;
}

.city-section-intro {
    color: var(--color-muted);
}

/* Inline links in body copy follow the brand colour, not the Bootstrap blue. */
.city-section p a,
.city-faq-item a {
    color: var(--color-primary);
}

/* --------------------------------------------------------------------------
 * Summary — one verdict, two figures
 *
 * No cards here on purpose. The section states the answer, then shows the two
 * totals it compares; type size and a single hairline carry the structure that
 * three bordered boxes used to fake.
 * -------------------------------------------------------------------------- */

/* Beats `.city-section h2` (0,1,1) on specificity — this heading is the
 * section's headline, not a label above it. */
.city-summary .city-verdict {
    margin: 0 0 0.5rem;
    font-size: clamp(1.5rem, 3.4vw, 2.15rem);
    line-height: 1.2;
    /* Not `balance`: evening the lines out breaks this sentence mid-phrase
     * ("Over de grens tank / je € 7,32 goedkoper"). Left to wrap naturally the
     * nbsp keeps the amount whole and the break lands after "je". */
    text-wrap: pretty;
}

.city-summary .city-verdict.is-empty {
    font-size: clamp(1.2rem, 2.4vw, 1.5rem);
    color: var(--color-muted);
}

.city-summary .city-verdict[data-summary-value] {
    --city-marker-delay: 120ms;
}

.city-summary .city-compare-amount.is-marker-highlighted {
    --city-marker-delay: 220ms;
}

.city-summary .city-verdict[data-summary-value] .city-verdict-highlight,
.city-summary .city-compare-amount.is-marker-highlighted:not(.is-empty) {
    display: inline-block;
    border-radius: 0.8em 0.3em;
    background-image: linear-gradient(
        to right,
        rgba(255, 189, 89, 0.1),
        rgba(255, 189, 89, 0.73) 7%,
        rgba(255, 189, 89, 0.15)
    );
    background-position: left center;
    background-repeat: no-repeat;
    background-size: 0% 100%;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
    animation: city-marker-swipe 650ms cubic-bezier(0.16, 1, 0.3, 1) var(--city-marker-delay) both;
    will-change: background-size;
}

.city-summary .city-verdict[data-summary-value] .city-verdict-highlight {
    margin: 0 -0.22em;
    padding: 0.08em 0.34em;
    color: var(--color-text);
}

.city-summary .city-compare-amount.is-marker-highlighted:not(.is-empty) {
    margin: -0.07em -0.26em 0.28rem;
    padding: 0.07em 0.26em 0.08em;
    color: var(--color-text);
}

@keyframes city-marker-swipe {
    from {
        background-size: 0% 100%;
    }

    to {
        background-size: 100% 100%;
    }
}

@media (prefers-reduced-motion: reduce) {
    .city-summary .city-verdict[data-summary-value] .city-verdict-highlight,
    .city-summary .city-compare-amount.is-marker-highlighted:not(.is-empty) {
        animation: none;
        background-size: 100% 100%;
        will-change: auto;
    }
}

/* These are <p> inside .city-section, so every rule that resets the shared
 * paragraph defaults has to out-specify `.city-section p` (0,1,1). */
.city-summary .city-verdict-note {
    margin: 0;
    font-size: 0.95rem;
    line-height: 1.6;
    color: var(--color-muted);
    max-width: 58ch;
}

.city-summary .city-verdict-note[hidden] {
    display: none;
}

.city-compare {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin: 1.75rem 0 1.25rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--color-border);
}

/* The rule sits between the two figures rather than around each of them. */
.city-compare-side + .city-compare-side {
    margin-left: clamp(1.25rem, 4vw, 2.75rem);
    padding-left: clamp(1.25rem, 4vw, 2.75rem);
    border-left: 1px solid var(--color-border);
}

.city-summary .city-compare-label {
    margin: 0 0 0.3rem;
    font-size: 0.95rem;
    font-weight: 500;
    line-height: 1.4;
}

.city-summary .city-compare-amount {
    margin: 0 0 0.35rem;
    font-family: var(--font-family-title);
    font-size: clamp(1.6rem, 3vw, 2rem);
    font-weight: 700;
    line-height: 1.1;
    /* Two amounts meant to be compared digit for digit. */
    font-variant-numeric: tabular-nums;
}

/* The winner is named in the verdict above; the colour only makes it scannable,
 * so it never carries the meaning alone. */
.city-summary .city-compare-side.is-best .city-compare-amount {
    color: var(--color-primary-700);
}

.city-summary .city-compare-amount.is-empty {
    font-size: 1.15rem;
    font-weight: 500;
    color: var(--color-muted);
}

.city-summary .city-compare-meta {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.5;
    color: var(--color-muted);
}

.city-summary-note {
    font-size: 0.9rem;
    color: var(--color-muted);
}

/* --------------------------------------------------------------------------
 * Station table
 * -------------------------------------------------------------------------- */

/* The table itself scrolls horizontally; the page never does.
 * position:relative matters: it makes this the containing block for the
 * absolutely positioned .visually-hidden labels in the header cells, which
 * would otherwise resolve against the viewport and widen the whole document. */
.city-table-wrapper {
    position: relative;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-2);
}

.city-station-table {
    width: 100%;
    border-collapse: collapse;
    min-width: 640px;
}

.city-station-table th,
.city-station-table td {
    padding: 0.75rem 0.9rem;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--color-border-subtle);
}

.city-station-table thead th {
    background: rgba(var(--rgb-black), 0.03);
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--color-muted);
    white-space: nowrap;
}

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

.city-station-table tbody tr.is-highlighted {
    background: rgba(var(--rgb-primary), 0.09);
}

.city-station-table tbody tr.city-table-ad-row td {
    padding: 0;
    background: rgba(var(--rgb-black), 0.015);
}

.city-table-ad-viewport {
    position: sticky;
    left: 0;
    z-index: 1;
    box-sizing: border-box;
    display: flex;
    justify-content: center;
    width: min(100%, calc(100vw - 2rem));
    padding: 0.8rem;
}

.city-table-ad {
    position: relative;
    overflow: hidden;
    box-sizing: border-box;
    width: min(100%, 640px);
    height: 250px;
    min-height: 250px;
    max-height: 250px;
    padding: 0.65rem;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-1);
    text-align: center;
}

.city-table-ad,
.city-table-ad * {
    box-sizing: border-box;
}

.city-table-ad .adsbygoogle {
    display: block !important;
    width: 100% !important;
    flex: 1 1 auto;
    min-height: 225px;
}

.city-col-rank {
    width: 3rem;
    color: var(--color-muted);
    font-variant-numeric: tabular-nums;
}

/* Claim enough width that the place and its badges sit on one line, which
 * keeps the rows short enough to scan. */
.city-station-table thead th:nth-child(2),
.city-station-table tbody td:nth-child(2) {
    min-width: 16rem;
}

.city-station-cell {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
}

.city-brand-logo {
    width: 24px;
    height: auto;
    flex-shrink: 0;
    margin-top: 0.15rem;
}

.city-station-name {
    font-weight: 600;
    color: var(--color-text);
    text-decoration: none;
}

.city-station-name:hover,
.city-station-name:focus-visible {
    color: var(--color-primary);
    text-decoration: underline;
}

.city-station-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.2rem;
    font-size: 0.85rem;
    color: var(--color-muted);
}

.city-badge {
    display: inline-block;
    padding: 0.1em 0.5em;
    border-radius: 999px;
    border: 1px solid var(--color-border);
    font-size: 0.75rem;
    line-height: 1.5;
    white-space: nowrap;
}

.city-badge--de {
    border-color: rgba(var(--rgb-primary), 0.45);
    background: rgba(var(--rgb-primary), 0.1);
}

.city-badge--be {
    border-color: rgba(var(--rgb-amber), 0.55);
    background: rgba(var(--rgb-amber), 0.14);
}

.city-col-price {
    white-space: nowrap;
}

.city-price {
    display: block;
    font-family: var(--font-family-title);
    font-weight: 700;
    font-size: 1.1rem;
    font-variant-numeric: tabular-nums;
}

.city-price--unknown {
    font-family: var(--font-family-body);
    font-weight: 400;
    font-size: 0.9rem;
    color: var(--color-muted);
}

.city-price-updated {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.78rem;
    color: var(--color-muted);
}

.city-price-updated--stale {
    color: var(--fuel-type-e5);
    font-weight: 600;
}

/* Total cost is the sort key, so it reads as the primary number. */
.city-col-total {
    white-space: nowrap;
}

/* Sits on the brand-orange header band, so it cannot use --color-muted: #6c757d
 * on #F38651 is 1.86:1. Tinted from the band's own hue instead, at 4.7:1 — this
 * note is now the only place the distance mode is stated. Case, size and weight
 * already separate it from the uppercase column label. */
.city-col-note {
    display: block;
    font-size: 0.72rem;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    color: #5a2a12;
}

.city-total {
    display: block;
    font-family: var(--font-family-title);
    font-weight: 700;
    font-size: 1.1rem;
    font-variant-numeric: tabular-nums;
}

.city-total--unknown {
    color: var(--color-muted);
    font-weight: 400;
}

.city-total-note {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.78rem;
    color: var(--color-muted);
}

.city-col-distance {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.city-distance-note {
    display: block;
    font-size: 0.75rem;
    color: var(--color-muted);
}

.city-status {
    display: inline-block;
    font-size: 0.85rem;
    white-space: nowrap;
}

.city-status--open::before { content: "● "; color: var(--fuel-type-e10); }
.city-status--soon::before { content: "● "; color: var(--color-amber); }
.city-status--closed::before { content: "● "; color: var(--fuel-type-e5); }
.city-status--unknown { color: var(--color-muted); }

.city-map-button {
    padding: 0.4em 0.8em;
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-3);
    background: transparent;
    color: var(--color-primary);
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
    white-space: nowrap;
}

.city-map-button:hover {
    border-color: var(--color-primary);
    background: rgba(var(--rgb-primary), 0.08);
}

.city-more {
    margin-top: 1rem;
}

/* --------------------------------------------------------------------------
 * Ads
 * -------------------------------------------------------------------------- */

.city-ad-section {
    margin-top: -0.75rem;
}

.city-ad {
    position: relative;
    overflow: hidden;
    box-sizing: border-box;
    width: 100%;
    height: 280px;
    min-height: 280px;
    max-height: 280px;
    padding: 0.9rem;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-1);
    text-align: center;
}

.city-ad,
.city-ad * {
    box-sizing: border-box;
}

.city-ad-label {
    flex: 0 0 auto;
    margin-bottom: 0.45rem;
    color: var(--color-muted);
    font-size: 0.7rem;
    font-weight: 500;
    line-height: 1;
}

.city-ad .adsbygoogle {
    display: block !important;
    width: 100% !important;
    min-height: 250px;
}

@media (max-width: 768px) {
    .city-ad {
        height: 180px;
        min-height: 180px;
        max-height: 180px;
        padding: 0.5rem;
    }

    .city-ad .adsbygoogle {
        min-height: 160px;
    }
}

/* --------------------------------------------------------------------------
 * Map
 * -------------------------------------------------------------------------- */

.city-map-shell {
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-2);
    overflow: hidden;
}

/* Fixed aspect ratio reserves the space before Leaflet initialises, so the
 * page never shifts when the map hydrates. */
.city-map {
    width: 100%;
    height: clamp(320px, 55vw, 520px);
    background: var(--color-surface);
}

.city-map-fallback {
    padding: 1rem;
    margin: 0;
    color: var(--color-muted);
}

.city-map-popup {
    font-family: var(--font-family-body);
    min-width: 180px;
}

.city-map-popup a {
    color: var(--color-primary);
}

.city-map-popup-price {
    font-family: var(--font-family-title);
    font-weight: 700;
    font-size: 1.15rem;
}

/* --------------------------------------------------------------------------
 * Notices, buttons, calculator
 * -------------------------------------------------------------------------- */

.city-notice {
    padding: 1.25rem 1.5rem;
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-2);
    background: var(--color-surface);
}

.city-notice--error {
    border-color: rgba(218, 72, 72, 0.4);
    background: rgba(218, 72, 72, 0.06);
}

.city-notice h2 {
    margin-top: 0;
}

.city-notice-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 0;
}

.city-button {
    display: inline-flex;
    align-items: center;
    padding: 0.5em 1em;
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-3);
    background: transparent;
    color: var(--color-text);
    font: inherit;
    text-decoration: none;
    cursor: pointer;
}

.city-button:hover {
    border-color: var(--color-primary);
    color: var(--color-text);
    text-decoration: none;
}

.city-button--primary {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #000;
}

.city-button--primary:hover {
    background: var(--color-primary-600);
    border-color: var(--color-primary-600);
    color: #000;
}

/* The assumptions behind the ranking, kept visible rather than hidden in a
 * dialog: the numbers on this page mean nothing without them. */
.city-assumptions {
    /* Every control in the settings row resolves to this one height, which is
     * what stops the fuel chips, the number inputs, the dropdown and the
     * location button from each sitting at their own. */
    --city-control-h: 2.75rem;
    margin-bottom: 1rem;
    padding: 0.85rem 0;
    border: 1px solid #e5e7eb;
    border-radius: var(--border-radius-2);
    background: transparent;
}

.city-settings-header {
    margin-bottom: 0.75rem;
    padding: 0 1rem;
    border-bottom: 1px solid var(--color-border-subtle);
}

.city-settings-title {
    margin: 0 0 0.65rem;
    font-size: 1.05rem;
    font-weight: 600;
    color: #374151;
}

.city-settings-grid {
    display: grid;
    grid-template-columns: minmax(15rem, 1.4fr) repeat(4, minmax(8.25rem, 1fr));
    gap: 0.85rem 0.75rem;
    padding: 0 1rem;
    /* `end` used to align the fields by their bottom edge, so the taller
     * location button pushed its own label out of line with the other four.
     * With one shared control height, aligning from the top lines everything
     * up on both the label and the control row. */
    align-items: start;
}

.city-assumption-field label,
.city-control-label,
.city-fuel-label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.35rem;
    font-size: 0.85rem;
    font-weight: 500;
    line-height: 1.35;
    color: #374151;
    white-space: nowrap;
}

/* One size and one stroke for every icon in this panel. Sized in em so they
 * track the label they belong to. */
.city-icon {
    flex-shrink: 0;
    width: 1.05em;
    height: 1.05em;
    color: var(--color-muted);
}

.city-input-group {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    width: 100%;
}

.city-input-group input {
    width: 100%;
    min-width: 0;
    height: var(--city-control-h);
    padding: 0 0.7rem;
    border: 1px solid #d1d5db;
    border-radius: var(--border-radius-3);
    font: inherit;
    font-variant-numeric: tabular-nums;
}

.city-input-group input:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(var(--rgb-primary), 0.1);
}

.city-input-group span {
    flex-shrink: 0;
    font-size: 0.85rem;
    color: var(--color-muted);
}

.city-location-button {
    justify-content: center;
    width: 100%;
    height: var(--city-control-h);
    padding: 0 0.7rem;
    border-color: #d1d5db;
    background: #fff;
    font-size: 0.9rem;
    white-space: nowrap;
}

.city-location-button[aria-busy="true"] {
    opacity: 0.72;
    cursor: wait;
}

/* Distance dropdown — the same component as the time-range picker on
 * station.php, down to the .pro-badge, so a Pro-gated option looks the same
 * wherever it appears. A <select> cannot style an <option>, which is the whole
 * reason this is a listbox. */
.city-dropdown {
    /* --color-primary-700 (#c9633a) is 3.95:1 on white: fine for the large
     * comparison figure, but these are 10-14px and need 4.5:1. This shade is
     * 5.0:1. Borders keep the lighter brand orange — they carry no text. */
    --city-brand-text: #b0552f;
    position: relative;
    width: 100%;
}

.city-dropdown-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    width: 100%;
    height: var(--city-control-h);
    padding: 0 0.7rem;
    border: 1px solid #d1d5db;
    border-radius: var(--border-radius-3);
    background: #fff;
    color: var(--color-text);
    font: inherit;
    font-size: 0.9rem;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.city-dropdown-trigger:hover {
    border-color: #9ca3af;
}

.city-dropdown-trigger:focus-visible,
.city-dropdown-trigger[aria-expanded="true"] {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(var(--rgb-primary), 0.1);
}

.city-dropdown-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.city-dropdown-arrow {
    width: 1rem;
    height: 1rem;
    transition: transform 0.2s ease;
}

.city-dropdown-trigger[aria-expanded="true"] .city-dropdown-arrow {
    transform: rotate(180deg);
}

.city-dropdown-menu {
    position: absolute;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    z-index: 500;
    display: none;
    border: 1px solid #d1d5db;
    border-radius: var(--border-radius-3);
    background: #fff;
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

.city-dropdown-menu.is-open {
    display: block;
}

.city-dropdown-option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 0.7rem;
    font-size: 0.875rem;
    color: #374151;
    cursor: pointer;
    user-select: none;
    transition: background-color 0.15s ease;
}

.city-dropdown-option:hover,
.city-dropdown-option.is-active {
    background: #f9fafb;
}

.city-dropdown-option[aria-selected="true"] {
    background: #fff1e8;
    color: var(--city-brand-text);
    font-weight: 500;
}

.city-dropdown-option-text {
    flex: 1;
}

/* The badge from station.php: same box, border, size and tracking, with the
 * label darkened to clear 4.5:1 at 10px. */
.pro-badge {
    flex-shrink: 0;
    margin-left: auto;
    padding: 2px 6px;
    border: 1px solid var(--color-primary);
    border-radius: 6px;
    color: var(--city-brand-text);
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.city-assumption-note {
    margin: 0.75rem 0 0;
    padding: 0.65rem 1rem 0;
    border-top: 1px solid var(--color-border-subtle);
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--color-muted);
}

.city-assumption-status {
    display: block;
    margin-top: 0.25rem;
}

.city-assumption-note a {
    color: var(--color-primary);
}

@media (max-width: 980px) {
    .city-settings-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .city-assumption-field--fuel,
    .city-assumption-field--location {
        grid-column: 1 / -1;
    }
}

@media (max-width: 620px) {
    .city-settings-grid {
        grid-template-columns: 1fr;
    }

    .city-assumption-field--fuel,
    .city-assumption-field--location {
        grid-column: auto;
    }

    .city-fuel-options {
        flex-wrap: wrap;
    }

    .city-fuel-option {
        flex-basis: calc(33.333% - 0.34rem);
    }
}

.city-callout {
    margin-top: 1rem;
    padding: 0.8rem 1rem;
    border: 1px solid rgba(var(--rgb-primary), 0.18);
    border-radius: var(--border-radius-3);
    background: rgba(var(--rgb-primary), 0.07);
    font-size: 0.92rem;
    line-height: 1.6;
}

.city-callout[hidden] {
    display: none;
}

/* --------------------------------------------------------------------------
 * FAQ, link lists, index page
 * -------------------------------------------------------------------------- */

.city-faq-item {
    border-bottom: 1px solid var(--color-border-subtle);
    padding: 0.75rem 0;
}

.city-faq-item summary {
    cursor: pointer;
    list-style-position: outside;
}

.city-faq-item summary h3 {
    display: inline;
    font-size: 1.02rem;
    font-weight: 600;
}

.city-faq-item p {
    margin: 0.6rem 0 0;
    color: var(--color-text);
}

.city-link-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 0.75rem;
    list-style: none;
    padding: 0;
    margin: 0 0 1rem;
}

.city-link-list li {
    display: flex;
    flex-direction: column;
    padding: 0.75rem 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-3);
}

.city-link-list a {
    color: var(--color-primary);
    font-weight: 600;
    text-decoration: none;
}

.city-link-list a:hover,
.city-link-list a:focus-visible {
    text-decoration: underline;
}

.city-link-meta {
    font-size: 0.82rem;
    color: var(--color-muted);
}

.city-back-link a {
    color: var(--color-primary);
}

.city-province-group {
    margin-bottom: 1.65rem;
}

.city-province-group h3 {
    font-size: 1.15rem;
    margin-bottom: 0.75rem;
    padding-bottom: 0.35rem;
    border-bottom: 1px solid rgba(var(--rgb-primary), 0.28);
}

.city-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 0.75rem;
    list-style: none;
    padding: 0;
    margin: 0;
}

.city-card {
    display: flex;
    flex-direction: column;
    gap: 0;
    height: 100%;
    padding: 0.85rem 1rem;
    border: 1px solid var(--color-border);
    border-radius: var(--border-radius-3);
    background: var(--color-bg);
    text-decoration: none;
    color: var(--color-text);
    transition: border-color 0.2s ease, background-color 0.2s ease, transform 0.05s ease;
}

.city-card:hover {
    border-color: var(--color-primary);
    background: rgba(var(--rgb-primary), 0.06);
    text-decoration: none;
    color: var(--color-text);
}

.city-card:active {
    transform: translateY(1px);
}

.city-card-name {
    font-weight: 600;
}

/* --------------------------------------------------------------------------
 * Utilities and accessibility
 * -------------------------------------------------------------------------- */

.visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.city-page a:focus-visible,
.city-page button:focus-visible,
.city-page summary:focus-visible,
.city-page input:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

@media (max-width: 640px) {
    .city-container {
        margin-top: 5.5em;
    }

    .city-station-table th,
    .city-station-table td {
        padding: 0.6rem 0.7rem;
    }

    .city-station-table tbody tr.city-table-ad-row td {
        padding: 0;
    }

    .city-table-ad-viewport {
        width: min(100%, calc(100vw - 1.5rem));
        padding: 0.65rem;
    }

    .city-table-ad {
        width: min(100%, 320px);
        height: auto;
        min-height: 0;
        max-height: none;
        aspect-ratio: 1 / 1;
        padding: 0.5rem;
    }

    .city-table-ad .adsbygoogle {
        min-height: 0;
    }

    /* Stacked, the two figures separate top-to-bottom instead of side by side,
     * so the footnote needs more room to stop reading as part of the second. */
    .city-compare {
        grid-template-columns: minmax(0, 1fr);
        margin-bottom: 1.75rem;
    }

    .city-compare-side + .city-compare-side {
        margin: 1.35rem 0 0;
        padding: 1.35rem 0 0;
        border-left: 0;
        border-top: 1px solid var(--color-border);
    }
}

@media (prefers-reduced-motion: reduce) {
    .city-card,
    .city-fuel-option,
    .city-button {
        transition: none;
    }
}
