/* Tire Search — Browse by Vehicle
   -------------------------------------------------------------------------
   The redesigned shell and step 1. Added alongside by_vehicle/index.css rather
   than replacing it: steps 2 to 4 still render from that sheet until they are
   migrated in turn, so a half-finished rewrite never leaves a broken step.
   Delete from index.css only once all four are across.

   The "tire-search" bundle is loaded by this view alone now that brand and size
   own theirs, so these rules cannot reach another page. Everything is still
   namespaced tsv- and the shared-component overrides are qualified by the mount
   id, to keep it that way as the rest of the page migrates.
   ------------------------------------------------------------------------- */

#tire-search-vehicle {
    --tsv-blue: #1D4288;
    /* Bright #3EB049 is 2.7:1 on white, so green text takes this darker tone
       and the bright one is left to fills and rings. */
    --tsv-green: #3EB049;
    --tsv-green-text: #237A2E;
    /* Where a green link deepens on hover rather than changing hue. */
    --tsv-green-text-dark: #1B5E23;
    --tsv-ink: #1A1A1A;
    --tsv-muted: #555;
    --tsv-band: #F3F4F6;
    --tsv-rule: #D9DCE1;
    --tsv-radius: 6px;

    /* One elevation pair and one hover ring for everything pickable on the
       page, so a circle, a card and a tile all respond the same way. A tile on
       white keeps a 1px rule as well, which is its resting edge rather than a
       second elevation. */
    --tsv-elevation: 0 4px 20px rgba(0, 0, 0, .1);
    --tsv-elevation-hover: 0 8px 24px rgba(0, 0, 0, .12);
    --tsv-ring: 0 0 0 3px var(--tsv-green);

    background: #fff;

    /* SimpleLayout mounts Vuetify sidebars after the page body and their
       .v-application__wrap carries min-height: 100vh, which main.css only
       neutralises under #page-wrapper. Without this the wrap blankets the first
       screenful and swallows clicks above the fold. */
    position: relative;
    z-index: 1;

    /* Body is a flex column at min-height 100vh with the footer pushed down, so
       the last band grows into the slack instead of leaving bare background. */
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
}

.tsv-shell {
    max-width: 1400px;
    margin: 0 auto;
    padding-inline: 24px;
    width: 100%;
}

/* ---------- Breadcrumb ----------
   Pulled onto this page's column; the global partial ships its own gutter and
   top margin. Matched by sibling adjacency. */
#breadcrumb:has(~ #tire-search-vehicle) {
    margin-bottom: 0;
}

#breadcrumb:has(~ #tire-search-vehicle) > div {
    max-width: 1400px;
    margin: 0 auto !important;
    padding: 24px 24px 0 !important;
}

/* ---------- Band headings ---------- */

.tsv-band-title {
    font-family: BebasNeue;
    font-size: 36px;
    line-height: 1;
    color: #fff;
    margin: 0 0 28px;
}

/* The band titles take focus when a step changes, so a screen reader announces
   where the shopper has landed. They are headings rather than controls, so no
   ring: the announcement is the point, not a target to press. */
.tsv-band-title:focus {
    outline: none;
}

.tsv-band-title--dark {
    color: var(--tsv-blue);
}

/* ---------- Intro ---------- */

.tsv-intro {
    padding-block: 24px 40px;
}

.tsv-intro__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 20px;
}

.tsv-title {
    font-family: BebasNeue;
    font-size: 48px;
    line-height: 1;
    color: var(--tsv-blue);
    margin: 0;
}

.tsv-intro__actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* Sits above the pair rather than beside it, so the two buttons stay a unit
   and the label reads as the question they answer. */
.tsv-intro__actions-label {
    flex-basis: 100%;
    font-family: Inter;
    font-size: 15px;
    font-weight: 600;
    text-align: right;
    color: var(--tsv-ink);
    margin-bottom: 2px;
}

/* ---------- Step indicator ---------- */

.tsv-steps {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 18px 0 0;
    padding: 0;
}

/* Qualified by the mount id for the same reason as the directory list: main.css
   sets the marker and padding on the li rather than the ul, with five :not()
   classes that outscore a plain class selector. */
#tire-search-vehicle .tsv-steps li {
    list-style: none;
    padding: 0;
}

.tsv-steps__item {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* An answered step is a control; the rest of the row is text. The hit area
   covers the numeral and its label together, and the padding is pulled back
   out with a negative margin so growing the target does not move the step. */
#tire-search-vehicle .tsv-steps__go {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px;
    margin: -8px;
    color: inherit;
    background: none;
    border: 0;
    cursor: pointer;
}

/* Id-qualified so the numeral keeps its white: a globally loaded sheet colours
   button content, which was leaving the hovered step as a bare green dot. */
#tire-search-vehicle .tsv-steps__go:hover .tsv-steps__num {
    color: #fff;
    background: var(--tsv-green-text);
    border-color: var(--tsv-green-text);
}

.tsv-steps__go:hover .tsv-steps__label {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.tsv-steps__go:focus-visible {
    outline: 3px solid var(--tsv-green-text);
    outline-offset: 2px;
}

/* The rule between two steps belongs to the one on its right, so the last step
   has nothing trailing it. */
.tsv-steps__item + .tsv-steps__item::before {
    content: "";
    width: 28px;
    height: 1px;
    background: var(--tsv-rule);
}

.tsv-steps__num {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    font-family: Inter;
    font-size: 14px;
    font-weight: 700;
    line-height: 1;
    color: var(--tsv-muted);
    border: 1px solid var(--tsv-rule);
    border-radius: 50%;
}

.tsv-steps__label {
    font-family: Inter;
    font-size: 15px;
    font-weight: 600;
    color: var(--tsv-muted);
}

/* The darker green fills: white on bright #3EB049 is 2.7:1, and this numeral is
   small text. */
.tsv-steps__item.is-current .tsv-steps__num {
    color: #fff;
    background: var(--tsv-green-text);
    border-color: var(--tsv-green-text);
}

.tsv-steps__item.is-current .tsv-steps__label {
    font-weight: 700;
    color: var(--tsv-green-text);
}

/* A step already answered turns green but stays outlined, so the filled circle
   is still the one place the shopper is. */
.tsv-steps__item.is-done .tsv-steps__num {
    color: var(--tsv-green-text);
    border-color: var(--tsv-green-text);
}

.tsv-steps__item.is-done .tsv-steps__label {
    color: var(--tsv-green-text);
}

/* The rule belongs to the step on its right, so the one leading into the
   current step greens along with the step behind it. */
.tsv-steps__item.is-done::before,
.tsv-steps__item.is-current::before {
    background: var(--tsv-green-text);
}

/* ---------- Search ---------- */

.tsv-search {
    position: relative;
    max-width: 620px;
    margin-top: 28px;
}

.tsv-search__input {
    font-family: Inter;
    font-size: 16px;
    line-height: 24px;
    width: 100%;
    padding: 16px 48px 16px 20px;
    color: var(--tsv-ink);
    background: #fff;
    border: 1px solid var(--tsv-rule);
    border-radius: var(--tsv-radius);
}

.tsv-search__input::placeholder {
    color: var(--tsv-muted);
}

/* The border takes the darker green: bright #3EB049 is 2.7:1 on white, under
   the 3:1 a focus indicator owes its surroundings. The glow can stay bright,
   since the border is what carries the contrast. */
.tsv-search__input:focus {
    outline: none;
    border-color: var(--tsv-green-text);
    box-shadow: 0 0 0 3px rgba(62, 176, 73, .25);
}

.tsv-search__input::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
}

.tsv-search__clear {
    position: absolute;
    top: 50%;
    right: 8px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    color: var(--tsv-muted);
    background: none;
    border: 0;
    border-radius: 50%;
    cursor: pointer;
}

.tsv-search__clear:hover {
    color: var(--tsv-ink);
    background: var(--tsv-band);
}

.tsv-search__clear:focus-visible {
    outline: 3px solid var(--tsv-green-text);
    outline-offset: 2px;
}

/* ---------- Popular makes ---------- */

.tsv-popular {
    background: var(--tsv-blue);
    padding-block: 56px;
}

.tsv-popular__grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 24px;
}

/* A button rather than a link: picking a make advances the wizard in place
   instead of navigating. The name below the circle is the control's accessible
   name, so the img takes an empty alt rather than saying the make twice. */
.tsv-make {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    width: 100%;
    max-width: 150px;
    margin-inline: auto;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
}

.tsv-make__circle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    max-width: 130px;
    aspect-ratio: 1;
    /* Barely any inset, because the artwork carries its own margin. The old
       design reached the same proportion by forcing the img to the full outer
       diameter so it overflowed its parent and was clipped by overflow:hidden;
       the mark ends up the same size without the spill. */
    padding: 4%;
    background: #fff;
    border-radius: 50%;
    box-shadow: var(--tsv-elevation);
    transition: box-shadow .25s ease, transform .25s ease;
}

/* A ring rather than a border, so the circle does not resize on hover. */
.tsv-make:hover .tsv-make__circle {
    box-shadow: var(--tsv-ring), var(--tsv-elevation-hover);
    transform: translateY(-3px);
}

/* On the brand band, so white rather than the green the tiles on white take. */
.tsv-make:focus-visible {
    outline: 3px solid #fff;
    outline-offset: 3px;
    border-radius: var(--tsv-radius);
}

.tsv-make__name {
    font-family: Inter;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.25;
    text-align: center;
    color: #fff;
}

.tsv-make__logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

/* Marks are shown as supplied — never recoloured, dimmed or inverted. Sized to
   the well rather than capped by it, so a mark whose file is smaller than the
   circle still fills it; object-fit holds the aspect ratio either way.
   Step 2's summary circle uses this too. */
.tsv-make__logo img,
.tsv-selection__logo img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Fallback for a make the feed has no logo for — it is the label as well as the
   fallback, so it wraps rather than running out of the circle. */
.tsv-make__logo-text {
    font-family: BebasNeue;
    font-size: 22px;
    line-height: 1.1;
    text-align: center;
    overflow-wrap: anywhere;
    color: var(--tsv-blue);
}

/* ---------- Selected make (step 2) ---------- */

/* A quiet gray strip rather than another brand band: it reports a choice
   already made, so it sits between the intro and the step's own heading
   without competing with either. */
.tsv-selection {
    background: var(--tsv-band);
    padding-block: 24px;
}

/* The three parts read as one group in the middle of the band rather than
   being pushed to its edges, where a 1400px shell left a wide empty channel. */
.tsv-selection__inner {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 40px;
}

.tsv-selection__make {
    display: flex;
    align-items: center;
    gap: 28px;
}

/* The same circle the makes are picked from on step 1, at the same size, with a
   blue ring marking it as the chosen one rather than another target. Step 2
   only: the circles on step 1 are still being chosen between. */
.tsv-selection__logo {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 130px;
    height: 130px;
    padding: 4%;
    background: #fff;
    border-radius: 50%;
    box-shadow: 0 0 0 3px var(--tsv-blue), var(--tsv-elevation);
}

.tsv-selection__logo-text {
    font-family: BebasNeue;
    font-size: 15px;
    line-height: 1.1;
    text-align: center;
    overflow-wrap: anywhere;
    color: var(--tsv-blue);
}

/* Reads at the band-title size, since the make is the heading of what the
   shopper is choosing within. */
.tsv-selection__name {
    font-family: BebasNeue;
    font-size: 36px;
    line-height: 1;
    color: var(--tsv-blue);
}

/* ---------- Year and model tiles (steps 2 and 3) ---------- */

.tsv-years,
.tsv-models {
    padding-block: 44px 72px;
    flex: 1 0 auto;
}

.tsv-tiles {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 16px;
}

/* Fewer, wider tiles for model names, which run past what a year column fits. */
.tsv-tiles--wide {
    grid-template-columns: repeat(4, 1fr);
}

/* A soft rule carries the tile and the shadow only lifts it slightly: 40-odd
   heavily elevated tiles in one grid read as noise. */
.tsv-tile {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 56px;
    font-family: Inter;
    /* The size a shopper reads is 19px everywhere it appears: a tile here, a
       row on the trim step. */
    font-size: 19px;
    font-weight: 700;
    color: var(--tsv-blue);
    background: #fff;
    border: 1px solid var(--tsv-rule);
    border-radius: var(--tsv-radius);
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .05);
    transition: box-shadow .25s ease, transform .25s ease, border-color .25s ease;
}

.tsv-tile:hover {
    border-color: var(--tsv-green);
    box-shadow: var(--tsv-ring), var(--tsv-elevation-hover);
    transform: translateY(-3px);
}

/* Green rather than the white the circles use: these sit on white, not on the
   brand band. */
.tsv-tile:focus-visible {
    outline: 3px solid var(--tsv-green-text);
    outline-offset: 3px;
}

/* ---------- Trim cards (step 4) ---------- */

/* Content bands share one step: 44px in, 72px out, so the last band on a step
   sits off the footer the same way on all four. The brand band on step 1 is
   the exception and carries more, since a filled band needs it.

   This band is the other exception: the where-to-find-your-size section follows
   it rather than the footer, and that section is what a shopper who cannot
   identify their trim needs next, so it stays within reach. */
.tsv-trims {
    padding-block: 44px 32px;
    flex: 1 0 auto;
}

/* A narrower column than the rest of the page, centred: a row holds a size, a
   diameter and one action, so across the full 1400px shell the card was mostly
   empty to the right of its own content. */
.tsv-trims__inner {
    max-width: 880px;
}

/* A title introducing a lede tightens to it, so the pair reads as one block
   rather than the lede being pulled up out of the title's own space. */
.tsv-band-title:has(+ .tsv-trims__lede) {
    margin-bottom: 12px;
}

.tsv-trims__lede {
    font-family: Inter;
    font-size: 16px;
    line-height: 24px;
    color: var(--tsv-muted);
    max-width: 62ch;
    margin: 0 0 28px;
}

/* Inline in the lede and underlined, since it sits inside running copy where a
   colour shift alone would read as emphasis rather than a link. */
.tsv-trims__jump {
    font-weight: 600;
    color: var(--tsv-blue);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.tsv-trims__jump:hover {
    color: var(--tsv-green-text);
}

/* One line at desktop widths rather than wrapping inside a measure cap, which
   is what the shared explainer section below does too. */
@media (min-width: 992px) {
    .tsv-trims__lede {
        max-width: none;
    }
}

.tsv-trim-list {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.tsv-trim {
    background: #fff;
    border: 2px solid var(--tsv-rule);
    border-radius: var(--tsv-radius);
    overflow: hidden;
}

.tsv-trim__head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 12px;
    padding: 16px 20px;
}

.tsv-trim__name {
    font-family: BebasNeue;
    font-size: 28px;
    line-height: 1;
    color: var(--tsv-blue);
    margin: 0;
}

/* 15px is the page's secondary text size: this count, a wheel diameter, the
   run-flat flag, the closing aside. */
.tsv-trim__count {
    font-family: Inter;
    font-size: 15px;
    color: var(--tsv-muted);
}


/* Rows are separated by a hairline inset to the row's own padding, so the
   card's outline stays the only full-width line and a card of six sizes reads
   as a list rather than a table. */
.tsv-fitment::after,
.tsv-stagger::before {
    content: "";
    position: absolute;
    top: 0;
    left: 20px;
    right: 20px;
    height: 1px;
    background: var(--tsv-rule);
}

/* ---------- A plain fitment: the whole row is the target ---------- */

.tsv-fitment {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 12px;
    width: 100%;
    padding: 16px 20px;
    text-align: left;
    background: none;
    border: 0;
    cursor: pointer;
    position: relative;
    transition: background .2s ease;
}

/* The tick is the rest-state affordance that turns green on hover, so the row
   reads as clickable on a phone where no hover exists. */
.tsv-fitment::before {
    content: "";
    position: absolute;
    inset-block: 0;
    left: 0;
    width: 4px;
    background: var(--tsv-rule);
    transition: background .2s ease;
}

.tsv-fitment:hover {
    background: rgba(29, 66, 136, .04);
}

.tsv-fitment:hover::before {
    background: var(--tsv-green);
}

.tsv-fitment:focus-visible {
    outline: 3px solid var(--tsv-green-text);
    outline-offset: -3px;
}

/* Neutral, with the trim name above it carrying the blue: the tiles on steps 2
   and 3 are blue because the tile is the whole target, where a row here is one
   of several under a heading. */
.tsv-fitment__size {
    font-family: Inter;
    font-size: 19px;
    font-weight: 700;
    color: var(--tsv-ink);
}

.tsv-fitment__rim {
    font-family: Inter;
    font-size: 15px;
    color: var(--tsv-muted);
}

/* Pushed to the right edge of the capped row, not the card.
   Qualified by the mount id: a globally loaded sheet colours button elements
   with more than a single class of specificity, which is why this renders on a
   span in a plain row but went black once the staggered action became a
   button of its own. */
#tire-search-vehicle .tsv-fitment__cta,
.tsv-fitment__cta {
    display: inline-flex;
    align-items: center;
    margin-left: auto;
    font-family: Inter;
    font-size: 13px;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
    /* White on this green is 5.9:1, which 13px bold needs. */
    color: #fff;
    background: var(--tsv-green-text);
    border-radius: var(--tsv-radius);
    padding: 9px 14px;
    transition: background .2s ease;
}

/* The row is the target, so its hover drives the button rather than the
   button having a hover of its own. */
.tsv-fitment:hover .tsv-fitment__cta,
.tsv-stagger__main:hover .tsv-stagger__cta {
    background: var(--tsv-green-text-dark);
}

/* ---------- A staggered fitment: two axles and three destinations ---------- */

/* The padding sits on the two lines rather than the wrapper, so the values
   line can tint edge to edge on hover the way a plain row does. */
.tsv-stagger {
    padding: 0;
    position: relative;
}

/* The same shape as a plain row — values left, green action right — so the two
   kinds read as siblings inside one card. */
.tsv-stagger__main {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 10px;
    position: relative;
    padding: 14px 20px 6px;
    transition: background .2s ease;
}

/* The same rest-state tick and hover wash as a plain row. */
.tsv-stagger__main::before {
    content: "";
    position: absolute;
    inset-block: 0;
    left: 0;
    width: 4px;
    background: var(--tsv-rule);
    transition: background .2s ease;
}

.tsv-stagger__main:hover {
    background: rgba(29, 66, 136, .04);
}

.tsv-stagger__main:hover::before {
    background: var(--tsv-green);
}

.tsv-stagger__wheels {
    font-family: Inter;
    font-size: 15px;
    color: var(--tsv-muted);
    margin-left: 6px;
}

/* Lines up with the plain rows' actions down the right edge of the card, and
   stretches over the whole values line so pressing anywhere on it shops the
   set — the same target a plain row gives. The axle links sit on their own
   line above this, so they stay reachable. */
.tsv-stagger__cta {
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

.tsv-stagger__cta::after {
    content: "";
    position: absolute;
    inset: 0;
}

.tsv-stagger__cta:focus-visible {
    outline: 3px solid var(--tsv-green-text);
    outline-offset: 2px;
}

/* The axle-only options: a second line, quieter than the set above them, and
   stacked above the stretched target so they stay clickable. */
.tsv-stagger__links {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px 20px;
    position: relative;
    z-index: 1;
    margin: 0;
    padding: 5px 20px 14px 20px;
}

/* Each axle is a unit so the label never separates from its size, which is
   what lets the two stack cleanly on a phone. */
.tsv-axle {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
}

/* One micro-label recipe, shared with the all-four pill below. Blue, matching
   the labels on the saved-vehicle cards. */
.tsv-axle__label {
    font-family: Inter;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--tsv-blue);
}

.tsv-axle__size {
    font-family: Inter;
    font-size: 19px;
    font-weight: 700;
    color: var(--tsv-ink);
}

/* Underlined at rest: they sit in a dense row with no other affordance, and a
   colour shift alone would leave them looking like the labels beside them.
   Id-qualified for the same reason as the action above. */
#tire-search-vehicle .tsv-axle__link {
    display: inline-flex;
    align-items: center;
    font-family: Inter;
    font-size: 14px;
    font-weight: 600;
    color: var(--tsv-green-text);
    text-decoration: underline;
    text-underline-offset: 2px;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

.tsv-axle__link + .tsv-axle__link::before {
    content: "";
    width: 3px;
    height: 3px;
    margin-right: 20px;
    border-radius: 50%;
    background: var(--tsv-muted);
}

#tire-search-vehicle .tsv-axle__link:hover {
    color: var(--tsv-green-text-dark);
}

.tsv-axle__link:focus-visible {
    outline: 3px solid var(--tsv-green-text);
    outline-offset: 2px;
}

/* Run-flat, carried by the fitment and worth knowing before the results load:
   a run-flat set costs more and not every line offers one. The separator is
   drawn rather than written, so it is never read out. */
/* Plain inline text rather than a flex box: as a flex box its baseline came
   from the dot instead of the words, which dropped it below the rest of a
   baseline-aligned line. */
.tsv-flag {
    font-family: Inter;
    font-size: 15px;
    color: var(--tsv-muted);
}

.tsv-flag::before {
    content: "";
    display: inline-block;
    width: 3px;
    height: 3px;
    margin-right: 10px;
    vertical-align: middle;
    border-radius: 50%;
    background: currentColor;
}

/* The all-four label, which only appears on a card that also carries a
   staggered fitment. */
.tsv-kind {
    display: inline-block;
    font-family: Inter;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--tsv-blue);
    background: var(--tsv-band);
    border-radius: 999px;
    padding: 3px 10px;
}

.tsv-fitment .tsv-kind {
    margin-right: 4px;
}


/* ---------- Closing aside ---------- */

.tsv-trims__aside {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 4px 12px;
    font-family: Inter;
    font-size: 15px;
    text-align: center;
    color: var(--tsv-muted);
    margin: 24px 0 0;
}

.tsv-trims__aside a {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-weight: 700;
    color: var(--tsv-blue);
    text-decoration: underline;
}

.tsv-trims__aside a:hover {
    color: var(--tsv-green-text);
}

/* ---------- Empty and no-results panels ---------- */

.tsv-panel {
    background: #fff;
    border: 2px solid var(--tsv-rule);
    border-radius: var(--tsv-radius);
    padding: 28px 30px 30px;
    max-width: 640px;
}

.tsv-panel__title {
    font-family: BebasNeue;
    font-size: 26px;
    line-height: 1.1;
    color: var(--tsv-ink);
    margin: 0 0 10px;
}

.tsv-panel__body {
    font-family: Inter;
    font-size: 16px;
    line-height: 24px;
    color: var(--tsv-muted);
    margin: 0 0 20px;
}

.tsv-panel__link {
    display: block;
    font-family: Inter;
    font-size: 15px;
    font-weight: 700;
    color: var(--tsv-blue);
    text-decoration: underline;
    background: none;
    border: 0;
    padding: 0;
    margin-top: 16px;
    cursor: pointer;
}

.tsv-panel__link:hover {
    color: var(--tsv-green-text);
}

.tsv-panel__note {
    font-family: Inter;
    font-size: 15px;
    line-height: 22px;
    color: var(--tsv-muted);
    margin: 14px 0 0;
}

/* ---------- Loading ---------- */

.tsv-skeleton {
    display: block;
    height: 14px;
    background: var(--tsv-band);
    border-radius: 4px;
    animation: tsv-pulse 1.4s ease-in-out infinite;
}

.tsv-skeleton--name {
    width: 140px;
    height: 20px;
}

.tsv-skeleton--count {
    width: 96px;
}

.tsv-skeleton--size {
    width: 110px;
    height: 18px;
}

.tsv-skeleton--rim {
    width: 70px;
}

.tsv-skeleton--cta {
    width: 84px;
    margin-left: auto;
}

/* Matched to a real row so nothing moves when the trims land. */
.tsv-fitment--skeleton {
    pointer-events: none;
}

.tsv-trims__status {
    font-family: Inter;
    font-size: 15px;
    color: var(--tsv-muted);
    margin: 4px 0 0;
}

@keyframes tsv-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .55; }
}

@media (prefers-reduced-motion: reduce) {
    .tsv-skeleton {
        animation: none;
    }
}

/* ---------- A–Z directory ---------- */

/* White now that the intro carries the tint. */
.tsv-directory {
    padding-block: 44px 72px;
    flex: 1 0 auto;
}

/* Grid rather than multi-column so the letters read across each row and then
   down, which is how someone scans for a letter. Multi-column fills one column
   top to bottom first, which puts B under A rather than beside it.
   align-items: start keeps a short group from stretching to its row's height. */
.tsv-directory__cols {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    align-items: start;
    column-gap: 40px;
    row-gap: 32px;
}

.tsv-group__letter {
    font-family: BebasNeue;
    font-size: 28px;
    line-height: 1;
    color: var(--tsv-green-text);
    margin: 0 0 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--tsv-rule);
}

.tsv-group__list {
    margin: 0;
    padding: 0;
}

/* Qualified by the mount id: main.css carries a site-wide
   "ul:not(...):not(...) li { list-style: disc; padding: 5px 20px }" that sets
   the marker on the li rather than the ul, and its five :not() classes outscore
   a plain class selector here. */
#tire-search-vehicle .tsv-group__list li {
    list-style: none;
    padding: 0;
}

#tire-search-vehicle .tsv-group__list li + li {
    margin-top: 10px;
}

/* A button styled as a link, for the same reason as the cards above. */
.tsv-group__link {
    font-family: Inter;
    font-size: 16px;
    line-height: 24px;
    font-weight: 600;
    text-align: left;
    color: var(--tsv-ink);
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

.tsv-group__link:hover,
.tsv-group__link:focus-visible {
    color: var(--tsv-green-text);
}

/* A colour shift alone is not a focus indicator: someone tabbing the directory
   needs the same ring every other control here gives them. */
.tsv-group__link:focus-visible {
    outline: 3px solid var(--tsv-green-text);
    outline-offset: 2px;
}

.tsv-empty {
    font-family: Inter;
    font-size: 16px;
    color: var(--tsv-muted);
    margin: 0;
}

/* ---------- Responsive ---------- */

@media (max-width: 1399px) {
    .tsv-popular__grid {
        grid-template-columns: repeat(4, 1fr);
    }
}

@media (max-width: 1199px) {
    .tsv-popular__grid {
        grid-template-columns: repeat(3, 1fr);
    }

    .tsv-directory__cols {
        grid-template-columns: repeat(3, 1fr);
    }

    .tsv-tiles {
        grid-template-columns: repeat(5, 1fr);
    }

    .tsv-tiles--wide {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media (max-width: 767px) {
    .tsv-shell {
        padding-inline: 16px;
    }

    #breadcrumb:has(~ #tire-search-vehicle) > div {
        padding: 16px 16px 0 !important;
    }

    .tsv-title {
        font-size: 36px;
    }

    .tsv-band-title {
        font-size: 28px;
        margin-bottom: 20px;
    }

    .tsv-intro {
        padding-block: 16px 28px;
    }

    .tsv-intro__top {
        gap: 16px;
    }

    .tsv-intro__actions {
        width: 100%;
    }

    .tsv-intro__actions > * {
        flex: 1;
        justify-content: center;
    }

    /* Two by two rather than one wrapping row: four steps across a phone leaves
       the connectors doing the wrapping, which breaks the sequence in the
       middle of a pair. */
    .tsv-steps {
        display: grid;
        grid-template-columns: repeat(2, auto);
        justify-content: center;
        margin: 24px 0 0;
        gap: 14px 16px;
    }

    /* The connector belongs to the step on its right, so it only reads as a
       link between two steps when they share a row. */
    .tsv-steps__item:nth-child(odd)::before {
        display: none;
    }

    .tsv-steps__item + .tsv-steps__item::before {
        width: 16px;
    }

    .tsv-search {
        margin-top: 20px;
    }

    /* Three across rather than two: a circle carries no copy under it, so it
       stays legible at a third of the width. */
    .tsv-popular__grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 16px;
    }

    .tsv-make__logo-text {
        font-size: 18px;
    }

    .tsv-directory__cols {
        grid-template-columns: repeat(2, 1fr);
        column-gap: 24px;
    }

    /* The desktop spacing is generous for a stacked column at this width. */
    .tsv-selection__inner {
        gap: 16px;
    }

    .tsv-selection__make {
        gap: 16px;
    }

    .tsv-selection {
        padding-block: 20px;
    }

    /* Sized down once the button wraps below: at the step 1 diameter the mark
       dwarfs the name it belongs to, and the band costs most of the first
       screenful before any content. */
    .tsv-selection__logo {
        width: 96px;
        height: 96px;
    }

    .tsv-selection__name {
        font-size: 28px;
    }

    .tsv-years,
    .tsv-models {
        padding-block: 28px 48px;
    }

    .tsv-tiles {
        grid-template-columns: repeat(3, 1fr);
        gap: 12px;
    }

    .tsv-tiles--wide {
        grid-template-columns: repeat(2, 1fr);
    }

    .tsv-trims {
        padding-block: 28px 20px;
    }

    .tsv-trim__head,
    .tsv-fitment,
    .tsv-stagger__main,
    .tsv-stagger__links {
        padding-inline: 16px;
    }

    .tsv-fitment::after,
    .tsv-stagger::before {
        left: 16px;
        right: 16px;
    }


    .tsv-trim__name {
        font-size: 24px;
    }

    /* A row stacks into one thing per line: the kind label, the size, then the
       wheel and run-flat together, then the action. Side by side these three
       kinds of information ran together into one crowded line. */
    .tsv-fitment .tsv-kind,
    .tsv-fitment__size,
    .tsv-axle {
        flex-basis: 100%;
    }

    .tsv-fitment .tsv-kind {
        margin-right: 0;
    }

    .tsv-stagger__wheels {
        margin-left: 0;
    }

    #tire-search-vehicle .tsv-fitment__cta {
        flex-basis: 100%;
        justify-content: center;
        margin-left: 0;
        margin-top: 12px;
        padding-block: 12px;
    }

    .tsv-stagger__links {
        justify-content: center;
        padding-top: 14px;
    }

    .tsv-panel {
        padding: 22px 20px 24px;
    }

    .tsv-tile {
        min-height: 48px;
        font-size: 16px;
    }

    .tsv-popular {
        padding-block: 36px;
    }

    .tsv-directory {
        padding-block: 36px 48px;
    }
}

@media (max-width: 479px) {
    /* Side by side, "Shop By Brand" wraps to two lines while its neighbour
       stays on one, so the pair reads as two different buttons. Sizing the
       text down to fit only defers it to a narrower phone. */
    .tsv-intro__actions {
        flex-direction: column;
    }

    .tsv-intro__actions > * {
        width: 100%;
    }

    .tsv-intro__actions-label {
        text-align: center;
    }

    .tsv-selection__logo {
        width: 80px;
        height: 80px;
    }

    .tsv-directory__cols {
        grid-template-columns: 1fr;
    }

    .tsv-tiles {
        grid-template-columns: repeat(2, 1fr);
    }

    .tsv-tiles--wide {
        grid-template-columns: 1fr;
    }
}
