/* Rust hotspots pages (/rust-hotspots/). Loaded after styles.css and built on
   its variables. Severity colours are shared by the index and the car pages. */

:root {
  --hs-structural: #e8572a;
  --hs-mot: #e0a526;
  --hs-cosmetic: #8a8f99;
  /* Badge backgrounds only, deep enough for white text at 4.5:1 (5.2 and 5.8);
     the pins and the legend keep the colours above. */
  --hs-structural-deep: #c2401a;
  --hs-cosmetic-deep: #5f6673;
}

/* Index: one card per published car, a single column at every width. */
.hs-card-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  max-width: 760px;
  margin: 2rem 0;
}

.hs-car-card {
  display: block;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--border);
  border-radius: var(--border-radius);
  background: var(--background-alt);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.2s ease;
}

.hs-car-card:hover,
.hs-car-card:focus-visible {
  border-color: var(--primary);
}

.hs-car-card img {
  display: block;
  width: 100%;
  height: auto;
  margin-bottom: 1rem;
  border-radius: var(--border-radius);
}

.hs-index .hs-car-card h2 {
  margin: 0 0 0.25rem;
}

.hs-car-card__meta {
  margin: 0;
  color: var(--text-light);
}

.hs-car-card__count {
  margin: 0.5rem 0 0;
  color: var(--text-secondary);
  font-weight: 600;
}

/* Car pages: no sidebar (the page drops <Aside />), so the site's 3fr/1fr
   grid becomes one column at every width. minmax(0, 1fr), not 1fr: a 1fr
   track never shrinks below its content's min-content width, and the
   phone chip rail (one unwrapped row) would widen the page past the screen. */
.article-container.hs-single { grid-template-columns: minmax(0, 1fr); }

/* styles.css clips .article-content (overflow: hidden), and a clipping
   ancestor stops position: sticky on anything inside it. The article has the
   page background and no border or shadow, so nothing shows past its rounded
   corners without the clip. */
.hs-car.article-content { overflow: visible; }

/* The stage column and the notes. One column on narrow screens, where only
   the stage box sticks (below); from 993px (the site's own sidebar
   breakpoint is 992px) two columns, the stage column sticky beside the notes
   so the car stays in view while they scroll. With no model there is no stage
   column and the notes take the full width. */
@media (min-width: 993px) {
  .hs-layout {
    display: grid;
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    gap: 2rem;
    align-items: start;
  }

  /* On a short window the column (stage, hint, chips, legend, caption) can be
     taller than the screen; the cap and its own scroll keep every chip
     reachable while it is stuck. Only ancestors of a sticky element must not
     clip; the sticky element itself may scroll. */
  .hs-layout__stage {
    position: sticky;
    top: 1rem;
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
  }

  /* The caption ends the column; its bottom margin would only make the
     capped column overflow (the notes sit beside it, not below). */
  .hs-car .hs-layout__stage .hs-stage__caption { margin-bottom: 0; }

  .hs-layout__notes:only-child { grid-column: 1 / -1; }
}

/* Narrow screens: the stage box alone sticks to the top while the notes
   scroll (with the stage's own rules, below); the hint, chips, legend and
   caption scroll away beneath it. The column wrapper gives up its box so the
   stage's sticky range is the whole layout (stage column and notes), not just
   the column. */
@media (max-width: 992px) {
  .hs-layout__stage { display: contents; }
}

/* Notes stacked one per row, worst first. The stage (.hs-stage) and its pins
   are styled with the stage itself. */
.hs-callout {
  max-width: 760px;
  margin: 1.5rem 0;
  padding: 1rem 1.25rem;
  border-radius: var(--border-radius);
  background: var(--background-alt);
  font-weight: 500;
}

.hs-items {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  margin: 1.5rem 0 2rem;
}

/* scroll-margin-top keeps a card scrolled to by a pin click clear of the
   stage when it is stuck above the notes (--hs-stuck, set by the stage
   script; 0 when the stage sits beside them). */
.hs-item {
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--border);
  border-radius: var(--border-radius);
  background: var(--background-alt);
  scroll-margin-top: calc(var(--hs-stuck, 0px) + 0.75rem);
}

/* Set by the stage script when the card's pin or chip is picked: a ring
   outside the border. */
.hs-item.is-active { box-shadow: 0 0 0 2px var(--primary); }

.hs-car .hs-item h3 {
  margin: 0.5rem 0 0.75rem;
}

.hs-badge {
  display: inline-block;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  color: #fff;
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.4;
}

.hs-badge--structural { background: var(--hs-structural-deep); }
.hs-badge--mot-critical { background: var(--hs-mot); color: #222; }
.hs-badge--cosmetic { background: var(--hs-cosmetic-deep); }

.hs-item__notes {
  margin: 0;
}

.hs-item__notes dt {
  margin-top: 0.75rem;
  font-weight: 600;
}

.hs-item__notes dt:first-child {
  margin-top: 0;
}

.hs-item__notes dd {
  margin: 0.25rem 0 0;
}

.hs-read-next {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
  margin-top: 1rem;
  font-size: 0.9rem;
}

.hs-read-next__label {
  color: var(--text-secondary);
  font-weight: 600;
}

.hs-read-next ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Kit for this job (on each card) and the inspection kit (under the tips):
   the label, then one product per item (KitItem.astro): the name in bold,
   why it is in the kit on its own line, then the Buy on Amazon pill with the
   quiet "our test" link beside it. Scoped under .hs-car to outrank
   .article-content ul and li. */
.hs-kit {
  margin-top: 1rem;
  font-size: 0.9rem;
}

.hs-kit__label {
  display: block;
  color: var(--text-secondary);
  font-weight: 600;
}

.hs-car .hs-kit ul {
  margin: 0.25rem 0 0;
  padding: 0;
  list-style: none;
}

.hs-car .hs-kit li {
  margin: 0 0 0.75rem;
  line-height: 1.5;
}

.hs-kit__name {
  display: block;
  font-weight: 600;
}

.hs-kit__why {
  display: block;
  margin-bottom: 0.3rem;
  color: var(--text-light);
  font-size: 0.9rem;
}

.hs-car .hs-buy {
  display: inline-block;
  padding: 0.1rem 0.6rem;
  border: 1px solid var(--primary);
  border-radius: 999px;
  color: var(--primary-dark);
  font-size: 0.8rem;
  text-decoration: none;
}

.hs-car .hs-buy:hover,
.hs-car .hs-buy:focus-visible {
  background: var(--primary-dark);
  color: #fff;
}

.hs-car .hs-kit__test {
  margin-left: 0.6rem;
  color: var(--text-light);
  font-size: 0.85rem;
}

.hs-car .hs-kit__test:hover,
.hs-car .hs-kit__test:focus-visible {
  color: var(--primary-dark);
}

/* The page-level kit sits under the tips list, so it keeps the body size
   rather than the cards' smaller one, or it reads as a footnote. */
.hs-car .hs-kit--page {
  max-width: 760px;
  margin: 1rem 0 2rem;
  font-size: inherit;
}

.hs-confidence {
  margin: 1rem 0 0;
  color: var(--text-light);
  font-size: 0.85rem;
}

.hs-show {
  margin-top: 0.75rem;
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--primary);
  border-radius: var(--border-radius);
  background: transparent;
  color: var(--primary-dark);
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
}

.hs-show:not(:disabled):hover,
.hs-show:focus-visible {
  background: var(--primary-dark);
  color: #fff;
}

/* The stage: model-viewer laid over a poster image of the same view. The
   poster stays until model-viewer reports the model loaded (data-state set by
   src/scripts/hotspot-stage.ts), so a failed or slow model still shows a car.
   16:9 on narrow screens, where it sticks to the top and should leave room
   for the notes; 4:3 beside the notes from 993px, where the column is about
   600px wide and the 4:3 poster fills it with no side bands. */
/* width: 100%, not auto: with an auto width the height caps below would
   carry through the aspect ratio into a max-width and narrow the stage,
   instead of letterboxing it at full width. */
.hs-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  margin: 1.5rem 0 0;
  border-radius: var(--border-radius);
  background: var(--background-alt);
  overflow: hidden;
}

/* The height caps keep the stage from filling a short screen: beside the
   notes it leaves room for the chips under it; stuck over the notes on a
   landscape phone it leaves room to read them. A capped stage letterboxes in
   the stage colour (the poster is object-fit: contain, and model-viewer keeps
   its vertical field of view). */
@media (min-width: 993px) {
  .hs-stage {
    aspect-ratio: 4 / 3;
    max-height: 56vh;
  }
}

/* Narrow screens: stuck to the top over the notes (the stage script reads
   this position, and the capped height, to set the cards' scroll offset). */
@media (max-width: 992px) {
  .hs-stage {
    position: sticky;
    top: 0;
    z-index: 2;
    max-height: 45vh;
  }
}

/* contain, not cover: model-viewer keeps its vertical field of view as the
   stage widens to 16:9, so the car keeps its height and gains room at the
   sides; the 4:3 poster does the same this way, and its background is the
   stage colour, so the side bands do not show. */
.hs-stage__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: opacity 0.3s ease;
}

.hs-stage[data-state="loaded"] .hs-stage__poster { opacity: 0; }

.hs-stage model-viewer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  --poster-color: transparent;
  --min-hotspot-opacity: 0.25;
}

/* Until model-viewer's script defines the element (and for good without
   JavaScript) its pin buttons are plain buttons, which would stack down the
   poster's left edge; keep them hidden until the element is upgraded. */
.hs-stage model-viewer:not(:defined) { visibility: hidden; }

.hs-stage__error { display: none; }

.hs-stage[data-state="failed"] .hs-stage__error {
  display: block;
  position: absolute;
  right: 0.75rem;
  bottom: 0.75rem;
  left: 0.75rem;
  margin: 0;
  padding: 0.5rem 0.75rem;
  border-radius: var(--border-radius);
  background: var(--background);
  box-shadow: var(--box-shadow);
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.4;
}

/* Pins: a 32px round target around a dot in the severity colour. */
.hs-pin {
  position: relative;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
}

.hs-pin__dot {
  width: 14px;
  height: 14px;
  border: 2px solid #fff;
  border-radius: 50%;
  background: var(--hs-cosmetic);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

.hs-pin--structural .hs-pin__dot { background: var(--hs-structural); }
.hs-pin--mot-critical .hs-pin__dot { background: var(--hs-mot); }

.hs-pin__label {
  position: absolute;
  bottom: 100%;
  left: 50%;
  padding: 0.2rem 0.5rem;
  border-radius: var(--border-radius);
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  font-size: 0.8rem;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%);
  transition: opacity 0.15s ease;
}

.hs-pin:hover .hs-pin__label,
.hs-pin:focus .hs-pin__label,
.hs-pin.is-active .hs-pin__label {
  opacity: 1;
}

.hs-pin.is-pulsing .hs-pin__dot { animation: hs-pulse 1.2s ease-in-out; }

@keyframes hs-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.4); }
}

@media (prefers-reduced-motion: reduce) {
  .hs-pin.is-pulsing .hs-pin__dot { animation: none; }
  .hs-stage__poster { transition: none; }
}

.hs-car .hs-stage__hint {
  margin: 0.75rem 0 0;
  color: var(--text-secondary);
  font-size: 0.9rem;
}

/* Chips under the stage: one per pinned area, named as on the car, with a
   dot in its severity colour, then the two camera views. */
.hs-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.5rem 0 0.75rem;
}

.hs-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.35rem 0.8rem 0.35rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--background);
  color: var(--text-secondary);
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
}

/* The camera chips have no dot, so their padding is even. */
.hs-chip--view { padding-left: 0.8rem; }

.hs-chip__dot {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--hs-cosmetic);
}

.hs-chip--structural .hs-chip__dot { background: var(--hs-structural); }
.hs-chip--mot-critical .hs-chip__dot { background: var(--hs-mot); }

.hs-chip:not(:disabled):hover,
.hs-chip:focus-visible {
  border-color: var(--primary);
  color: var(--primary-dark);
}

/* Narrow screens: the chips are one row that scrolls sideways (wrapped, the
   longer names took up to 8 rows before the first card). The row bleeds to
   the screen edges so a chip cut off at the right shows there is more; the
   bleed is the content's inset from the viewport edge below 993px, the
   container's 1.5rem padding plus the article's 0.2rem, and the matching
   padding keeps the first chip in line with the text. */
@media (max-width: 992px) {
  .hs-chips {
    --hs-bleed: 1.7rem;
    flex-wrap: nowrap;
    margin-inline: calc(-1 * var(--hs-bleed));
    /* The block padding keeps focus rings inside the scroll box, which clips. */
    padding: 3px var(--hs-bleed);
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scroll-padding-inline: var(--hs-bleed);
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .hs-chips::-webkit-scrollbar { display: none; }

  .hs-chip {
    flex: none;
    scroll-snap-align: start;
  }
}

/* The picked area: white on --primary-dark (#571e00), 13:1. The dot keeps
   its colour. */
.hs-chip.is-active,
.hs-chip.is-active:hover,
.hs-chip.is-active:focus-visible {
  border-color: var(--primary-dark);
  background: var(--primary-dark);
  color: #fff;
}

/* The chips and "Show on model" buttons are disabled until the model loads,
   and stay so without JavaScript or when it fails: grey text and a dashed
   grey border (4.3:1 on the card, 4.5:1 on white), so the button still reads
   as a button but plainly not one to press yet. */
.hs-show:disabled,
.hs-chip:disabled {
  border-color: #767676;
  border-style: dashed;
  background: transparent;
  color: var(--text-light);
  cursor: not-allowed;
}

/* Scoped under .hs-car to outrank .article-content ul and li. */
.hs-car .hs-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
  margin: 0 0 0.5rem;
  padding: 0;
  list-style: none;
  font-size: 0.85rem;
}

.hs-car .hs-legend li {
  margin: 0;
}

.hs-legend li::before {
  content: "";
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: 0.4rem;
  border-radius: 50%;
  background: var(--hs-legend-colour);
}

.hs-car .hs-stage__caption {
  margin: 0 0 2rem;
  color: var(--text-light);
  font-size: 0.85rem;
}

.hs-credit {
  max-width: 760px;
  margin-top: 2rem;
  color: var(--text-light);
  font-size: 0.85rem;
}

.hs-faqs {
  max-width: 760px;
  margin: 1rem 0 2rem;
}

.hs-faq {
  border-bottom: 1px solid var(--border);
  padding: 0.75rem 0;
}

.hs-faq summary {
  font-weight: 600;
  cursor: pointer;
}

.hs-faq p {
  margin: 0.5rem 0 0;
}

.hs-footer-note {
  max-width: 760px;
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: 0.9rem;
}
