/*
  Revets - main.css

  Design: green/brass-on-white, matching the home-scout-white.html mockup palette and layout.
  Sources: 3_Projects/PartsPlatform/Branding/home-scout-white.html, 09-branding.md.

  Palette:
    --forest-900: #14301d  (header, hero, footer backgrounds)
    --forest-700: #21472c  (dark-band backgrounds, hover states)
    --forest-500: #2f6a40  (card accents, trust number chips, photo placeholders)
    --forest-300: #6f9a7c  (tertiary green, chip borders)
    --brass:      #c79a3a  (hero header border, eyebrow pills, CTA buttons, featured card border-top)
    --brass-dk:   #8a6315  (links and accents on white backgrounds)
    --white:      #ffffff  (page background, card fills)
    --mist:       #eef2ef  (icon chips, hover fill, subtle alternates)
    --line:       #e3e8e4  (card borders, subtle dividers)
    --ink:        #16201a  (primary body text)
    --ink-soft:   #545f58  (secondary body text)
    --shadow:     rgba(20, 48, 29, 0.08)

  Typography:
    - Headlines: "Arial Narrow", "Impact", sans-serif; uppercase, heavy weight.
    - Body: "Segoe UI", "Helvetica Neue", Arial, sans-serif.
    No external fonts loaded. All fonts are system stack fonts (CSP: font-src 'self').

  CSP notes:
    No inline styles, no external CDNs. All styling lives in this file.
    The strict CSP (style-src 'self') requires that every style declaration is
    in a .css file served from the same origin.

  Layout:
    - Sticky dark-green navigation bar with brass bottom border.
    - Full-width dark-green hero section with brass-stripe texture overlay.
    - White card sections for modules, trust steps, and featured generations.
    - Dark-green "band" sections (classic series, footer).
    - Max-width 1120px content container, 24px horizontal padding.
    - Mobile-first, responsive via media queries at 900px and 560px.
*/

/* ---------------------------------------------------------------------------
   Reset and base
   --------------------------------------------------------------------------- */

*, *::before, *::after {
  box-sizing: border-box;
}

html {
  /* Always reserve the vertical scrollbar gutter. Without this, short pages (no scrollbar) and
     tall pages (scrollbar) give different usable widths, so the centered layout shifts sideways
     when navigating between them. Reserving the gutter keeps every page the same width. */
  scrollbar-gutter: stable;
}

/* HTMX loading indicators. HTMX would normally inject these as an inline <style> on startup, but
   that is blocked by our CSP (style-src 'self'), so includeIndicatorStyles is disabled in the
   htmx-config meta tag and we define the rules here instead. */
.htmx-indicator {
  opacity: 0;
  transition: opacity 200ms ease-in;
}
.htmx-request .htmx-indicator {
  opacity: 1;
}
.htmx-request.htmx-indicator {
  opacity: 1;
}

:root {
  --forest-900: #14301d;
  --forest-700: #21472c;
  --forest-500: #2f6a40;
  --forest-300: #6f9a7c;
  --brass:      #c79a3a;
  --brass-dk:   #8a6315;
  --white:      #ffffff;
  --page:       #ffffff;
  --mist:       #eef2ef;
  --mist-2:     #f5f8f6;
  --line:       #e3e8e4;
  --line-strong: #c3cec6;
  --ink:        #16201a;
  --ink-soft:   #545f58;
  --shadow:     rgba(20, 48, 29, 0.08);
}

body {
  margin: 0;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  color: var(--ink);
  background: var(--page);
  line-height: 1.5;
  /* Sticky footer: the body is a full-viewport-tall column (header, main, footer). Pairing this
     with `main { flex: 1 }` pushes the footer to the bottom even on short pages. The messaging
     shell overrides this below with its own fixed-height flex layout (higher specificity). */
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

h1, h2, h3, h4 {
  font-family: "Arial Narrow", "Segoe UI", Impact, sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  font-weight: 800;
}

a {
  color: var(--brass-dk);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

/* ---------------------------------------------------------------------------
   Layout wrapper
   --------------------------------------------------------------------------- */

.wrap {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 24px;
}

/* ---------------------------------------------------------------------------
   Site navigation
   --------------------------------------------------------------------------- */

.site-header {
  background: var(--forest-900);
  position: sticky;
  top: 0;
  z-index: 100;
  border-bottom: 3px solid var(--brass);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 28px;
  height: 68px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: "Arial Narrow", Impact, sans-serif;
  text-transform: uppercase;
  font-weight: 800;
  letter-spacing: 0.02em;
  font-size: 27px;
  color: var(--white);
  text-decoration: none;
}
.brand:hover {
  text-decoration: none;
}

/* The skewed brass mark ("R" initial badge) - legacy, kept for any other usage */
.brand-mark {
  width: 36px;
  height: 36px;
  background: var(--brass);
  color: var(--forest-900);
  display: grid;
  place-items: center;
  font-weight: 900;
  font-size: 20px;
  transform: skewX(-8deg);
}
.brand-mark span {
  transform: skewX(8deg);
  display: inline-block;
}

/* The mascot mark used in the header/footer brand lock-up: a small circular Revet badge
   with a thin brass ring, replacing the old skewed "R". */
.brand-mark-img {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--white);
  /* Same treatment as the hero .mascot-img: white border with a brass ring outside it,
     scaled down for the small header/footer mark. */
  border: 2px solid #ffffff;
  box-shadow: 0 0 0 2px var(--brass);
  flex-shrink: 0;
}

.nav-links {
  display: flex;
  /* Baseline, not center: the Knowledge <details> carries a taller line box than the plain
     links, so centering leaves its label sitting a few px lower. */
  align-items: baseline;
  gap: 22px;
  margin-left: 8px;
}
.nav-links a {
  color: #cdd9d0;
  font-weight: 700;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.nav-links a:hover {
  color: var(--white);
  text-decoration: none;
}

.nav-spacer {
  flex: 1;
}

/* Academy dropdown in the main nav: the trigger dresses like the sibling nav links, and the
   panel opens left-aligned (the account menu's right:0 would push it off toward the logo). The
   panel links drop the nav's uppercase treatment so they match the account menu's panel. */
.nav-links .nav-menu-trigger {
  color: #cdd9d0;
  font-weight: 700;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.nav-links .nav-menu-trigger:hover {
  color: var(--white);
}
.nav-academy .nav-menu-panel {
  left: 0;
  right: auto;
}
.nav-links .nav-menu-panel a {
  text-transform: none;
  letter-spacing: normal;
}

.nav-cta {
  display: flex;
  align-items: center;
  gap: 14px;
}

/* Mobile navigation hamburger. Hidden on desktop; the max-width:900px block below reveals it
   at the same breakpoint that hides .nav-links and the desktop account/auth controls. */
.nav-mobile {
  display: none;
}
.nav-mobile-trigger {
  padding: 8px 6px;
  color: #cdd9d0;
}
.nav-mobile-trigger:hover {
  color: var(--white);
}
/* Three-bar hamburger drawn in CSS (no inline SVG needed). */
.nav-hamburger,
.nav-hamburger::before,
.nav-hamburger::after {
  display: block;
  width: 22px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
}
.nav-hamburger {
  position: relative;
}
.nav-hamburger::before,
.nav-hamburger::after {
  content: "";
  position: absolute;
  left: 0;
}
.nav-hamburger::before {
  top: -6px;
}
.nav-hamburger::after {
  top: 6px;
}
/* Small uppercase group heading inside a nav-menu panel (account menu sections).
   The top border draws the section boundary, so each group reads as its own block. */
.nav-menu-label {
  display: block;
  margin-top: 6px;
  padding: 10px 12px 3px;
  border-top: 1px solid var(--line-strong);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
/* Links that belong to a labelled group are indented under their heading. */
.nav-menu-panel a.nav-menu-sub {
  padding-left: 22px;
}
/* Thin rule separating the main-nav links from the account links in the mobile panel. */
.nav-menu-divider {
  display: block;
  height: 1px;
  margin: 8px 0;
  background: var(--line-strong);
}
/* The mobile panel can list many links; cap its height and let it scroll on short viewports. */
.nav-mobile-panel {
  max-height: calc(100vh - 90px);
  overflow-y: auto;
}
/* Language row inside the mobile panel: reset the top-bar switch's dark-header treatment
   (border/padding) and lay it out as a labelled row that matches the panel's link padding. */
.nav-mobile-lang {
  padding: 9px 12px;
  border-right: 0;
  gap: 10px;
}
.nav-mobile-lang-label {
  color: var(--ink-soft);
  font-weight: 700;
  font-size: 14px;
  margin-right: auto;
}
.nav-mobile-lang .lang-select {
  background: var(--white);
  color: var(--ink);
  border-color: var(--line);
}

/* Desktop auth cluster: sign-in link + join button. Space them so the two do not crowd. */
.nav-auth-desktop {
  display: inline-flex;
  align-items: center;
  gap: 18px;
}

/* Header navigation breakpoint. The full desktop row (nav links + language + auth) crowds the
   global search below ~1024px, collapsing it to a useless pill. So we switch to the hamburger
   here - wider than the 900px content breakpoint - leaving the top bar as logo + search +
   hamburger, which gives the search real width. Everything hidden here is folded into the menu. */
@media (max-width: 1024px) {
  /* .site-nav prefix keeps these ahead of the base .lang-switch { display:flex } rule that is
     defined later in the file (equal-specificity, later-wins would otherwise re-show it). */
  .site-nav .nav-links,
  .site-nav .nav-account-desktop,
  .site-nav .nav-auth-desktop,
  .site-nav .lang-switch-desktop {
    display: none;
  }
  .nav-mobile {
    display: inline-flex;
  }
  /* Inset the bars from the wrap edge so the icon is not jammed into the corner. */
  .nav-mobile-trigger {
    padding-right: 2px;
  }
}

/* Phone header. Logo + wordmark + search + up to four icons (chat, bell, bundle, hamburger) do
   not fit a ~375px row: the search collapsed to 0px for signed-in users and the icons still ran
   past the edge. So on phones the wordmark goes (the mascot alone carries the brand, and its alt
   text keeps the link's name), and the side padding and gaps tighten to the 16px phone gutter.
   That leaves the search ~135px signed in and ~200px signed out at 375px. */
@media (max-width: 560px) {
  .site-nav {
    gap: 10px;
    padding: 0 16px;
  }
  .site-nav .brand-word {
    display: none;
  }
  .nav-cta {
    gap: 8px;
  }
}

.link-quiet {
  color: #cdd9d0;
  font-weight: 700;
  text-transform: none;
  font-size: 13px;
  letter-spacing: 0.04em;
}
.link-quiet:hover {
  color: var(--white);
  text-decoration: none;
}

/* ---------------------------------------------------------------------------
   Account menu (navbar dropdown for logged-in users)

   Built on a native <details>/<summary> so it toggles without inline JS (CSP).
   The panel is absolutely positioned so opening it never shifts the navbar.
   --------------------------------------------------------------------------- */

.nav-menu {
  position: relative;
}

/* The trigger is a <summary>; strip the native disclosure marker. */
.nav-menu-trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.nav-menu-trigger::-webkit-details-marker {
  display: none;
}
.nav-menu-trigger::marker {
  content: "";
}

/* Caret that flips when the menu is open. */
.nav-menu-caret {
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  transition: transform 120ms ease;
}
.nav-menu[open] .nav-menu-caret {
  transform: rotate(180deg);
}

.nav-menu-panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 200px;
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 3px solid var(--brass);
  border-radius: 6px;
  box-shadow: 0 6px 20px var(--shadow);
  padding: 6px;
  z-index: 50;
}

.nav-menu-panel a {
  display: block;
  padding: 9px 12px;
  border-radius: 4px;
  color: var(--ink);
  font-weight: 700;
  font-size: 14px;
}
.nav-menu-panel a:hover {
  background: var(--mist);
  text-decoration: none;
}

/* Language selector: a data-driven dropdown (options loop the configured LANGUAGES in base.html).
   lang-switch.js submits on change and hides the .lang-go fallback; a right divider separates the
   switch from the Sign in / Join free actions. */
.lang-switch {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding-right: 14px;
  border-right: 1px solid rgba(255, 255, 255, 0.18);
}
.lang-select {
  background: var(--forest-700);
  color: #cdd9d0;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 4px;
  cursor: pointer;
  font: inherit;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 13px;
  letter-spacing: 0.04em;
  padding: 5px 8px;
}
.lang-select:hover {
  color: var(--white);
}

/* Set by lang-switch.js once JS is active, to hide the no-JS fallback submit button. */
.js-hidden {
  display: none;
}

/* ---------------------------------------------------------------------------
   Announcement banner
   --------------------------------------------------------------------------- */

.site-banner {
  background: var(--brass);
  color: var(--forest-900);
  text-align: center;
  padding: 10px 24px;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.02em;
}
.site-banner p {
  margin: 0;
}

/* ---------------------------------------------------------------------------
   Buttons
   --------------------------------------------------------------------------- */

.btn {
  display: inline-block;
  border: 0;
  cursor: pointer;
  font: inherit;
  /* Compact, sentence-case, weight 600 - deliberately not the old caps/800 "shout".
     The brand stays fancy and serious through the brass + forest palette, not loud buttons. */
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0;
  padding: 7px 13px;
  border-radius: 5px;
  text-decoration: none;
}
.btn:hover {
  text-decoration: none;
}

/* Brass CTA - primary action */
/* Compact variant for secondary spots (e.g. the browse filter, where autosubmit does the
   real work and the button is the no-JS fallback). */
.btn-small {
  padding: 7px 14px;
  font-size: 13px;
}

.btn-primary {
  background: var(--brass);
  color: var(--forest-900);
}
.btn-primary:hover {
  background: #b7892c;
}

/* Forest green secondary */
.btn-green {
  background: var(--forest-500);
  color: #fff;
}
.btn-green:hover {
  background: var(--forest-700);
}

/* Outline secondary - a quiet button for in-row actions (e.g. "Edit chapter"). The border is
   an inset shadow so it lines up with the zero-border solid buttons without a size jump. */
.btn-line {
  background: transparent;
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--line);
}
.btn-line:hover {
  background: var(--forest-500);
  color: #fff;
  box-shadow: inset 0 0 0 1px var(--forest-500);
}

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

.hero {
  background: linear-gradient(115deg, var(--forest-900) 0%, var(--forest-700) 52%, #2c5538 185%);
  color: #fff;
  position: relative;
  overflow: hidden;
}

/* Brass diagonal stripe texture overlay (pure CSS, no image, no inline style) */
.hero::after {
  content: "";
  position: absolute;
  top: -20%;
  right: -8%;
  width: 46%;
  height: 160%;
  background: repeating-linear-gradient(
    125deg,
    rgba(199, 154, 58, 0) 0 38px,
    rgba(199, 154, 58, 0.12) 38px 44px
  );
  transform: skewX(-12deg);
  pointer-events: none;
}

.hero-grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: 30px;
  align-items: center;
  /* Vertical-only padding (longhand) so .wrap's horizontal 24px gutter still applies and the hero
     content lines up with the header nav and the rest of the site, instead of sitting flush. */
  padding-top: 58px;
  padding-bottom: 66px;
  position: relative;
  z-index: 1;
}

/* Brass eyebrow kicker above hero headline.
   Deliberately NOT a filled pill: the solid brass pill is reserved for .btn-primary (the CTA),
   so the eyebrow (a non-clickable label) is a quiet text kicker with a short leading rule. This
   keeps labels and buttons visually distinct. The leading rule is drawn with ::before so no
   template markup is needed. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  color: var(--brass);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 12px;
  font-weight: 700;
}
.eyebrow::before {
  content: "";
  width: 22px;
  height: 2px;
  background: var(--brass);
  flex: 0 0 auto;
}

.hero h1 {
  font-size: 62px;
  line-height: 0.95;
  margin: 16px 0 14px;
  text-transform: uppercase;
}

/* Brass accent span inside the h1 */
.hero h1 .accent {
  color: var(--brass);
}

.hero .lead {
  font-size: 19px;
  color: #dde7df;
  max-width: 29em;
  margin: 0 0 26px;
}

.hero-cta-group {
  display: flex;
  gap: 14px;
  align-items: center;
  flex-wrap: wrap;
}

/* Mascot placeholder (circular badge) */
.mascot-placeholder {
  width: 100%;
  max-width: 280px;
  margin: 0 auto;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 35%, var(--forest-500), var(--forest-900));
  border: 6px solid #ffffff;
  box-shadow: 0 0 0 4px var(--brass), 0 20px 40px rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 8px;
  color: var(--brass);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  text-align: center;
  padding: 24px;
}

/* Real mascot image, framed in the SAME circular badge (white border + brass ring + shadow) as the
   original placeholder. object-fit:cover keeps it circular; the corner crop also hides the source
   asset's corner watermark. Swap for a transparent final asset later. */
.mascot-img {
  display: block;
  width: 100%;
  max-width: 280px;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  margin: 0 auto;
  border-radius: 50%;
  border: 6px solid #ffffff;
  box-shadow: 0 0 0 4px var(--brass), 0 20px 40px rgba(0, 0, 0, 0.4);
}

/* ---------------------------------------------------------------------------
   Home hero search box (Parts + By-car tabs)
   --------------------------------------------------------------------------- */
.hero-search-wrap {
  position: relative;
  z-index: 1;
  padding-bottom: 58px;
}
.hero-search {
  /* Full width within the hero content wrap. */
  width: 100%;
}
.hero-search-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 14px;
}
.hero-search-tab {
  border: 0;
  cursor: pointer;
  font: inherit;
  font-weight: 700;
  font-size: 14px;
  padding: 8px 20px;
  border-radius: 22px;
  background: rgba(255, 255, 255, 0.12);
  color: #cdd9d0;
  transition: background 0.12s ease, color 0.12s ease;
}
.hero-search-tab:hover {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
}
.hero-search-tab.is-active {
  background: #fff;
  color: var(--forest-900);
}
.hero-search-bar {
  background: #fff;
  border-radius: 12px;
  padding: 16px;
  display: flex;
  gap: 14px;
  align-items: flex-end;
  flex-wrap: wrap;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.25);
}
/* The generic [hidden] rule is display:none, but the flex declaration above would override it,
   so the inactive panel needs this explicit hide. */
.hero-search-bar[hidden] {
  display: none;
}
.hero-search-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-width: 150px;
}
.hero-search-field-grow {
  flex: 2;
}
.hero-search-field label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
}
.hero-search-field input,
.hero-search-field select {
  font: inherit;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 10px 12px;
}
.hero-search-field input:focus,
.hero-search-field select:focus {
  outline: 2px solid var(--forest-500);
  border-color: transparent;
}
.hero-search-btn {
  /* Taller than the base .btn so it lines up with the search inputs it sits beside. */
  padding: 10px 20px;
}
@media (max-width: 560px) {
  .hero-search-field {
    flex: 1 1 100%;
  }
  .hero-search-btn {
    width: 100%;
  }
}

/* Wordmark inside the mascot placeholder circle */
.mascot-wordmark {
  font-size: 36px;
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #fff;
}

.mascot-placeholder .mascot-note {
  font-size: 11px;
  color: var(--forest-300);
  line-height: 1.4;
}

/* ---------------------------------------------------------------------------
   Section scaffolding
   --------------------------------------------------------------------------- */

section {
  padding: 20px 0px 50px 0px ;
}

.section-head {
  text-align: center;
  max-width: 42em;
  margin: 0 auto 38px;
}
.section-head h2 {
  font-size: 38px;
  margin: 0 0 10px;
}
.section-head h2 .accent {
  color: var(--brass-dk);
}
.section-head p {
  color: var(--ink-soft);
  font-size: 17px;
  margin: 0;
  text-transform: none;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400;
}

/* Dark-green section bands */
.band {
  background: var(--forest-900);
  color: #fff;
}
.band .section-head h2 .accent {
  color: var(--brass);
}
.band .section-head p {
  color: #c3d3c7;
}

/* ---------------------------------------------------------------------------
   Module cards (4-column, white with green top border)
   --------------------------------------------------------------------------- */

.modules-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}

/* Two-up centred variant: use when a section has only two cards, so they sit
   centred instead of hanging off the left of the 4-column track. The base
   .modules-grid media queries still collapse it to 2 then 1 column. */
.modules-grid-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: 760px;
  margin-inline: auto;
}

/* Big-link row: large section links used as a closing navigation CTA. Sits on
   a dark .band, so links read white and turn brass on hover. */
.big-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px 36px;
}
.big-link {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: 0.01em;
  color: #fff;
  text-decoration: none;
  transition: color 0.12s ease;
}
.big-link:hover {
  color: var(--brass);
  text-decoration: none;
}

.card {
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 4px solid var(--forest-500);
  border-radius: 6px;
  padding: 24px 20px;
  box-shadow: 0 1px 3px var(--shadow);
  transition: transform 0.12s ease, border-color 0.12s ease, box-shadow 0.12s ease;
}
.card:hover {
  transform: translateY(-3px);
  border-top-color: var(--brass);
  box-shadow: 0 12px 26px var(--shadow);
}

/* Card used as a link: keep the plain card look, no underline or link color */
.card-link {
  display: block;
  color: inherit;
  text-decoration: none;
}

.card-icon {
  width: 44px;
  height: 44px;
  border-radius: 6px;
  background: var(--mist);
  display: grid;
  place-items: center;
  font-size: 22px;
  margin-bottom: 14px;
}
.card h3 {
  margin: 0 0 6px;
  font-size: 19px;
  /* A card always sits on a light background, so pin its heading to ink.
     Without this the heading inherits the parent color and turns white
     when a card is placed inside a dark .band section. */
  color: var(--ink);
}
.card p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 14.5px;
  text-transform: none;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400;
}

/* ---------------------------------------------------------------------------
   Featured generation shelf
   --------------------------------------------------------------------------- */

.featured-grid {
  --grid-gap: 16px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--grid-gap);
}

/*
  Featured generation cards are non-linking display cards.
  TODO: once the wiki generation page view exists (Phase 1), replace
  these divs with <a href="{% url 'wiki:generation' ... %}"> links.
*/
.gen-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 4px solid var(--brass);
  border-radius: 6px;
  padding: 0;
  overflow: hidden;
  box-shadow: 0 1px 3px var(--shadow);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.gen-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 26px var(--shadow);
}

/* Green photo placeholder area. A fixed 3:2 frame (the convention on enthusiast car sites such as
   BaT, Cars & Bids and Collecting Cars) instead of a fixed height, so every card has the same shape
   at every column width and a 4:3 phone photo loses only a thin strip to the cover crop. */
.gen-card-image {
  aspect-ratio: 3 / 2;
  background: linear-gradient(135deg, var(--forest-500) 0%, var(--forest-900) 135%);
  display: grid;
  place-items: center;
  color: rgba(255, 255, 255, 0.5);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 700;
}

.gen-card-body {
  padding: 14px 16px;
}

.gen-card-brand {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  margin: 0 0 2px;
}

.gen-card-name {
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 800;
  font-size: 20px;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  margin: 0 0 4px;
  color: var(--ink);
}

.gen-card-meta {
  color: var(--ink-soft);
  font-size: 13px;
  margin: 0;
}

/* ---------------------------------------------------------------------------
   Watch/follow/save toggle - ONE shared button (components/_watch_button.html) for all four
   targets (listing, car, wiki page, user). Same classes everywhere; two layouts share them:
   the compact variant (.watch-btn-compact) is a floating icon-only circle over a card
   thumbnail, the default is a pill (heart + label) used top-right of a hero (.page-hero-watch).
   .gen-card-wrap gives the compact button something to sit on top of without touching
   .gen-card's own overflow:hidden box.
   --------------------------------------------------------------------------- */
.gen-card-wrap {
  position: relative;
}

/* .share-btn (the Share pill, components/_share_button.html) shares the Watch pill's look. */
.watch-btn,
.share-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.92);
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  text-decoration: none;
  transition: color 0.12s ease, background 0.12s ease, border-color 0.12s ease, transform 0.12s ease;
}
.watch-btn:hover,
.share-btn:hover {
  transform: scale(1.03);
}
.watch-btn .watch-btn-heart {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.watch-btn.is-active {
  color: #fff;
  background: var(--forest-500);
  border-color: var(--forest-500);
}
.watch-btn.is-active .watch-btn-heart {
  fill: currentColor;
}
.watch-btn:focus-visible,
.share-btn:focus-visible {
  outline: 2px solid var(--forest-500);
  outline-offset: 2px;
}

/* Compact: icon-only floating circle over a card thumbnail (browse/watchlist listing cards). */
.watch-btn-compact {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
  width: 32px;
  height: 32px;
  padding: 0;
  display: grid;
  place-items: center;
}
.watch-btn-compact .watch-btn-heart {
  width: 18px;
  height: 18px;
}

/* Watchlist listings table: the compact heart sits in a normal cell, not floating over a thumb. */
.watchlist-unwatch-cell .watch-btn-compact {
  position: static;
}

.listing-watch-count {
  color: var(--ink-soft);
}

/* Top-right hero placement (listing detail, garage car detail, wiki generation page, public
   profile) - .page-hero .wrap (and the wiki generation hero's own .wrap.page-hero-inner) are
   already position:relative, so this anchors to the hero's own box. */
/* The hero control row (the Share control left of the Watch/Follow/Save button) sits on the
   eyebrow line: the title starts right under it and can run the full width (a long listing or
   issue title), so any lower and the pills covered it. */
.page-hero-watch {
  position: absolute;
  top: 0;
  right: 24px;
  z-index: 3;
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
/* A hero with a photo on its right (the wiki generation, wheel style and wiki home heroes): the
   row sits on the photo's top corner instead, as the generation page's Save button always did;
   the title column ends before the photo, so it never reaches the row there. */
@media (min-width: 561px) {
  .page-hero--with-image .page-hero-watch,
  .wheel-hero--has-photo .page-hero-watch,
  .wiki-hero-inner:has(> .wiki-hero-image) > .page-hero-watch {
    top: 20px;
  }
}
/* The brand hero's small logo tile (right of the text from 901px) would disappear under the row:
   it starts below the row. Narrower, the logo stacks above the text on the left, clear of it. */
@media (min-width: 901px) {
  .wiki-hero-inner > .page-hero-watch ~ .wiki-hero-logo {
    margin-top: 44px;
  }
}
/* A hero with a bottom-right CTA lays its wrap out as a grid and puts every child in column 1;
   the row must stay positioned against the whole wrap, not that column. */
.page-hero .wrap:has(.page-hero-cta) > .page-hero-watch {
  grid-column: auto;
  grid-row: auto;
}
/* Very narrow screens drop the Share label (the icon stays) so the row clears the eyebrow text. */
@media (max-width: 359px) {
  .page-hero-watch .share-btn-label {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
   Share control (components/_share_button.html, static/js/share.js): the Share pill in the hero
   control row and its Facebook / WhatsApp / Copy link menu. A <details>: the summary is the pill,
   the menu drops down under it, right-aligned with it.
   --------------------------------------------------------------------------- */
.share-control {
  position: relative;
}
.share-btn {
  list-style: none;
  user-select: none;
}
.share-btn::-webkit-details-marker {
  display: none;
}
.share-btn::marker {
  content: "";
}
.share-control[open] > .share-btn {
  color: var(--ink);
  border-color: var(--line-strong);
}
.share-btn .share-btn-icon {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
}
.share-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 20;
  min-width: 190px;
  padding: 6px 0;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 8px 24px var(--shadow);
}
.share-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 14px;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  line-height: 1.2;
  text-align: left;
  cursor: pointer;
}
.share-menu-item:hover,
.share-menu-item:focus-visible {
  background: var(--mist);
  text-decoration: none;
}
.share-menu-item:focus-visible {
  outline: 2px solid var(--forest-500);
  outline-offset: -2px;
}
/* Two classes: the generic .icon rule further down sets 1em and would win at equal weight. */
.share-menu .share-menu-icon {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}
.share-menu-icon-facebook {
  color: #1877f2;
}
.share-menu-icon-whatsapp {
  color: #25a35a;
}
.share-menu-icon-link {
  color: var(--forest-500);
}
/* The off-screen field share.js copies from when the Clipboard API is not available. */
.share-copy-field {
  position: fixed;
  top: 0;
  left: -9999px;
  opacity: 0;
}

/* Denormalised "N followers" aggregate shown to the owner instead of the follow button
   (GarageCar.follower_count / accounts.User.follower_count) - same look as listing-watch-count. */
.follower-count-badge {
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------------------
   Watchlist page: tabs (reuses .profile-tabs/.profile-tab), label filter chips and the
   per-row inline label editor (32-watchlist-and-requests.md "Watch" increment 2).
   --------------------------------------------------------------------------- */
.watchlist-label-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 14px 0;
}
/* Always rendered even with zero labels (core/_watch_label_chips.html) so an hx-swap-oob
   response always has a real id to land on - collapse its margin when there is nothing in it. */
.watchlist-label-chips:empty {
  margin: 0;
}
.watchlist-label-chip {
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
}
.watchlist-label-chip.is-active {
  background: var(--forest-500);
  color: #fff;
  border-color: var(--forest-500);
}

.watchlist-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.watch-label-form {
  display: flex;
  gap: 6px;
  align-items: center;
}
.watch-label-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
  font-size: 12px;
}

/* Small square icon button - the site's one control for manage actions (edit, delete, publish,
   hide, archive, remove) in tables, lists, comments and detail heroes. Rendered by
   components/_icon_action.html; a real <button> or <a>, keyboard-reachable, visible focus ring. */
.icon-btn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #fff;
  color: var(--ink-soft);
  font: inherit;
  text-decoration: none;
  cursor: pointer;
}
.icon-btn:hover {
  color: var(--forest-500);
  border-color: var(--forest-500);
  text-decoration: none;
}
.icon-btn:focus-visible {
  outline: 2px solid var(--forest-500);
  outline-offset: 2px;
}
.icon-btn svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Colour modifiers: go = publish / make visible, danger = delete / remove. */
.icon-btn-go {
  color: var(--forest-500);
}
.icon-btn-danger {
  color: #8a1c16;
}
.icon-btn-danger:hover {
  color: #fff;
  background: #8a1c16;
  border-color: #8a1c16;
}
/* A row of icon buttons; forms inside it (POST actions) sit inline with no margin. */
.icon-actions {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.icon-actions form {
  display: inline-flex;
  margin: 0;
}
/* On the dark page hero: a solid button (green, red for danger), slightly larger to match hero
   buttons; on hover it turns into the translucent brass outline. */
.page-hero .icon-btn {
  width: 32px;
  height: 32px;
  background: var(--forest-500);
  border-color: var(--forest-500);
  color: #fff;
}
.page-hero .icon-btn svg {
  width: 16px;
  height: 16px;
}
.page-hero .icon-btn:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: #b7892c;
  color: #fff;
}
.page-hero .icon-btn-danger {
  background: #8a1c16;
  border-color: #8a1c16;
  color: #fff;
}
.page-hero .icon-btn-danger:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: #b7892c;
  color: #f0a8a0;
}
/* Hover/focus tooltip: data-tip holds the label (aria-label carries it for screen readers).
   It opens ABOVE the button by default. Inside .table-wrap, the notifications list and a bundle
   group it opens to the LEFT instead, vertically centred, because those containers clip anything
   above the row. */
.icon-btn[data-tip] {
  position: relative;
}
.icon-btn[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  padding: 3px 8px;
  border-radius: 4px;
  background: var(--forest-900);
  color: #fff;
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: normal;
  text-transform: none;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s ease 0.15s;
  z-index: 5;
}
.table-wrap .icon-btn[data-tip]::after,
.notif-item-actions .icon-btn[data-tip]::after,
.bundle-group .icon-btn[data-tip]::after {
  bottom: auto;
  left: auto;
  right: calc(100% + 6px);
  top: 50%;
  transform: translateY(-50%);
}
.page-hero .icon-btn[data-tip]::after {
  background: #fff;
  color: var(--ink);
}
.icon-btn[data-tip]:hover::after,
.icon-btn[data-tip]:focus-visible::after {
  opacity: 1;
}

/* The label editor's read-only state: a plain-text chip plus the pencil edit button. */
.watch-label-display {
  display: flex;
  align-items: center;
  gap: 6px;
}
.watch-label-chip {
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  color: var(--ink-soft);
}

.watchlist-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  display: grid;
  place-items: center;
  background: var(--forest-500);
  color: #fff;
  font-weight: 800;
}

/* ---------------------------------------------------------------------------
   Saved searches: the browse-page "Save this search" button, its confirmation, the inline
   rename/alert controls on the watchlist's "Saved searches" tab and the "N new" match badge
   (32-watchlist-and-requests.md "SavedSearch" / "The matcher").
   --------------------------------------------------------------------------- */
.save-search-form {
  display: inline-flex;
}
.save-search-confirm {
  font-size: 13px;
  color: var(--ink-soft);
}
.save-search-confirm a {
  margin-left: 6px;
}

.saved-search-name-form {
  display: flex;
  gap: 6px;
  align-items: center;
}
.saved-search-name-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
  font-size: 13px;
}

.saved-search-alert-form {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
}
.saved-search-alert-select {
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
  font-size: 12px;
}
.saved-search-alert-error {
  margin: 0;
  font-size: 12px;
  color: #7a2f2f;
}
.saved-search-price-label {
  font-size: 11px;
  color: var(--ink-soft);
}
.saved-search-price-input {
  width: 7em;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
  font-size: 12px;
}

/* The unseen-match count next to a saved search's name (core.views builds it with ONE
   aggregate query for the page). Reads as a badge, not as a link. */
.saved-search-new-badge {
  display: inline-block;
  margin-top: 4px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--brass);
  color: var(--forest-900);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   Icons (inline SVG sprite)
   components/_icon_sprite.html defines the <symbol>s; components/_icon.html emits
   <svg class="icon"><use href="#icon-NAME"></svg>. Colour comes from currentColor,
   size defaults to 1em - override via a wrapper or an extra class (e.g. .nav-bell-icon).
   --------------------------------------------------------------------------- */

.svg-sprite {
  display: none;
}

.icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: middle;
  flex-shrink: 0;
}

/* ---------------------------------------------------------------------------
   Trust steps row
   --------------------------------------------------------------------------- */

.trust-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 22px;
}

.trust-item {
  text-align: center;
}

/* Skewed numbered chip. Used by the How-it-works step sequence, where the
   1-2-3-4 order is meaningful (find -> offer -> confirm -> rate). */
.trust-num {
  width: 46px;
  height: 46px;
  margin: 0 auto 10px;
  background: var(--forest-500);
  color: #fff;
  border-radius: 6px;
  display: grid;
  place-items: center;
  font-weight: 900;
  font-size: 22px;
  transform: skewX(-8deg);
  font-family: "Arial Narrow", Impact, sans-serif;
}
.trust-num span {
  transform: skewX(8deg);
  display: inline-block;
}

/* Home "guarantees" variant: the four points are parallel promises, not steps,
   so they drop the step numbers for subject-specific line icons and become
   left-aligned cards that lift and turn brass on hover. */
.trust-grid--pillars {
  gap: 16px;
}
.trust-grid--pillars .trust-item {
  text-align: left;
  background: linear-gradient(180deg, var(--forest-700), transparent);
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 10px;
  padding: 24px 22px;
  transition: transform 0.25s ease, border-color 0.25s ease;
}
.trust-grid--pillars .trust-item:hover {
  transform: translateY(-4px);
  border-color: var(--brass);
}

/* Line icon: currentColor keeps the SVG brass without any inline style. */
.trust-icon {
  display: block;
  width: 38px;
  height: 38px;
  margin-bottom: 16px;
  color: var(--brass);
}
.trust-icon svg {
  width: 100%;
  height: 100%;
  display: block;
}

.trust-item h3 {
  font-size: 16px;
  margin: 0 0 6px;
}
.trust-item p {
  margin: 0;
  /* Light green for readable contrast on the dark forest band, matching the
     band's intro paragraph. */
  color: #c3d3c7;
  font-size: 14px;
  text-transform: none;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400;
}

/* ---------------------------------------------------------------------------
   Classics / series chip cloud (on dark band)
   --------------------------------------------------------------------------- */

.chip-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
}

.chip {
  background: var(--forest-700);
  border: 1px solid var(--forest-500);
  color: #fff;
  border-radius: 4px;
  padding: 9px 16px;
  font-weight: 700;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.chip.chip-active {
  background: var(--brass);
  border-color: var(--brass);
  color: var(--forest-900);
}
.chip.chip-next {
  background: transparent;
  border-color: var(--brass);
  color: var(--brass);
}

/* Marque-by-marque layout (Option A): one row per brand, label beside its chips.
   The label column is fixed-width and right-aligned on wide screens so the chip
   rows line up; on narrow screens the row stacks and the label left-aligns. */
.marque-clusters {
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
}
.marque-cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  justify-content: center;
}
.marque-label {
  min-width: 96px;
  text-align: right;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--brass-dk);
}
.marque-chips {
  justify-content: flex-start;
}
@media (max-width: 640px) {
  .marque-label {
    min-width: 0;
    text-align: center;
    width: 100%;
  }
}

.band-note {
  text-align: center;
  color: #c3d3c7;
  margin-top: 22px;
  font-size: 15px;
}

/* On white sections the note uses the soft ink colour instead */
.band-note-light {
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------------------
   HTMX demo section (preserved for Stage 3 test compatibility)
   --------------------------------------------------------------------------- */

.htmx-demo {
  margin-top: 2rem;
  padding: 24px;
  background: var(--mist-2);
  border: 1px solid var(--line);
  border-radius: 6px;
}

/* ---------------------------------------------------------------------------
   Site footer
   --------------------------------------------------------------------------- */

.site-footer {
  background: var(--forest-900);
  color: #c3d3c7;
  padding: 46px 0 30px;
  border-top: 3px solid var(--brass);
}

.site-footer a {
  color: #eef4ef;
}
.site-footer a:hover {
  color: var(--white);
}

/* ---------------------------------------------------------------------------
   Legal flatpages (templates/flatpages/default.html). Before this block the
   pages had NO styles at all and no .wrap, so the prose sat flush against the
   viewport edge and ran the full window width.

   Layout: prose first in the source, contents rail second, but the grid places
   the rail on the right. Screen readers and no-CSS browsers get the document
   before the navigation.
   --------------------------------------------------------------------------- */
.legal-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 210px;
  gap: 48px;
  align-items: start;
}
/* Pages with too few sections for a rail (the legal notice) still get a measure. */
.legal-layout-narrow {
  grid-template-columns: minmax(0, 1fr);
}

.legal-body {
  /* The single biggest legibility win: cap the line length. Prose at 1400px is
     unreadable no matter how good the typography is. */
  max-width: 62ch;
  font-size: 16px;
  line-height: 1.75;
}
.legal-body p {
  margin: 0 0 18px;
}
.legal-body h2 {
  font-size: 21px;
  color: var(--forest-900);
  margin: 34px 0 12px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  /* Clears the sticky site header (~71px) when the TOC scrolls to a heading, with some air. */
  scroll-margin-top: 90px;
}
.legal-body h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}
.legal-body h3 {
  font-size: 17px;
  color: var(--forest-700);
  margin: 24px 0 8px;
}
.legal-body ul {
  margin: 0 0 18px;
  padding-left: 22px;
}
.legal-body li {
  margin-bottom: 8px;
}
.legal-body a {
  color: var(--forest-500);
}

.legal-toc {
  position: sticky;
  top: 20px;
  font-size: 13px;
  border-left: 2px solid var(--line);
  padding-left: 14px;
}
.legal-toc-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  margin: 0 0 10px;
}
.legal-toc ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.legal-toc a {
  color: var(--ink-soft);
  text-decoration: none;
  line-height: 1.4;
  display: block;
}
.legal-toc a:hover {
  color: var(--forest-500);
  text-decoration: underline;
}
/* The section in view (static/js/section-menu.js). */
.legal-toc a.is-current {
  color: var(--forest-700);
  font-weight: 700;
}
.legal-toc-extra {
  margin: 16px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 12px;
}

.legal-siblings {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-top: 44px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}
.legal-siblings-label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  font-weight: 700;
}
.legal-siblings a {
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  padding: 5px 11px;
  font-size: 13px;
  color: var(--forest-900);
  text-decoration: none;
}
.legal-siblings a:hover {
  border-color: var(--forest-500);
  color: var(--forest-500);
}

/* Below this the rail has nowhere useful to sit, so it moves above the prose as a
   plain list. Media queries add no specificity, so this must stay BELOW the rules
   above - the same trap the footer grid hit. */
@media (max-width: 860px) {
  .legal-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
  }
  .legal-toc {
    position: static;
    order: -1;
    border-left: 0;
    border-bottom: 1px solid var(--line);
    padding-left: 0;
    padding-bottom: 16px;
  }
  .legal-toc ul {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px 16px;
  }
}

.footer-grid {
  /* Five columns: the brand block (with the About link) plus Explore, Sell, Help, Legal.
     The brand gets extra width because it carries a paragraph, Legal a little because
     "Community guidelines" and "Report illegal content" are the longest labels. A sixth
     column means re-tuning these tracks, not appending to them. */
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1fr 1.3fr;
  gap: 24px;
}

/* The column headings are written in sentence case in the source and translations; the capitals
   are presentation only, so screen readers read a word instead of spelling out letters. */
.site-footer h4 {
  color: #fff;
  margin: 0 0 12px;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.site-footer ul {
  list-style: none;
  padding: 0;
  margin: 0;
}
.site-footer li {
  margin-bottom: 8px;
  font-size: 14px;
}

.footer-brand p {
  font-size: 14px;
  max-width: 26em;
  color: #aebfb2;
  text-transform: none;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400;
}

.footer-brand-link {
  margin-bottom: 12px;
  display: inline-flex;
}

.footer-bottom {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 30px;
  padding-top: 20px;
  border-top: 1px solid var(--forest-700);
  font-size: 13px;
  color: #8ea394;
}
.footer-spacer {
  flex: 1;
}
/* Book XII Art. XII.6 identity line: present on every page, muted so it informs
   without competing with the footer nav. Wraps to its own line on narrow screens.
   It takes the .footer-bottom colour (5.3:1 on forest-900): the earlier, dimmer #7d9184 was
   4.25:1, under the WCAG AA 4.5:1 minimum for 13px text, on the one line the law wants easy
   to find. */
.footer-legal-id {
  color: inherit;
}
.footer-legal-id a {
  color: inherit;
  text-decoration: underline;
}
.footer-legal-id a:hover {
  color: #c9d8cd;
}
/* Media queries carry no extra specificity, so these MUST stay below the base
   .footer-grid rule above. Putting them with the other 1024px rules near the top of the
   file silently loses to later-wins. */
@media (max-width: 1024px) {
  /* Five columns stop fitting: the brand takes its own full-width row and the four link
     columns share the rest evenly. */
  .footer-grid {
    grid-template-columns: repeat(4, 1fr);
  }
  .footer-brand {
    grid-column: 1 / -1;
  }
}

@media (max-width: 640px) {
  .footer-bottom {
    flex-wrap: wrap;
    gap: 8px;
  }
  .footer-legal-id {
    flex-basis: 100%;
  }
}

/* ---------------------------------------------------------------------------
   Main content area
   --------------------------------------------------------------------------- */

main {
  /* Grow to absorb the leftover viewport height so the footer sits at the bottom on short pages. */
  flex: 1;
}

/* ---------------------------------------------------------------------------
   Responsive breakpoints
   --------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .hero-grid {
    grid-template-columns: 1fr;
  }
  .mascot-img {
    order: -1;
    max-width: 200px;
  }
  .modules-grid,
  .trust-grid,
  .featured-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  /* Two link columns from here down to phone width: Explore | Sell, then Help | Legal. One
     column made the phone footer about 1,200px tall. minmax(0, 1fr) lets a long label wrap
     instead of widening its column. */
  .footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .footer-brand {
    grid-column: 1 / -1;
  }
  .hero h1 {
    font-size: 46px;
  }
  .section-head h2 {
    font-size: 30px;
  }
}

@media (max-width: 560px) {
  .modules-grid,
  .trust-grid,
  .featured-grid {
    grid-template-columns: 1fr;
  }
  .hero-cta-group {
    flex-direction: column;
    align-items: flex-start;
  }
  .hero h1 {
    font-size: 36px;
  }
}

/* ---------------------------------------------------------------------------
   Wiki - gen-card as a link (Phase 1: home featured cards are now <a> elements)
   --------------------------------------------------------------------------- */

.gen-card-link {
  display: block;
  text-decoration: none;
  color: inherit;
}
.gen-card-link:hover {
  text-decoration: none;
  color: inherit;
}

/* ---------------------------------------------------------------------------
   Wiki pages
   --------------------------------------------------------------------------- */

/* Breadcrumb navigation strip */
.wiki-breadcrumb {
  background: var(--mist);
  border-bottom: 1px solid var(--line);
  padding: 10px 0;
  font-size: 13px;
}
.breadcrumb-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
}
.breadcrumb-item {
  display: flex;
  align-items: center;
  gap: 4px;
}
.breadcrumb-item a {
  color: var(--brass-dk);
  font-weight: 600;
}
.breadcrumb-item [aria-current="page"] {
  color: var(--ink-soft);
  font-weight: 600;
}
.breadcrumb-sep {
  color: var(--ink-soft);
}


/* Page-level hero for brand / model / generation / trim pages */
.page-hero {
  background: var(--forest-900);
  color: #fff;
  padding: 38px 0 34px;
  border-bottom: 3px solid var(--brass);
}
.page-hero .eyebrow {
  /* Inherits the text-kicker look from the base .eyebrow rule; only the bottom spacing differs
     here since there is no longer any pill padding to sit above the headline. */
  font-size: 11px;
  margin-bottom: 10px;
}
.page-hero h1 {
  font-size: 46px;
  line-height: 0.95;
  margin: 8px 0 10px;
  color: #fff;
}
.page-hero h1 .accent {
  color: var(--brass);
}
.page-subtitle {
  font-size: 18px;
  color: #c3d3c7;
  margin: 0 0 10px;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400;
  text-transform: none;
}
.wiki-meta-line {
  font-size: 14px;
  color: #c3d3c7;
  margin: 0 0 4px;
  text-transform: none;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400;
}
.wiki-meta-line strong {
  color: #fff;
}
.page-hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin-top: 8px;
}
/* Hero call-to-action (Write a tutorial, Suggest an issue, Log in to create...): sits at the
   bottom-right of the green hero on regular screens, in the normal flow on narrow ones. */
.page-hero .wrap {
  position: relative;
}
@media (min-width: 700px) {
  /* When the hero carries a bottom-right CTA, lay the wrap out as two columns - flexible text on
     the left, the CTA on the right - so a long headline or subtitle can never run underneath the
     button. It self-adjusts to the CTA's width (no fixed reserve to keep in sync). The explicit
     rows give the CTA something to span so align-self:end pins it to the text block's bottom;
     spare rows are 0-height. Heroes without a CTA (and any width below 700px) keep normal flow. */
  .page-hero .wrap:has(.page-hero-cta) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: repeat(8, auto);
    align-items: end;
    column-gap: 28px;
  }
  .page-hero .wrap:has(.page-hero-cta) > * {
    grid-column: 1;
  }
  .page-hero .wrap:has(.page-hero-cta) > .page-hero-cta {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: end;
    margin-top: 0;
  }
}
/* Hero action button row (See N in the Garage): normal flow under the hero meta line. */
.page-hero-actions {
  margin-top: 16px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.page-hero-meta-item {
  font-size: 14px;
  color: #c3d3c7;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  text-transform: none;
}
.page-hero-meta-item strong {
  color: #fff;
}

/* Hero with a primary image: text left, image right filling the hero height.
   align-items: stretch makes the image column match the text column height, and the image
   itself is height:100% with object-fit:cover so it fills that height (focal-point.js sets
   object-position from the image focal data). Falls back to text-only when no image. */
.page-hero-inner {
  display: flex;
  align-items: stretch;
  gap: 32px;
}
.page-hero-text {
  flex: 1 1 auto;
  align-self: center;
  min-width: 0;
}
.page-hero-image {
  flex: 0 0 40%;
  border-radius: 4px;
  overflow: hidden;
}
.page-hero-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Hero photo as a jump link to the gallery slideshow */
.page-hero-image--link {
  position: relative;
  display: block;
  cursor: pointer;
}
.page-hero-image--link img {
  transition: transform 0.3s ease;
}
.page-hero-image--link:hover img {
  transform: scale(1.03);
}
.page-hero-image-badge {
  position: absolute;
  bottom: 10px;
  right: 10px;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  pointer-events: none;
}

/* Main wiki body container */
.page-body {
  padding-top: 36px;
  padding-bottom: 56px;
}

/* Section headings within a wiki page */
.wiki-section {
  margin-bottom: 44px;
}
.wiki-section-title {
  font-size: 22px;
  margin: 0 0 16px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--brass);
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.wiki-section-prose {
  max-width: 60em;
}
.wiki-prose {
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink);
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400;
  text-transform: none;
}
.wiki-prose p {
  margin: 0 0 1em;
}

/* Skeleton notice - shown when a node has no prose */
.wiki-skeleton-notice {
  background: var(--mist);
  border: 1px solid var(--line);
  border-left: 4px solid var(--brass);
  border-radius: 4px;
  padding: 16px 20px;
  margin-bottom: 32px;
  font-size: 15px;
  color: var(--ink-soft);
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  text-transform: none;
  font-weight: 400;
}
.wiki-skeleton-notice p {
  margin: 0;
}
.wiki-skeleton-notice strong {
  color: var(--ink);
}

/* Sub-heading (not the main section title) */
.wiki-sub-heading {
  font-size: 18px;
  margin: 0 0 12px;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Brand grid on the wiki index */
.wiki-brand-grid {
  --grid-gap: 14px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--grid-gap);
}

/* Centred card row: add next to .featured-grid or .wiki-brand-grid when the set is short (e.g. 3
   featured tiles). Each card keeps its 4-column width and any partial row is centred instead of
   leaving empty slots on the right. Flex, not grid, so a lone tile on the 2-column tablet row is
   centred too. Leave it off list grids (garage, marketplace) where the last row should stay left. */
.grid-center {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
.grid-center > * {
  flex: 0 0 calc((100% - 3 * var(--grid-gap, 16px)) / 4);
}
@media (max-width: 900px) {
  .grid-center > * {
    flex-basis: calc((100% - var(--grid-gap, 16px)) / 2);
  }
}
@media (max-width: 560px) {
  .grid-center > * {
    flex-basis: 100%;
  }
}
.wiki-brand-card {
  display: block;
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 4px solid var(--forest-500);
  border-radius: 6px;
  padding: 20px 18px;
  text-decoration: none;
  color: var(--ink);
  box-shadow: 0 1px 3px var(--shadow);
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-top-color 0.12s ease;
}
.wiki-brand-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 22px var(--shadow);
  border-top-color: var(--brass);
  text-decoration: none;
  color: var(--ink);
}
.wiki-brand-card-inner {
  /* Two columns: text on the left, brand logo on the right. */
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
.wiki-brand-card-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

/* Brand logo (or fallback initial), right column of the card */
/* The logo box sets the card's content height; the logo fills 85% of it, leaving 7.5%
   breathing room above and below. */
.wiki-brand-card-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 84px;
  flex-shrink: 0;
}
.wiki-brand-card-logo img {
  max-height: 85%;
  max-width: 120px;
  width: auto;
  object-fit: contain;
}
.wiki-brand-card-logo-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 85%;
  aspect-ratio: 1 / 1;
  border-radius: 8px;
  background: var(--mist);
  border: 1px solid var(--line);
  color: var(--forest-500);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 26px;
  font-weight: 800;
}
.wiki-brand-name {
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 20px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  margin: 0;
}
.wiki-brand-meta {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 0;
  text-transform: none;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400;
}
.wiki-brand-count {
  font-size: 12px;
  color: var(--forest-300);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin: 6px 0 0;
}

/* Skeleton brand chips - lighter display */
.wiki-skeleton-brands {
  margin-top: 8px;
}
.chip-link {
  text-decoration: none;
  cursor: pointer;
  color: var(--ink);
  transition: background 0.1s ease, color 0.1s ease;
}
.chip-link:hover {
  background: var(--forest-500);
  color: #fff;
  text-decoration: none;
}

/* Badge - small label pill */
.wiki-badge {
  display: inline-block;
  background: var(--mist);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  border-radius: 3px;
  vertical-align: middle;
}
.wiki-badge-special {
  background: var(--brass);
  border-color: var(--brass);
  color: var(--forest-900);
}
/* Waiting for review: one of the owner's items posted while the account is on hold (core/holds.py,
   spec 47; components/_held_badge.html). Brass outline on a pale fill, like the Community badge: a
   state that resolves, not an error. Works on .wiki-badge and .wiki-issue-badge alike. */
.held-badge {
  color: var(--brass-dk);
  border-color: var(--brass);
  background: #fbf3e0;
}
/* The "Your limits" line of an account on hold (components/_hold_notice.html). */
.limit-usage-held {
  margin: 8px 0;
  padding: 8px 12px;
  color: var(--brass-dk);
  background: #fbf3e0;
  border: 1px solid var(--brass);
  border-radius: 8px;
  font-size: 14px;
}
/* Work-in-progress badge: brass fill so an unfinished generation reads at a glance. */
.wiki-badge-wip {
  background: var(--brass);
  border-color: var(--brass);
  color: var(--forest-900);
}
/* On the generation hero (dark header) the badge sits beside the h1; lift it off the baseline. */
.wiki-badge-wip-hero {
  vertical-align: 0.35em;
  margin-left: 10px;
}

/* Alias grid */
.wiki-alias-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.wiki-alias-item {
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 8px 14px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.wiki-alias-text {
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 800;
  font-size: 16px;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--ink);
}
.wiki-alias-kind {
  font-size: 11px;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 600;
}

/* Trims / spec table */
.table-wrap {
  overflow-x: auto;
}
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}
.table th,
.table td {
  text-align: left;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.table thead th {
  background: var(--mist);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}
.table tbody tr:hover {
  background: var(--mist-2);
}
.table-row-special {
  background: #fffbf0;
}
.table-row-special:hover {
  background: #fff8e1;
}

/* Year boxes in the trims table. Green = ran the full production period (years left blank, so the
   inherited generation/series span is shown). Yellow = built only part of the period (explicit
   years). Tints chosen to sit with the forest/brass theme. */
.wiki-year-badge {
  display: inline-block;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-size: 14px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 3px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.wiki-year-full {
  background: #e7f1ea;
  border-color: #bcd8c6;
  color: var(--forest-700);
}
.wiki-year-partial {
  background: #faf3df;
  border-color: #ecd9a6;
  color: var(--brass-dk);
}

/* Engine overview: fixed column widths so every per-manufacturer table lines up identically,
   instead of each table sizing its columns to its own content. */
.table-engines {
  table-layout: fixed;
}
.table-engines th:nth-child(1),
.table-engines td:nth-child(1) {
  width: 30%;
}
.table-engines th:nth-child(2),
.table-engines td:nth-child(2) {
  width: 50%;
}
.table-engines th:nth-child(3),
.table-engines td:nth-child(3) {
  width: 20%;
}
.table-title-link {
  font-weight: 700;
  color: var(--brass-dk);
}
.table-title-link:hover {
  text-decoration: underline;
}

/* Spec table on trim page (key-value layout) */
.table-spec th {
  width: 180px;
  background: var(--mist);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}
.table-spec td {
  font-size: 15px;
}

/* Mono code spans */
.wiki-code {
  font-family: "Courier New", Courier, monospace;
  font-size: 13px;
  background: var(--mist);
  border: 1px solid var(--line);
  padding: 1px 5px;
  border-radius: 3px;
  color: var(--ink);
}

/* Empty / not-recorded placeholder */
.empty-note {
  color: var(--ink-soft);
  opacity: 0.5;
}

/* Body styles list */
.wiki-body-styles {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.wiki-body-style-item {
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 8px 14px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
}
.wiki-body-style-name {
  font-weight: 700;
  color: var(--ink);
}
.wiki-body-style-code,
.wiki-body-style-years {
  color: var(--ink-soft);
  font-size: 13px;
}

/* Factory color grid */
.wiki-color-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
}
.wiki-color-item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 12px;
}
.wiki-color-swatch {
  display: block;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 4px;
  border: 1px solid rgba(0,0,0,0.12);
}
.wiki-color-info {
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.wiki-color-name {
  font-weight: 700;
  font-size: 14px;
  color: var(--ink);
}
.wiki-color-code {
  font-size: 12px;
}

/* Options list */
.wiki-option-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.wiki-option-item {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}
.wiki-option-name {
  flex: 1;
  font-weight: 600;
  color: var(--ink);
}

/* Factory wheel grid: uniform cards, image on top, name below, whole card clickable. */
.wiki-wheel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 14px;
}
.wiki-wheel-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
a.wiki-wheel-card:hover {
  border-color: var(--brand, var(--ink));
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08);
  transform: translateY(-2px);
}
.wiki-wheel-card-photo {
  width: 100%;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 6px;
}
.wiki-wheel-card-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.wiki-wheel-card-name {
  margin-top: 8px;
  text-align: center;
  font-weight: 600;
  font-size: 14px;
  color: var(--ink);
}
/* Reused on the wheel-style detail page sizes table. */
.wiki-wheel-size-spec {
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.wiki-wheel-size-partnr {
  font-size: 12px;
  font-family: var(--mono, monospace);
  color: var(--ink-soft);
}

/* Wheel-style hero: the wheel photo fills the full height of the green hero bar, pinned to the
   right edge (bleeds past the hero padding). Text is padded so it never runs under the photo. */
.wheel-hero {
  position: relative;
  overflow: hidden;
}
.wheel-hero--has-photo {
  min-height: 260px;
}
.wheel-hero .wiki-hero-inner {
  min-height: inherit;
  align-items: center;
}
.wheel-hero--has-photo .wiki-hero-text {
  padding-right: 280px;
}
/* The photo is a full-bar-height layer constrained to the SAME centred content column as .wrap
   (max-width + padding), so its right edge lines up with the page content, not the viewport edge.
   pointer-events:none lets the hero text/links underneath stay clickable; the photo link re-enables
   them for itself. */
.wheel-hero-photo {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  pointer-events: none;
}
/* Photo is ~70% of the hero height, vertically centred, and opens the full image in a lightbox. */
.wheel-hero-photo-link {
  display: block;
  height: 70%;
  pointer-events: auto;
  cursor: zoom-in;
  transition: opacity 0.15s ease;
}
.wheel-hero-photo-link:hover {
  opacity: 0.9;
}
.wheel-hero-photo img {
  height: 100%;
  width: auto;
  object-fit: cover;
  display: block;
  border-radius: 6px;
}
@media (max-width: 700px) {
  .wheel-hero--has-photo {
    min-height: 0;
  }
  .wheel-hero--has-photo .wiki-hero-text {
    padding-right: 0;
  }
  .wheel-hero-photo {
    position: static;
    max-width: none;
    margin: 16px 0 0;
    padding: 0;
    display: block;
  }
  .wheel-hero-photo-link {
    height: auto;
  }
  .wheel-hero-photo img {
    width: 100%;
    height: auto;
    max-height: 280px;
    object-fit: contain;
  }
}

/* Image lightbox overlay (lightbox.js) */
.lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(0, 0, 0, 0.85);
  cursor: zoom-out;
}
.lightbox-overlay[hidden] {
  display: none;
}
.lightbox-img {
  max-width: 90vw;
  max-height: 90vh;
  object-fit: contain;
  border-radius: 6px;
  box-shadow: 0 6px 30px rgba(0, 0, 0, 0.5);
}
body.lightbox-open {
  overflow: hidden;
}
/* Full-screen photo sets (gallery main image -> lightbox.js): close, prev/next, counter. The
   explicit [hidden] rules matter because display:flex would beat the UA [hidden] rule. */
.lightbox-close,
.lightbox-nav {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  line-height: 1;
  cursor: pointer;
}
.lightbox-close:hover,
.lightbox-nav:hover,
.lightbox-close:focus-visible,
.lightbox-nav:focus-visible {
  background: rgba(255, 255, 255, 0.28);
}
.lightbox-close {
  top: 16px;
  right: 16px;
  width: 40px;
  height: 40px;
  font-size: 26px;
}
.lightbox-nav {
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  padding-bottom: 4px;
  font-size: 34px;
}
.lightbox-prev {
  left: 16px;
}
.lightbox-next {
  right: 16px;
}
.lightbox-nav[hidden],
.lightbox-counter[hidden] {
  display: none;
}
.lightbox-counter {
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  color: rgba(255, 255, 255, 0.85);
  font-size: 14px;
}
.lightbox-overlay .lightbox-img {
  cursor: default;
}
@media (max-width: 560px) {
  .lightbox-overlay {
    padding: 8px;
  }
  .lightbox-overlay .lightbox-img {
    max-width: 100vw;
  }
  .lightbox-nav {
    width: 40px;
    height: 40px;
    font-size: 28px;
  }
  .lightbox-prev {
    left: 6px;
  }
  .lightbox-next {
    right: 6px;
  }
}
/* A gallery main image that opens the full-screen view (set by car-gallery.js). */
.gallery-zoomable {
  cursor: zoom-in;
}

/* Model page: generation lineage timeline */
.wiki-lineage {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.wiki-lineage-item {
  display: flex;
  align-items: stretch;
  gap: 0;
  text-decoration: none;
  color: var(--ink);
}
.wiki-lineage-item:hover .wiki-lineage-card {
  background: var(--mist);
  border-left-color: var(--brass);
}
.wiki-lineage-connector {
  width: 20px;
  flex-shrink: 0;
  position: relative;
  display: flex;
  justify-content: center;
}
.wiki-lineage-connector::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  background: var(--line);
  transform: translateX(-50%);
}
.wiki-lineage-connector::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 10px;
  height: 10px;
  background: var(--brass);
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
.wiki-lineage-card {
  flex: 1;
  margin: 4px 0 4px 12px;
  padding: 14px 18px;
  background: var(--white);
  border: 1px solid var(--line);
  border-left: 3px solid var(--forest-500);
  border-radius: 4px;
  transition: background 0.1s ease, border-left-color 0.1s ease;
}
.wiki-lineage-deprecated .wiki-lineage-card {
  opacity: 0.5;
}
.wiki-lineage-header {
  display: flex;
  align-items: center;
  gap: 14px;
}
.wiki-lineage-name {
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 18px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--ink);
}
.wiki-lineage-years {
  font-size: 13px;
  color: var(--ink-soft);
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-weight: 600;
}
.wiki-lineage-subtitle {
  font-size: 14px;
  color: var(--ink-soft);
  margin: 4px 0 0;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400;
  text-transform: none;
}
/* Body styles on each generation card: one .wiki-badge tag per body style. */
.wiki-lineage-bodies {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}

/* Brand page: generation chips per model */
.wiki-model-block {
  margin-bottom: 28px;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--line);
}
.wiki-model-block:last-child {
  border-bottom: none;
}
.wiki-model-heading {
  font-size: 20px;
  margin: 0 0 12px;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.wiki-model-heading a {
  color: var(--ink);
}
.wiki-model-heading a:hover {
  color: var(--brass-dk);
}
.wiki-gen-timeline {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.wiki-gen-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 6px 12px;
  text-decoration: none;
  color: var(--ink);
  font-size: 14px;
  transition: background 0.1s ease, border-color 0.1s ease;
}
.wiki-gen-chip:hover {
  background: var(--forest-500);
  color: #fff;
  border-color: var(--forest-500);
  text-decoration: none;
}
.wiki-gen-chip-name {
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 13px;
}
.wiki-gen-chip-years {
  font-size: 12px;
  opacity: 0.75;
}
.wiki-gen-chip-deprecated {
  opacity: 0.5;
  text-decoration: line-through;
}
/* Completed generation: green fill so a documented generation reads as "done" against the plain
   (in-progress) chips. In-progress generations intentionally keep the default .wiki-gen-chip look. */
.wiki-gen-chip-complete {
  background: var(--forest-500);
  border-color: var(--forest-500);
  color: #fff;
}
.wiki-gen-chip-complete .wiki-gen-chip-years {
  opacity: 0.85;
}

/* Legend under the Models title: tells readers what the green vs plain chips mean. */
.wiki-gen-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin: 0 0 20px;
  font-size: 12px;
  color: var(--ink-soft);
}
.wiki-gen-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.wiki-gen-legend-swatch {
  width: 14px;
  height: 14px;
  border-radius: 3px;
  background: var(--mist);
  border: 1px solid var(--line);
  flex-shrink: 0;
}
.wiki-gen-legend-swatch-complete {
  background: var(--forest-500);
  border-color: var(--forest-500);
}

/* Brand page: compact engine-family grid (variant counts, not expanded chips). auto-fit makes
   it responsive without breakpoints - the columns reflow to the available width. */
.wiki-engine-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 8px;
}
.wiki-engine-cell {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 12px;
  transition: border-color 0.1s ease, background 0.1s ease;
}
.wiki-engine-cell:hover {
  border-color: var(--forest-300);
  background: var(--mist-2);
  text-decoration: none;
}
.wiki-engine-cell-name {
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 16px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--ink);
}
.wiki-engine-cell-count {
  font-size: 12px;
  font-weight: 700;
  color: var(--forest-300);
  white-space: nowrap;
}

/* "Used by" line on the engine family page - on the WHITE body, so dark text (the hero's
   .wiki-meta-line is light-on-green and unreadable here). */
.wiki-used-by {
  font-size: 14px;
  color: var(--ink-soft);
  margin: 0 0 20px;
}
.wiki-used-by-label {
  font-weight: 700;
  color: var(--ink);
}

/* Known issues section (generation + engine family pages) */
.wiki-section-intro {
  font-size: 14px;
  color: var(--ink-soft);
  margin: 0 0 14px;
}
/* Factory-size preset chips above the wheel results: separate the whole block from the cards. */
.wiki-fitment-hint {
  margin-bottom: 24px;
}
/* Wheel table Sizes cell: each size a wiki-code pill, wrapping with a small gap. */
.wiki-size-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.wiki-issue-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.wiki-issue {
  background: var(--white);
  border: 1px solid var(--line);
  border-left: 4px solid var(--forest-300);
  border-radius: 8px;
  padding: 12px 14px;
}
.wiki-issue-sev-moderate {
  border-left-color: var(--brass);
}
.wiki-issue-sev-major {
  border-left-color: #b3261e;
}
.wiki-issue-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}
.wiki-issue-title {
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 800;
  font-size: 16px;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--ink);
}
.wiki-issue-badge {
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-soft);
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 9px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.wiki-issue-badge-minor {
  color: var(--forest-500);
  border-color: var(--forest-300);
}
.wiki-issue-badge-moderate {
  color: var(--brass-dk);
  border-color: var(--brass);
  background: #fbf3e0;
}
.wiki-issue-badge-major {
  color: #8a1c16;
  border-color: #e6a39e;
  background: #fbeae9;
}
.wiki-issue-desc {
  font-size: 15px;
  color: var(--ink);
  margin: 0;
  line-height: 1.55;
}
/* Verified-by-us vs community-suggested trust badges */
.wiki-issue-verified {
  color: var(--forest-500);
  border-color: var(--forest-300);
  background: #eaf3ec;
}
.wiki-issue-community {
  color: var(--brass-dk);
  border-color: var(--brass);
  background: #fbf3e0;
}
/* Community-suggested (unverified) issues are softened so the verified ones read as primary. */
.wiki-issue-unverified {
  border-style: dashed;
  background: var(--mist-2);
}
/* "I've seen this" vote control on a known issue */
.wiki-issue-vote {
  margin-top: 10px;
}
.wiki-vote-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px 12px;
  cursor: pointer;
  text-decoration: none;
  transition: border-color 0.1s ease, color 0.1s ease, background 0.1s ease;
}
.wiki-vote-btn:hover {
  border-color: var(--forest-300);
  color: var(--forest-500);
  text-decoration: none;
}
.wiki-vote-btn.is-voted {
  color: var(--forest-500);
  border-color: var(--forest-500);
  background: #eaf3ec;
}
.wiki-vote-icon {
  font-size: 10px;
}
.wiki-vote-count {
  font-weight: 800;
}
.wiki-vote-btn-login {
  color: var(--brass-dk);
}

/* ---------------------------------------------------------------------------
   Known issues: card foot, full list page, detail page and threaded comments
   --------------------------------------------------------------------------- */

/* A title that is also a link (list cards + featured cards link to the detail page). */
a.wiki-issue-title {
  text-decoration: none;
}
a.wiki-issue-title:hover {
  color: var(--forest-500);
}

.wiki-issue-discuss {
  font-size: 13px;
  font-weight: 700;
  color: var(--brass-dk);
  text-decoration: none;
}
.wiki-issue-discuss:hover {
  text-decoration: underline;
}
.wiki-issue-showall {
  margin: 16px 0 0;
}
/* A plain "see more ->" style link, reused across the wiki. */
.wiki-link-arrow {
  font-weight: 700;
  color: var(--forest-500);
  text-decoration: none;
}
.wiki-link-arrow:hover {
  text-decoration: underline;
}

/* Issue filter fieldsets - live inside the reusable filter-page aside (see filter-page-*). */
.wiki-filter-group {
  border: none;
  margin: 0 0 18px;
  padding: 0;
}
.wiki-filter-group legend {
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
  padding: 0;
  margin-bottom: 8px;
}
.wiki-filter-radio {
  display: block;
  font-size: 14px;
  margin-bottom: 6px;
  cursor: pointer;
}
.wiki-filter-label {
  display: block;
  font-size: 13px;
  font-weight: 700;
  margin: 10px 0 4px;
}
/* Trust-tier groups in the results column. */
.wiki-issues-tier {
  margin-bottom: 28px;
}
.wiki-issues-tier-count {
  font-size: 13px;
  font-weight: 800;
  color: var(--ink-soft);
  background: var(--mist);
  border-radius: 999px;
  padding: 1px 9px;
}
.wiki-issues-tier-note {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 0 0 12px;
}
/* Issue detail: the title/badges live in the page hero (page-hero); the body is plain
   prose like every other wiki page. */
.wiki-issue-detail-desc {
  margin: 0 0 14px;
  max-width: 72ch;
}

/* Issue detail layout: a main column of sections beside a sticky facts rail. The prose sections
   reuse .wiki-section-title so they match Solutions; the two anchors (the "what to check" panel
   and the "what it costs" callout) keep their own treatment. No left accent stripes. */
.issue-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 272px;
  gap: 34px;
  align-items: start;
}
.issue-main {
  min-width: 0;
}
.issue-main > * {
  margin-bottom: 28px;
}
.issue-main > *:last-child {
  margin-bottom: 0;
}
.issue-main .wiki-prose {
  max-width: 68ch;
}

/* "What to check" - bordered panel, icon-chip header, tick-box checklist. */
/* The known-issue jump targets (#check panel and the What you notice / Why / Cost sections) clear
   the sticky site header when the "On this page" list scrolls to them. */
.issue-main > .issue-panel,
.issue-main > section {
  scroll-margin-top: 90px;
}
.issue-panel {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--white);
  overflow: hidden;
}
.issue-panel-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--mist-2);
}
.issue-chip-ic {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: var(--white);
  border: 1px solid var(--line);
  color: var(--brass-dk);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}
.issue-chip-ic svg {
  width: 17px;
  height: 17px;
}
.issue-panel-head h2 {
  font-size: 16px;
  margin: 0;
  letter-spacing: 0.03em;
}
.issue-panel-hint {
  margin-left: auto;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
}
.issue-checks {
  list-style: none;
  margin: 0;
  padding: 15px 18px 17px;
  display: flex;
  flex-direction: column;
  gap: 13px;
}
.issue-checks li {
  display: flex;
  gap: 12px;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
}
.issue-check-box {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  border: 1.5px solid var(--brass);
  border-radius: 4px;
  margin-top: 3px;
  background: var(--mist-2);
}

/* "What it costs" - tinted callout with an inset label + icon (the moderate warm palette). */
.issue-cost {
  display: flex;
  gap: 13px;
  align-items: flex-start;
  padding: 15px 17px;
  border: 1px solid var(--brass);
  border-radius: 12px;
  background: #fbf3e0;
}
.issue-cost > svg {
  width: 20px;
  height: 20px;
  color: var(--brass-dk);
  flex: 0 0 auto;
  margin-top: 3px;
}
.issue-cost-label {
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--brass-dk);
  margin: 0 0 4px;
}
.issue-cost .wiki-prose {
  font-size: 15px;
  max-width: none;
}
.issue-cost .wiki-prose p:last-child {
  margin-bottom: 0;
}

/* Facts rail */
.issue-rail {
  position: sticky;
  top: 16px;
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.issue-rc {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--mist-2);
  padding: 14px 16px;
}
.issue-rc-h {
  font-size: 12px;
  margin: 0 0 11px;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}
.issue-glance {
  margin: 0;
  font-size: 13px;
}
.issue-glance > div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  border-bottom: 1px solid var(--line);
}
.issue-glance > div:first-child {
  padding-top: 0;
}
.issue-glance > div:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}
.issue-glance dt {
  color: var(--ink-soft);
  margin: 0;
}
.issue-glance dd {
  margin: 0;
  text-align: right;
  color: var(--ink);
}
.issue-glance dd a {
  color: var(--brass-dk);
}
.issue-glance .g-major {
  color: #8a1c16;
  font-weight: 700;
}
.issue-glance .g-moderate {
  color: var(--brass-dk);
  font-weight: 700;
}
.issue-glance .g-minor {
  color: var(--forest-500);
  font-weight: 700;
}
.issue-owner-note {
  font-size: 12px;
  color: var(--ink-soft);
  margin: 11px 0 0;
  line-height: 1.4;
}
.issue-jump {
  list-style: none;
  margin: 0;
  padding: 0;
}
.issue-jump li a {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 13px;
  color: var(--brass-dk);
  text-decoration: none;
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
}
.issue-jump li:first-child a {
  padding-top: 0;
}
.issue-jump li:last-child a {
  border-bottom: 0;
  padding-bottom: 0;
}
.issue-jump li a:hover {
  text-decoration: underline;
}
/* The section in view (static/js/section-menu.js). */
.issue-jump li a.is-current {
  color: var(--forest-700);
  font-weight: 700;
}
.issue-jump span {
  color: var(--ink-soft);
}

@media (max-width: 800px) {
  .issue-layout {
    grid-template-columns: 1fr;
  }
  .issue-rail {
    position: static;
  }
}

/* Comments */
.wiki-comments {
  margin-top: 32px;
  border-top: 1px solid var(--line);
  padding-top: 20px;
}
.wiki-comments-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 14px;
}
.wiki-comments-title {
  font-size: 18px;
  margin: 0;
}
.wiki-comments-sort {
  display: inline-flex;
  gap: 4px;
}
.wiki-sort-tab {
  font-size: 13px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid transparent;
  color: var(--ink-soft);
  text-decoration: none;
}
.wiki-sort-tab:hover {
  color: var(--forest-500);
}
.wiki-sort-tab.is-active {
  background: var(--mist);
  border-color: var(--line);
  color: var(--ink);
}
.wiki-comments-login {
  margin: 0 0 18px;
}
/* One-off notice above the composer (e.g. the rate-limit warning). */
.wiki-comments-notice {
  margin: 0 0 14px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-left: 3px solid #b3261e;
  border-radius: 6px;
  background: var(--mist);
  font-size: 13px;
  color: var(--ink);
}

/* Comment composer (top-level, reply and edit all share .wiki-comment-form). */
.wiki-comment-form {
  margin-bottom: 18px;
}
.wiki-comment-textarea {
  width: 100%;
  font-family: inherit;
  font-size: 14px;
  line-height: 1.5;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  resize: vertical;
}
.wiki-comment-textarea:focus {
  outline: none;
  border-color: var(--forest-300);
}
.wiki-comment-form-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
}

/* The thread + recursive branches. Each reply level is indented with a guide line. */
.wiki-comment-thread {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.wiki-comment-children {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 14px;
  margin-left: 16px;
  padding-left: 14px;
  position: relative; /* anchors the clickable thread line below */
}
/* The vertical thread line is a real clickable element, not just a border: clicking anywhere
   along it collapses the parent comment (same action as the [-] button; comments.js handles the
   data-comment-collapse attribute). It covers only the left gutter, so nested comment content
   stays clickable. */
.wiki-comment-thread-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 14px;
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}
.wiki-comment-thread-line::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 2px;
  background: var(--line);
}
.wiki-comment-thread-line:hover::before {
  width: 3px;
  background: var(--forest-500);
}
.wiki-comment-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--ink-soft);
  margin-bottom: 3px;
}
.wiki-comment-author {
  font-weight: 800;
  color: var(--ink);
}
/* The meta-row author is a profile link since the member profile landed; keep the ink
   colour so threads stay calm, underline only on hover. */
a.wiki-comment-author {
  text-decoration: none;
}
a.wiki-comment-author:hover {
  text-decoration: underline;
  color: var(--forest-500);
}
.wiki-comment-edited {
  font-style: italic;
  color: var(--ink-soft);
}
.wiki-comment-text {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink);
}
.wiki-comment-deleted {
  font-style: italic;
  color: var(--ink-soft);
  margin: 0;
}
.wiki-comment-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 6px;
}
.wiki-comment-delete {
  display: inline;
  margin: 0;
}
.wiki-comment-action {
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0.03em;
  color: var(--ink-soft);
  cursor: pointer;
}
.wiki-comment-action:hover {
  color: var(--forest-500);
}
.wiki-comment-subform {
  margin-top: 10px;
}

/* Collapsible thread (Reddit-style). The compact [+] header is hidden until the comment carries
   .is-collapsed (toggled client-side by comments.js); collapsing then hides the body, actions,
   any open reply/edit boxes and the whole replies subtree, leaving just the header. */
.wiki-comment-collapsed {
  display: none;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  font-size: 12px;
  color: var(--ink-soft);
  cursor: pointer;
}
.wiki-comment-collapse-icon {
  font-weight: 800;
  color: var(--ink-soft);
}
.wiki-comment-collapse-count {
  color: var(--ink-soft);
}
.wiki-comment.is-collapsed > .wiki-comment-body,
.wiki-comment.is-collapsed > .wiki-comment-actions,
.wiki-comment.is-collapsed > .wiki-comment-subform,
.wiki-comment.is-collapsed > .wiki-comment-children {
  display: none;
}
.wiki-comment.is-collapsed > .wiki-comment-collapsed {
  display: inline-flex;
}

/* Per-comment up/down vote control: two arrows with the net score between them. */
.wiki-comment-vote {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.wiki-vote-arrow {
  font-family: inherit;
  font-size: 12px;
  line-height: 1;
  color: var(--ink-soft);
  background: none;
  border: none;
  padding: 2px 3px;
  cursor: pointer;
  text-decoration: none;
  border-radius: 4px;
}
.wiki-vote-arrow:hover {
  color: var(--forest-500);
}
.wiki-vote-down:hover {
  color: #b3261e;
}
.wiki-vote-up.is-active {
  color: var(--forest-500);
}
.wiki-vote-down.is-active {
  color: #b3261e;
}
.wiki-vote-score {
  font-size: 12px;
  font-weight: 800;
  color: var(--ink);
  min-width: 14px;
  text-align: center;
}

/* Deep comment threads: trim the reply indent on narrow screens so they stay readable. */
@media (max-width: 760px) {
  .wiki-comment-children {
    margin-left: 8px;
    padding-left: 10px;
  }
}

/* Generation page: a section summary beside the FULL-WIDTH content. The content stays in the normal
   .wrap so it lines up with the hero and matches other pages. By default the summary is a compact
   bar above the content; on wide screens it lifts into the left page margin, pinned in view. */
.wiki-layout {
  position: relative;
}
.wiki-toc {
  margin: 0 0 20px;
}
.wiki-toc-title {
  font-family: "Arial Narrow", Impact, sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 13px;
  font-weight: 800;
  color: var(--ink-soft);
  margin: 0 0 8px;
}
.wiki-toc-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.wiki-toc-list a {
  display: block;
  padding: 4px 12px;
  font-size: 14px;
  color: var(--ink-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  text-decoration: none;
}
.wiki-toc-list a:hover {
  color: var(--forest-500);
  border-color: var(--forest-300);
  text-decoration: none;
}
/* The section in view (static/js/section-menu.js sets .is-current while scrolling). */
.wiki-toc-list a.is-current {
  color: var(--forest-700);
  border-color: var(--forest-500);
  background: var(--mist);
  font-weight: 700;
}
/* Offset anchor jumps so a section title is not hidden under the sticky header. */
.wiki-section {
  scroll-margin-top: 90px;
}
/* A section that received focus from an in-page menu click (section-menu.js gives it
   tabindex="-1") draws no focus ring around the whole block; focus only moves there so the next
   Tab continues from the section. */
[tabindex="-1"]:focus {
  outline: none;
}
/* Wide screens: lift the summary into the left page margin, pinned below the header, so the content
   keeps the full page width. A 160px list + 24px gap needs ~1460px of viewport before there is room
   beside the 1072px content column. */
@media (min-width: 1460px) {
  /* Two columns, with the summary column pulled out into the left page margin (negative margin) so
     the content column keeps the full page width and stays aligned with the hero above. */
  .wiki-layout {
    display: grid;
    grid-template-columns: 160px minmax(0, 1fr);
    column-gap: 32px;
    align-items: start;
    margin-left: -192px;
  }
  /* Sticky (not fixed): the summary starts at the top of the white content and only pins below the
     header once you scroll past it. */
  .wiki-toc {
    position: sticky;
    top: 87px;
    margin: 0;
  }
  .wiki-toc-list {
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 0;
    border-left: 2px solid var(--line);
  }
  .wiki-toc-list a {
    border: none;
    border-left: 2px solid transparent;
    border-radius: 0;
    margin-left: -2px;
    padding: 5px 12px;
  }
  .wiki-toc-list a:hover {
    border-left-color: var(--forest-300);
  }
  .wiki-toc-list a.is-current {
    background: none;
    border-left-color: var(--brass);
  }
}

/* Generation images --------------------------------------------------------- */
/* Featured-card thumbnail: fill the placeholder area. position:relative so focal-point.js can
   absolutely-position the image to centre the focal point. */
.gen-card-image {
  overflow: hidden;
  position: relative;
}
.gen-card-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Model lineage card: primary image on the right. */
.wiki-lineage-card {
  display: flex;
  align-items: center;
  gap: 16px;
}
.wiki-lineage-text {
  flex: 1;
  min-width: 0;
}
.wiki-lineage-image {
  flex-shrink: 0;
  width: 120px;
  height: 72px;
  border-radius: 4px;
  overflow: hidden;
  position: relative;
}
.wiki-lineage-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Generation detail: slideshow above the overview. */
.wiki-gallery-section {
  margin-bottom: 8px;
}
.wiki-slideshow {
  position: relative;
}
.wiki-slide {
  display: none;
  margin: 0;
  position: relative;
}
.wiki-slide.is-active {
  display: block;
}
.wiki-slide img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 8px;
  display: block;
}
.wiki-slide figcaption {
  font-size: 13px;
  color: var(--ink-soft);
  margin-top: 8px;
}
.wiki-slideshow-nav {
  position: absolute;
  top: calc(50% - 20px);
  width: 40px;
  height: 40px;
  border: none;
  border-radius: 50%;
  background: rgba(20, 48, 29, 0.55);
  color: #fff;
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.wiki-slideshow-nav:hover {
  background: rgba(20, 48, 29, 0.85);
}
.wiki-slideshow-prev {
  left: 12px;
}
.wiki-slideshow-next {
  right: 12px;
}
.wiki-slideshow-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}
.wiki-slideshow-dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--line);
  cursor: pointer;
}
.wiki-slideshow-dot.is-active {
  background: var(--forest-500);
}

/* Back link on trim page */
.wiki-back-link {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  font-size: 14px;
}

/* Wiki-specific responsive breakpoints */
@media (max-width: 900px) {
  .wiki-brand-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .page-hero h1 {
    font-size: 34px;
  }
  /* Stack the hero: image below the text, with a fixed ratio so it keeps a height once the
     flex column no longer has a sibling to stretch against. */
  .page-hero-inner {
    flex-direction: column;
    gap: 20px;
  }
  .page-hero-image {
    flex: none;
    aspect-ratio: 16 / 9;
  }
  .table-spec th {
    width: 120px;
  }
}
@media (max-width: 560px) {
  .wiki-brand-grid {
    grid-template-columns: 1fr;
  }
  .page-hero h1 {
    font-size: 28px;
  }
  .wiki-color-grid {
    grid-template-columns: 1fr;
  }
  .wiki-wheel-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------------------------------------------------------------------------
   Garage module (Phase 1)
   Reuses the green/brass palette and the wiki page-hero/section shells. Adds form,
   listing-grid, photo-grid and timeline styling. No inline styles (strict CSP).
   --------------------------------------------------------------------------- */

/* Flash messages */
/* Flash messages, rendered once globally in base.html. Neutral naming since they appear on every
   page (not just the garage). Shown as a toast stack fixed to the bottom-right corner; level
   modifiers tint the left border for errors/warnings. messages.js handles (auto-)dismissal. */
/* Floating back-to-top button (base.html, wired by back-to-top.js). Fixed bottom-right, conventional
   for the control. Sits below the flash-toast layer (z-index 1000) so a transient toast overlays it
   rather than clashing. Hidden by default; back-to-top.js adds .is-visible once the user scrolls a
   long page. Honours reduced-motion by skipping the fade transition. */
.back-to-top {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 900;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--forest-500);
  color: #fff;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22);
  cursor: pointer;
  /* Hidden state: faded out, nudged down, and non-interactive until revealed. */
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease, background 0.2s ease;
}
/* On pages with the floating save bar (same bottom-right corner), lift back-to-top above it. */
body:has(.sticky-save) .back-to-top {
  bottom: 92px;
}
.back-to-top.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.back-to-top:hover {
  background: var(--forest-600, var(--forest-500));
}
.back-to-top-icon {
  width: 22px;
  height: 22px;
}
@media (prefers-reduced-motion: reduce) {
  .back-to-top {
    transition: opacity 0.2s ease;
    transform: none;
  }
  .back-to-top.is-visible {
    transform: none;
  }
}

.site-messages {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-end;
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: min(360px, calc(100vw - 48px));
}
.site-message {
  background: var(--mist);
  border-left: 3px solid var(--forest-500);
  padding: 12px 16px;
  border-radius: 10px;
  font-size: 14px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
  cursor: pointer;
  animation: site-message-in 0.25s ease-out;
}
.site-message-error,
.site-message-danger {
  border-left-color: #b3261e;
}
.site-message-warning {
  border-left-color: var(--brass);
}
/* messages.js adds this class before removing the toast so it fades out smoothly. */
.site-message-leaving {
  opacity: 0;
  transform: translateX(12px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}
@keyframes site-message-in {
  from {
    opacity: 0;
    transform: translateX(24px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* Car listing grid (reuses .featured-grid layout) */
.garage-grid {
  margin-top: 8px;
}
.garage-car-card {
  text-decoration: none;
  color: inherit;
}
.garage-car-card:hover {
  text-decoration: none;
}
.garage-card-image {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--forest-500);
  color: #fff;
  overflow: hidden;
}
.garage-card-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.garage-card-noimg {
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 48px;
  font-weight: 800;
  opacity: 0.5;
}
.garage-card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}

/* Owner row on community listings: initials avatar + display name, its own link below the
   car link (the card is a div wrapper so the two anchors never nest). */
.garage-card-owner {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-top: 1px solid var(--line);
  text-decoration: none;
  color: var(--ink-soft);
  font-size: 14px;
}
.garage-card-owner:hover {
  color: var(--ink);
  text-decoration: none;
}
.garage-card-owner:hover .garage-card-owner-name {
  text-decoration: underline;
}
.garage-card-avatar {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--forest-500);
  color: var(--white);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 800;
  font-size: 13px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Visibility badge colours */
.garage-vis-private {
  background: #7a2f2f;
  color: #fff;
}
.garage-vis-unlisted {
  background: var(--brass-dk);
  color: #fff;
}
.garage-vis-public {
  background: var(--forest-500);
  color: #fff;
}

/* Garage overview (community garage front page): stacked car rows, each with a heading and an
   optional "browse all" link on the same line. The grids inside reuse .featured-grid. */
.garage-section {
  margin-bottom: 40px;
}
.garage-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.garage-section-head h2 {
  margin: 0;
  font-size: 20px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Empty states */
/* The box carries .empty-note for its muted look, but only the sentence is dimmed: the image
   and the CTA button stay at full strength. */
.empty-state {
  text-align: center;
  padding: 40px 0;
  opacity: 1;
}
.empty-state p {
  margin-bottom: 16px;
  color: var(--ink-soft);
  opacity: 0.5;
}
.empty-state-img {
  display: block;
  width: 120px;
  height: auto;
  margin: 0 auto 12px;
}
.empty-state-sm {
  padding: 16px 0;
}
.empty-state-sm .empty-state-img {
  width: 72px;
  margin-bottom: 8px;
}
.empty-state-sm p {
  margin-bottom: 0;
}
.empty-state-strong p {
  color: var(--ink);
  opacity: 1;
}
.garage-muted {
  color: var(--ink-soft);
  font-size: 14px;
}

/* Forms (the shared form kit). ONE .form-field definition lives here - the auth section used to
   redefine it lower in this file, which silently won the cascade everywhere. The merged rules
   below reproduce that final computed style, so nothing shifts visually. */
.form-panel {
  max-width: 640px;
  /* Center the panel in the content container instead of hugging its left edge. */
  margin-inline: auto;
}
.form-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 16px;
}
/* The display:flex above is author-origin and so beats the UA [hidden]{display:none} rule, which
   left toggled-off fields (the custom colour / custom wheels inputs) visible. Restore the hide. */
.form-field[hidden] {
  display: none;
}
.form-field label {
  display: block;
  font-weight: 700;
  font-size: 14px;
  margin-bottom: 4px;
  color: var(--ink);
}
.form-field input,
.form-field select,
.form-field textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
  background: var(--white);
  color: var(--ink);
}
.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: 2px solid var(--forest-300);
  border-color: var(--forest-500);
}
/* Checkboxes must not stretch full-width like a text input. Lay the row out as
   [checkbox] [label], left-aligned, with a regular-weight label. Scoped to DIRECT children so
   nested widgets (the colour grid radios, the VIN reveal toggle) keep their own layout. */
.form-field > input[type="checkbox"],
.form-field > input[type="radio"] {
  width: auto;
  order: 1;
  margin: 0;
}
.form-field:has(> input[type="checkbox"]) {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}
.form-field:has(> input[type="checkbox"]) label {
  order: 2;
  font-weight: 400;
  margin-bottom: 0;
}
.form-help {
  display: block;
  color: var(--ink-soft);
  font-size: 13px;
  margin: 0;
}

/* Brand grid selector (car form): logo tiles over plain radios, same pattern as the
   factory-colour grid below. The checked radio highlights its tile. */
.garage-brand-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 8px;
}
.garage-brand-option {
  display: block;
  margin: 0;
  cursor: pointer;
}
.garage-brand-grid input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.garage-brand-tile {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 2px solid var(--line);
  border-radius: 6px;
  background: #fff;
  font-weight: 600;
  font-size: 13.5px;
  line-height: 1.2;
}
.garage-brand-option:hover .garage-brand-tile {
  border-color: var(--forest-300);
}
.garage-brand-grid input[type="radio"]:checked + .garage-brand-tile {
  border-color: var(--brass);
  box-shadow: inset 0 0 0 1px var(--brass);
}
.garage-brand-grid input[type="radio"]:focus-visible + .garage-brand-tile {
  outline: 2px solid var(--forest-300);
  outline-offset: 1px;
}
.garage-brand-logo {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  object-fit: contain;
}
/* No logo uploaded yet: a lettered disc keeps the tile's shape. */
.garage-brand-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--mist);
  border: 1px solid var(--line);
  color: var(--forest-700);
  font-weight: 800;
  font-size: 15px;
}

/* Factory-colour grid selector (replaces the colour dropdown on the car form). Each option is a
   hidden radio + a swatch tile; the checked radio highlights its tile. */
.form-field-label {
  display: block;
  font-weight: 700;
  font-size: 14px;
  margin-bottom: 4px;
}
.garage-color-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(165px, 1fr));
  gap: 8px;
  max-height: 320px;
  overflow-y: auto;
  padding: 2px;
}
.garage-color-empty {
  margin: 0;
  color: var(--ink-soft);
  font-size: 13px;
}
.garage-color-grid .garage-color-option {
  display: block;
  margin: 0;
  cursor: pointer;
}
.garage-color-grid input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.garage-color-tile {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 9px;
  border: 2px solid var(--line);
  border-radius: 6px;
  background: #fff;
  font-weight: 400;
  font-size: 13px;
  line-height: 1.2;
}
.garage-color-grid .garage-color-option:hover .garage-color-tile {
  border-color: var(--forest-300);
}
.garage-color-grid input[type="radio"]:checked + .garage-color-tile {
  border-color: var(--brass);
  box-shadow: inset 0 0 0 1px var(--brass);
}
.garage-color-grid input[type="radio"]:focus-visible + .garage-color-tile {
  outline: 2px solid var(--forest-300);
  outline-offset: 1px;
}
.garage-color-swatch {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.18);
  background: var(--mist);
}
.garage-color-swatch-none {
  background: repeating-linear-gradient(45deg, #fff, #fff 3px, var(--line) 3px, var(--line) 5px);
}
.garage-color-name {
  color: var(--ink);
}
.garage-color-code {
  color: var(--ink-soft);
  font-size: 11px;
}
.garage-color-search {
  margin-bottom: 8px;
}
/* Filtered-out tiles: override the .garage-color-option display:block so [hidden] hides them. */
.garage-color-grid .garage-color-option[hidden] {
  display: none;
}
.garage-color-noresults {
  margin: 6px 0 0;
  color: var(--ink-soft);
  font-size: 13px;
}

/* Factory-wheel grid picker: same tile grid as the colour picker, but each tile shows the wheel's
   thumbnail image instead of a paint swatch. Radios are visually hidden; the tile is the control. */
.garage-wheel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(175px, 1fr));
  gap: 8px;
  max-height: 340px;
  overflow-y: auto;
  padding: 2px;
}
.garage-wheel-grid .garage-wheel-option {
  display: block;
  margin: 0;
  cursor: pointer;
}
.garage-wheel-grid .garage-wheel-option[hidden] {
  display: none;
}
.garage-wheel-grid input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.garage-wheel-tile {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 8px;
  border: 2px solid var(--line);
  border-radius: 6px;
  background: #fff;
  font-weight: 400;
  font-size: 13px;
  line-height: 1.2;
}
.garage-wheel-grid .garage-wheel-option:hover .garage-wheel-tile {
  border-color: var(--forest-300);
}
.garage-wheel-grid input[type="radio"]:checked + .garage-wheel-tile {
  border-color: var(--brass);
  box-shadow: inset 0 0 0 1px var(--brass);
}
.garage-wheel-grid input[type="radio"]:focus-visible + .garage-wheel-tile {
  outline: 2px solid var(--forest-300);
  outline-offset: 1px;
}
/* The thumbnail square (also reused, smaller, in the collapsed picker summary). */
.garage-wheel-thumb {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 5px;
  border: 1px solid rgba(0, 0, 0, 0.14);
  background: var(--mist);
  overflow: hidden;
}
.garage-wheel-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.garage-wheel-thumb-none {
  background: repeating-linear-gradient(45deg, #fff, #fff 3px, var(--line) 3px, var(--line) 5px);
}
.garage-wheel-name {
  color: var(--ink);
  min-width: 0;
}
.garage-wheel-maker {
  color: var(--ink-soft);
  font-size: 11px;
}
.garage-wheel-noresults {
  margin: 6px 0 0;
  color: var(--ink-soft);
  font-size: 13px;
}
/* Custom-colour field is toggled by color-custom-toggle.js (shown only for "No factory colour"). */
#color-custom-field[hidden] {
  display: none;
}
/* Error text conventions: .form-field-error (per field) and .form-errors (non-field) are the
   canonical pair, rendered by components/_field.html / _form_fields.html with role="alert".
   The auth/account pages keep their own .form-error (hand-looped <p> errors, also role="alert")
   - two names, one accessibility bar. */
.form-field-error,
.form-errors {
  color: #7a2f2f;
  font-size: 13px;
  margin-top: 4px;
}
/* Required marker rendered by components/_field.html next to the label. */
.form-required {
  color: #7a2f2f;
}
/* A field with errors: the control itself signals the problem, not only the text below. */
.form-field-invalid input,
.form-field-invalid select,
.form-field-invalid textarea {
  border-color: #7a2f2f;
}
.form-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 8px;
}
/* A decision the form asks mid-way ("this number is already known as X - is that your part?"):
   a boxed question with its answer buttons, rendered next to the field it is about. Not an
   error (nothing is wrong yet), so it takes the neutral mist tone, not the error red. */
.form-decision {
  margin: 8px 0 12px;
  padding: 12px 14px;
  background: var(--mist-2);
  border: 1px solid var(--line);
  border-radius: 6px;
}
.form-decision-text {
  margin: 0 0 10px;
}
.form-decision-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 6px;
}
.garage-action-box {
  margin-top: 20px;
  padding: 18px;
  background: var(--mist-2);
  border: 1px solid var(--line);
  border-radius: 6px;
}

/* Timeline heading row (garage car timeline, wiki brand history): title left, the controls
   (layout toggle, filter, "Add event") right. The row takes over the title's brass underline so
   the border spans controls and title alike. */
.timeline-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 16px;
  border-bottom: 2px solid var(--brass);
  padding-bottom: 8px;
  margin-bottom: 16px;
}
.timeline-head .wiki-section-title {
  width: auto;
  margin: 0;
  padding-bottom: 0;
  border-bottom: 0;
}

/* "Add event": the timeline entry form collapsed behind a button (<details>, no JS).
   Opening it wraps the details onto its own full-width row, dropping the form under the
   heading. Renders open when the submitted form came back with errors, so they are never
   hidden. */
.garage-entry-add summary {
  list-style: none;
  display: inline-flex;
  cursor: pointer;
}
.garage-entry-add summary::-webkit-details-marker {
  display: none;
}
.garage-entry-add[open] {
  width: 100%;
}
.garage-entry-add .garage-action-box {
  margin-top: 12px;
}
.garage-inline-form {
  max-width: 100%;
}

/* Specs row */
.garage-specs {
  margin-top: 4px;
}
.garage-mono {
  font-family: "Consolas", "Courier New", monospace;
  letter-spacing: 0.04em;
}

/* Photo grid */
.garage-photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
}
.garage-photo {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  background: #fff;
}
.garage-photo img {
  width: 100%;
  height: 160px;
  object-fit: cover;
  display: block;
}
.garage-photo figcaption {
  padding: 6px 8px;
  font-size: 13px;
  color: var(--ink-soft);
}

/* Timeline - the shared rail (.timeline-rail*) and compact logbook (.timeline-log*) layouts from
   components/_timeline_rail.html and _timeline_log.html, used by the garage car timeline and the
   wiki brand history. Each page sets --entry-colour per type with its own <prefix><type> class. */
.garage-timeline {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* Entry type colour, shared by the rail node and the compact row icon (garage-type-<value>). */
.garage-type-post { --entry-colour: var(--forest-500); }
.garage-type-mod { --entry-colour: var(--brass-dk); }
.garage-type-maintenance { --entry-colour: var(--brass); }
.garage-type-milestone { --entry-colour: var(--forest-700); }
.garage-type-status_change { --entry-colour: var(--ink-soft); }
.garage-type-media_embed { --entry-colour: #c4302b; }
.garage-type-odometer { --entry-colour: var(--ink-soft); }
/* Brand history category colour (brand-history-type-<BrandHistoryCategory value>). Stays inside
   the site palette on purpose: the history should read as calm as the rest of the wiki. */
.brand-history-type-model { --entry-colour: var(--forest-500); }
.brand-history-type-logo { --entry-colour: var(--brass); }
.brand-history-type-racing { --entry-colour: var(--forest-700); }
.brand-history-type-news { --entry-colour: var(--ink-soft); }
.brand-history-type-controversy { --entry-colour: var(--brass-dk); }

/* Timeline / Compact toggle sits right of the heading, before the owner's "Add event". */
.timeline-head .list-view-toggle {
  margin: 0 0 0 auto;
}

/* Brand history: the controls group (category filter + layout toggle) right of the heading. */
.brand-history-controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-left: auto;
}
.brand-history-controls .list-view-toggle {
  margin: 0;
}
.brand-history-filter {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
}
.brand-history-filter select {
  font: inherit;
  font-size: 13px;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--white);
  color: var(--ink);
}
/* The category badge in the rail card takes the category colour. */
.brand-history-badge {
  background: var(--entry-colour, var(--forest-700));
  color: var(--white);
}
.brand-history-text {
  margin: 0 0 6px;
  color: var(--ink-soft);
}
/* A historic logo inside the entry: small, on white, never stretched. */
.brand-history-logo {
  display: block;
  width: 64px;
  height: 64px;
  object-fit: contain;
  margin: 6px 0;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 4px;
}
.brand-history-links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin: 4px 0 0;
  font-size: 13px;
}
.brand-history .pager {
  margin-top: 12px;
}

/* Rail layout: date column | node on a vertical line | entry card. */
.timeline-rail {
  list-style: none;
  margin: 0;
  padding: 0;
}
.timeline-rail-item {
  display: grid;
  grid-template-columns: 56px 28px minmax(0, 1fr);
  column-gap: 12px;
  position: relative;
  padding-bottom: 22px;
}
/* The vertical line runs through the node column down to the next entry. */
.timeline-rail-item::before {
  content: "";
  position: absolute;
  left: calc(56px + 12px + 13px);
  top: 4px;
  bottom: 0;
  width: 2px;
  background: var(--line-strong);
}
.timeline-rail-item:last-child::before {
  display: none;
}
.timeline-rail-date {
  text-align: right;
  line-height: 1.2;
  padding-top: 4px;
}
.timeline-rail-day {
  display: block;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
}
.timeline-rail-year {
  display: block;
  font-size: 11px;
  color: var(--ink-soft);
}
.timeline-rail-node {
  position: relative;
  z-index: 1;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--entry-colour, var(--forest-500));
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  box-shadow: 0 0 0 3px var(--page);
}
.timeline-rail-card {
  min-width: 0;
}
.timeline-rail-card .garage-entry-title {
  margin-top: 4px;
}

/* Compact layout: one continuous logbook list. A year row opens each year and sticks just under
   the sticky site header while that year's rows scroll past; the next year row takes its place.
   --timeline-log-sticky-top is the site header's height (70.7px at every width, measured). */
.timeline-log {
  --timeline-log-sticky-top: 70px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--white);
}
.timeline-log-year {
  position: sticky;
  top: var(--timeline-log-sticky-top);
  z-index: 2;
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 14px;
  background: var(--forest-700);
  color: var(--white);
}
.timeline-log-year:first-child {
  border-radius: 7px 7px 0 0;
}
.timeline-log-year-title {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.timeline-log-year-count {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.75);
}
.timeline-log-row {
  margin: 0;
  border-top: 1px solid var(--line);
}
.timeline-log-year + .timeline-log-row {
  border-top: 0;
}
.timeline-log-summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  list-style: none;
}
details.timeline-log-row > summary {
  cursor: pointer;
}
.timeline-log-summary::-webkit-details-marker {
  display: none;
}
details.timeline-log-row > summary:hover {
  background: var(--mist);
}
.timeline-log-date {
  flex: 0 0 52px;
  font-size: 13px;
  color: var(--ink-soft);
}
.timeline-log-icon {
  flex: 0 0 auto;
  color: var(--entry-colour, var(--forest-500));
  font-size: 16px;
  display: inline-flex;
}
.timeline-log-title {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.timeline-log-meta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
  font-size: 13px;
  color: var(--ink-soft);
}
.timeline-log-marker {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
.timeline-log-private {
  color: var(--brass-dk);
}
.timeline-log-chevron {
  display: inline-flex;
  color: var(--ink-soft);
  transform: rotate(90deg);
  transition: transform 0.15s ease;
}
details[open] > summary .timeline-log-chevron {
  transform: rotate(-90deg);
}
.timeline-log-body {
  padding: 0 14px 14px calc(14px + 52px + 12px);
}
@media (max-width: 560px) {
  .timeline-rail-item {
    grid-template-columns: 44px 24px minmax(0, 1fr);
    column-gap: 8px;
  }
  .timeline-rail-item::before {
    left: calc(44px + 8px + 11px);
  }
  .timeline-rail-node {
    width: 24px;
    height: 24px;
    font-size: 12px;
  }
  .timeline-log-summary {
    flex-wrap: wrap;
    gap: 4px 10px;
  }
  .timeline-log-title {
    flex-basis: calc(100% - 100px);
  }
  .timeline-log-meta {
    margin-left: calc(52px + 10px);
  }
  .timeline-log-body {
    padding-left: 14px;
  }
}
.garage-entry-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-soft);
}
/* The owner's Edit / Delete icons sit at the far right of the entry head and the compact row. */
.garage-entry-actions {
  margin-left: auto;
}
.garage-entry-type {
  background: var(--forest-700);
  color: #fff;
}
.garage-entry-title {
  font-size: 18px;
  margin: 6px 0 4px;
}
.garage-entry-body {
  margin: 0;
  color: var(--ink);
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  text-transform: none;
  font-weight: 400;
}
/* Entry media: the YouTube player and/or the photo slideshow under the entry text. Capped in
   width so a landscape slideshow never towers over the timeline on a wide screen. */
.garage-entry-media {
  max-width: 640px;
  margin-top: 10px;
}
.garage-entry-media .video-embed {
  margin: 0 0 10px;
}
.garage-entry-media .garage-gallery {
  margin-bottom: 0;
}
.garage-entry-media .garage-gallery-main-wrap {
  aspect-ratio: 16 / 9;
}
/* Type-specific blocks of the add-entry form (garage-entry-add.js hides the ones that do not
   match the chosen type). .form-row is display:grid, which would beat the UA [hidden] rule. */
.form-row[hidden] {
  display: none;
}
.garage-entry-private {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  margin: 8px 0 0;
  padding: 8px 12px;
  background: #fbf6e8;
  border: 1px dashed var(--brass);
  border-radius: 4px;
}
.garage-entry-private dt {
  font-size: 12px;
  color: var(--ink-soft);
  font-weight: 700;
}
.garage-entry-private dd {
  margin: 0;
  font-size: 15px;
}
.garage-private-tag {
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--brass-dk);
}

/* ---------------------------------------------------------------------------
   Garage: car_form enhancements (cascade selects, fieldsets, photo preview)
   --------------------------------------------------------------------------- */

/* Wider form for the add/edit car page which has more sections */
.form-panel-wide {
  max-width: 780px;
}

/* Fieldset groupings within the car form */
.form-fieldset {
  /* <fieldset> defaults to min-width:min-content, so a wide child (an input-group, a long select)
     stops it shrinking and overflows narrow screens. Reset it so the fieldset tracks its box. */
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 20px 20px 12px;
  margin-bottom: 24px;
  background: var(--white);
}
.form-fieldset-legend {
  font-family: "Arial Narrow", "Segoe UI", Impact, sans-serif;
  font-size: 14px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--forest-700);
  padding: 0 6px;
}

/* Step marker inside a fieldset legend ("step 1 of 4") */
.form-fieldset-step {
  color: var(--ink-soft);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.04em;
  margin-left: 8px;
}
/* One-line intro under a fieldset legend ("Fill in what you know..."). */
.form-fieldset-intro {
  margin: 0 0 16px;
}

/* Single-line list input (suggest-an-issue "What to check"): one row per check, each row a
   tick-box marker (the issue page's .issue-check-box), the input and a remove button. The remove
   buttons only show once check-list.js has wired them (.is-ready); without JS the rows simply
   stay as rendered. */
.check-list-rows {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.check-list-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.check-list-row .issue-check-box {
  margin-top: 0;
}
.form-field .check-list-row input {
  flex: 1;
  min-width: 0;
}
.check-list-row .btn-icon {
  display: none;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  font-size: 18px;
}
.check-list.is-ready .check-list-row .btn-icon {
  display: inline-flex;
}
.check-list-add {
  align-self: flex-start;
  margin-top: 4px;
}
.check-list-add[hidden] {
  display: none;
}

/* A number input with its unit select beside it (cost + currency, mileage + km/miles).
   The amount grows; the unit stays a compact fixed-ish width. */
.form-input-group {
  display: flex;
  gap: 8px;
}
.form-field .form-input-group input {
  flex: 1;
  min-width: 0;
  width: auto;
}
.form-field .form-input-group select {
  flex: 0 0 auto;
  width: auto;
  min-width: 96px;
}

/* Currency prefix glued to the input's left edge (the euro sign on "Offers from",
   the offer forms). Use the -flush variant so prefix and input read as one control. */
.form-input-group-flush {
  gap: 0;
}
.form-input-prefix {
  display: flex;
  align-items: center;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-right: none;
  border-radius: 4px 0 0 4px;
  background: var(--mist);
  color: var(--ink-soft);
  font-weight: 700;
  flex-shrink: 0;
}
.form-input-group .form-input-prefix + input {
  border-radius: 0 4px 4px 0;
}

/* Two fields side by side on desktop, stacked on small screens. */
.form-row {
  display: grid;
  /* minmax(0, 1fr), not 1fr: a bare 1fr track is minmax(min-content, 1fr) and a field with a wide
     child (input + currency select) forces the track past the viewport. minmax(0,...) lets the
     track shrink and the field's own min-width:0 flex children absorb it. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0 16px;
}
@media (max-width: 560px) {
  .form-row {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Cascade select: disabled appearance when cascade parent not yet chosen */
.garage-cascade-select:disabled {
  background: var(--mist);
  color: var(--ink-soft);
  cursor: not-allowed;
}

/* ---------------------------------------------------------------------------
   Form kit: segmented control + chip group (styled radio groups)
   Plain radios underneath, so both submit and work without JavaScript.
   --------------------------------------------------------------------------- */

/* Segmented control: a small, fixed set of exclusive choices (e.g. visibility). */
.seg-control {
  display: flex;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: var(--white);
}
.seg-option {
  flex: 1;
  display: block;
  margin: 0;
  cursor: pointer;
  border-right: 1px solid var(--line);
}
.seg-option:last-child {
  border-right: 0;
}
.seg-option input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.seg-option-label {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 44px;
  height: 100%;
  padding: 8px 10px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--ink-soft);
}
.seg-option:hover .seg-option-label {
  background: var(--mist-2);
  color: var(--ink);
}
.seg-option input[type="radio"]:checked + .seg-option-label {
  background: var(--forest-500);
  color: #fff;
}
.seg-option input[type="radio"]:focus-visible + .seg-option-label {
  outline: 2px solid var(--brass);
  outline-offset: -2px;
}
/* Button-driven segment (a JS-only toggle with no backing form field, e.g. the listing
   catalogue switch). Same look as the radio segments above. */
.seg-option-btn {
  flex: 1;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  border: 0;
  border-right: 1px solid var(--line);
  background: transparent;
  color: var(--ink-soft);
  min-height: 44px;
  padding: 8px 10px;
  cursor: pointer;
}
.seg-option-btn:last-child {
  border-right: 0;
}
.seg-option-btn:hover {
  background: var(--mist-2);
  color: var(--ink);
}
.seg-option-btn[aria-pressed="true"] {
  background: var(--forest-500);
  color: #fff;
}
.seg-option-btn:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: -2px;
}

/* On/off switch (a real checkbox styled as a pill; works + submits without JS). Used for the
   listing "allow offers" setting. Scoped under .form-field so it beats the generic
   `.form-field label` rule (which would otherwise force display:block + bold). */
.form-field .switch-control {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
  margin: 0;
  font-weight: 400;
}
.switch-control input[type="checkbox"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.switch-track {
  display: inline-block;
  flex-shrink: 0;
  position: relative;
  width: 46px;
  height: 26px;
  border-radius: 999px;
  background: var(--line-strong);
  transition: background 0.15s;
  margin-top: 2px;
}
.switch-track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  transition: transform 0.15s;
}
.switch-control input:checked ~ .switch-track {
  background: var(--forest-500);
}
.switch-control input:checked ~ .switch-track::after {
  transform: translateX(20px);
}
.switch-control input:focus-visible ~ .switch-track {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}
.switch-text b {
  display: block;
  font-size: 14px;
}
.switch-text .form-help {
  margin-top: 2px;
}

/* Listing form, price & availability: the pricing-mode choice sits above the price row, so give
   it some air. listing-form.js toggles the `hidden` attribute on the amount input / labels and
   the "offers from" field per mode; form elements set their own display, so enforce it here. */
.pricing-row {
  margin-top: 16px;
}
.pricing-row [hidden] {
  display: none !important;
}

/* Chip group: exclusive choices with too many options for a single segmented row
   (e.g. the 7 car statuses). Radio pills that wrap. */
.chip-select {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.chip-option {
  display: block;
  margin: 0;
  cursor: pointer;
}
.chip-option input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.chip-option-label {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 6px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--white);
}
.chip-option:hover .chip-option-label {
  border-color: var(--forest-300);
  color: var(--ink);
}
.chip-option input[type="radio"]:checked + .chip-option-label {
  background: var(--forest-500);
  border-color: var(--forest-500);
  color: #fff;
}
.chip-option input[type="radio"]:focus-visible + .chip-option-label {
  outline: 2px solid var(--brass);
  outline-offset: 1px;
}

/* seg/chip/reveal/search-select labels sit inside .form-field, which styles bare labels as
   bold field titles - undo that for these control labels. */
.form-field .seg-option,
.form-field .chip-option,
.form-field .field-reveal,
.form-field .search-select-option {
  margin-bottom: 0;
  font-weight: 400;
}

/* "Show password" toggle on the auth pages: a small checkbox row under the input.
   field-reveal.js flips the password input to text while it is ticked. */
.field-reveal {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  font-weight: 400;
  color: var(--ink-soft);
  cursor: pointer;
}
.field-reveal input[type="checkbox"] {
  width: 15px;
  height: 15px;
  margin: 0;
  accent-color: var(--forest-500);
}

/* ---------------------------------------------------------------------------
   Form kit: photo upload dropzone (a real <input type=file> inside a big label)
   --------------------------------------------------------------------------- */
.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 26px 20px;
  border: 2px dashed var(--line);
  border-radius: 10px;
  background: var(--mist-2);
  text-align: center;
  cursor: pointer;
  font-weight: 400;
}
/* .form-field label (display: block) outranks .dropzone, which flattened the icon, text and
   hint onto one line inside every form field. Restore the stacked column. */
.form-field label.dropzone {
  display: flex;
}
.dropzone:hover,
.dropzone.dropzone-drag {
  border-color: var(--forest-500);
  background: var(--mist);
}
.dropzone:focus-within {
  outline: 2px solid var(--forest-300);
}
/* Keep the input focusable/submittable but visually out of the way. */
.dropzone input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.dropzone-icon {
  color: var(--forest-500);
}
.dropzone-text {
  font-size: 14px;
  color: var(--ink);
}
.dropzone-browse {
  color: var(--brass-dk);
  font-weight: 700;
  text-decoration: underline;
}
.dropzone-hint {
  font-size: 12.5px;
  color: var(--ink-soft);
}

/* Preview thumbnails under the dropzone; each carries a remove button. */
.photo-upload {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
.photo-upload-item {
  position: relative;
}
.photo-upload-thumb {
  width: 80px;
  height: 60px;
  object-fit: cover;
  border-radius: 4px;
  border: 1px solid var(--line);
  display: block;
}
.photo-upload-remove {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 18px;
  height: 18px;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-size: 12px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
}
.photo-upload-remove:hover {
  background: #7a2f2f;
}

/* "Cover" tag on the first photo. The badge markup exists on every thumb; CSS shows
   only the first one, so reordering rows moves the tag along with no JS. */
.photo-cover-badge {
  position: absolute;
  top: 3px;
  left: 3px;
  padding: 2px 6px;
  border-radius: 3px;
  background: var(--brass);
  color: var(--forest-900);
  font-size: 10px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  pointer-events: none;
}
.photo-upload-item:not(:first-child) .photo-cover-badge,
.photo-manage-row:not(:first-child) .photo-cover-badge {
  display: none;
}
/* On a manage row the badge anchors to the thumbnail, not the whole row. */
.photo-manage-thumbwrap {
  position: relative;
  flex-shrink: 0;
  display: block;
}

/* Existing photos on the edit form: one row per photo - thumbnail, caption input, up/down
   movers, and a tick-to-remove control. Everything applies on save; a ticked row dims.
   Caption + remove work without JS; the movers need it (order just stays put without). */
.photo-manage {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.photo-manage-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--mist-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 6px 10px;
}
.photo-manage-row img {
  width: 64px;
  height: 48px;
  object-fit: cover;
  border-radius: 3px;
  border: 1px solid var(--line);
  flex-shrink: 0;
  display: block;
}
/* The caption input shares the row; undo the full-width .form-field input default. */
.form-field .photo-manage-caption {
  flex: 1;
  width: auto;
  min-width: 0;
  padding: 6px 9px;
  font-size: 13px;
}
.photo-manage-btns {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}
.photo-manage-remove {
  flex-shrink: 0;
  margin: 0;
  cursor: pointer;
  display: flex;
}
.photo-manage-remove input[type="checkbox"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.photo-manage-x {
  width: 28px;
  height: 28px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--white);
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.photo-manage-remove:hover .photo-manage-x {
  background: #7a2f2f;
  border-color: #7a2f2f;
  color: #fff;
}
.photo-manage-remove input:focus-visible + .photo-manage-x {
  outline: 2px solid var(--forest-300);
}
/* Ticked = marked for removal on save: the whole row dims, the badge stays red. */
.photo-manage-row:has(input[name="delete_photos"]:checked) {
  opacity: 0.5;
  border-color: #7a2f2f;
}
.photo-manage-row:has(input[name="delete_photos"]:checked) .photo-manage-x {
  background: #7a2f2f;
  border-color: #7a2f2f;
  color: #fff;
}

/* ---------------------------------------------------------------------------
   Form kit: collapsed grid picker (<details>) for long tile grids - the colour
   grid (many colours) and the brand grid (many brands) share it. Works without
   JS (details opens natively); garage-color-picker.js / car-cascade.js only
   refresh the summary after a pick.
   --------------------------------------------------------------------------- */
.color-picker summary {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--white);
  cursor: pointer;
  font-size: 14px;
}
.color-picker summary::-webkit-details-marker {
  display: none;
}
.color-picker summary:hover {
  border-color: var(--forest-500);
}
.color-picker[open] summary {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.color-picker-caret {
  margin-left: auto;
  color: var(--ink-soft);
}
.color-picker[open] .color-picker-caret {
  transform: rotate(180deg);
}
.color-picker-panel {
  border: 1px solid var(--line);
  border-top: 0;
  border-radius: 0 0 6px 6px;
  padding: 12px;
  background: var(--white);
}

/* ---------------------------------------------------------------------------
   Form kit: searchable select (components/_search_select.html)
   A <details> dropdown whose options are styled radios bound to a form field.
   Preloaded mode filters client-side (no-JS safe); remote mode fetches rows
   from a suggest endpoint (search-select.js). List rows today; a tile-grid
   variant for image-backed items slots onto the same shell later.
   --------------------------------------------------------------------------- */
.search-select {
  position: relative;
}
.search-select summary {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--white);
  cursor: pointer;
  font-size: 14px;
}
.search-select summary::-webkit-details-marker {
  display: none;
}
.search-select summary:hover {
  border-color: var(--forest-500);
}
.search-select[open] summary {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.search-select-current {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.search-select-current-sub {
  color: var(--ink-soft);
  font-size: 12.5px;
  font-family: "Consolas", "Courier New", monospace;
}
.search-select-placeholder {
  color: var(--ink-soft);
}
.search-select-caret {
  color: var(--ink-soft);
}
.search-select[open] .search-select-caret {
  transform: rotate(180deg);
}
.search-select-panel {
  border: 1px solid var(--line);
  border-top: 0;
  border-radius: 0 0 6px 6px;
  padding: 10px;
  background: var(--white);
}
.search-select-search {
  margin-bottom: 8px;
}
/* Scope the input sizing here: the generic .form-field input rule already styles it. */
.search-select-options {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 320px;
  overflow-y: auto;
  padding: 2px;
}
.search-select-option {
  display: block;
  margin: 0;
  cursor: pointer;
  font-weight: 400;
}
/* Preloaded (client-side) search hides non-matching rows by setting the [hidden] attribute
   (search-select.js). The display:block above outranks the browser default [hidden]{display:none},
   so without this the filter changes nothing on screen - restore the hide explicitly. (The form
   pickers never hit this: they use remote mode, which swaps rows instead of hiding them.) */
.search-select-option[hidden] {
  display: none;
}
.search-select-option input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
/* Plain dropdown-list rows (not bordered "pills"): full-width hover/selected fill,
   like a native <select>, with the search + radio behaviour layered on. */
.search-select-option-body {
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 6px 10px;
  border-radius: 4px;
  background: transparent;
  font-size: 13.5px;
  line-height: 1.3;
}
.search-select-option:hover .search-select-option-body {
  background: var(--mist);
}
.search-select-option input[type="radio"]:checked + .search-select-option-body {
  background: var(--forest-500);
}
.search-select-option input[type="radio"]:checked + .search-select-option-body .search-select-option-label,
.search-select-option input[type="radio"]:checked + .search-select-option-body .search-select-option-none,
.search-select-option input[type="radio"]:checked + .search-select-option-body .search-select-option-hint,
.search-select-option input[type="radio"]:checked + .search-select-option-body .search-select-option-sub {
  color: #fff;
}
.search-select-option input[type="radio"]:focus-visible + .search-select-option-body {
  outline: 2px solid var(--forest-300);
  outline-offset: -2px;
}
.search-select-option-label {
  color: var(--ink);
}
.search-select-option-none {
  color: var(--ink-soft);
}
.search-select-option-sub {
  color: var(--ink-soft);
  font-size: 11.5px;
  font-family: "Consolas", "Courier New", monospace;
}
/* Short explainer on an option row (e.g. what the "Not in the catalogue" choice does). */
.search-select-option-hint {
  color: var(--ink-soft);
  font-size: 11.5px;
  font-style: italic;
}
/* One x style everywhere: suppress the browser-native clear button on the search box, so the
   kit's own .search-select-clear is the only x the seller sees. */
.search-select-search input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}
.search-select-search input[type="search"]::-ms-clear {
  display: none;
}
/* The x on a stamped trigger: clears the recorded unmatched number. */
.search-select-clear {
  appearance: none;
  border: 0;
  background: none;
  margin-left: 4px;
  padding: 0 4px;
  color: var(--ink-soft);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.search-select-clear:hover {
  color: var(--ink);
}
/* Status badge on the trigger (e.g. an unmatched part number shown as "Not verified"). */
.search-select-status {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: 999px;
  border: 1px solid var(--brass);
  background: var(--mist);
  color: var(--brass-dk);
  font-size: 11.5px;
  font-weight: 600;
  vertical-align: 1px;
}
.search-select-empty,
.search-select-more {
  margin: 6px 0 0;
  color: var(--ink-soft);
  font-size: 13px;
}
/* Filter-bar usage (garage/marketplace/tutorials/wiki filters): here the component stands in for
   a native <select>, so its open panel must OVERLAY the fields below (like a real dropdown) rather
   than push them down, and sit above the result cards. Scoped to .market-filter-field so the
   in-form usages (listing/settings) keep their original in-flow panel. */
.market-filter-field .search-select {
  width: 100%;
}
/* Match the trigger to the native .market-filter-input beside it (same padding, radius, height),
   so the searchable and native filter dropdowns line up as one consistent set. */
.market-filter-field .search-select summary {
  padding: 9px 11px;
  border-radius: 4px;
  gap: 8px;
  /* Hard clip: a long selected value can never spill past the trigger box, whatever the font. */
  overflow: hidden;
}
/* Chop a long selected value with an ellipsis instead of overflowing (belt-and-suspenders over
   the base rule, in case a font/engine renders it wider than the box). The caret keeps its space. */
.market-filter-field .search-select-current {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.market-filter-field .search-select-caret {
  flex: 0 0 auto;
}
.market-filter-field .search-select[open] summary {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.market-filter-field .search-select-panel {
  position: absolute;
  left: 0;
  right: auto;
  /* At least as wide as the (often narrow) trigger, but free to grow to fit the option text so
     long labels don't wrap into 3-4 lines; capped so it stays a tidy dropdown. */
  min-width: 100%;
  width: max-content;
  max-width: 340px;
  z-index: 30;
  border-radius: 0 0 4px 4px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
}

/* ---------------------------------------------------------------------------
   Garage: car_detail two-column layout
   --------------------------------------------------------------------------- */

/* Two-column grid: wider left (gallery), narrower right (story + specs) */
.garage-detail-layout {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 32px;
  align-items: start;
  margin-bottom: 40px;
}

.garage-detail-left {
  min-width: 0;
}

.garage-detail-right {
  min-width: 0;
}

/* ---------------------------------------------------------------------------
   Garage: photo gallery (large main + thumbnail row)
   --------------------------------------------------------------------------- */

.garage-gallery {
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 16px;
}

.garage-gallery-main-wrap {
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--forest-500);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.garage-gallery-main {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.garage-gallery-thumbs {
  display: flex;
  gap: 6px;
  padding: 8px;
  overflow-x: auto;
  background: var(--mist-2);
  border-top: 1px solid var(--line);
}

.garage-gallery-thumb {
  width: 72px;
  height: 54px;
  object-fit: cover;
  border-radius: 4px;
  border: 2px solid transparent;
  flex-shrink: 0;
  cursor: pointer;
  transition: border-color 0.12s ease;
}

.garage-gallery-thumb:hover {
  border-color: var(--brass);
}

.gallery-thumb-active {
  border-color: var(--brass);
}

/* Previous/next arrows on the main image (galleries with more than one photo). They ship
   `hidden` and car-gallery.js reveals them; the explicit [hidden] rule keeps them gone without JS,
   because the display:flex below would otherwise beat the browser's [hidden]{display:none}. */
.garage-gallery-main-wrap {
  position: relative;
}
.gallery-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0 3px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.9);
  color: var(--ink);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
}
.gallery-nav:hover,
.gallery-nav:focus-visible {
  border-color: var(--brass);
  background: var(--white);
}
.gallery-nav[hidden] {
  display: none;
}
.gallery-nav-prev {
  left: 10px;
}
.gallery-nav-next {
  right: 10px;
}

/* Whole-photo variant (components/_gallery.html fit="whole": the About photo blocks). Every photo
   shows uncropped on a stage as tall as the set's tallest photo at the gallery's width: the hidden
   <svg> spacer carries that photo's viewBox, so its height sets the stage and stepping through the
   set never resizes it. Capped at 80% of the screen height so a tall phone photo still fits. */
.garage-gallery-whole .garage-gallery-main-wrap {
  display: block;
  aspect-ratio: auto;
}
.gallery-stage {
  display: block;
  width: 100%;
  height: auto;
  max-height: 80vh;
}
.garage-gallery-whole .garage-gallery-main {
  position: absolute;
  inset: 0;
  object-fit: contain;
}

/* Empty gallery placeholder */
.garage-gallery-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 220px;
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-bottom: 16px;
}

/* ---------------------------------------------------------------------------
   Garage: photo grid - fixed-aspect cells, no stretching (object-fit: cover)
   --------------------------------------------------------------------------- */

/* The photo frame enforces a fixed aspect ratio so images are always cropped,
   never stretched, regardless of the original dimensions. */
.garage-photo-frame {
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--forest-500);
}

.garage-photo-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* A photo grid with lightbox=True wraps each thumbnail in a link that opens it full screen. The
   link carries the frame's own 4:3 shape, because the image's 100% height needs a parent whose
   height is known and an inline link around it has none. */
.garage-photo-link {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
}

.garage-photo-caption {
  padding: 6px 8px;
  font-size: 13px;
  color: var(--ink-soft);
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  text-transform: none;
}

/* ---------------------------------------------------------------------------
   Garage: spec list (key-value pairs in the right column of car detail)
   --------------------------------------------------------------------------- */

.garage-spec-list {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 0;
  padding: 0;
}

.garage-spec-row {
  display: flex;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}

.garage-spec-row:last-child {
  border-bottom: none;
}

.garage-spec-label {
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  min-width: 90px;
  flex-shrink: 0;
}

.garage-spec-value {
  font-size: 15px;
  color: var(--ink);
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  text-transform: none;
  font-weight: 400;
  margin: 0;
}

/* ---------------------------------------------------------------------------
   Garage: icon buttons (photo-row movers on the edit form, and other icon-only actions)
   --------------------------------------------------------------------------- */

/* Icon-only button (e.g. the photo up/down movers) */
.btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--white);
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0;
}

.btn-icon:hover {
  background: var(--forest-500);
  color: #fff;
  border-color: var(--forest-500);
}

/* ---------------------------------------------------------------------------
   Garage: responsive breakpoints for the detail layout
   --------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .garage-detail-layout {
    grid-template-columns: 1fr;
  }
  .garage-gallery-main-wrap {
    aspect-ratio: 16 / 9;
  }
}

@media (max-width: 560px) {
  .garage-gallery-thumbs {
    gap: 4px;
    padding: 6px;
  }
  .garage-gallery-thumb {
    width: 56px;
    height: 42px;
  }
}

/* ---------------------------------------------------------------------------
   Wiki brand hero: two-column layout (text left, logo right)
   --------------------------------------------------------------------------- */

.wiki-hero-inner {
  display: flex;
  align-items: flex-start;
  gap: 28px;
}

.wiki-hero-text {
  flex: 1;
  min-width: 0;
}

.wiki-hero-logo {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Optional hero image on the wiki index (admin-managed via WikiContent) */
.wiki-hero-image {
  flex-shrink: 0;
  display: flex;
  align-items: center;
}
.wiki-hero-image img {
  max-height: 130px;
  max-width: 240px;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 8px;
}

/* Brand logo image shown on the right of the green hero bar */
.wiki-brand-logo-img {
  max-width: 110px;
  max-height: 80px;
  width: auto;
  height: auto;
  object-fit: contain;
  background: rgba(255, 255, 255, 0.12);
  border-radius: 6px;
  padding: 8px;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

/* Fallback: first-initial chip when no logo is uploaded */
.wiki-brand-logo-fallback {
  width: 80px;
  height: 80px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.15);
  border: 2px solid rgba(255, 255, 255, 0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 42px;
  font-weight: 900;
  color: rgba(255, 255, 255, 0.7);
  text-transform: uppercase;
}

/* Short description shown inside the hero bar (below meta lines) */
.wiki-hero-desc {
  font-size: 15px;
  color: #c3d3c7;
  margin: 10px 0 0;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400;
  text-transform: none;
  max-width: 54em;
  line-height: 1.55;
}

/* ---------------------------------------------------------------------------
   Country flag: self-hosted Twemoji 14.0 SVG shown next to the country of origin.
   Self-hosted (not an emoji) so it renders on Windows and stays within the CSP.
   --------------------------------------------------------------------------- */

.flag-icon {
  display: inline-block;
  height: 0.95em;
  width: auto;
  margin-left: 6px;
  vertical-align: -0.12em;
  border-radius: 2px;
}

/* ---------------------------------------------------------------------------
   Wiki section-title underline: ensure consistent width across all sections.
   The title uses display:block so border-bottom spans the full container width,
   matching every other section underline (fixes the narrower model page bug).
   --------------------------------------------------------------------------- */

.wiki-section-title {
  display: block;
  width: 100%;
}

/* ---------------------------------------------------------------------------
   Responsive adjustments for the cascade strips and brand hero
   --------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .wiki-hero-inner {
    flex-direction: column-reverse;
    gap: 16px;
  }
  .wiki-brand-logo-img {
    max-width: 80px;
    max-height: 60px;
  }
  .wiki-brand-logo-fallback {
    width: 60px;
    height: 60px;
    font-size: 32px;
  }
}

/* ---------------------------------------------------------------------------
   Marketplace module (Phase 1, Stage 4)
   Listing detail two-column layout + horizontal filter bar.
   No inline styles (strict CSP: style-src 'self').
   --------------------------------------------------------------------------- */

/* Horizontal filter bar: all fields in one row across the top of the browse page */
.market-filter-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  background: var(--mist-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 16px 18px;
  margin-bottom: 28px;
}

/* Individual field wrapper inside the filter bar */
.market-filter-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 140px;
}
/* The "include unknown markets" checkbox sits under the market select as a compact inline row
   (checkbox + label on one line), not a stacked field like the selects above it. */
.market-filter-check {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.85em;
  font-weight: 400;
  cursor: pointer;
}
/* Derived-market suggestion chip (spec 11). A quiet OUTLINE pill, not the solid brass CTA, because
   it is off by default - a suggestion the buyer opts into, not the primary action. Sits under the
   market select with a muted note beside it. */
.market-filter-suggest {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  padding: 4px 12px;
  border: 1px solid var(--forest-300);
  border-radius: 999px;
  background: var(--mist);
  color: var(--forest-500);
  font-size: 0.85em;
  line-height: 1.3;
  text-decoration: none;
  cursor: pointer;
}
.market-filter-suggest:hover {
  border-color: var(--forest-500);
  background: #e4ece6;
}
.market-filter-suggest-plus {
  font-weight: 500;
}
.market-filter-suggest-note {
  display: block;
  margin-top: 4px;
  font-size: 0.78em;
  color: var(--text-muted, #6b6b6b);
}
/* A filter field holding a searchable select must not grow to its (possibly long) selected value
   the way a native <select> never does - otherwise one long trim/colour value balloons its field
   and pushes the HORIZONTAL filter row past the box. Cap the width so it truncates with an ellipsis
   instead (the .search-select summary/current rules above). max-width (not flex-basis) is used on
   purpose: flex-basis is the MAIN axis, so in the column layouts it would set the field HEIGHT.
   Scoped to the row layouts only - the stacked (<=560px) and sidebar (>=1460px filter-page-aside)
   layouts are columns where the field should stay full width. Marketplace's bar is a row even
   >=1460px (it has no sidebar), so it is capped there too. */
@media (min-width: 561px) and (max-width: 1459px) {
  .market-filter-bar .market-filter-field:has(.search-select) {
    max-width: 200px;
  }
}
@media (min-width: 1460px) {
  .market-filter-green .market-filter-field:has(.search-select) {
    max-width: 200px;
  }
}

/* The keyword field sits inline with the vehicle/condition/country selects on the same row - it
   is the widest field so it takes the remaining width and grows, wrapping only when the row runs
   out of space (narrow screens, or once the vehicle cascade adds model/generation/trim). */
.market-filter-search {
  flex: 2 1 240px;
}
/* Search input + its Search button sit on one row; the input grows to fill the field width, the
   button stays its own width beside it. */
.market-search-row {
  display: flex;
  gap: 8px;
}
.market-search-row .market-filter-input {
  flex: 1;
  min-width: 0;
}
.market-search-btn {
  flex: none;
}

.market-filter-label {
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}

.market-filter-input {
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 4px;
  font: inherit;
  background: var(--white);
  color: var(--ink);
  font-size: 14px;
}

.market-filter-input:focus {
  outline: 2px solid var(--forest-300);
  border-color: var(--forest-500);
}

/* Submit + reset buttons aligned to the bottom of the bar */
.market-filter-actions {
  display: flex;
  gap: 8px;
  align-items: flex-end;
  padding-bottom: 0;
  flex-shrink: 0;
}

/* Button and reset link side by side (the field wrapper's column direction would stack them),
   centered within the filter box. */
.market-filter-actions-row {
  flex-direction: row;
  align-items: center;
  justify-content: center;
}

/* Listings grid: matches the home featured-grid layout */
.market-listings-grid {
  margin-top: 0;
}

/* ---------------------------------------------------------------------------
   Card slider: one row of cards that scrolls sideways (snap per card), with
   prev/next arrows over the edges. static/js/card-slider.js wires the arrows
   ([data-card-slider-prev/next]) and hides them at the ends; without JS the
   track still scrolls. Card widths follow the featured-grid columns: 4 visible
   on desktop, 2 on tablet, 1.2 on phones (a peek of the next card).
   --------------------------------------------------------------------------- */
.card-slider {
  position: relative;
}
/* position: relative makes the track (the scroller) the containing block for anything absolutely
   positioned inside a card, e.g. the visually-hidden .wiki-vote-label. Without it those resolve
   against .card-slider, escape the track's clip and widen the whole page on phones, which pushes the
   fixed feedback / back-to-top buttons off-screen. */
.card-slider-track {
  position: relative;
  display: flex;
  gap: 16px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  padding-bottom: 4px;
}
.card-slider-track::-webkit-scrollbar {
  display: none;
}
.card-slider-track > * {
  flex: 0 0 calc((100% - 3 * 16px) / 4);
  min-width: 0;
  scroll-snap-align: start;
}
.card-slider-arrow {
  position: absolute;
  top: 40%;
  z-index: 2;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--ink);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(22, 32, 26, 0.15);
  transform: translateY(-50%);
}
.card-slider-arrow:hover {
  border-color: var(--brass);
}
.card-slider-arrow[hidden] {
  display: none;
}
.card-slider-prev {
  left: -20px;
}
.card-slider-next {
  right: -20px;
}
.card-slider-more {
  margin: 14px 0 0;
  text-align: right;
  font-weight: 600;
}
@media (prefers-reduced-motion: reduce) {
  .card-slider-track {
    scroll-behavior: auto;
  }
}
@media (max-width: 900px) {
  .card-slider-track > * {
    flex-basis: calc((100% - 16px) / 2);
  }
}
@media (max-width: 560px) {
  .card-slider-track > * {
    flex-basis: 80%;
  }
  .card-slider-prev {
    left: 4px;
  }
  .card-slider-next {
    right: 4px;
  }
}

/* Known-issues slider on the generation / engine wiki pages: three cards per row on desktop
   (the wiki column is narrower than the marketplace page); tablet and phone fall back to the
   base .card-slider widths above. Card height and clamps are shared with .card-list-grid. */
@media (min-width: 901px) {
  .issue-slider-track > * {
    flex-basis: calc((100% - 2 * 16px) / 3);
  }
}

/* ---------------------------------------------------------------------------
   Tabbed filter block on the browse entry page (Fits my car / Search).
   The tab toggle is home-search.js (data-search-tab / data-search-panel); the
   inactive panel is hidden.

   The whole block sits in market-filter-green: the same light-green box as the
   results-page left filter aside (.market-filter-bar, mist-2 + line border). The
   tabs and the fields share this one box, so the inner form bar drops its own
   box styling (background/border/padding) to avoid a box-in-a-box.
   --------------------------------------------------------------------------- */
.market-filter-green {
  background: var(--mist-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 16px 18px;
  margin-bottom: 28px;
}
.market-filter-green .market-filter-tabbed,
.market-filter-green .market-filter-bar {
  margin-bottom: 0;
}
/* Inside the green box the form bar is not its own box - the box is the wrapper. */
.market-filter-green .market-filter-bar {
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
}
.market-filter-tabbed {
  margin-bottom: 28px;
}

/* "Fits my car" tab: the garage as tiny cards (thumb + name + taxonomy line), each linking to
   that car's parts. Shown when there are few cars; above the threshold the grid selector is
   used instead (see browse.html). */
.market-mycar-tiles {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.market-mycar-tile {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 8px 14px 8px 8px;
  text-decoration: none;
  color: var(--ink);
  min-width: 180px;
}
.market-mycar-tile:hover {
  border-color: var(--forest-300);
  box-shadow: 0 2px 8px var(--shadow);
}
.market-mycar-tile-thumb img,
.market-mycar-tile-noimg {
  width: 44px;
  height: 44px;
  border-radius: 4px;
  object-fit: cover;
  display: block;
  flex-shrink: 0;
}
.market-mycar-tile-noimg {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--forest-500);
  color: var(--white);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 700;
  font-size: 20px;
}
.market-mycar-tile-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.market-mycar-tile-name {
  font-weight: 700;
}
.market-mycar-tile-meta {
  font-size: 12px;
  color: var(--ink-soft);
}
.market-filter-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}
.market-filter-tab {
  border: 1px solid var(--line);
  cursor: pointer;
  font: inherit;
  font-weight: 700;
  font-size: 14px;
  padding: 8px 20px;
  border-radius: 22px;
  background: var(--white);
  color: var(--ink-soft);
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.market-filter-tab:hover {
  border-color: var(--forest-300);
  color: var(--ink);
}
.market-filter-tab.is-active {
  background: var(--forest-900);
  border-color: var(--forest-900);
  color: var(--white);
}
/* The mist filter bar sets margin-bottom for its standalone use; inside a tab it is the panel. */
.market-filter-tabbed .market-filter-bar {
  margin-bottom: 0;
}
/* The generic [hidden] rule is display:none, but market-filter-bar is display:flex and the
   mycar panel is a plain block, so the inactive panel needs an explicit hide (like hero-search). */
.market-filter-panel[hidden],
.market-filter-bar[hidden] {
  display: none;
}

/* ---------------------------------------------------------------------------
   Reusable dropdown selector (components/_selector.html)
   A <details> disclosure with a trigger, an optional search box and either a
   single-column list or a responsive tile grid of options. Ported from Hive's
   grid-selector; styled with the site tokens (no PrimeNG theme). CSP-safe:
   open/close is the native <details>, JS only adds the search filter.
   --------------------------------------------------------------------------- */
.selector {
  position: relative;
  min-width: 220px;
}

/* The trigger row (the <summary>). list-style:none removes the default disclosure marker. */
.selector-trigger {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 12px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 6px;
  font-size: 14px;
  color: var(--ink);
  user-select: none;
}
.selector-trigger::-webkit-details-marker {
  display: none;
}
.selector-trigger:hover {
  border-color: var(--forest-300);
}
.selector-current {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.selector-current-thumb img {
  width: 28px;
  height: 28px;
  object-fit: cover;
  border-radius: 4px;
  display: block;
}
.selector-current-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}
.selector-placeholder {
  color: var(--ink-soft);
  font-weight: 400;
}
/* The caret glyph swaps (down -> up) when the disclosure is open. Driven by CSS content
   rather than a transform so it does not depend on the element's box type. */
.selector-caret {
  color: var(--ink-soft);
  font-size: 12px;
  flex-shrink: 0;
}
.selector-caret::before {
  content: "\25BE";
}
.selector[open] .selector-caret::before {
  content: "\25B4";
}

/* The open panel: absolutely positioned so it overlays the page rather than pushing it. */
.selector-panel {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  min-width: 260px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 12px 30px var(--shadow);
  max-height: 50vh;
  overflow-y: auto;
}

/* Search box: sticky at the top of the scrolling panel (shown only when > threshold items). */
.selector-search {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: var(--mist-2);
  border-bottom: 1px solid var(--line);
}
.selector-search-icon {
  font-size: 13px;
  opacity: 0.6;
}
.selector-search-input {
  flex: 1;
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 7px 9px;
  font: inherit;
  font-size: 14px;
  background: var(--white);
  color: var(--ink);
}
.selector-search-input:focus {
  outline: 2px solid var(--forest-300);
  border-color: var(--forest-500);
}

.selector-items {
  padding: 6px;
}

/* One option. In list layout it is a row; in grid layout the tile styling below overrides. */
.selector-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 6px;
  color: var(--ink);
  text-decoration: none;
}
.selector-item:hover,
.selector-item:focus {
  background: var(--mist);
}
.selector-item-selected {
  background: var(--mist);
  box-shadow: inset 0 0 0 1px var(--forest-300);
}
.selector-item-thumb img {
  width: 44px;
  height: 44px;
  object-fit: cover;
  border-radius: 4px;
  display: block;
}
.selector-item-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.selector-item-label {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
}
.selector-item-sublabel {
  font-size: 12px;
  color: var(--ink-soft);
}

/* Grid layout: responsive tile columns (2 / 3 / 4), thumbnail on top of each tile.
   Mirrors Hive's small-up-2 medium-up-3 xxlarge-up-4. */
.selector-grid .selector-items {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
.selector-grid .selector-item {
  flex-direction: column;
  align-items: stretch;
  text-align: left;
  gap: 6px;
  border: 1px solid var(--line);
  padding: 6px;
}
.selector-grid .selector-item-thumb img,
.selector-grid .selector-item-noimg {
  width: 100%;
  height: 84px;
  object-fit: cover;
  border-radius: 4px;
  display: block;
}
/* Letter placeholder tile when a grid option has no photo. */
.selector-grid .selector-item-noimg {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--forest-500);
  color: var(--white);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 28px;
  font-weight: 700;
}
@media (min-width: 700px) {
  .selector-grid .selector-items {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (min-width: 1200px) {
  .selector-grid .selector-items {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* "Nothing found" empty state (toggled by selector-dropdown.js when the filter clears the list). */
.selector-empty {
  text-align: center;
  color: var(--ink-soft);
  padding: 16px;
  margin: 0;
}

/* ---------------------------------------------------------------------------
   Marketplace: category browse (the /parts/ entry page)
   Competitor-style tile grid: one mist box per main category, its subcategories
   as plain links inside. 4 across on desktop, collapsing with the viewport.
   --------------------------------------------------------------------------- */

.market-section-title {
  margin: 28px 0 14px;
  font-size: 20px;
}

.market-cat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}
@media (max-width: 1100px) {
  .market-cat-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (max-width: 800px) {
  .market-cat-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 520px) {
  .market-cat-grid {
    grid-template-columns: 1fr;
  }
}

.market-cat-tile {
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 14px 16px;
  overflow: hidden;
}

/* The optional tile image sits flush against the tile's top/side edges (negative margins
   cancel the padding) so it reads as a card header. Thumbnails only, never the full image. */
.market-cat-img {
  display: block;
  margin: -14px -16px 12px;
  height: 110px;
  background: linear-gradient(135deg, var(--forest-500) 0%, var(--forest-900) 135%);
}
.market-cat-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.market-cat-title {
  margin: 0 0 8px;
  font-size: 15px;
}
.market-cat-title a {
  color: var(--forest-700);
  text-decoration: none;
}
.market-cat-title a:hover {
  text-decoration: underline;
}

.market-cat-subs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.market-cat-subs a {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 13.5px;
}
.market-cat-subs a:hover {
  color: var(--forest-700);
  text-decoration: underline;
}

/* My listings: "fix my uncategorised listings" banner (spec 36 increment 1). A quiet amber
   note above the grid, not an error - the seller did nothing wrong, the listing is just
   unfindable by category until they pick one. */
.listing-warning-note {
  margin: 0 0 18px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--brass);
  border-radius: 6px;
  background: var(--mist);
  font-size: 14px;
  color: var(--ink);
}
.listing-warning-note p {
  margin: 0;
}
.listing-warning-note a {
  margin-left: 6px;
  font-weight: 700;
}

/* ---------------------------------------------------------------------------
   Marketplace: results view toggle (cards / list) + the list table
   --------------------------------------------------------------------------- */

.market-view-toggle {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
  margin: 0 0 14px;
}

.market-view-btn {
  padding: 5px 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
  text-decoration: none;
  background: var(--white);
}
a.market-view-btn:hover {
  border-color: var(--forest-500);
  color: var(--forest-700);
}
.market-view-active {
  background: var(--forest-700);
  border-color: var(--forest-700);
  color: var(--white);
}

/* Thumbnail cell in the list table: a small fixed square so rows stay compact.
   The _thumb img inside scales to cover it (thumbnails only, never full-size). */
.market-table-thumbcol {
  width: 64px;
}
.market-table-thumb {
  display: block;
  width: 56px;
  height: 56px;
  border-radius: 6px;
  overflow: hidden;
  background: linear-gradient(135deg, var(--forest-500) 0%, var(--forest-900) 135%);
}
.market-table-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.market-table-noimg {
  display: grid;
  place-items: center;
  color: var(--white);
  font-weight: 800;
}
.market-table-titlecell .table-desc {
  margin: 2px 0 0;
}
.market-table-price {
  white-space: nowrap;
  font-weight: 700;
}

/* ---------------------------------------------------------------------------
   Marketplace: listing detail two-column layout
   LEFT (wider): gallery + spec card + description.
   RIGHT (narrower): sticky price card.
   --------------------------------------------------------------------------- */

.market-detail-layout {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 32px;
  align-items: start;
}

.market-detail-left {
  min-width: 0;
}

.market-detail-right {
  min-width: 0;
}

/* Sticky price card in the right column */
.market-price-card {
  position: sticky;
  top: 88px;
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 4px solid var(--brass);
  border-radius: 8px;
  padding: 24px 22px;
  box-shadow: 0 2px 8px var(--shadow);
}

/* Large price display at the top of the price card */
.market-price-amount {
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 36px;
  font-weight: 900;
  color: var(--ink);
  line-height: 1;
  margin-bottom: 6px;
  letter-spacing: 0.01em;
}

/* Location line below price */
.market-price-location {
  font-size: 14px;
  color: var(--ink-soft);
  margin-bottom: 18px;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  text-transform: none;
}

/* Primary CTA button: full-width inside the price card */
.market-price-cta {
  display: block;
  width: 100%;
  text-align: center;
  margin-bottom: 12px;
  box-sizing: border-box;
}

/* Owner-only edit / delete actions below the CTA */
.market-owner-actions {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.market-owner-actions .btn {
  flex: 1;
  text-align: center;
  font-size: 13px;
  padding: 9px 10px;
}

/* Small meta block at the bottom of the price card (condition, qty, status) */
.market-price-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
  color: var(--ink-soft);
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  text-transform: none;
}

.market-price-meta strong {
  color: var(--ink);
}

/* Compatibility badge list inside the spec card */
.market-compat-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* ---------------------------------------------------------------------------
   Marketplace: responsive breakpoints
   --------------------------------------------------------------------------- */

@media (max-width: 900px) {
  /* Detail layout: single column, price card above content on mobile */
  .market-detail-layout {
    grid-template-columns: 1fr;
  }

  /* Un-stick the price card on mobile (it would overlap content in single column) */
  .market-price-card {
    position: static;
  }

  /* Right column moves below the gallery on mobile -- reorder it above spec/desc */
  .market-detail-right {
    order: -1;
  }

  /* Filter bar: slightly tighter on tablet */
  .market-filter-bar {
    gap: 10px;
    padding: 14px 16px;
  }
}

@media (max-width: 560px) {
  /* Filter bar: each field full-width, stacked vertically */
  .market-filter-bar {
    flex-direction: column;
    gap: 10px;
  }

  .market-filter-field,
  .market-filter-search {
    width: 100%;
    min-width: 0;
  }

  .market-filter-actions {
    width: 100%;
  }

  .market-filter-actions .btn {
    flex: 1;
    text-align: center;
  }

  .market-price-amount {
    font-size: 28px;
  }
}

/* ---------------------------------------------------------------------------
   Auth pages (login, signup, password reset, email verify, MFA)

   A single centered card on the white page background, with the brass top
   border used by the featured cards. Form controls are styled by element
   selector inside .auth-form so the allauth/Django widgets need no extra
   classes (keeps the CSP-safe, no-inline-style rule and the markup readable).
   --------------------------------------------------------------------------- */

.auth-shell {
  padding: 56px 24px 72px;
  display: flex;
  justify-content: center;
}

.auth-card {
  width: 100%;
  max-width: 440px;
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 3px solid var(--brass);
  border-radius: 6px;
  box-shadow: 0 2px 14px var(--shadow);
  padding: 32px 30px 30px;
}

.auth-title {
  margin: 0 0 6px;
  font-size: 26px;
}

.auth-intro {
  margin: 0 0 22px;
  color: var(--ink-soft);
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* .form-field / .form-help are defined once in the shared forms section above; only the
   auth-specific input sizing and focus treatment live here. */
.auth-form input,
.auth-form select {
  font: inherit;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--white);
  color: var(--ink);
}

.auth-form input:focus,
.auth-form select:focus {
  outline: 2px solid var(--forest-500);
  outline-offset: 1px;
  border-color: var(--forest-500);
}

/* Field-level and non-field error text. role="alert" set in the template. */
.form-error {
  margin: 0;
  font-size: 14px;
  color: #9a2b2b;
}

.form-error p {
  margin: 0 0 4px;
}

/* Full-width submit button inside the card. */
.btn-block {
  display: block;
  width: 100%;
  text-align: center;
  margin-top: 4px;
}

/* Secondary link rows under the form (forgot password, switch to signup). */
.auth-links {
  margin: 16px 0 0;
  font-size: 14px;
}

.auth-alt {
  margin: 18px 0 0;
  padding-top: 18px;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 14px;
}

/* ---------------------------------------------------------------------------
   Account settings page (Proposal C layout)

   Wide, two-column settings page: identity banner across the top, the profile
   form beside the profile-picture card, then account actions as a tile grid.
   Uses its own wide shell instead of the narrow 440px .auth-card (that card is
   for login/signup). Reuses .auth-form / .form-field for the fields themselves.
   --------------------------------------------------------------------------- */
.settings-shell {
  padding: 40px 24px 72px;
}
.settings-wide {
  max-width: 720px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
/* The profile form stacks its cards + Save button with the same rhythm as the page. */
.settings-form {
  gap: 20px;
}

/* Shared card shell for every settings block. */
.settings-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: 0 2px 14px var(--shadow);
  padding: 22px 24px 24px;
}
.settings-card-title {
  margin: 0 0 16px;
  font-size: 19px;
}

/* Identity banner: avatar + public name + resolved profile URL. */
.settings-banner {
  display: flex;
  align-items: center;
  gap: 20px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: 0 2px 14px var(--shadow);
  padding: 22px 24px;
}
.settings-banner-name {
  margin: 0;
  font-size: 26px;
}
.settings-banner-url {
  margin: 6px 0 0;
  color: var(--ink-soft);
  font-size: 14px;
  word-break: break-all;
}
.settings-banner-url a {
  color: var(--brass-dk);
}

/* Banner picture controls, pushed to the right of the name/URL. */
.settings-banner-id {
  flex: 1;
  min-width: 0;
}
.settings-banner-actions {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  text-align: right;
}
.settings-pic-form {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}
.settings-pic-label {
  font-weight: 700;
  font-size: 13px;
  color: var(--ink);
}
.settings-pic-form input[type="file"] {
  font: inherit;
  font-size: 13px;
  max-width: 220px;
}
.settings-pic-remove {
  margin: 0;
}
/* The real file input is hidden; the "Change picture" label-button opens it (for=) and
   avatar-upload.js submits on pick. Kept in the tab order + screen-reader tree (not
   display:none) so keyboard users can still reach it. */
.settings-pic-file input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Account actions as a scannable stack of tiles. */
.settings-tiles {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.settings-tile {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 15px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--mist-2);
  color: var(--ink);
  text-decoration: none;
}
.settings-tile:hover {
  border-color: var(--forest-300);
  background: var(--white);
  text-decoration: none;
}
.settings-tile b {
  font-size: 14.5px;
}
.settings-tile span {
  font-size: 12.5px;
  color: var(--ink-soft);
}
.settings-tile--danger {
  background: #fbf3f3;
  border-color: #eccaca;
}
.settings-tile--danger:hover {
  border-color: #d9a3a3;
  background: #fff;
}
.settings-tile--danger b {
  color: #9a2b2b;
}

/* ---------------------------------------------------------------------------
   Sticky save bar (components/_sticky_save.html + static/js/sticky-save.js)

   Reusable floating save control, pinned bottom-right. Left to right: an optional
   Cancel link, the "Unsaved changes" pill, the Save button. Save always floats; the
   pill appears (via JS toggling [hidden]) only while the linked form has edits.
   Not tied to the settings page - reuse on any form.
   --------------------------------------------------------------------------- */
.sticky-save {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 200;
  display: flex;
  align-items: center;
  gap: 10px;
}
.sticky-save-btn {
  padding: 11px 22px;
  font-size: 15px;
  box-shadow: 0 6px 20px rgba(20, 48, 29, 0.22);
}
/* Cancel sits left of the note. Same white pill as the note so the bar reads as one cluster,
   but quiet text so it never competes with Save. .link-quiet is for dark backgrounds only. */
.sticky-save-cancel {
  display: inline-flex;
  align-items: center;
  padding: 8px 15px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: 0 4px 14px var(--shadow);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}
.sticky-save-cancel:hover {
  color: var(--ink);
  text-decoration: none;
}
.sticky-save-note {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 13px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: 0 4px 14px var(--shadow);
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
}
/* Class selector beats the UA [hidden] rule, so restore the hide explicitly. */
.sticky-save-note[hidden] {
  display: none;
}
.sticky-save-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brass);
}
.sticky-save.is-dirty .sticky-save-dot {
  animation: sticky-save-pulse 1.6s ease-in-out infinite;
}
@keyframes sticky-save-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
@media (prefers-reduced-motion: reduce) {
  .sticky-save.is-dirty .sticky-save-dot {
    animation: none;
  }
}

/* Banner controls drop below the name/URL on narrow screens. */
@media (max-width: 560px) {
  .settings-banner {
    flex-wrap: wrap;
  }
  .settings-banner-actions {
    align-items: flex-start;
    text-align: left;
  }
  .settings-pic-form {
    align-items: flex-start;
  }
  /* Cancel + note + Save side by side overflow a phone at full size, so tighten all three. */
  .sticky-save {
    right: 16px;
    bottom: 16px;
    gap: 6px;
  }
  .sticky-save-btn {
    padding: 9px 16px;
    font-size: 14px;
  }
  .sticky-save-cancel,
  .sticky-save-note {
    padding: 6px 10px;
    font-size: 12px;
  }
}

/* Below ~420px even the tightened trio overflows, so the note drops to just its dot. The label
   stays in the DOM (clipped, not display:none) so role="status" still announces the change. */
@media (max-width: 420px) {
  .sticky-save-note {
    padding: 6px;
    gap: 0;
  }
  .sticky-save-note-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* Photo post progress (static/js/photo-upload-progress.js): the submit button turns busy and a
   brass bar (the academy's restyled native <progress>) with a status line sits beside it. Inline
   after the button in a form; a white pill left of Save in the floating save bar, where Cancel and
   the unsaved note step aside while it shows. */
.btn.is-busy {
  cursor: progress;
  white-space: nowrap;
}
.btn-primary.is-busy,
.btn-primary.is-busy:hover {
  background: #e3d3ad;
  color: var(--ink-soft);
}
.btn-green.is-busy,
.btn-green.is-busy:hover {
  background: var(--mist);
  color: var(--forest-700);
}
.upload-progress {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-left: 14px;
  vertical-align: middle;
  font-size: 12px;
  color: var(--ink-soft);
}
.upload-progress .upload-progress-bar {
  flex: 0 0 auto;
  width: 200px;
}
.upload-progress-status {
  white-space: nowrap;
}
.upload-progress.is-error {
  color: #7a2f2f;
}
.upload-progress.is-error .upload-progress-status {
  white-space: normal;
}
.upload-progress-pill {
  max-width: calc(100vw - 32px);
  margin-left: 0;
  padding: 8px 14px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: 0 4px 14px var(--shadow);
}
.sticky-save.is-uploading .sticky-save-cancel,
.sticky-save.is-uploading .sticky-save-note {
  display: none;
}
/* A phone has no room for the pill and the button side by side: the pill goes on top. */
@media (max-width: 560px) {
  .sticky-save.is-uploading {
    flex-direction: column;
    align-items: flex-end;
  }
  .upload-progress {
    gap: 8px;
  }
  .upload-progress .upload-progress-bar {
    width: 90px;
  }
  .upload-progress-pill {
    padding: 6px 10px;
  }
}

/* ---------------------------------------------------------------------------
   Inline formset editor (static/js/formset.js)

   Repeatable child rows (tutorial steps/parts, course chapters) added, removed and
   drag-reordered client-side, saved with the one page-level Save. A removed row is
   hidden (.is-deleted) but stays in the DOM so Django deletes the saved record; the
   DELETE checkbox that drives it is hidden - the Remove button is the visible control.
   --------------------------------------------------------------------------- */
.formset-rows {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-bottom: 16px;
}
.formset-row {
  position: relative;
  padding: 16px 16px 4px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 2px 8px var(--shadow);
}
.formset-row.is-deleted {
  display: none;
}
.formset-row.is-dragging {
  opacity: 0.5;
}
.formset-row-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.formset-row-title {
  font-weight: 700;
  color: var(--ink);
}
/* Step number badge in the row head; formset.js fills it and keeps it in drag order.
   Empty (JS off) it takes no space. */
.formset-row-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 4px;
  border-radius: 50%;
  background: var(--forest-700);
  color: #fff;
  font-size: 12px;
  font-weight: 800;
}
.formset-row-num:empty {
  display: none;
}
.formset-row-spacer {
  flex: 1;
}
/* The DELETE checkbox is driven by the Remove button, never shown directly. */
.formset-delete {
  display: none;
}
.formset-handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--white);
  color: var(--ink);
  font-size: 15px;
  line-height: 1;
  cursor: grab;
}
.formset-handle:active {
  cursor: grabbing;
}
.formset-handle:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}
.formset-empty-note {
  color: var(--muted, #6b7280);
}
/* Collapsible cards: the head stays visible (handle, title, controls); the body folds away
   and a text preview of the first filled field appears while collapsed. */
.formset-row.is-collapsed .formset-row-body {
  display: none;
}
.formset-row-preview {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--muted, #6b7280);
  font-size: 13px;
}
.formset-collapse {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--white);
  color: var(--ink);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.formset-collapse::before {
  content: "\25BE"; /* down chevron when expanded */
}
.formset-row.is-collapsed .formset-collapse::before {
  content: "\25B8"; /* right chevron when collapsed */
}
.formset-collapse:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}
.formset-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
/* Row cap reached (formset.js, data-formset-max): the add controls are disabled and a muted
   note says why. */
[data-formset] .btn:disabled,
[data-formset] [data-formset-quick-add]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.formset-max-note {
  font-size: 13px;
  color: var(--ink-soft);
}
.formset-collapse-all {
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--white);
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
}
.formset-collapse-all:hover {
  border-color: var(--forest-500);
}

/* Avatar component (components/_avatar.html): the caller's circle class does the sizing;
   .avatar-img makes an uploaded picture fill that circle instead of the initials. */
.avatar-img {
  object-fit: cover;
  display: block;
}

/* Profile-picture block on account settings: a large preview + the upload/remove forms. */
.settings-avatar {
  flex: 0 0 auto;
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background: var(--forest-500);
  color: var(--white);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 800;
  font-size: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.settings-avatar-row {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
}
.settings-avatar-row .form-help {
  margin: 0;
}
.settings-avatar-remove {
  margin-top: 10px;
}

/* Live handle-availability status swapped in beside the handle field via HTMX: a status
   chip (green available / red taken / quiet hint), with a glyph painted by CSS. */
.handle-input-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.handle-input-row input {
  flex: 1;
  min-width: 0;
  width: auto;
}
.handle-availability {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}
.handle-availability:empty {
  display: none;
}
.handle-available-ok {
  background: var(--mist);
  border: 1px solid var(--forest-500);
  color: var(--forest-700);
}
.handle-available-ok::before {
  content: "\2713";
}
.handle-available-bad {
  background: #f7ecec;
  border: 1px solid #9a2b2b;
  color: #9a2b2b;
}
.handle-available-bad::before {
  content: "\2715";
}
.handle-available-hint {
  background: var(--mist-2);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  font-weight: 400;
}

/* A second-level heading inside an auth card (e.g. "Add email address"). */
.auth-subtitle {
  margin: 26px 0 14px;
  font-size: 18px;
}

/* Email-management page: one row per address - the address with its status badges underneath
   on the left, the row's own icon actions (components/_icon_action.html) on the right. */
.email-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.email-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 2px;
  border-bottom: 1px solid var(--line);
}
.email-row-main {
  flex: 1;
  min-width: 0;
}
.email-addr {
  display: block;
  font-weight: 700;
  overflow-wrap: anywhere;
}
.email-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 3px;
}
.email-badge {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 2px 8px;
  border-radius: 999px;
}
.email-badge.is-verified {
  background: #e3f0e7;
  color: #1f5b32;
}
.email-badge.is-unverified {
  background: #f6ead0;
  color: #8a6315;
}
.email-badge.is-primary {
  background: var(--mist);
  color: var(--ink-soft);
}

/* Danger button (e.g. remove email). */
.btn-danger {
  background: #9a2b2b;
  color: #fff;
}
.btn-danger:hover {
  background: #7f2222;
}

/* A short code/secret shown to the user (e.g. the MFA otpauth link). */
.auth-code {
  display: block;
  word-break: break-all;
  background: var(--mist-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 10px 12px;
  font-size: 13px;
}

/* MFA enrolment (accounts/mfa_setup.html): QR code + manual setup key fallback.
   The QR frame stays white in every theme: phone cameras need dark modules on a light
   quiet zone, so it must never follow a dark-mode background. */
.mfa-qr {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-bottom: 18px;
}
.mfa-qr-img {
  display: block;
  width: 176px;
  height: 176px;
  padding: 12px;
  background: #ffffff;
  border: 1px solid var(--line);
  border-radius: 6px;
}
.mfa-qr-caption {
  margin: 0;
  font-size: 14px;
  color: var(--ink-soft);
}
.mfa-manual {
  border-top: 1px solid var(--line);
  padding-top: 14px;
  margin-bottom: 20px;
}
/* The setup key: groups of 4 in a fixed 4-column grid, so it always wraps evenly (4 + 4). */
.mfa-key {
  display: grid;
  grid-template-columns: repeat(4, auto);
  justify-content: center;
  gap: 4px 14px;
  font-family: Consolas, "SFMono-Regular", Menlo, monospace;
  font-size: 15px;
  letter-spacing: 1px;
  word-break: normal;
}
.mfa-account {
  margin: 6px 0 0;
  font-size: 12px;
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------------------
   Pager (components/_pagination.html) - shared by every paginated list view.
   --------------------------------------------------------------------------- */
.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  margin: 28px 0 8px;
}
.pager-link {
  color: var(--forest-700);
  font-weight: 600;
  text-decoration: none;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #fff;
}
.pager-link:hover {
  background: var(--mist-2);
}
.pager-link-disabled {
  color: var(--ink-soft);
  opacity: 0.45;
  pointer-events: none;
}
.pager-status {
  color: var(--ink-soft);
  font-size: 14px;
}

/* ---------------------------------------------------------------------------
   Repair tutorials (tutorials app)
   Cards on /tutorials/ and in the issue page's Solutions section, the detail
   page (video embed, steps, parts) and the author edit page. Reuses the
   wiki-issue badge palette so trust/severity read the same everywhere.
   --------------------------------------------------------------------------- */

/* Deep-link context banner above a filter-page layout (e.g. "Parts in: <category>"). */
.filter-page-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  background: var(--mist);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 14px;
  margin: 0 0 16px;
}

/* Reusable filter-page structure (tutorials browse, known-issues list, ...).
   Markup shape:
     <div class="wiki-layout filter-page-layout">
       <aside class="filter-page-aside">
         <p class="wiki-toc-title">Filter</p>
         <form class="market-filter-bar" data-autosubmit> page-specific fields </form>
       </aside>
       <div class="wiki-main"> page-specific results </div>
     </div>
   On very wide screens the first grid column spans the whole white space left of the content
   and the boxed filter (it keeps its mist background) centers inside it, sticky below the
   header, so the content keeps its full width. Below that it is the usual boxed horizontal
   filter bar above the results. filter-autosubmit.js applies the filters on every change. */
.filter-page-aside {
  margin: 0 0 20px;
}
@media (min-width: 1460px) {
  .filter-page-layout {
    grid-template-columns: calc((100vw - 1120px) / 2 - 40px) minmax(0, 1fr);
    margin-left: calc((1120px - 100vw) / 2 + 8px);
  }
  .filter-page-aside {
    position: sticky;
    top: 87px;
    margin: 0;
    /* The 160px floor keeps the fields usable right at the breakpoint, where the white-space
       column is narrower than the box; it then overhangs its column a little on both sides. */
    width: clamp(160px, 100%, 260px);
    justify-self: center;
  }
  .filter-page-aside .market-filter-bar {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    margin: 0;
    /* Without min-width:0 the bar takes its content's min size (the longest field, e.g. a long
       selected trim) as a floor and overhangs the sidebar box on the right. Cap it to the box. */
    min-width: 0;
    max-width: 100%;
  }
  .filter-page-aside .market-filter-field {
    /* Same floor removal on each field, plus a ceiling, so a long value truncates inside the box
       instead of widening the field past the sidebar's right edge. */
    min-width: 0;
    max-width: 100%;
  }
  /* Selects must not exceed the box: their intrinsic (longest option) width is wider. */
  .filter-page-aside .market-filter-input {
    width: 100%;
    min-width: 0;
  }
  /* Search-select fields fill the column like the native selects; a long value truncates via the
     trigger's own overflow/ellipsis (no width cap here - the cap is row-layout only). */
  .filter-page-aside .market-filter-field .search-select {
    width: 100%;
    min-width: 0;
  }
  .filter-page-aside .market-filter-actions {
    align-items: center;
    padding-top: 2px;
  }
}
/* ---------------------------------------------------------------------------
   Faceted filter aside (marketplace results).
   The aside holds link facets with counts (components/_facet_list.html) instead of form
   selects: .market-facets reuses the .market-filter-bar box so the filter-page-aside rules
   above (column layout, sticky) apply unchanged. The vehicle cascade lives in its own bar
   across the top of the results (.market-vehicle-bar) - the car rarely changes once picked.
   --------------------------------------------------------------------------- */

.market-vehicle-bar {
  margin-bottom: 16px;
}

/* Facet groups read top-down; the bar's flex-end (made for aligned form fields) would
   dangle the shorter groups at the bottom edge. */
.market-facets {
  align-items: flex-start;
}

/* No-reload feedback: while a boosted filter request is in flight, htmx puts .htmx-request
   on #browse-content (its hx-indicator), so fade the results until the swap lands. The
   default htmx indicator styles are off (htmx-config includeIndicatorStyles:false). */
#browse-content.htmx-request {
  opacity: 0.55;
  transition: opacity 0.12s ease;
}

/* One facet group (Category / Condition / Country) inside the facets box. */
.facet-group {
  min-width: 160px;
}

.facet-list {
  list-style: none;
  margin: 2px 0 0;
  padding: 0;
}

/* Nested subcategory list under an expanded main category: indented with a tree guide
   line, so the open branch reads like an expanded JSON tree node. */
.facet-list .facet-list {
  margin: 2px 0 8px 9px;
  padding-left: 9px;
  border-left: 1px solid var(--line);
}

/* One facet option: the lead (caret + name) left, the count right, whole row clickable. */
.facet-link {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 3px 6px;
  border-radius: 4px;
  color: var(--ink);
  text-decoration: none;
  font-size: 14px;
}

.facet-link:hover {
  background: var(--white);
}

.facet-lead {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

/* Disclosure triangle on the expandable (main) categories: the template renders a
   right-pointing triangle when collapsed and a down-pointing one when its branch is open -
   the collapsed/open markers of a JSON tree node. Fixed width so the main labels line up;
   subcategories carry no caret. */
.facet-caret {
  display: inline-block;
  width: 0.8em;
  font-size: 11px;
  line-height: 1;
  color: var(--ink-soft);
  text-align: center;
}

.facet-active .facet-caret {
  color: var(--forest-500);
}

/* Main categories read a touch stronger than their subcategories. */
.facet-list > li > .facet-link .facet-name {
  font-weight: 700;
}

/* Subcategories: lighter and slightly smaller, so the two levels are distinct at a glance. */
.facet-list .facet-list .facet-link {
  font-size: 13px;
}

.facet-list .facet-list .facet-name {
  font-weight: 400;
  color: var(--ink-soft);
}

.facet-count {
  font-size: 12px;
  color: var(--ink-soft);
  flex-shrink: 0;
}

/* Options with no matching listings stay visible but muted. */
.facet-zero .facet-name {
  color: var(--ink-soft);
}

/* The active option (either level) always wins the styling; high specificity so it beats
   the main/sub weight rules above. Clicking it again clears the filter. */
.facet-list .facet-link.facet-active .facet-name {
  font-weight: 800;
  color: var(--forest-500);
}

/* Removable active-filter chips above the results; the whole chip links to the URL
   without that filter. */
.filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 14px;
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--mist-2);
  font-size: 13px;
  color: var(--ink);
  text-decoration: none;
}

.filter-chip:hover {
  border-color: var(--forest-500);
}

.filter-chip-x {
  font-weight: 800;
  color: var(--ink-soft);
}

/* Shared table cell helpers (tutorials browse, known-issues list): a title-plus-
   description lead cell, and a no-wrap cell for short facts like durations and counts. */
.table-titlecell {
  min-width: 260px;
}
.table-desc {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--ink-soft);
  line-height: 1.5;
  font-weight: 400;
}
.table-nowrap {
  white-space: nowrap;
}
.tut-table-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* Tutorial card (list card grid): photo-led like iFixit / Autodoc Club. The whole card is one
   link; the photo carries the vehicle stamp, then the title and one meta line. Summary,
   difficulty and step count live on the detail page on purpose. */
.tut-card-link {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--ink);
  text-decoration: none;
}
.tut-card-media {
  position: relative;
  display: block;
  aspect-ratio: 16 / 10;
  border-radius: 8px;
  overflow: hidden;
  background: var(--mist);
  margin-bottom: 4px;
}
.tut-card-media img,
.tut-tile-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* No cover and no step photo: a light mist panel with the known issue's category icon (light,
   so a grid of photo-less tutorials does not turn into a wall of dark green). */
.tut-card-noimg {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: var(--mist);
  color: var(--forest-300);
  font-size: 44px;
}
/* Vehicle stamp on the photo's bottom-left edge: the generation, the engine underneath. */
.tut-card-stamp {
  position: absolute;
  left: 0;
  bottom: 10px;
  max-width: calc(100% - 20px);
  background: var(--forest-900);
  color: var(--white);
  border-left: 4px solid var(--brass);
  padding: 6px 10px 6px 8px;
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 800;
  font-size: 15px;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tut-card-stamp small {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--brass);
}
.tut-card-video {
  position: absolute;
  top: 8px;
  right: 8px;
  background: rgba(20, 48, 29, 0.85);
  color: var(--white);
  font-size: 11px;
  font-weight: 700;
  border-radius: 4px;
  padding: 2px 6px;
}
.tut-card-title {
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 800;
  font-size: 16px;
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: 0.01em;
}
.tut-card-link:hover .tut-card-title,
.tut-tile-link:hover .tut-tile-title {
  color: var(--forest-500);
}
.tut-card-link:hover .tut-card-media img {
  opacity: 0.92;
}
/* One meta line: trust tier (icon + word) then the estimated time. */
.tut-card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--ink-soft);
}
.tut-card-trust {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-weight: 700;
}
.tut-card-verified {
  color: var(--forest-500);
}
.tut-card-community {
  color: var(--brass-dk);
}
/* Header chips on the detail page (still uses the badge row). */
.tut-card-badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

/* Difficulty badges: green -> brass -> red, same scale the severity badges use. */
.tut-badge-easy {
  color: var(--forest-500);
  border-color: var(--forest-300);
  background: #eaf3ec;
}
.tut-badge-intermediate {
  color: var(--brass-dk);
  border-color: var(--brass);
  background: #fbf3e0;
}
.tut-badge-advanced {
  color: #8a1c16;
  border-color: #e6a39e;
  background: #fbeae9;
}

/* Detail page */
/* Detail sidebar: creator card plus the Tools and Parts blocks. The sidebar never takes width
   away from the content column - like the section summary on the left, it hangs in the RIGHT
   page margin, but only once the viewport has room for it (1072px content + 192px summary
   overhang left + 312px sidebar overhang right). Below that it stacks under the content. */
.tut-detail-aside {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 24px;
}
.tut-aside-block {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 14px 16px;
}
@media (min-width: 1460px) {
  /* The base .wiki-layout grid (160px summary + content) is active: keep the stacked sidebar
     in the content column, not under the summary. */
  .tut-detail-layout--with-aside .tut-detail-aside {
    grid-column: 2;
  }
}
@media (min-width: 1700px) {
  /* Room on both sides: the third column spans the white space between the content and the
     right page edge ((100vw - 1120px wrap)/2 + 24px wrap padding, minus the 32px column gap),
     and the sidebar centers inside it so equal margin remains on either side of it.
     Scrolls with the content. */
  .tut-detail-layout--with-aside {
    grid-template-columns: 160px minmax(0, 1fr) calc((100vw - 1120px) / 2 - 40px);
    margin-right: calc((1120px - 100vw) / 2 + 8px);
  }
  .tut-detail-layout--with-aside .tut-detail-aside {
    grid-column: 3;
    grid-row: 1;
    margin-top: 0;
    width: 280px;
    justify-self: center;
  }
}
.tut-author-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
/* Initial-letter avatar: the platform has no profile photos, so a lettermark circle. */
.tut-author-avatar {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--forest-500);
  color: var(--white);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 800;
  font-size: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tut-author-idline {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.tut-author-name {
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 800;
  font-size: 17px;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--ink);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.tut-author-name:hover {
  color: var(--forest-500);
}
.tut-author-since {
  font-size: 13px;
  color: var(--ink-soft);
}
.tut-author-stat {
  font-size: 14px;
  color: var(--ink-soft);
  margin: 0 0 12px;
}
.tut-detail-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
.tut-summary {
  max-width: 72ch;
}
.video-embed {
  position: relative;
  width: 100%;
  max-width: 860px;
  aspect-ratio: 16 / 9;
  /* Centered in its column when the column is wider than the embed. */
  margin: 18px auto;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--forest-900);
}
.video-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.video-embed-fallback {
  margin: 12px 0;
}
/* Click-to-play placeholder (components/_video_embed.html, static/js/video-embed.js): the video's
   own thumbnail, stored and served by Revets, under a large play button; after the click the
   script swaps the box's content for the iframe above. Without a stored thumbnail the box is a
   neutral dark rectangle with the same button. */
.video-embed-placeholder {
  background: var(--ink);
}
/* hqdefault is 4:3 with black bars above and below a 16:9 video; cover crops the bars away. */
.video-embed-thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* The link (no JavaScript) and the button (JavaScript) both fill the box, so the whole picture is
   the click target. Only one of them shows: the script puts js-video-embed on <html>. */
.video-embed-link,
.video-embed-play {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--white);
  cursor: pointer;
}
.video-embed-play {
  display: none;
}
.js-video-embed .video-embed-play {
  display: flex;
}
.js-video-embed .video-embed-link {
  display: none;
}
.video-embed-play-circle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 76px;
  height: 76px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.68);
  border: 2px solid rgba(255, 255, 255, 0.9);
  transition: background-color 0.15s ease, transform 0.15s ease;
}
.video-embed-play-icon {
  width: 38px;
  height: 38px;
  /* The triangle's centre of mass sits left of its box; nudge it so it looks centred. */
  margin-left: 4px;
}
.video-embed-link:hover .video-embed-play-circle,
.video-embed-play:hover .video-embed-play-circle {
  background: var(--forest-500);
  transform: scale(1.06);
}
.video-embed-link:focus-visible,
.video-embed-play:focus-visible {
  outline: 3px solid var(--brass);
  outline-offset: -5px;
}
@media (prefers-reduced-motion: reduce) {
  .video-embed-play-circle {
    transition: none;
  }
  .video-embed-link:hover .video-embed-play-circle,
  .video-embed-play:hover .video-embed-play-circle {
    transform: none;
  }
}
/* The one small line: over the picture, legible on any thumbnail, not part of the click target. */
.video-embed-note {
  position: absolute;
  left: 10px;
  bottom: 10px;
  margin: 0;
  padding: 2px 8px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.7);
  color: var(--white);
  font-size: 0.78rem;
  line-height: 1.4;
  pointer-events: none;
}
@media (max-width: 480px) {
  .video-embed-play-circle {
    width: 60px;
    height: 60px;
  }
  .video-embed-play-icon {
    width: 30px;
    height: 30px;
  }
}

.tut-step-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  counter-reset: tut-step;
}
.tut-step {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 14px 16px;
}
.tut-step-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}
.tut-step-number {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--forest-500);
  color: var(--white);
  font-weight: 800;
  font-size: 14px;
}
.tut-step-title {
  margin: 0;
  font-size: 16px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--ink);
}
.tut-step-content {
  font-size: 15px;
  line-height: 1.55;
}
.tut-step-photo {
  display: inline-block;
  margin-top: 8px;
}
.tut-step-photo img {
  max-width: 320px;
  width: 100%;
  height: auto;
  border-radius: 6px;
  border: 1px solid var(--line);
  display: block;
}
.tut-step-manage-thumb {
  max-width: 160px;
  border-radius: 6px;
  border: 1px solid var(--line);
  display: block;
  margin-top: 6px;
}

.tut-part-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tut-part {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 12px;
}
.tut-part-label {
  font-weight: 700;
  color: var(--ink);
}
/* Sidebar variant: a plain bulleted list, no boxed rows. */
.tut-aside-list {
  margin: 0;
  padding-left: 18px;
}
.tut-aside-list li {
  margin: 4px 0;
  font-size: 14px;
}
.tut-part-note {
  font-size: 13px;
  color: var(--ink-soft);
}
.tut-link-broken {
  color: #8a1c16;
  border-color: #e6a39e;
  background: #fbeae9;
}
.tut-referral-note {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 8px 0 0;
}

/* Issue page: write-a-tutorial CTA + affects chips */
.tut-write-cta {
  margin: 14px 0 0;
}
.page-hero-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}
.page-hero-chips .wiki-issue-affects-label {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.75);
}

/* Author edit page bits */
.tut-inline-delete {
  display: inline;
  margin-left: auto;
}
.tut-inline-delete .chip-link {
  cursor: pointer;
  font: inherit;
  font-size: 13px;
}
.tut-add-title {
  margin: 18px 0 8px;
  font-size: 15px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--ink);
}
.tut-form-hint {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 6px 0 10px;
}

/* Chips inside the dark page hero (tutorial + issue detail): the default chip-link colors
   are made for white backgrounds and vanish on forest-900, so invert them here. */
.page-hero .tut-detail-chips .chip-link,
.page-hero .page-hero-chips .chip-link {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.45);
  background: rgba(255, 255, 255, 0.08);
}
.page-hero .tut-detail-chips .chip-link:hover,
.page-hero .page-hero-chips .chip-link:hover {
  background: rgba(255, 255, 255, 0.18);
}


/* Solutions tile (issue page): iFixit-style small horizontal tile - title and meta on the
   left, square photo on the right. No vehicle stamp: the issue is already the page subject. */
.tut-tile-link {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 72px;
  min-height: 72px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  color: var(--ink);
  text-decoration: none;
}
.tut-tile-link:hover {
  border-color: var(--forest-300);
}
.tut-tile-body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  padding: 8px 10px;
}
.tut-tile-title {
  font-size: 14px;
  font-weight: 700;
  line-height: 1.25;
}
.tut-tile-media {
  display: block;
  background: var(--mist);
}
.tut-tile-media .tut-card-noimg {
  font-size: 24px;
}

/* Solutions grid on the issue page: up to three tiles side by side (the featured cap is
   three), collapsing to two then one column on narrower screens. */
.tut-card-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  align-items: stretch;
}
.tut-card-grid .tut-tile,
.tut-card-grid .tut-tile-link {
  height: 100%;
}
@media (max-width: 900px) {
  .tut-card-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 600px) {
  .tut-card-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------------------------------------------------------------------------
   Global nav search (the search bar in the header + its live dropdown)

   The input sits in the dark header; on focus it flips to a light field. The results panel is
   filled by HTMX and hides itself while empty (:empty), so the reveal needs no JS - nav-search.js
   only adds keyboard nav and outside-click close.
   --------------------------------------------------------------------------- */

.nav-search {
  position: relative;
  flex: 1;
  /* Allow the search to shrink below its input's intrinsic width; without this the flex item
     refuses to shrink on narrow screens and pushes the nav a few px past the viewport edge. */
  min-width: 0;
  max-width: 560px;
  margin: 0 8px;
}

.nav-search-input {
  width: 100%;
  height: 38px;
  padding: 0 14px;
  border-radius: 19px;
  border: 1px solid transparent;
  background: rgba(255, 255, 255, 0.12);
  color: var(--white);
  font-size: 14px;
}
.nav-search-input::placeholder {
  color: #b7c6bb;
}
.nav-search-input:focus {
  outline: none;
  background: var(--white);
  color: var(--ink);
  border-color: var(--brass);
  box-shadow: 0 0 0 3px rgba(199, 154, 58, 0.35);
}
.nav-search-input:focus::placeholder {
  color: var(--ink-soft);
}

.nav-search-panel {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  min-width: 320px;
  max-height: 70vh;
  overflow-y: auto;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 16px 40px rgba(20, 48, 29, 0.18);
  z-index: 200;
}
/* Hide the dropdown whenever it holds no results (its initial and cleared state). */
.nav-search-panel:empty {
  display: none;
}

.nav-search-group {
  padding: 6px 0;
  border-top: 1px solid var(--line);
}
.nav-search-group:first-child {
  border-top: 0;
}
.nav-search-group-head {
  margin: 0;
  padding: 8px 14px 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  font-weight: 800;
}
.nav-search-group-icon {
  margin-right: 4px;
}

.nav-search-hit {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  color: var(--ink);
  text-decoration: none;
}
.nav-search-hit:hover,
.nav-search-hit.is-active {
  background: var(--mist);
  text-decoration: none;
}
.nav-search-hit-thumb {
  width: 40px;
  height: 40px;
  border-radius: 6px;
  object-fit: cover;
  background: var(--mist-2);
  flex-shrink: 0;
}
.nav-search-hit-thumb-empty {
  display: grid;
  place-items: center;
  font-size: 18px;
  color: var(--forest-300);
}
.nav-search-hit-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.nav-search-hit-label {
  font-weight: 700;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.nav-search-hit-sub {
  font-size: 12px;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nav-search-all {
  display: block;
  padding: 10px 14px;
  text-align: center;
  font-weight: 700;
  font-size: 13px;
  color: var(--brass-dk);
  background: var(--mist-2);
  border-top: 1px solid var(--line);
}
.nav-search-all:hover,
.nav-search-all.is-active {
  background: var(--mist);
  text-decoration: none;
}

.nav-search-empty {
  padding: 16px 14px;
  color: var(--ink-soft);
  font-size: 14px;
}

/* The header hides the text nav links below 900px; let the search bar take the freed room, and
   keep its dropdown inside the viewport on small screens. */
@media (max-width: 900px) {
  .nav-search {
    max-width: none;
  }
}
@media (max-width: 560px) {
  .nav-search {
    margin: 0 6px;
  }
  .nav-search-panel {
    min-width: 0;
    left: auto;
    right: 0;
    width: min(92vw, 360px);
  }
}

/* ---------------------------------------------------------------------------
   Global search results page (/search/)
   --------------------------------------------------------------------------- */

.search-page {
  padding: 32px 0 64px;
}
.search-page-title {
  margin: 0 0 16px;
}
.search-page-form {
  display: flex;
  gap: 10px;
  max-width: 640px;
  margin-bottom: 28px;
}
.search-page-input {
  flex: 1;
  height: 46px;
  padding: 0 16px;
  font-size: 16px;
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 8px;
}
.search-page-input:focus {
  outline: none;
  border-color: var(--brass);
  box-shadow: 0 0 0 3px rgba(199, 154, 58, 0.3);
}
.search-page-note {
  color: var(--ink-soft);
}

.search-page-group {
  margin-bottom: 28px;
}
.search-page-group-head {
  margin: 0 0 12px;
  padding-bottom: 8px;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
  border-bottom: 2px solid var(--line);
}
.search-page-hits {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 8px;
}
.search-page-hit {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  text-decoration: none;
}
.search-page-hit:hover {
  border-color: var(--brass);
  box-shadow: 0 4px 12px var(--shadow);
  text-decoration: none;
}
.search-page-hit-thumb {
  width: 56px;
  height: 56px;
  border-radius: 6px;
  object-fit: cover;
  background: var(--mist-2);
  flex-shrink: 0;
}
.search-page-hit-thumb-empty {
  display: grid;
  place-items: center;
  font-size: 24px;
  color: var(--forest-300);
}
.search-page-hit-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.search-page-hit-label {
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.search-page-hit-sub {
  font-size: 13px;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ============================================================================
   Academy (courses, chapters, quiz blocks)
   The lesson page stacks .academy-block cards; the quiz form and its graded
   result card share the .academy-quiz-* family. Everything else on the academy
   pages reuses the generic table-*/page-*/filter-page-* families.
   ============================================================================ */
.academy-blocks {
  display: flex;
  flex-direction: column;
  gap: 28px;
  max-width: 760px;
}
.academy-block h2 {
  margin: 0 0 10px;
}
.academy-block-text table {
  border-collapse: collapse;
  margin: 12px 0;
}
.academy-block-text th,
.academy-block-text td {
  border: 1px solid var(--line);
  padding: 6px 10px;
  text-align: left;
}
.academy-block-text blockquote {
  margin: 12px 0;
  padding: 8px 14px;
  border-left: 3px solid var(--brass);
  background: var(--mist-2);
  color: var(--ink-soft);
}
.academy-block-text pre {
  background: var(--mist-2);
  border: 1px solid var(--line);
  padding: 10px 12px;
  overflow-x: auto;
}
.academy-block-quiz {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 16px 18px;
  background: var(--mist-2);
}
.academy-quiz-note {
  color: var(--ink-soft);
  font-size: 14px;
  margin: 0 0 10px;
}
.academy-quiz-question {
  border: 0;
  margin: 0 0 14px;
  padding: 0;
}
.academy-quiz-question legend,
.academy-quiz-question-text {
  font-weight: 700;
  margin: 0 0 6px;
  padding: 0;
}
.academy-quiz-choice {
  display: block;
  margin: 4px 0;
  cursor: pointer;
}
.academy-quiz-score {
  font-weight: 700;
  margin: 0 0 12px;
}
.academy-quiz-right {
  color: var(--forest-500);
  margin: 2px 0;
}
.academy-quiz-wrong {
  color: var(--brass-dk);
  margin: 2px 0;
}
.academy-quiz-explanation {
  color: var(--ink-soft);
  font-size: 14px;
  margin: 4px 0 0;
}
.academy-chapter-nav {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin: 28px 0;
  max-width: 760px;
}
.academy-done {
  color: var(--forest-500);
  font-weight: 700;
}

/* ============================================================================
   List view toggle + shared card grid (academy, tutorials, known-issues overviews)
   The toggle is two links (view=table / view=cards); .card-list-grid is the one
   shared grid, the cards themselves stay app-specific (.academy-card, .issue-card,
   .tut-card) per the components convention.
   ============================================================================ */
.list-view-toggle {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
  margin: 0 0 14px;
}
.list-view-option {
  padding: 4px 12px;
  font-size: 13px;
  text-decoration: none;
  color: var(--ink-soft);
  background: var(--white);
}
.list-view-option + .list-view-option {
  border-left: 1px solid var(--line);
}
.list-view-active {
  background: var(--forest-500);
  color: var(--white);
  font-weight: 700;
}
/* One row holding the view toggle and (cards view) the Sort by dropdown
   (components/_sort_select.html). The toggle's own bottom margin moves to the row. */
.list-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 14px;
}
.list-controls .list-view-toggle,
.list-controls .market-view-toggle {
  margin: 0;
}
.sort-select-form {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.sort-select-label {
  font-size: 13px;
  color: var(--ink-soft);
}
.sort-select {
  padding: 4px 8px;
  font-size: 13px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--white);
  color: var(--ink);
}
/* Sortable table headers (components/_sort_th.html): the label is a link that keeps
   the header's look; the active column shows a direction arrow and stays bold. */
.sort-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: inherit;
  text-decoration: none;
}
.sort-link:hover,
.sort-link:focus {
  text-decoration: underline;
}
.sort-arrow {
  font-size: 9px;
  line-height: 1;
}
.card-list-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  /* stretch: every card in a row gets the same height (fixed below). */
  align-items: stretch;
}
@media (max-width: 900px) {
  .card-list-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 600px) {
  .card-list-grid {
    grid-template-columns: 1fr;
  }
}
/* Tutorial cards size to their photo instead of the grid's fixed card height; cards in a row
   still line up because the grid stretches them. */
.card-list-grid > article.tut-card {
  height: auto;
  overflow: visible;
}

/* Academy course card ("progress card"): image header, topic/level line, title, the
   viewer's own status (progress bar / completed / chapter count + trust badge) and a
   footer call to action. Inside .card-list-grid it fills the shared fixed height; the
   footer is pushed to the bottom by the flexible body. */
.academy-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}
.academy-card-media {
  display: block;
  flex: 0 0 auto;
  height: 120px;
  background: linear-gradient(135deg, var(--forest-500) 0%, var(--forest-900) 135%);
}
.academy-card-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* No image: the site-wide "R" placeholder, as in the tables. */
.academy-card-noimg {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--mist);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 34px;
  font-weight: 800;
}
.academy-card-body {
  flex: 1;
  padding: 10px 14px 8px;
  min-height: 0;
}
.academy-card-meta {
  margin: 0 0 4px;
  font-size: 12px;
  color: var(--ink-soft);
}
.academy-card-title {
  margin: 0 0 8px;
  font-size: 16px;
}
.academy-card-title a {
  color: var(--ink);
}
/* Course table: the viewer's progress cell (bar above its "x of y" count). */
.academy-table-progress {
  min-width: 110px;
}
.academy-table-progress .academy-progress {
  display: block;
  width: 100%;
  margin: 0 0 3px;
}

/* Two-line teaser; longer summaries end in an ellipsis. */
.academy-card-summary {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--ink-soft);
}
.academy-card-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 13px;
  color: var(--ink-soft);
}
.academy-card-done {
  color: var(--forest-500);
  font-weight: 700;
}
.academy-card-progress {
  display: block;
  width: 100%;
  max-width: none;
  margin: 0 0 4px;
}
.academy-card-cta {
  flex: 0 0 auto;
  padding: 8px 14px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  font-weight: 700;
  color: var(--brass-dk);
}
.academy-card-cta:hover {
  background: var(--mist-2);
  text-decoration: none;
}


/* ---------------------------------------------------------------------------
   Academy landing (/academy/ without filters): topic tiles + Continue learning.
   The tiles reuse the marketplace category tile (market-cat-*); only the course
   count and the continue rows are academy-specific.
   --------------------------------------------------------------------------- */

/* Section heading with its "see all" link on the right. The h2 keeps the shared
   market-section-title size; its top margin moves to the row so the link aligns. */
.academy-home-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 28px 0 14px;
}
.academy-home-head .market-section-title {
  margin: 0;
}

.academy-topic-tile .market-cat-title {
  margin-bottom: 2px;
}
.academy-topic-count {
  margin: 0;
  font-size: 13px;
  color: var(--ink-soft);
}

.academy-continue-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--line);
}
.academy-continue-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}
/* Small thumbnail slot; the green block is the fallback when a course has no image. */
.academy-continue-thumb {
  flex: 0 0 72px;
  height: 48px;
  border-radius: 6px;
  overflow: hidden;
  background: linear-gradient(135deg, var(--forest-500) 0%, var(--forest-900) 135%);
}
.academy-continue-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.academy-continue-body {
  flex: 1;
  min-width: 0;
}
.academy-continue-title {
  display: block;
  font-weight: 700;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.academy-continue-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
}
.academy-continue-count {
  font-size: 13px;
  color: var(--ink-soft);
  white-space: nowrap;
}
/* Native <progress>, restyled: brass fill on a line-coloured track. */
.academy-progress {
  flex: 1;
  max-width: 320px;
  height: 6px;
  border: 0;
  border-radius: 3px;
  background: var(--line);
  appearance: none;
  -webkit-appearance: none;
  overflow: hidden;
}
.academy-progress::-webkit-progress-bar {
  background: var(--line);
  border-radius: 3px;
}
.academy-progress::-webkit-progress-value {
  background: var(--brass);
  border-radius: 3px;
}
.academy-progress::-moz-progress-bar {
  background: var(--brass);
  border-radius: 3px;
}
@media (max-width: 520px) {
  .academy-continue-thumb {
    display: none;
  }
}
/* Known-issue card - "inspection sheet" layout (see taxonomy/wiki/_issue_card.html):
   head (category chip, severity meter, trust mark), title, summary, a Fits/Area glance
   table pinned above the foot, and a vote + comments foot. The trust tier sets the top
   border: forest for verified, brass for community. */
.issue-card {
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 3px solid var(--forest-500);
  border-radius: 0 0 8px 8px;
  padding: 12px 14px;
}
.issue-card-community {
  border-top-color: var(--brass);
}
.issue-card-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 8px;
}
.issue-card-cat {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 6px;
  background: var(--mist);
  color: var(--forest-500);
  font-size: 18px;
}
.issue-card-sev {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Three segments; issue-sev-meter-<1..3> fills that many in the severity colour. */
.issue-sev-meter {
  display: flex;
  gap: 3px;
}
.issue-sev-meter > span {
  width: 18px;
  height: 5px;
  border-radius: 2px;
  background: var(--line);
}
.issue-sev-meter-1 > span:nth-child(-n+1) { background: var(--forest-500); }
.issue-sev-meter-2 > span:nth-child(-n+2) { background: var(--brass); }
.issue-sev-meter-3 > span { background: #c0392b; }
.issue-sev-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  line-height: 1.2;
}
.issue-sev-label-minor { color: var(--forest-500); }
.issue-sev-label-moderate { color: var(--brass-dk); }
.issue-sev-label-major { color: #8a1c16; }
.issue-card-trust {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 700;
}
.issue-card-trust .icon {
  font-size: 14px;
}
.issue-card-trust-verified { color: var(--forest-500); }
.issue-card-trust-community { color: var(--brass-dk); }
.issue-card-title {
  margin: 0 0 6px;
  font-size: 16px;
}
.issue-card-title a {
  color: var(--ink);
}
.issue-card-title a:hover {
  color: var(--forest-500);
}
.issue-card-summary {
  margin: 0 0 10px;
  font-size: 14px;
  color: var(--ink-soft);
}
.issue-card-facts {
  margin: auto 0 0;
  font-size: 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  overflow: hidden;
}
.issue-card-facts > div {
  display: flex;
  gap: 8px;
  padding: 4px 8px;
}
.issue-card-facts > div + div {
  border-top: 1px solid var(--line);
  background: var(--mist-2);
}
.issue-card-facts dt {
  flex: none;
  width: 44px;
  color: var(--ink-soft);
}
.issue-card-facts dd {
  margin: 0;
  min-width: 0;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.issue-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 8px;
}
.issue-card-foot .wiki-issue-vote {
  margin-top: 0;
}
/* Count-only vote pill on the card; the label stays for screen readers. */
.issue-card-foot .wiki-vote-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ============================================================================
   Academy block editor (chapter_edit.html): one boxed card per block with a
   badge/reorder/delete header, the block's own form, and the slideshow/quiz
   sub-editors underneath.
   ============================================================================ */
.academy-editor-block {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 14px 16px;
  margin: 0 0 18px;
  background: var(--white);
}
.academy-editor-block-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 10px;
}
.academy-editor-block-pos {
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 700;
}
.academy-editor-sub {
  border-top: 1px solid var(--line);
  margin-top: 14px;
  padding-top: 12px;
}
.academy-editor-thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.academy-editor-thumb {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.academy-editor-thumb-img {
  width: 120px;
  height: 90px;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid var(--line);
}
.academy-editor-question {
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 10px 12px;
  margin: 0 0 12px;
  background: var(--mist-2);
}
.academy-editor-choices {
  list-style: none;
  margin: 8px 0;
  padding: 0;
}
.academy-editor-choices li {
  margin: 4px 0;
}

/* Chapter completion (button for quiz-less chapters, checkmark note when done) */
.academy-mark-done {
  margin: 24px 0 0;
  max-width: 760px;
}

/* ============================================================================
   Fixed-size cards in the toggle card grids (academy, tutorials, known issues).
   Every card is the same height; titles clamp to 2 lines and summaries to 4
   (ellipsis via line-clamp), anything longer is cut off, and a "..." link
   pinned to the card bottom opens the detail page. The link is hidden outside
   these grids so the issue-page Solutions cards keep their natural size.
   ============================================================================ */
.card-list-grid > article,
.issue-slider-track > article {
  display: flex;
  flex-direction: column;
  height: 300px;
  overflow: hidden;
}
.card-list-grid .academy-card-title,
.issue-slider-track .issue-card-title,
.card-list-grid .issue-card-title,
.card-list-grid .tut-card-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
.card-list-grid .issue-card-summary,
.issue-slider-track .issue-card-summary {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
}
.card-more {
  display: none;
}
.card-list-grid .card-more {
  display: block;
  margin-top: auto;
  padding-top: 6px;
  color: var(--forest-500);
  font-weight: 800;
  font-size: 18px;
  line-height: 1;
  letter-spacing: 2px;
  text-decoration: none;
}
.card-list-grid .card-more:hover {
  color: var(--brass-dk);
}

/* Section heading with an action button beside it (My courses page) */
.academy-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 10px;
}
.academy-section-head .wiki-section-title {
  margin: 0;
}

/* ---------------------------------------------------------------------------
   Notifications (the navbar bell + the bell page + the settings page)
   --------------------------------------------------------------------------- */

/* Bell icon in the navbar: a plain link with an absolutely positioned unread badge. */
.nav-bell {
  position: relative;
  display: inline-flex;
  align-items: center;
  color: #cdd9d0;
  padding: 4px;
}
.nav-bell:hover {
  color: var(--white);
  text-decoration: none;
}
/* Bell glyph size (previously set via width/height attributes on the inline SVG,
   now that it renders through the shared .icon sprite component). */
.nav-bell-icon {
  width: 20px;
  height: 20px;
}
.nav-bell-badge {
  position: absolute;
  top: -4px;
  right: -6px;
  min-width: 16px;
  padding: 1px 4px;
  border-radius: 9px;
  background: var(--brass);
  color: var(--forest-900);
  font-size: 11px;
  font-weight: 800;
  line-height: 14px;
  text-align: center;
}

/* Bell page: title row with the Mark all read / Clear all / Settings actions beside it. */
.notif-shell {
  padding: 28px 24px 48px;
}
.notif-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.notif-title {
  margin: 0;
}
.notif-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}
.notif-actions form {
  margin: 0;
}
/* The action buttons sit inside POST forms; reset the button chrome so they read as the
   same quiet links as the Settings anchor next to them. */
.notif-actions button.link-quiet {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  color: var(--ink-soft);
  font-weight: 700;
  text-transform: none;
  font-size: 13px;
  letter-spacing: 0.04em;
}
.notif-actions button.link-quiet:hover {
  color: var(--ink);
}
/* On the light page background the quiet-link grey from the dark navbar is too pale. */
.notif-actions a.link-quiet {
  color: var(--ink-soft);
}
.notif-actions a.link-quiet:hover {
  color: var(--ink);
}
.notif-actions .notif-action-danger,
.notif-actions .notif-action-danger:hover {
  color: #a33a2a;
}

/* components/_notification_settings_link.html - the small gear + text link dropped on the bell
   page, the watchlist and My requests so the per-kind switches are findable from all three.
   Default colours match .link-quiet's own default: both watchlist and My requests drop it into
   the dark green .page-hero, so the pale grey/white pair is what reads there. */
.notif-settings-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: #cdd9d0;
  font-weight: 700;
  text-transform: none;
  font-size: 13px;
  letter-spacing: 0.04em;
}
.notif-settings-link:hover {
  color: var(--white);
  text-decoration: none;
}
.notif-settings-link-icon {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* The bell page's header sits on the plain light page background (.notif-shell), not a
   .page-hero - same "too pale on light" fix as .notif-actions a.link-quiet just above. The
   profile's Requests tab toolbar (My requests) sits on the same light background. */
.notif-actions .notif-settings-link,
.profile-tab-actions .notif-settings-link {
  color: var(--ink-soft);
}
.notif-actions .notif-settings-link:hover,
.profile-tab-actions .notif-settings-link:hover {
  color: var(--ink);
}

/* The list itself: one full-width link per row, unread rows tinted and edge-marked. */
.notif-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}
.notif-item + .notif-item {
  border-top: 1px solid var(--line);
}
/* The row is now the link (text + time) PLUS a small actions column beside it - the link no
   longer fills the whole row alone, since a <button> cannot nest inside it (invalid HTML). */
.notif-item {
  display: flex;
  align-items: stretch;
}
.notif-link {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 16px;
  color: var(--ink);
}
.notif-item-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  padding: 0 16px;
}
.notif-link:hover {
  background: var(--mist-2);
  text-decoration: none;
}
.notif-item-unread .notif-link {
  background: var(--mist);
  box-shadow: inset 3px 0 0 var(--brass);
  font-weight: 700;
}
.notif-item-unread .notif-link:hover {
  background: var(--mist-2);
}
.notif-time {
  flex-shrink: 0;
  color: var(--ink-soft);
  font-size: 13px;
}
.notif-empty {
  color: var(--ink-soft);
  padding: 24px 0;
}

/* ---------------------------------------------------------------------------
   Settings side menu + section cards - shared by the two settings pages
   (core/notification_settings.html, account/settings.html). A sticky menu of in-page links
   sits next to a column of white section cards; settings-menu.js highlights the link of the
   card at the top of the viewport. The sticky offsets clear the sticky .site-header.
   --------------------------------------------------------------------------- */
.settings-page {
  padding: 28px 24px 96px;
}
.settings-page-intro {
  margin: 4px 0 0;
  color: var(--ink-soft);
}
.settings-menu-layout {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: 28px;
  align-items: start;
  max-width: 920px;
}
.settings-menu {
  position: sticky;
  top: 76px;
  font-size: 14px;
}
.settings-menu-title {
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  margin: 0 0 8px;
}
.settings-menu ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.settings-menu-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 10px;
  border-radius: 6px;
  color: var(--ink);
  text-decoration: none;
}
.settings-menu-link:hover,
.settings-menu-link.is-current {
  background: var(--mist);
  text-decoration: none;
}
.settings-menu-link.is-current {
  font-weight: 700;
}
/* Footer links under the list (back to notifications, the other settings page). */
.settings-menu-foot {
  margin: 16px 0 0;
  padding: 12px 10px 0;
  border-top: 1px solid var(--line);
  font-size: 13px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.settings-menu-foot a {
  color: var(--ink-soft);
  font-weight: 700;
  text-decoration: none;
}
.settings-menu-foot a:hover {
  color: var(--ink);
}
.settings-sections {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.settings-section {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 16px 20px 18px;
  scroll-margin-top: 76px;
}
.settings-section-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 10px;
}
.settings-section-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--mist);
  color: var(--forest-500);
  font-size: 17px;
  flex-shrink: 0;
}
.settings-section-title {
  flex: 1;
  margin: 0;
  font-size: 18px;
}
.settings-section-note {
  margin: 0 0 10px;
  color: var(--ink-soft);
  font-size: 13px;
}

/* Limit usage (components/_limit_usage.html): the "Your limits" section of the account settings
   and the business dashboard card. The section, the card and every group are native <details>,
   closed by default; the summaries carry the FAQ's "+" / "-" marker. The bar is a <meter>: its
   low / high attributes pick the colour (green, brass from 80%, red when full), styled through the
   meter pseudo-elements so no inline style is needed (strict CSP). */
.limit-usage > summary,
.limit-usage-group > summary {
  cursor: pointer;
  list-style: none;
}
.limit-usage > summary::-webkit-details-marker,
.limit-usage-group > summary::-webkit-details-marker {
  display: none;
}
.limit-usage-summary {
  display: flex;
  align-items: center;
  gap: 10px;
}
.limit-usage:not([open]) > .limit-usage-summary {
  padding-bottom: 0;
}
.limit-usage-summary::after,
.limit-usage-group-summary::after {
  content: "+";
  margin-left: auto;
  font-size: 22px;
  line-height: 1;
  font-weight: 400;
  color: var(--brass-dk);
}
.limit-usage[open] > .limit-usage-summary::after,
.limit-usage-group[open] > .limit-usage-group-summary::after {
  content: "\2212";
}
.limit-usage-summary:focus-visible,
.limit-usage-group-summary:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}
.settings-card.limit-usage > .limit-usage-summary .settings-card-title {
  margin: 0;
}
.limit-usage-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  background: #fbe9e7;
  color: #b3261e;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}
.limit-usage-tier {
  margin: 0 0 6px;
  font-size: 14px;
  color: var(--ink-soft);
}
.limit-usage-tier strong {
  color: var(--ink);
}
.limit-usage-group {
  margin-top: 12px;
}
.limit-usage-group-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
}
.limit-usage-group-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.limit-usage-list {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 10px;
}
.limit-usage-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 6px 16px;
  padding: 10px 14px;
}
.limit-usage-row + .limit-usage-row {
  border-top: 1px solid var(--line);
}
.limit-usage-what {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.limit-usage-label {
  font-weight: 600;
  font-size: 15px;
  color: var(--ink);
}
.limit-usage-more {
  font-size: 13px;
  color: var(--ink-soft);
}
.limit-usage-now {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  min-width: 140px;
  margin-left: auto;
  text-align: right;
}
.limit-usage-count {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
}
.limit-usage-row.is-full .limit-usage-count {
  font-weight: 700;
  color: #b3261e;
}
.limit-usage-reset {
  margin-top: 4px;
  font-size: 12px;
  color: #b3261e;
}
.limit-usage-meter {
  display: block;
  width: 140px;
  height: 6px;
  margin-top: 6px;
  border: 0;
  border-radius: 3px;
  background: var(--mist);
}
.limit-usage-meter::-webkit-meter-bar {
  height: 6px;
  border: 0;
  border-radius: 3px;
  background: var(--mist);
}
.limit-usage-meter::-webkit-meter-optimum-value {
  border-radius: 3px;
  background: var(--forest-500);
}
.limit-usage-meter::-webkit-meter-suboptimum-value {
  border-radius: 3px;
  background: var(--brass);
}
.limit-usage-meter::-webkit-meter-even-less-good-value {
  border-radius: 3px;
  background: #b3261e;
}
.limit-usage-meter:-moz-meter-optimum::-moz-meter-bar {
  border-radius: 3px;
  background: var(--forest-500);
}
.limit-usage-meter:-moz-meter-sub-optimum::-moz-meter-bar {
  border-radius: 3px;
  background: var(--brass);
}
.limit-usage-meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
  border-radius: 3px;
  background: #b3261e;
}
.limit-usage-foot {
  margin: 14px 0 0;
}
/* Two fields side by side in a section card (stacked on phones, see the media query below). */
.settings-field-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0 16px;
}
.settings-fields {
  padding-top: 4px;
}
/* Small pill in a section head, e.g. "Shown publicly" on the business storefront cards. */
.settings-section-badge {
  flex-shrink: 0;
  font-size: 12px;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--mist);
  color: var(--forest-700);
}
.settings-section > .form-field:last-child,
.settings-fields > .form-field:last-child,
.settings-field-pair > .form-field {
  margin-bottom: 4px;
}
.settings-fields > .settings-field-pair + .settings-field-pair,
.settings-fields > .form-field + .settings-field-pair {
  margin-top: 12px;
}
/* A stack of .switch-control rows: label left, pill right, hairline between rows. */
.switch-list .form-field {
  margin: 0;
  border-top: 1px solid var(--line);
}
.switch-list .form-field .switch-control {
  align-items: center;
  justify-content: space-between;
  padding: 11px 0;
}
.switch-list .switch-text {
  font-size: 14px;
}
/* A stack of link rows (icon, title + hint, chevron), e.g. the account security links. */
.settings-link-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.settings-link-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-top: 1px solid var(--line);
  color: var(--ink);
  text-decoration: none;
}
.settings-link-row:hover {
  text-decoration: none;
}
.settings-link-row:hover .settings-link-title {
  color: var(--forest-500);
}
.settings-link-row .icon {
  color: var(--forest-500);
  font-size: 17px;
  flex-shrink: 0;
}
.settings-link-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.settings-link-title {
  font-size: 14px;
  font-weight: 700;
}
.settings-link-hint {
  font-size: 12.5px;
  color: var(--ink-soft);
}
.settings-link-chevron {
  color: var(--ink-soft);
  font-size: 18px;
  line-height: 1;
}
.settings-link-row--danger .icon,
.settings-link-row--danger .settings-link-title,
.settings-link-row--danger:hover .settings-link-title {
  color: #a33a2a;
}

/* Below this the menu moves above the cards as a wrapping row of chips (same move as the legal
   page rail). Must stay BELOW the rules above - media queries add no specificity. */
@media (max-width: 760px) {
  .settings-page {
    padding: 20px 16px 96px;
  }
  .settings-menu-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
  }
  .settings-menu {
    position: static;
  }
  .settings-menu ul {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px;
  }
  .settings-menu-link {
    border: 1px solid var(--line);
    padding: 5px 10px;
    font-size: 13px;
  }
  .settings-menu-foot {
    border-top: 0;
    padding-top: 0;
    margin-top: 10px;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px 16px;
  }
  .settings-section {
    padding: 14px 16px 16px;
  }
  .settings-field-pair {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Notification settings extras: the 'on/total' pill in each menu link (red at 0) and the
   per-group "Turn all on / off" button (revealed by notification-settings.js). */
.notif-pref-count {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 400;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--mist-2);
  border: 1px solid var(--line);
  color: var(--ink-soft);
}
.notif-pref-count.is-none {
  color: #a33a2a;
}
.notif-pref-bulk {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  color: var(--brass-dk);
}
.notif-pref-bulk:hover {
  text-decoration: underline;
}
.notif-pref-bulk[hidden] {
  display: none;
}
.notif-pref-card {
  padding-bottom: 6px;
}

/* Account settings extras: the identity row at the top of the Profile card, and the display
   name + handle side by side (stacked on phones). */
.account-identity {
  display: flex;
  align-items: center;
  gap: 16px;
  padding-bottom: 16px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--line);
}
.account-identity .settings-avatar {
  flex-shrink: 0;
  width: 64px;
  height: 64px;
  font-size: 26px;
}
.account-identity-id {
  flex: 1;
  min-width: 0;
}
.account-identity-name {
  margin: 0;
  font-size: 20px;
}
.account-identity .settings-banner-url {
  margin-top: 2px;
  font-size: 13px;
}
.account-profile-fields {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-top: 12px;
}
@media (max-width: 560px) {
  .account-identity {
    flex-wrap: wrap;
  }
  .account-identity .settings-banner-actions,
  .account-identity .settings-pic-form {
    align-items: flex-start;
    text-align: left;
  }
  .account-identity .settings-banner-actions {
    flex-basis: 100%;
    flex-direction: row;
    align-items: center;
  }
}

/* Business settings (orgs/settings.html): the shared settings layout under the org tab strip;
   bottom room so the floating save bar never covers the last card. */
.org-settings {
  margin-top: 20px;
  padding-bottom: 72px;
}

/* In-page confirm dialog (confirm-submit.js builds it for form[data-confirm]). */
.confirm-dialog {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 22px 24px;
  max-width: 420px;
  box-shadow: 0 12px 32px var(--shadow);
}
.confirm-dialog::backdrop {
  background: rgba(20, 48, 29, 0.45);
}
.confirm-dialog-text {
  margin: 0 0 18px;
  color: var(--ink);
}
.confirm-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
.confirm-dialog-cancel {
  background: var(--mist);
  color: var(--ink);
  border: 1px solid var(--line);
}

/* ------------------------------------------------------------------
   Member profile (/u/<handle>/): hero head, tab strip, comments tab
   ------------------------------------------------------------------ */

/* Hero: avatar + name on the green page-hero. The initials circle keeps the forest fill
   but gains a light ring so it reads against the green background. */
.profile-hero {
  display: flex;
  align-items: center;
  gap: 18px;
}
.profile-avatar {
  flex: 0 0 auto;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--forest-500);
  color: var(--white);
  border: 2px solid rgba(255, 255, 255, 0.55);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 800;
  font-size: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Tab strip: pill links, same pattern as .wiki-sort-tab but a size up (page-level nav). */
/* .section-tabs is the generic twin of .profile-tabs: the same pill tab bar for any sectioned
   page (the /review/ queues, spec 36). Grouped selectors so the two never drift apart. */
.profile-tabs,
.section-tabs {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 20px;
}
.profile-tab,
.section-tab {
  font-size: 14px;
  font-weight: 700;
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid transparent;
  color: var(--ink-soft);
  text-decoration: none;
}
.profile-tab:hover,
.section-tab:hover {
  color: var(--forest-500);
}
.profile-tab.is-active,
.section-tab.is-active {
  background: var(--mist);
  border-color: var(--line);
  color: var(--ink);
}
/* Open-item count on a section tab (the /review/ queues): same brass pill as the unread badge
   on the Messages tabs (.msg-item-badge), so "needs you" reads the same everywhere. */
.section-tab-count {
  display: inline-block;
  min-width: 20px;
  margin-left: 4px;
  padding: 1px 6px;
  border-radius: 10px;
  background: var(--brass);
  color: var(--forest-900);
  font-size: 12px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  text-align: center;
  line-height: 1.4;
}

/* Action row above a tab's content: visibility filter + cards/table toggle + owner CTA.
   The toggle carries its own bottom margin; align-items centre keeps the row tidy. */
.profile-tab-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  justify-content: flex-end;
  margin: 0 0 14px;
}
.profile-tab-actions .list-view-toggle {
  margin: 0;
}
/* "2 of 5 open" next to the Post a request button it limits (the owner's Requests tab). */
.profile-tab-count {
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}
.profile-garage-filter {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-right: auto;
}

/* Segmented control: a boxed toggle group that filters the list inside one tab. Deliberately
   square and quieter than .section-tab, so a filter never reads as a second row of tabs. */
.segmented {
  display: inline-flex;
  flex-wrap: wrap;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}
.segmented-option {
  font-size: 13px;
  font-weight: 700;
  padding: 5px 12px;
  color: var(--ink-soft);
  text-decoration: none;
  background: var(--page);
}
.segmented-option + .segmented-option {
  border-left: 1px solid var(--line);
}
.segmented-option:hover {
  background: var(--mist);
  color: var(--forest-500);
}
.segmented-option.is-active {
  background: var(--mist);
  color: var(--ink);
}

/* "hidden" marker on the owner's switched-off tabs (visitors never see those tabs). */
.profile-tab-hidden-mark {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--ink-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 1px 6px;
  margin-left: 6px;
}

/* About tab: rendered bio prose (markdown output, sanitised server-side). */
.profile-bio {
  max-width: 720px;
}
.profile-bio h2,
.profile-bio h3,
.profile-bio h4 {
  margin: 18px 0 8px;
}
.profile-bio p,
.profile-bio ul,
.profile-bio ol,
.profile-bio blockquote {
  margin: 0 0 12px;
}
.profile-bio blockquote {
  border-left: 3px solid var(--line);
  padding-left: 12px;
  color: var(--ink-soft);
}

/* About tab (templates/account/about/*): the story column and a sidebar of cards. The owner sees
   each block framed with its manage icons; visitors see the content only. Stacks under 900px,
   sidebar first (the short summary before the long story). */
.about-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 260px;
  gap: 24px;
  align-items: start;
}
.about-blocks {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 760px;
}
.about-block.is-owned {
  border: 1px dashed var(--line-strong);
  border-radius: 6px;
  padding: 8px 12px 12px;
}
.about-block.is-editing {
  border-style: solid;
  background: var(--mist-2);
}
.about-block-actions {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 4px;
}
.about-block .garage-gallery,
.about-block .video-embed {
  margin: 0;
}
/* The block gap spaces the story; a block's own first and last elements add nothing to it. */
.about-block .profile-bio > :first-child {
  margin-top: 0;
}
.about-block .profile-bio > :last-child {
  margin-bottom: 0;
}
.about-placeholder {
  margin: 0;
  color: var(--ink-soft);
  font-style: italic;
}
.about-notice {
  margin: 0;
}
.about-add {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.about-add-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.about-add .btn .icon {
  width: 14px;
  height: 14px;
  vertical-align: -2px;
}
.about-add-count {
  margin-left: auto;
  font-size: 12px;
  color: var(--ink-soft);
}
.about-form-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
}
.about-fieldset {
  border: 0;
  margin: 0 0 14px;
  padding: 0;
}
.about-photo-pick {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 8px;
}
.about-photo-tile {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  cursor: pointer;
}
.about-photo-img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border: 1px solid var(--line);
  border-radius: 4px;
}
.about-photo-tile:has(input:checked) .about-photo-img {
  outline: 3px solid var(--forest-500);
  outline-offset: -3px;
}
.about-photo-check {
  display: flex;
  align-items: center;
  gap: 4px;
  color: var(--ink-soft);
  overflow: hidden;
  white-space: nowrap;
}

/* About sidebar cards: numbers, at a glance, links. */
.about-side {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.about-card {
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 12px 14px;
  background: var(--white);
}
.about-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}
.about-card-title {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.about-stats {
  background: var(--mist-2);
}
.about-stats-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}
.about-stat {
  display: flex;
  flex-direction: column;
  padding: 4px 6px;
  border-radius: 4px;
  color: var(--ink);
  text-decoration: none;
}
.about-stat:hover {
  background: var(--mist);
  text-decoration: none;
}
.about-stat-num {
  font-size: 22px;
  font-weight: 700;
  line-height: 1.1;
}
.about-stat-label {
  font-size: 12px;
  color: var(--ink-soft);
}
.about-glance-list {
  margin: 0;
}
.about-glance-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 0;
  border-bottom: 1px solid var(--mist);
  font-size: 14px;
}
.about-glance-row:last-child {
  border-bottom: 0;
}
.about-glance-row dt {
  color: var(--ink-soft);
}
.about-glance-row dd {
  margin: 0;
  font-weight: 600;
  text-align: right;
}
.about-link-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.about-link {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  color: var(--ink);
  font-size: 14px;
  text-decoration: none;
}
.about-link:hover {
  border-color: var(--forest-500);
  background: var(--mist-2);
  text-decoration: none;
}
.about-link .icon {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  color: var(--forest-500);
}
.about-link-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.about-card-form .form-field {
  margin-bottom: 10px;
}
.about-card-form select,
.about-card-form input[type="text"] {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
}
/* One "find me" row: the link pill, then the owner's pencil + trash (always visible, phones have
   no hover). The open row (_link_form.html) takes the full width as a small framed form. */
.about-link-item {
  display: flex;
  align-items: center;
  gap: 6px;
}
.about-link-item .about-link {
  flex: 1 1 auto;
  min-width: 0;
}
.about-link-edit {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  gap: 6px;
  padding: 8px;
  border: 1px solid var(--forest-500);
  border-radius: 6px;
  background: var(--mist-2);
}
/* Same look as the site's .form-field inputs, a size smaller for the sidebar. */
.about-link-edit select,
.about-link-edit input[type="text"] {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  padding: 7px 10px;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  font: inherit;
  font-size: 14px;
  background: var(--white);
  color: var(--ink);
}
.about-link-edit select:focus,
.about-link-edit input[type="text"]:focus {
  outline: 2px solid var(--forest-300);
  border-color: var(--forest-500);
}
.about-link-edit.form-field-invalid input[type="text"] {
  border-color: #7a2f2f;
}
.about-link-edit-actions {
  justify-content: flex-end;
}
/* The plus once the card is full: stays visible so its tooltip can say why nothing opens. */
.about-card-head .icon-btn[aria-disabled="true"],
.about-card-head .icon-btn[aria-disabled="true"]:hover {
  cursor: default;
  color: var(--line-strong);
  border-color: var(--line);
}
.about-check label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
}
@media (max-width: 900px) {
  .about-layout {
    grid-template-columns: minmax(0, 1fr);
  }
  .about-side {
    order: -1;
  }
}

/* Rich-text editor (static/js/rich-text.js): toolbar + editing surface over a hidden markdown
   textarea. The surface also carries .profile-bio, so what you type looks like what visitors get. */
.rt {
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: var(--white);
}
.rt:focus-within {
  border-color: var(--forest-500);
}
.rt-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 6px;
  border-bottom: 1px solid var(--line);
  background: var(--mist);
}
.rt-btn {
  min-width: 32px;
  padding: 6px 8px;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: var(--white);
  color: var(--ink);
  font: inherit;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.rt-btn:hover {
  border-color: var(--forest-500);
}
.rt-btn.is-active {
  border-color: var(--forest-500);
  background: var(--forest-500);
  color: var(--white);
}
.rt-btn-bold {
  font-weight: 800;
}
.rt-btn-italic {
  font-style: italic;
}
.rt-linkbar {
  display: flex;
  gap: 4px;
  padding: 6px;
  border-bottom: 1px solid var(--line);
}
.rt-linkbar[hidden] {
  display: none;
}
.rt-linkbar input {
  flex: 1;
  min-width: 0;
}
.rt-surface .ProseMirror {
  min-height: 160px;
  padding: 10px 12px;
  outline: none;
  line-height: 1.6;
}
.rt-source {
  display: none;
}
.rt-count {
  text-align: right;
}
.rt-count.is-over {
  color: #9a2b2b;
  font-weight: 700;
}
/* Tiptap's own base rules (normally injected as a <style> tag, which the CSP forbids; the editor
   runs with injectCSS: false). Copied from @tiptap/core 3.31.4 - update with the bundle. */
.ProseMirror {
  position: relative;
}

.ProseMirror {
  word-wrap: break-word;
  white-space: pre-wrap;
  white-space: break-spaces;
  -webkit-font-variant-ligatures: none;
  font-variant-ligatures: none;
  font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */
}

.ProseMirror [contenteditable="false"] {
  white-space: normal;
}

.ProseMirror [contenteditable="false"] [contenteditable="true"] {
  white-space: pre-wrap;
}

.ProseMirror pre {
  white-space: pre-wrap;
}

img.ProseMirror-separator {
  display: inline !important;
  border: none !important;
  margin: 0 !important;
  width: 0 !important;
  height: 0 !important;
}

.ProseMirror-gapcursor {
  display: none;
  pointer-events: none;
  position: absolute;
  margin: 0;
}

.ProseMirror-gapcursor:after {
  content: "";
  display: block;
  position: absolute;
  top: -2px;
  width: 20px;
  border-top: 1px solid black;
  animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;
}

@keyframes ProseMirror-cursor-blink {
  to {
    visibility: hidden;
  }
}

.ProseMirror-hideselection *::selection {
  background: transparent;
}

.ProseMirror-hideselection *::-moz-selection {
  background: transparent;
}

.ProseMirror-hideselection * {
  caret-color: transparent;
}

.ProseMirror-focused .ProseMirror-gapcursor {
  display: block;
}

/* Account settings: the profile tab switches fieldset. */
/* Plain switch list inside the Public-tabs card (no bordered fieldset box). */
.settings-tab-switches {
  border: 0;
  margin: 12px 0;
  padding: 0;
}
.settings-tab-switch {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 6px 0;
  font-weight: 600;
}
.settings-tab-switch input {
  width: auto;
  margin: 0;
}

/* Owner-only tints for non-public cars in the garage grid: unlisted warm, private muted.
   Visitors only ever receive public cars, so these classes never render for them. */
.garage-card-unlisted {
  background: #fdf6e3;
  border-color: #e4d3a1;
}
.garage-card-private {
  background: var(--mist);
  border-color: var(--line);
  filter: saturate(0.8);
}

/* Comments tab: one bordered row per comment - host line, body excerpt, score. */
.profile-comments {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.profile-comment {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 12px 14px;
}
.profile-comment-context {
  margin: 0 0 8px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--ink-soft);
}
.profile-comment-host {
  font-weight: 700;
}
.profile-comment-score {
  margin: 6px 0 0;
  font-size: 13px;
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------------------
   Fitment picker (marketplace listing form): the catalogue part's verified
   fitment as read-only rows on top, the seller's garage cars as chips, then a
   repeater of BRAND cards, each holding one or more generation rows with an
   optional trim multiselect. Built by fitment-picker.js.
   --------------------------------------------------------------------------- */

.fitment-field {
  display: block;
}

/* The garage-chips and choose-by-brand sections, stacked with a small uppercase heading. */
.fitment-section {
  margin-top: 12px;
}
.fitment-section-label {
  margin: 0 0 4px;
  font-family: "Arial Narrow", "Segoe UI", Impact, sans-serif;
  font-size: 12.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--forest-700);
}

/* "Choose by brand" header row: the section label left, the "Add from garage" dropdown right. */
.fitment-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.fitment-section-head .fitment-section-label {
  margin: 0;
}

/* "Add from garage": the _selector shell (native <details>) as a compact button whose panel lists
   the seller's own cars as toggle rows. The panel stays open while ticking, so several cars go in
   at once; each tick lands in the brand cards, which stay editable. A car the verified fitment
   covers renders ticked and inert. */
.fitment-garage-menu {
  min-width: 0;
}
.fitment-garage-trigger {
  justify-content: flex-start;
  gap: 8px;
  padding: 6px 12px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--forest-700);
}
.fitment-garage-icon {
  font-size: 17px;
}
.fitment-garage-count {
  min-width: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--forest-500);
  color: var(--white);
  font-size: 12px;
  line-height: 20px;
  text-align: center;
}
.fitment-garage-panel {
  left: auto;
  right: 0;
  min-width: 300px;
  padding: 4px 0;
}
.fitment-garage-list {
  display: flex;
  flex-direction: column;
}
.fitment-garage-car {
  display: grid;
  grid-template-columns: 18px 1fr;
  column-gap: 10px;
  align-items: center;
  width: 100%;
  text-align: left;
  padding: 8px 14px;
  border: 0;
  border-radius: 0;
  background: none;
  cursor: pointer;
  font: inherit;
}
.fitment-garage-car:hover {
  background: var(--mist-2);
}
/* The tick box, drawn in CSS so the row stays a plain toggle button (aria-pressed). */
.fitment-garage-car::before {
  content: "";
  grid-row: 1 / span 2;
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--line-strong);
  border-radius: 4px;
  background: var(--white);
  box-sizing: border-box;
}
.fitment-garage-car.is-added::before {
  content: "\2713";
  border-color: var(--forest-500);
  background: var(--forest-500);
  color: var(--white);
  font-size: 11px;
  font-weight: 700;
  line-height: 13px;
  text-align: center;
}
.fitment-garage-car-label {
  font-weight: 600;
  color: var(--ink);
}
.fitment-garage-car-sub {
  grid-column: 2;
  font-size: 12.5px;
  color: var(--ink-soft);
}
.fitment-garage-help {
  margin: 4px 14px 6px;
}

/* "From donor car": a single-choice picker in the same shell and row look as "Add from garage"
   above, full field width. The rows are real radios (visually hidden) with a CSS-drawn circle. */
.car-pick {
  width: 100%;
}
.car-pick-trigger {
  width: 100%;
  justify-content: space-between;
  gap: 8px;
}
.car-pick-current,
.car-pick-placeholder {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: left;
}
.car-pick-placeholder {
  color: var(--ink-soft);
}
.car-pick-current:empty {
  display: none;
}
.car-pick-panel {
  left: 0;
  right: 0;
  padding: 4px 0;
}
.car-pick .car-pick-row {
  display: grid;
  grid-template-columns: 18px 1fr;
  column-gap: 10px;
  align-items: center;
  padding: 8px 14px;
  margin: 0;
  cursor: pointer;
}
.car-pick-row:hover {
  background: var(--mist-2);
}
.car-pick-row input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.car-pick-row::before {
  content: "";
  grid-row: 1 / span 2;
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--line-strong);
  border-radius: 50%;
  background: var(--white);
  box-sizing: border-box;
}
.car-pick-row:has(input:checked)::before {
  border: 5px solid var(--forest-500);
}
.car-pick-row:has(input:focus-visible) {
  outline: 2px solid var(--brass);
  outline-offset: -2px;
}
.car-pick-label {
  font-weight: 600;
  color: var(--ink);
}
.car-pick-none {
  font-weight: 400;
  color: var(--ink-soft);
}
.car-pick-sub {
  grid-column: 2;
  font-size: 12.5px;
  color: var(--ink-soft);
}

/* Status badges in the fitment picker: green = the catalogue's verified fitment (read-only),
   brass = a seller suggestion recorded for later verification. */
.badge-verified {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  border: 1px solid var(--forest-300);
  background: var(--mist);
  color: var(--forest-700);
  font-size: 11.5px;
  font-weight: 600;
}
.badge-suggest {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  border: 1px solid var(--brass);
  background: var(--mist);
  color: var(--brass-dk);
  font-size: 11.5px;
  font-weight: 600;
}
/* The display above beats the UA [hidden] rule; the picker hides the pill via the attribute. */
.badge-suggest[hidden] {
  display: none;
}

/* A LOCKED (verified) generation row inside a brand card: read-only catalogue data, styled
   like a fits-list line - check, the car in bold, the trim summary, a right-aligned
   "Verified fitment" marker. Its verified trims are checked+disabled; the other trims stay
   tickable as suggestions - the per-trim Suggestion badge only shows once its box is ticked. */
.fitment-gen-row.fitment-row-locked {
  border: 1px solid var(--line);
  border-left: 3px solid var(--forest-300);
  background: var(--white);
  border-radius: 6px;
  padding: 4px 12px 6px;
}
.fitment-locked-line {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0 2px;
}
.fitment-locked-check {
  flex: none;
  color: var(--forest-500);
  font-weight: 800;
}
.fitment-locked-label {
  min-width: 0;
  font-size: 14px;
  color: var(--ink);
}
.fitment-locked-badge {
  margin-left: auto;
  flex: none;
  font-family: "Arial Narrow", "Segoe UI", Impact, sans-serif;
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--forest-700);
  white-space: nowrap;
}
.fitment-check input:not(:checked) ~ .fitment-trim-suggest {
  display: none;
}
.fitment-trim-suggest {
  margin-left: 4px;
}
/* Extra ticks beyond the verified set flip the locked row to the yellow own-claim state,
   with a "+N trims" suggestion pill in the header line. */
.fitment-gen-row.fitment-row-locked.fitment-row-suggest {
  border-left-color: var(--brass);
}
.fitment-locked-extra {
  display: none;
  flex: none;
}
.fitment-row-suggest .fitment-locked-extra {
  display: inline-block;
}

/* A brand pinned by verified fitment: static label instead of the picker. */
.fitment-brand-fixed {
  flex: 1;
  padding: 6px 2px;
  color: var(--forest-900);
}

/* Collapse toggle: folds a brand card to just its head so long fits-lists stay scannable. */
.fitment-collapse {
  flex: none;
  width: 32px;
  height: 32px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--white);
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
}
.fitment-collapse:hover {
  color: var(--ink);
}
.fitment-brand-card.is-collapsed .fitment-collapse {
  transform: rotate(-90deg);
}
.fitment-brand-card.is-collapsed [data-fitment-gen-host],
.fitment-brand-card.is-collapsed [data-fitment-add-gen] {
  display: none;
}

/* A generation row folds too: its trims list and whole-generation note hide, the row line stays. */
.fitment-gen-row.is-collapsed .fitment-row-trims,
.fitment-gen-row.is-collapsed .fitment-note {
  display: none;
}
.fitment-gen-row.is-collapsed [data-fitment-collapse-row] {
  transform: rotate(-90deg);
}

/* Deviation marker: a seller row that goes beyond the catalogue's known matches carries the
   yellow/brass bar - same green-vs-yellow convention as the wiki's trim-year boxes
   (green = verified/inherited, yellow = the seller's own claim). */
.fitment-row-suggest {
  border-left-color: var(--brass);
}

/* Collapsed overviews (built by fitment-picker.js at collapse time): a folded card shows a
   one-line summary of its rows; a folded row shows its trim count inline. */
.fitment-card-summary {
  display: none;
}
.fitment-brand-card.is-collapsed .fitment-card-summary {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-top: 6px;
}
.fitment-sum-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--ink-soft);
}
/* The green/yellow square in front of each summary item mirrors the row bars. */
.fitment-sum-item::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--forest-300);
}
.fitment-sum-item.is-suggest::before {
  background: var(--brass);
}
.fitment-row-sum {
  display: none;
}
.fitment-gen-row.is-collapsed .fitment-row-sum {
  display: inline;
  font-size: 12.5px;
  color: var(--ink-soft);
  white-space: nowrap;
}

.fitment-brands {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 8px 0;
}

/* Brand card */
.fitment-brand-card {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 12px;
  background: var(--mist-2);
}
.fitment-brand-head {
  display: flex;
  align-items: center;
  gap: 8px;
}
/* Brand/generation pickers are searchable selects (fitment-picker.js builds them,
   reusing the .search-select kit). Make the control fill the flex row next to the
   remove button, and keep the brand trigger emphasised as before. */
.fitment-brand-head .search-select {
  flex: 1;
  min-width: 0;
}
.fitment-brand-head .search-select-current {
  font-weight: 700;
  color: var(--forest-900);
}

/* Generation rows nested inside a brand card */
.fitment-gen-host {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 8px 0 0 4px;
}
.fitment-gen-row {
  border-left: 2px solid var(--line);
  padding: 2px 0 4px 10px;
}
.fitment-gen-line {
  display: flex;
  align-items: center;
  gap: 8px;
}
.fitment-gen-line .search-select {
  flex: 1;
  min-width: 0;
}

.fitment-remove {
  flex: none;
  width: 32px;
  height: 32px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--white);
  color: var(--ink-soft);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.fitment-remove:hover {
  border-color: var(--brass-dk);
  color: var(--brass-dk);
}

/* Trims flow as compact inline chips that wrap; the legend and note each take a full row. */
.fitment-row-trims {
  margin-top: 8px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
}
.fitment-row-trims:empty {
  margin-top: 0;
}
.fitment-trims-legend {
  flex-basis: 100%;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 2px;
}
.fitment-no-trims {
  font-size: 13px;
  color: var(--ink-soft);
}
.fitment-check {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  padding: 2px 4px;
  border-radius: 5px;
  cursor: pointer;
}
.fitment-check:hover {
  background: var(--mist);
}
.fitment-check input {
  margin: 0;
}
.fitment-note {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--brass-dk);
}

/* "Add generation" (inside a card) is a quiet inline link; "Add brand" is a button. */
.fitment-add-gen {
  margin-top: 8px;
  border: none;
  background: transparent;
  color: var(--brass-dk);
  font-size: 13px;
  cursor: pointer;
  padding: 2px 0;
}
.fitment-add-gen:hover {
  text-decoration: underline;
}
.fitment-add-brand {
  margin-top: 4px;
}

/* .btn's display:inline-block beats the UA [hidden] rule; single-vehicle mode hides this button. */
.fitment-add-brand[hidden] {
  display: none;
}

/* ---------------------------------------------------------------------------
   Per-generation parts catalogue (wiki_generation_parts). Reuses the marketplace
   browse layout (facet aside + card grid / list). Parts carry no image, so the
   card is text-only: name, category, OEM number chips, a "for sale" badge.
   --------------------------------------------------------------------------- */
/* Text-only cards size to their content instead of stretching to the row's tallest card
   (grid items default to align-self: stretch), which otherwise leaves an empty gap under the
   shorter cards. Scoped to the catalogue so the image-based marketplace cards stay equal-height. */
.catalog-card {
  align-self: start;
}
.catalog-card .gen-card-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.catalog-card-nums {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.catalog-listing-badge {
  background: var(--forest-500);
  color: var(--white);
  white-space: nowrap;
}
/* When the "for sale" count is a link to the filtered marketplace, keep the badge look + a hover. */
a.catalog-listing-badge {
  text-decoration: none;
}
a.catalog-listing-badge:hover {
  background: var(--forest-700);
}
/* Number chips in the catalogue list link to the part page; keep the chip look, add a hover. */
.catalog-num-link {
  text-decoration: none;
}
.catalog-num-link:hover code {
  background: var(--mist);
  color: var(--brass-dk);
}
/* Marketplace -> catalogue jump shown above the results list when a car is selected. */
.catalog-cta {
  margin: 0 0 14px;
  padding: 10px 14px;
  background: var(--mist-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  color: var(--ink-soft);
}
.catalog-cta a {
  font-weight: 700;
}
/* The car's landing heading above the results once a generation is picked ("BMW 5 Series E34
   parts", marketplace.views._vehicle_landing): the section title flush with the top of the
   results column, then the intro line with the counts and the known-issues / catalogue links. */
.vehicle-landing {
  margin: 0 0 14px;
}
.vehicle-landing .market-section-title {
  margin: 0 0 6px;
}
.vehicle-landing-intro {
  margin: 0;
  font-size: 15px;
  color: var(--ink-soft);
}
.vehicle-landing-intro a {
  font-weight: 700;
}

/* The "Also in the catalogue" strip on a results page: catalogue parts matching the query that
   have no listing for sale right now. Set apart from the listings grid below it. */
.catalog-match-strip {
  margin: 0 0 24px;
  padding: 0 0 18px;
  border-bottom: 1px solid var(--line);
}

/* ---------------------------------------------------------------------------
   Messaging (the inbox list + one conversation)

   The navbar chat bubble reuses .nav-bell / .nav-bell-badge above: it is the same
   control with a different glyph, so there is no second set of badge rules.
   --------------------------------------------------------------------------- */

/* Both use the full content width of .wrap (same as the site nav), and keep its gutters. The
   conversation trims the vertical padding because its height is fixed - see .msg-app-shell. */
.msg-shell {
  padding: 28px 24px 48px;
}
.msg-thread-shell {
  padding: 16px 24px 12px;
}
.msg-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.msg-title {
  margin: 0;
}
/* The inbox tab strip reuses .order-tabs / .order-tab so Messages and My orders read as one
   family; it only drops the full-width rule so it can sit beside the title. */
.msg-tabs {
  border-bottom: none;
  margin: 0;
}
.msg-tabs .order-tab {
  padding: 6px 2px;
}
.msg-tab-badge {
  align-self: center;
  font-size: 11px;
  min-width: 18px;
  padding: 0 5px;
}
/* The "Sold" pill on the Completed tab links to the order; keep it readable as a link. */
.msg-item-sold {
  text-decoration: none;
  align-self: center;
}
.msg-item-sold:hover {
  text-decoration: none;
  filter: brightness(1.08);
}

/* Inbox: one row per conversation. Same framed list as the bell page, with a thumbnail column. */
.msg-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
}
.msg-item + .msg-item {
  border-top: 1px solid var(--line);
}
.msg-link {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  color: var(--ink);
}
.msg-link:hover {
  background: var(--mist-2);
  text-decoration: none;
}
.msg-item-unread .msg-link {
  background: var(--mist);
  box-shadow: inset 3px 0 0 var(--brass);
}
.msg-item-unread .msg-link:hover {
  background: var(--mist-2);
}
.msg-item-thumb {
  flex-shrink: 0;
  width: 56px;
  height: 56px;
}
.msg-thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 6px;
  display: block;
}
.msg-thumb-empty {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 6px;
  background: var(--mist-2);
}
.msg-item-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.msg-item-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.msg-item-who {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.msg-item-time {
  flex-shrink: 0;
  color: var(--ink-soft);
  font-size: 13px;
}
.msg-item-subject {
  font-size: 14px;
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.msg-item-snippet {
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.msg-item-unread .msg-item-snippet {
  font-weight: 700;
}
.msg-item-badge {
  flex-shrink: 0;
  min-width: 20px;
  padding: 1px 6px;
  border-radius: 10px;
  background: var(--brass);
  color: var(--forest-900);
  font-size: 12px;
  font-weight: 800;
  text-align: center;
}
.msg-empty {
  color: var(--ink-soft);
  padding: 24px 0;
}

/* ---------------------------------------------------------------------------
   One conversation (rebuilt from the 2026-07-26 mockup)

   The whole thread lives in one bordered pane: header (listing + who + actions menu), the
   safety line, the messages, then the composer. Messages group into RUNS - the sender name
   and time render once per run, and one read receipt sits on the newest run you sent - so a
   long negotiation reads quietly instead of repeating a label above every bubble.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   Conversation as an app shell: the PAGE does not scroll. The navbar, the chat header, the
   banners and the composer stay put, and the message list is the only scrolling region.

   :has() keeps this local to the page - no base-template edit, and every other page keeps its
   normal document scrolling and its footer.
   --------------------------------------------------------------------------- */

/* The body becomes the column: header, then a growing <main>, and the shell fills it. Measuring
   from the header's real height instead of subtracting a magic number keeps this correct if the
   navbar ever changes size. */
body:has(.msg-app-shell) {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
body:has(.msg-app-shell) > main {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
/* The sitewide footer has no place in a fixed-height chat view. */
body:has(.msg-app-shell) .site-footer {
  display: none;
}
.msg-app-shell {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  /* width:100% is load-bearing: as a flex item, .wrap's `margin: 0 auto` would otherwise beat the
     cross-axis stretch and shrink the shell to its content width instead of the 1120px content
     column. With it, max-width + auto margins centre it like every other page. */
  width: 100%;
  padding-bottom: 12px;
}
.msg-app-shell .msg-pane {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.msg-back {
  display: inline-block;
  margin-bottom: 10px;
  color: var(--ink-soft);
}
.msg-back:hover {
  color: var(--ink);
}
/* No overflow:hidden here on purpose: it would create a scroll container and silently kill
   position:sticky for the pinned offer card inside. The full-bleed children round their own
   outer corners instead (see .msg-composer / .msg-composer-closed). */
.msg-pane {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
  /* The anchor for the deal bar's popovers and for the "new messages" jump button. */
  position: relative;
}

/* Header: thumbnail, what the thread is about, who it is with, actions menu. */
.msg-head {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
}
.msg-head-thumb {
  width: 56px;
  height: 56px;
  display: block;
}
.msg-head-thumb .msg-thumb-img,
.msg-head-thumb .msg-thumb-empty {
  width: 56px;
  height: 56px;
}
.msg-head-title {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}
.msg-head-title a {
  font-family: "Arial Narrow", "Segoe UI", Impact, sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  font-weight: 800;
  font-size: 19px;
  color: var(--ink);
}
/* Right-hand column: actions menu on top, the deal terms under it. Bottom-aligned so the price
   sits on the same baseline as the seller line whatever the title wraps to. */
.msg-head-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
}
.msg-head-terms {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  white-space: nowrap;
}
.msg-head-price {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* Status of the listing the thread is about: it can sell mid-conversation. */
.msg-head-pill {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--mist);
  border: 1px solid var(--line);
  color: var(--forest-500);
}
.msg-head-pill-off {
  color: #a33a2a;
}
.msg-head-gone {
  color: var(--ink-soft);
}
.msg-head-who {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 3px;
  font-size: 13px;
  color: var(--ink-soft);
}
.msg-avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--forest-500);
  color: var(--white);
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 700;
  flex-shrink: 0;
}

/* Actions menu: the shared nav-menu disclosure, restyled for a light pane. */
.msg-menu-trigger {
  width: 34px;
  height: 34px;
  border: 1px solid var(--line);
  border-radius: 6px;
  justify-content: center;
  color: var(--ink-soft);
  font-size: 18px;
  line-height: 1;
}
.msg-menu-trigger:hover {
  color: var(--ink);
  border-color: var(--forest-300);
}
.msg-menu[open] .msg-menu-trigger {
  color: var(--ink);
  border-color: var(--forest-300);
}
.msg-menu-panel form {
  margin: 0;
}
.msg-menu-panel button {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 8px 10px;
  border-radius: 4px;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
}
.msg-menu-panel button:hover {
  background: var(--mist-2);
}
.msg-menu-panel .msg-menu-danger {
  color: #a33a2a;
}

/* Safety line: one sentence at the top, read before you type rather than after. */
.msg-safety-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 10px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--mist-2);
  font-size: 13px;
  color: var(--ink-soft);
}
.msg-safety-icon {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  color: var(--brass-dk);
}

.msg-older {
  margin: 14px 0 0;
  text-align: center;
}

/* The thread itself - the one scrolling region in the shell. */
.msg-thread {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  padding: 8px 18px 18px;
}
/* "Load older messages" sits at the top of the scroll area. */
.msg-load-more {
  align-self: center;
  margin: 4px 0 10px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--white);
  color: var(--ink-soft);
  font: inherit;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: none;
  cursor: pointer;
}
.msg-load-more:hover {
  color: var(--ink);
  border-color: var(--forest-300);
}
.msg-load-more.htmx-request {
  opacity: 0.5;
  cursor: default;
}
/* Day divider. NOT sticky: the pinned offer card owns the top of the thread, and two competing
   sticky items just cover each other. (It never actually stuck before either - the pane's
   overflow:hidden disabled it.) */
.msg-day {
  align-self: center;
  margin: 12px 0 10px;
  padding: 3px 12px;
  border-radius: 999px;
  background: var(--mist);
  border: 1px solid var(--line);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
/* Where you stopped reading last time. */
.msg-unread-line {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 14px 0 6px;
  color: #a33a2a;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.msg-unread-line::before,
.msg-unread-line::after {
  content: "";
  flex: 1;
  height: 1px;
  background: rgba(163, 58, 42, 0.4);
}

/* One run: consecutive messages from the same sender, labelled once. */
.msg-run {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  gap: 10px;
  margin: 6px 0;
}
.msg-run-mine {
  grid-template-columns: minmax(0, 1fr);
  justify-items: end;
}
.msg-run-avatar {
  grid-row: span 2;
  align-self: end;
}
.msg-run-meta {
  grid-column: 2;
  margin: 0 0 4px;
  font-size: 12px;
  color: var(--ink-soft);
}
.msg-run-meta strong {
  color: var(--ink);
  font-weight: 700;
}
.msg-run-mine .msg-run-meta {
  grid-column: 1;
  text-align: right;
}
/* Percentage of the row, but capped: in a full-width pane 78% would be ~750px of unbroken line,
   which reads badly. The absolute cap is what keeps a bubble a bubble. */
.msg-stack {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
  max-width: min(78%, 620px);
}
.msg-run-mine .msg-stack {
  grid-column: 1;
  align-items: flex-end;
  max-width: min(72%, 580px);
}
/* Bubble tails point at the speaker; a second bubble in the same run drops the tail. */
.msg-bubble {
  padding: 9px 13px;
  border: 1px solid var(--line);
  border-radius: 12px 12px 12px 3px;
  background: var(--mist);
}
.msg-run-mine .msg-bubble {
  border-radius: 12px 12px 3px 12px;
  background: var(--forest-900);
  border-color: var(--forest-900);
  color: #eef2ef;
}
.msg-bubble + .msg-bubble {
  border-radius: 12px;
}
.msg-bubble-text {
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.msg-bubble-images {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}
.msg-bubble-image .msg-thumb-img {
  width: 96px;
  height: 96px;
}
/* One receipt per thread, under the newest run you sent - not one per bubble. */
.msg-receipt {
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--ink-soft);
}

/* Composer: labelled textarea plus Send, with the attach control and hint underneath. */
.msg-composer {
  border-top: 1px solid var(--line);
  border-radius: 0 0 10px 10px;
  background: var(--mist-2);
  padding: 12px 18px 14px;
}
/* The message field is full width; the actions sit in their own row underneath it. */
.msg-composer-fields {
  display: block;
  margin: 0;
}
.msg-composer-label {
  display: block;
  margin-bottom: 4px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
/* Send is the last item in the action row, pushed to the right edge. */
.msg-composer-send {
  font: inherit;
  font-weight: 700;
  padding: 0 18px;
  height: 38px;
  margin-left: auto;
  border-radius: 6px;
  border: 1px solid var(--brass);
  background: var(--brass);
  color: var(--forest-900);
  cursor: pointer;
}
.msg-composer-send:hover {
  background: var(--brass-dk);
  border-color: var(--brass-dk);
  color: var(--white);
}
.msg-composer-send:focus-visible {
  outline: 2px solid var(--forest-500);
  outline-offset: 2px;
}
/* Action row under the message field: Add photos, the offer trigger, then Send on the right. */
.msg-composer-foot {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 8px;
}
.msg-composer-hint {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--ink-soft);
}
/* Shared by the thread composer and the "ask the seller" box on a listing. Same border, radius
   and focus ring as .form-field inputs so it reads as one form system, with a taller comfortable
   box because people type a paragraph here, not a word. */
.msg-composer-input {
  flex: 1;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-size: 15px;
  line-height: 1.45;
  min-height: 76px;
  resize: vertical;
}
.msg-composer-input::placeholder {
  color: var(--ink-soft);
  opacity: 1;
}
.msg-composer-input:focus {
  outline: 2px solid var(--forest-300);
  border-color: var(--forest-500);
}
.msg-composer-send {
  flex-shrink: 0;
}
.msg-composer-closed {
  margin: 0;
  padding: 14px 18px;
  border-top: 1px solid var(--line);
  border-radius: 0 0 10px 10px;
  color: var(--ink-soft);
  background: var(--mist-2);
}

@media (max-width: 640px) {
  .msg-stack,
  .msg-run-mine .msg-stack {
    max-width: 88%;
  }
  .msg-item-thumb {
    width: 44px;
    height: 44px;
  }
  .msg-head {
    grid-template-columns: 44px minmax(0, 1fr) auto;
  }
  .msg-head-thumb,
  .msg-head-thumb .msg-thumb-img,
  .msg-head-thumb .msg-thumb-empty {
    width: 44px;
    height: 44px;
  }
}

/* "Message the seller" composer in the listing price card (messaging start form). */
.market-contact-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0 0 12px;
}
/* Quiet label above the box, in the same small-caps voice as the other price-card labels. */
.market-contact-label {
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.market-contact-form .market-price-cta {
  margin: 2px 0 0;
}
/* Trust line under the button: what the seller gets to see. */
.market-contact-hint {
  color: var(--ink-soft);
  font-size: 12px;
  line-height: 1.4;
}

/* The inbox row action and the seller's bulk-archive link on a listing. (The per-thread
   archive / mute / block actions moved into the header disclosure - see .msg-menu-panel.) */
.msg-item-action {
  margin: 0;
}
.msg-item-action button.link-quiet,
button.msg-listing-archive {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  color: var(--ink-soft);
  font-weight: 700;
  text-transform: none;
  font-size: 13px;
  letter-spacing: 0.04em;
}
.msg-item-action button.link-quiet:hover,
button.msg-listing-archive:hover {
  color: var(--ink);
}
/* The row is a flex link plus this trailing action; keep the action off the row's click target. */
.msg-item {
  display: flex;
  align-items: center;
}
.msg-item .msg-link {
  flex: 1;
  min-width: 0;
}
.msg-item-action {
  padding: 0 16px;
}
button.msg-listing-archive {
  margin-top: 10px;
}

/* Composer with an attach control: textarea on top, the file input under it. */
.msg-composer-fields {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.msg-composer-attach {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0.04em;
}
.msg-composer-attach input[type="file"] {
  font: inherit;
  font-size: 12px;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}

/* Seller identity line in the listing price card (display_name only, never the email). */
.market-price-seller {
  margin: 0 0 12px;
  color: var(--ink-soft);
  font-size: 14px;
}

/* ---------------------------------------------------------------------------
   Messages inbox: the filter rail, the active-filter row and the bulk toolbar.

   The filter FIELDS reuse the shared .market-filter-* family (marketplace, tutorials,
   known-issues), so only the rail layout lives here. The page-margin filter-page-layout is
   deliberately not reused: its column maths is built around the 1120px content column, while
   the inbox column is narrower.

   Chips reuse the marketplace .filter-chip family.
   --------------------------------------------------------------------------- */

/* One column on narrow screens (rail above the list), two side by side once there is room. */
.msg-layout {
  display: grid;
  gap: 24px;
}
@media (min-width: 900px) {
  .msg-layout {
    grid-template-columns: 250px minmax(0, 1fr);
    align-items: start;
  }
  /* Sticky like the other filter asides: it pins below the header once you scroll past it. */
  .msg-rail {
    position: sticky;
    top: 87px;
  }
}
.msg-main {
  min-width: 0;
}
/* Stack the shared filter bar vertically inside the rail (it is a wrapping row by default). */
.msg-rail .market-filter-bar {
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  margin: 0;
}
.msg-rail .market-filter-field {
  min-width: 0;
}
/* Selects would otherwise size to their longest option and overflow the rail. */
.msg-rail .market-filter-input {
  width: 100%;
  min-width: 0;
}
.msg-filter-check {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
}

/* Active filters on the left, the Sort by dropdown pushed to the right. */
.msg-toolbar-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin: 0 0 12px;
}
.msg-chips {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

/* Bulk toolbar above the list; buttons grey out while nothing is ticked. */
.msg-bulk-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  background: var(--mist-2);
}
.msg-bulk-all {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-soft);
  cursor: pointer;
}
.msg-bulk-count {
  font-weight: 700;
}
.msg-bulk-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}
.msg-bulk-actions button.link-quiet {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  color: var(--ink-soft);
  font-weight: 700;
  text-transform: none;
  font-size: 13px;
  letter-spacing: 0.04em;
}
.msg-bulk-actions button.link-quiet:hover:not(:disabled) {
  color: var(--ink);
}
.msg-bulk-actions button.link-quiet:disabled {
  opacity: 0.45;
  cursor: default;
}
/* The list sits directly under the toolbar, so drop its top corners. */
.msg-bulk-form .msg-list {
  border-radius: 0 0 8px 8px;
}
.msg-item-check {
  display: flex;
  align-items: center;
  padding: 0 0 0 14px;
}
/* Quiet "Muted" marker on a row whose emails are off. */
.msg-item-muted {
  flex-shrink: 0;
  color: var(--ink-soft);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ---------------------------------------------------------------------------
   Offers: the listing price card (make an offer, your standing offer, the seller's
   queue) and the live-offer card in a conversation.
   --------------------------------------------------------------------------- */

/* The offer form is a <details> so it opens with no JS; the summary is styled as the button. */
.offer-panel {
  margin: 0 0 12px;
}
.offer-open-trigger {
  display: block;
  cursor: pointer;
  list-style: none;
}
.offer-open-trigger::-webkit-details-marker { display: none; }
.offer-open-trigger::marker { content: ""; }
.offer-panel[open] .offer-open-trigger {
  border-radius: 6px 6px 0 0;
}
.offer-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  border: 1px solid var(--line);
  border-top: none;
  border-radius: 0 0 6px 6px;
  background: var(--mist-2);
}
/* Amounts in the offer/order forms use the shared form kit: .form-field labels and the
   .form-input-group-flush currency-prefix group (defined with the form kit above). */

/* A buyer who already has a live offer sees its state instead of the form. */
.offer-standing {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 1px solid var(--brass);
  border-radius: 6px;
  background: var(--mist-2);
}
.offer-standing-label,
.offer-card-label,
.offer-standing-note {
  font-size: 12px;
  color: var(--ink-soft);
}
.offer-standing-label,
.offer-card-label {
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.offer-standing-amount {
  font-size: 20px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.offer-reserved-note {
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--mist);
  color: var(--ink-soft);
  font-size: 13px;
}

/* Seller's queue in the price card: best offer first. */
.offer-queue {
  margin: 0 0 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.offer-queue-list {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.offer-queue-item {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.offer-queue-amount {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.offer-queue-who {
  font-size: 13px;
  color: var(--ink-soft);
  flex: 1;
  min-width: 0;
}
.offer-queue-actions {
  display: flex;
  align-items: center;
  gap: 10px;
}
.offer-queue-actions form { margin: 0; }

/* The deal as a second banner under the safety line: status and amount at a glance, the full
   picture in the panel it opens. Same shape and rhythm as .msg-safety-bar so the two read as a pair
   of context strips above the messages. */
.offer-banner {
  position: relative;
  border-bottom: 1px solid var(--line);
  background: var(--mist-2);
}
.offer-banner-line {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 18px;
  font-size: 13px;
  color: var(--ink-soft);
  flex-wrap: wrap;
}
.offer-banner-amount {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.offer-banner-state {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--brass-dk);
}
.offer-banner-more {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: none;
  color: var(--ink-soft);
}
.offer-banner-more:hover { color: var(--ink); }
.deal-pop[open] > .offer-banner-more { color: var(--ink); }

/* The actions live ON the bar (2026-08-01). Pushed right so the amount and state read as a unit on the
   left and the buttons form one group on the right. */
.deal-bar-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.deal-bar-form { margin: 0; }
.deal-bar-actions button.link-quiet {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-soft);
}
.deal-bar-actions button.link-quiet:hover { color: var(--ink); }

/* A control that needs more than one click is a <details> whose panel is an absolute popover anchored
   under ITS OWN trigger - so two open popovers never land on top of each other, and none of them takes
   layout space in a page that cannot scroll. */
.deal-pop {
  position: relative;
  margin: 0;
}
.deal-pop-trigger {
  cursor: pointer;
  list-style: none;
}
.deal-pop-trigger::-webkit-details-marker { display: none; }
.deal-pop-trigger::marker { content: ""; }
.deal-pop > .deal-pop-panel,
.deal-pop > .offer-banner-panel {
  top: calc(100% + 6px);
  left: 0;
}
/* Anchored to the right edge for a trigger that sits at the end of the bar, so the panel cannot run
   off the pane. */
.deal-pop-right > .deal-pop-panel,
.deal-pop-right > .offer-banner-panel {
  left: auto;
  right: 0;
}

/* Narrow pane: the action group drops to its own full-width row and wraps between buttons, instead of
   overflowing the line (measured at a 420px pane - "Accept 130.00 EUR" plus two more does not fit). */
@media (max-width: 620px) {
  .offer-banner-line {
    row-gap: 8px;
    padding: 8px 14px;
  }
  .deal-bar-actions {
    margin-left: 0;
    width: 100%;
    justify-content: flex-start;
  }
  .deal-pop-right > .deal-pop-panel,
  .deal-pop-right > .offer-banner-panel {
    right: auto;
    left: 0;
  }
}
/* The banner's own icon colour tracks the state, so the strip reads at a glance. */
.offer-banner-accepted .msg-safety-icon,
.offer-banner-accepted .offer-banner-state {
  color: var(--forest-500);
}
.offer-banner-declined .msg-safety-icon,
.offer-banner-declined .offer-banner-state,
.offer-banner-expired .msg-safety-icon,
.offer-banner-expired .offer-banner-state {
  color: #a33a2a;
}
.offer-banner-withdrawn .msg-safety-icon,
.offer-banner-withdrawn .offer-banner-state,
.offer-banner-superseded .msg-safety-icon,
.offer-banner-superseded .offer-banner-state {
  color: var(--ink-soft);
}
/* The panel: everything about the deal, plus its actions. An OVERLAY hanging under the banner line,
   not a box in the layout - the conversation is a fixed-height app shell, so a panel that took its
   own space pushed the composer off a page that cannot scroll and made Send unreachable (measured in
   the browser on 2026-08-01, 401px of banner in a 720px viewport). Overlaying keeps every control
   where it was, and matches what the panel is: a popover with the full picture. Capped in height so a
   long panel scrolls itself instead of running off the screen. */
.offer-banner-panel,
.deal-pop-panel {
  position: absolute;
  top: 100%;
  left: 18px;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
  box-shadow: 0 8px 24px var(--shadow);
  width: 340px;
  max-width: 90vw;
  max-height: min(60vh, 460px);
  overflow-y: auto;
  text-align: left;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink);
  cursor: auto;
}
.deal-pop-panel .offer-form { padding: 0; border: 0; }
.offer-card-top {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}
.offer-card-amount {
  font-size: 20px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.offer-card-state {
  margin-left: auto;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--brass-dk);
}
.offer-card-message {
  margin: 0;
  padding: 8px 10px;
  border-radius: 6px;
  background: var(--white);
  border: 1px solid var(--line);
}
.offer-card-note {
  margin: 0;
  font-size: 12px;
  color: var(--ink-soft);
}
.offer-card-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.offer-card-actions form,
.offer-card form {
  margin: 0;
}
.offer-card button.link-quiet {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  color: var(--ink-soft);
  font-weight: 700;
  text-transform: none;
  font-size: 13px;
  letter-spacing: 0.04em;
}
.offer-card button.link-quiet:hover { color: var(--ink); }
.offer-counter summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
}
.offer-counter summary:hover { color: var(--ink); }
.offer-counter[open] summary { margin-bottom: 8px; }
.offer-counter .offer-form {
  border-radius: 6px;
  border-top: 1px solid var(--line);
}

/* The listing form's Offers group: the minimum reads as nested under the switch. */
/* The start-an-offer control lives in the composer's action row, so its panel opens UPWARD as a
   popover instead of reflowing the row (and pushing Send around) when it expands. */
.offer-panel-thread {
  position: relative;
  margin: 0;
}
.offer-panel-thread .offer-open-trigger {
  display: inline-block;
  padding: 8px 14px;
}
.offer-panel-thread > .offer-form {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  z-index: 3;
  width: 300px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--white);
  box-shadow: 0 6px 20px var(--shadow);
}

/* ---------------------------------------------------------------------------
   Orders - the deal itself (03 "The offer and order flow", 2026-08-01 mockup)
   --------------------------------------------------------------------------- */

/* The order takes the offer's banner over once a deal exists, so it reuses .offer-banner and only
   restates the state colours: waiting on you reads brass (act), completed forest (done), the two
   dead ends grey. */
.order-banner-open .msg-safety-icon,
.order-banner-open .offer-banner-state {
  color: var(--brass-dk);
}
.order-banner-completed .msg-safety-icon,
.order-banner-completed .offer-banner-state {
  color: var(--forest-500);
}
.order-banner-none .msg-safety-icon,
.order-banner-none .offer-banner-state,
.order-banner-cancelled .msg-safety-icon,
.order-banner-cancelled .offer-banner-state,
.order-banner-lapsed .msg-safety-icon,
.order-banner-lapsed .offer-banner-state {
  color: var(--ink-soft);
}
/* "It didn't happen" sits inline beside the link to the order, so its form must not break the row. */
.order-cancel-inline,
.order-cancel-inline form {
  display: inline;
  margin: 0;
}
.order-cancel-inline button.link-quiet {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
  color: var(--ink-soft);
}
.order-cancel-inline button.link-quiet:hover { color: var(--ink); }

/* The orders list: tab strip, then bordered rows (a dense list, not a grid of cards). */
.order-tabs {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--line);
  margin: 0 0 4px;
}
.order-tab {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 10px 2px;
  margin-bottom: -1px;
  border-bottom: 3px solid transparent;
  color: var(--ink-soft);
  font-weight: 700;
  text-decoration: none;
}
.order-tab:hover { color: var(--ink); text-decoration: none; }
.order-tab-on {
  color: var(--ink);
  border-bottom-color: var(--brass);
}
.order-tab-count {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}
.order-tabs-side {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 13px;
}
.order-role-on {
  color: var(--ink);
  text-decoration: underline;
}

.order-list {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
}
.order-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 2px;
  border-bottom: 1px solid var(--line);
}
.order-row-thumb {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  border-radius: 8px;
  overflow: hidden;
  background: var(--mist);
  display: block;
}
.order-thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.order-row-body {
  flex: 1;
  min-width: 0;
}
.order-row-title {
  margin: 0;
  font-weight: 700;
}
.order-row-meta {
  margin: 2px 0 0;
  font-size: 13px;
  color: var(--ink-soft);
}

/* One pill carries the whole to-do: your turn, their turn, or done. */
.order-pill {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--mist);
  color: var(--ink-soft);
}
.order-pill-mine {
  background: var(--brass);
  color: var(--forest-900);
}
.order-pill-waiting {
  background: var(--mist-2);
  color: var(--brass-dk);
  border: 1px solid var(--line);
}
.order-pill-done {
  background: var(--forest-500);
  color: var(--white);
}

/* One order's record. The three amounts are the point of the page, so they get the tiles. */
.order-detail {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 720px;
}
.order-detail-line {
  margin: 0;
  color: var(--ink-soft);
}
.order-amounts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
}
.order-amount {
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--mist-2);
}
.order-amount-label {
  display: block;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.order-amount-value {
  font-size: 22px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.order-facts {
  display: grid;
  grid-template-columns: 160px 1fr;
  gap: 8px 16px;
  margin: 0;
  padding: 14px 0 0;
  border-top: 1px solid var(--line);
}
.order-facts dt {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.order-facts dd { margin: 0; }
.order-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--mist-2);
}
.order-confirm-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
}

/* "Listing as agreed on <date>" on the order page: the frozen copy of each listing line, one block
   per line under the same hairline the ratings section uses. The rows are the .order-facts list. */
.order-snapshot {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.order-snapshot-title {
  font-size: 15px;
  margin: 0;
}
.order-snapshot-item {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.order-snapshot-item + .order-snapshot-item {
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.order-snapshot-name {
  font-size: 17px;
  margin: 0;
}
.order-snapshot .order-facts {
  padding-top: 10px;
}
/* The photo grid's cells are wider here than on the pages it was made for, and its fixed 160px image
   height (.garage-photo img) then leaves a green strip under each photo; fill the 4:3 frame instead. */
.order-snapshot .garage-photo img {
  height: 100%;
}
/* The notes above a copy ("the seller changed this listing after the sale", "captured after the
   sale") are the reason to read this section, so they use the body size, not the 12px card note. */
.order-snapshot-note {
  margin: 0;
  font-size: 15px;
  color: var(--ink-soft);
}
.order-snapshot-description p {
  margin: 0 0 8px;
}
.order-snapshot-description p:last-child {
  margin-bottom: 0;
}

@media (max-width: 640px) {
  /* Phone: three thumbnails per row instead of one full-width photo each; a tap opens the photo
     full screen (lightbox.js), so the small size loses nothing. */
  .order-snapshot .garage-photo-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .order-snapshot .garage-photo figcaption { padding: 4px 6px; font-size: 12px; }
  .order-facts { grid-template-columns: 1fr; gap: 2px 0; }
  .order-facts dd { margin-bottom: 8px; }
  .order-row { flex-wrap: wrap; }
  .order-row-body { flex-basis: 60%; }
}

/* ---------------------------------------------------------------------------
   Ratings - stars, the rating form, and the profile's reviews tab
   --------------------------------------------------------------------------- */

/* components/_stars.html. Whole stars in brass plus the number, because a row of glyphs alone tells
   a screen reader nothing and tells a skimmer less than "4.8" does. */
.stars {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  white-space: nowrap;
}
.stars-glyphs {
  color: var(--brass);
  letter-spacing: 1px;
}
.stars-off { color: var(--line); }
.stars-value {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.stars-count {
  font-size: 12px;
  color: var(--ink-soft);
}

/* The rating form: five radios laid out as a star row. No JS and no star-widget library - the inputs
   ARE the control, so it works by keyboard and reads correctly to a screen reader; CSS only makes the
   labels look like stars. */
.order-ratings {
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.order-ratings-title {
  font-size: 15px;
  margin: 0 0 10px;
}
.rating-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: flex-start;
  max-width: 420px;
}
.rating-stars ul,
.rating-stars {
  display: flex;
  gap: 10px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.rating-stars label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.rating-stars label:hover { border-color: var(--brass); }
/* :has() keeps the checked state on the LABEL, so the whole pill highlights rather than a dot. */
.rating-stars label:has(input:checked) {
  background: var(--brass);
  border-color: var(--brass-dk);
  color: var(--forest-900);
}
.rating-stars label:has(input:focus-visible) {
  outline: 2px solid var(--forest-500);
  outline-offset: 2px;
}
.rating-star-input { margin: 0; }

.rating-received {
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--mist-2);
  max-width: 420px;
}
.rating-received-stars { margin: 0 0 6px; font-size: 18px; }
.rating-received-text { margin: 0; }

/* My own posted rating: read only, because a rating is written once (2026-08-02). */
.rating-mine {
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
  max-width: 420px;
}
.rating-mine-date {
  font-size: 12px;
  color: var(--ink-soft);
  margin-left: 8px;
}
/* The addendum is visibly a later addition, not part of the original text: indented off a rule, with
   its own date. */
.rating-addendum {
  margin-top: 10px;
  padding-left: 12px;
  border-left: 2px solid var(--brass);
}
.rating-addendum-label {
  margin: 0 0 2px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* The profile's reviews tab: the two sides of a reputation, then the reviews themselves. */
.profile-reputation {
  display: flex;
  gap: 28px;
  flex-wrap: wrap;
  margin: 0 0 18px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--mist-2);
}
.profile-reputation-side {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 18px;
}
.profile-reputation-label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.profile-reputation-none {
  font-size: 14px;
  color: var(--ink-soft);
}
.profile-rate-nudge {
  margin: 0 0 18px;
  padding: 12px 14px;
  border-left: 3px solid var(--brass);
  background: var(--mist-2);
  border-radius: 0;
}
.profile-rate-list {
  margin: 6px 0 0;
  padding-left: 18px;
}
.profile-reviews {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.profile-review {
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}
.profile-review-top {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0 0 4px;
}
.profile-review-role {
  font-size: 12px;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 700;
}
.profile-review-who {
  margin: 6px 0 0;
  font-size: 13px;
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------------------
   Live thread (polled): the invisible poller and the "new messages" jump
   --------------------------------------------------------------------------- */

/* The pollers must take no space and catch no clicks - they only exist to hold their hx-get. */
.msg-live {
  display: block;
  height: 0;
  overflow: hidden;
}
.nav-badge-poll {
  display: none;
}

/* Shown only when messages arrive while the reader is scrolled up, so nothing moves under them.
   Anchored to the pane's bottom edge, above the composer. */
.msg-jump {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 132px;
  z-index: 5;
  padding: 6px 14px;
  border: 1px solid var(--brass-dk);
  border-radius: 999px;
  background: var(--brass);
  color: var(--forest-900);
  font: inherit;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: none;
  cursor: pointer;
  box-shadow: 0 4px 14px var(--shadow);
}
.msg-jump:hover { background: #d8ab48; }
.msg-jump[hidden] { display: none; }

/* ---------------------------------------------------------------------------
   Site-wide feedback tab + dialog (components/_feedback_tab.html, feedback.js)
   Desktop: a vertical tab hugging the right edge, mid-screen. Mobile: a pill above the
   back-to-top button. Deliberately prominent in the early phase; demote to a footer link later.
   --------------------------------------------------------------------------- */
.feedback-tab {
  position: fixed;
  right: 0;
  top: 50%;
  z-index: 900;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 14px 9px 14px 10px;
  writing-mode: vertical-rl;
  transform: translateY(-50%);
  background: var(--forest-500);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: 8px 0 0 8px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22);
}
.feedback-tab:hover,
.feedback-tab:focus-visible {
  background: var(--forest-700);
  color: #fff;
  text-decoration: none;
}
.feedback-tab-icon {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}
@media (max-width: 699px) {
  .feedback-tab {
    top: auto;
    bottom: 84px;
    right: 16px;
    transform: none;
    writing-mode: horizontal-tb;
    padding: 10px 14px;
    border-radius: 999px;
    font-size: 12px;
  }
}
@media print {
  .feedback-tab { display: none; }
}

.feedback-dialog {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0;
  width: min(560px, calc(100vw - 32px));
  box-shadow: 0 16px 40px var(--shadow);
  color: var(--ink);
}
.feedback-dialog::backdrop {
  background: rgba(20, 48, 29, 0.45);
}
.feedback-dialog-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--mist-2);
  border-radius: 10px 10px 0 0;
}
.feedback-dialog-title {
  margin: 0;
  font-size: 20px;
}
.feedback-dialog-close {
  border: none;
  background: transparent;
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  color: var(--ink-soft);
  padding: 0 4px;
}
.feedback-dialog-close:hover {
  color: var(--ink);
}
.feedback-dialog-body {
  padding: 18px;
  max-height: min(78vh, 720px);
  overflow: auto;
}
.feedback-loading {
  margin: 0;
  color: var(--ink-soft);
}
.feedback-form .form-field {
  margin-bottom: 14px;
}
/* A tighter dropzone for the single screenshot. */
.dropzone-compact {
  padding: 16px 14px;
  gap: 4px;
}
.feedback-notice {
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 1px solid var(--brass);
  border-radius: 6px;
  background: #fff8e8;
  font-size: 14px;
}
/* Submit button: idle label normally; "Sending..." + a disabled look while the HTMX request runs.
   The upload itself is the slow part for a big screenshot, so the wait has to be visible. */
.feedback-submit-busy {
  display: none;
}
.feedback-form.htmx-request .feedback-submit-idle {
  display: none;
}
.feedback-form.htmx-request .feedback-submit-busy {
  display: inline;
}
.feedback-submit[disabled] {
  opacity: 0.75;
  cursor: progress;
}
.feedback-privacy {
  margin: 0 0 12px;
  font-size: 12.5px;
  color: var(--ink-soft);
}
/* Good-faith declaration on the public notice form (core/illegal_content_notice.html): a long
   checkbox label, so the box sits at the top of the first line and the text wraps beside it.
   Overrides the generic .form-field label/input rules, which would bold the label and stretch
   the checkbox full width. */
.notice-declaration-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.form-field .notice-declaration-row input[type="checkbox"] {
  width: auto;
  flex: none;
  margin: 3px 0 0;
}
.form-field .notice-declaration-row label {
  font-weight: 400;
  margin: 0;
}
/* Spare field on the public forms (ContactForm.website in core/forms.py): off-screen, never
   visible, never in the tab order. The class name is bland on purpose: this file and the page
   HTML are public, and a name that says what the field is for tells a bot to leave it empty. */
.form-extra {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
/* Cloudflare Turnstile slot (components/_turnstile.html, only while Turnstile is on): the widget
   is 65px tall; reserving it keeps the submit button from jumping when the widget appears. */
.turnstile-slot {
  min-height: 65px;
  margin: 4px 0 14px;
}
.feedback-thanks {
  text-align: center;
  padding: 12px 6px 6px;
}
.feedback-thanks-title {
  margin: 0 0 6px;
}
.feedback-thanks p {
  margin: 0 0 16px;
  color: var(--ink-soft);
}
/* The no-JS full page: the same fragment inside a form panel; the dialog-only controls stay hidden. */
.feedback-page {
  max-width: 620px;
}

/* ---------------------------------------------------------------------------
   Part requests - the public request board (32-watchlist-and-requests.md).
   The board, the cards and the detail page reuse the existing families
   (filter-page-*, gen-card, market-detail-*, garage-spec-*, wiki-badge); only the
   few request-specific bits below are new.
   --------------------------------------------------------------------------- */

/* A request card has no photo, so it needs its own minimum height to sit level
   with listing cards in a mixed grid, and a little more room for its text. */
.request-card {
  min-height: 150px;
}
.request-card .gen-card-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
/* Who is asking, at the foot of the card: avatar + public name, muted. */
.request-card-who {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: auto;
  font-size: 13px;
  color: var(--ink-soft);
}
/* The "N new matches" badge earns the accent colour - it is the one thing on the
   owner's own list that is news rather than state. */
.request-new-badge {
  font-weight: 600;
}
/* The requester block in the detail page's right column. */
.request-asker {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
/* The owner's action stack: buttons and the one-button forms sit in a row that
   wraps, so a narrow column stacks them instead of overflowing. */
.request-manage {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.request-manage form {
  margin: 0;
}
/* Report: a native <details> disclosure, so it stays quiet until opened (no JS,
   CSP-safe). The panel inside gets normal form spacing. */
.request-report > summary {
  cursor: pointer;
}
.request-report .form-panel {
  margin-top: 10px;
}

/* Safety / legal notice for the restraints branch (components/_safety_notice.html), shown on the
   category browse and a listing's detail page. Warm caution treatment matching the codebase's
   --brass warning accent (same family as .wiki-skeleton-notice and .site-message-warning). */
.safety-notice {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: var(--mist);
  border: 1px solid var(--line);
  border-left: 4px solid var(--brass);
  border-radius: 6px;
  padding: 14px 18px;
  margin: 0 0 24px;
  color: var(--ink-soft);
  font-size: 15px;
}
.safety-notice-icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  color: var(--brass);
  margin-top: 1px;
}
.safety-notice-body {
  min-width: 0;
}
.safety-notice-body strong {
  display: block;
  margin-bottom: 2px;
  color: var(--ink);
}
.safety-notice-body p {
  margin: 0;
}

/* Limit-reached message (components/_limit_reached.html): a member hit an upload or creation
   ceiling. Same panel shape as .safety-notice but a neutral, informational accent - this is not a
   warning about the content, it is a door with a "Contact us" handle on it. */
.limit-notice {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: var(--mist);
  border: 1px solid var(--line);
  border-left: 4px solid var(--ink-soft);
  border-radius: 6px;
  padding: 14px 18px;
  margin: 0 0 24px;
  color: var(--ink-soft);
  font-size: 15px;
}
.limit-notice-icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  color: var(--ink-soft);
  margin-top: 1px;
}
.limit-notice-body {
  min-width: 0;
}
.limit-notice-body strong {
  display: block;
  margin-bottom: 2px;
  color: var(--ink);
}
.limit-notice-body p {
  margin: 0 0 6px;
}
.limit-notice-body p:last-child {
  margin-bottom: 0;
}
.limit-notice-contact {
  font-weight: 600;
  text-decoration: underline;
}
/* The same notice as a flash toast (base.html): the panel IS the toast, so the li goes bare. */
.site-message-limit {
  padding: 0;
  border-left: 0;
  background: transparent;
  box-shadow: none;
  cursor: default;
}
.site-message-limit .limit-notice {
  margin: 0;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
  font-size: 14px;
}

/* "replaced by <number>" note on a superseded part number (catalog_part_detail chip cloud). */
/* Catalogue detail: part numbers + fitments side by side so the listings grid is in view on load.
   Stacks to one column on narrow screens. */
.catalog-detail-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px 32px;
  align-items: start;
  margin-bottom: 44px;
}
.catalog-detail-cols > .wiki-section {
  margin-bottom: 0;
}
@media (max-width: 720px) {
  .catalog-detail-cols {
    grid-template-columns: 1fr;
  }
}

/* Left-aligned variant of the chip cloud (catalogue fitments), overriding the centred default.
   Also drops the default <ul> left padding so the chips line up with the heading and the part
   numbers instead of being indented. */
.chip-cloud-left {
  justify-content: flex-start;
  margin-left: 0;
  padding-left: 0;
  list-style: none;
}

/* Fitment chip as a link to the target's wiki page. Keeps the pill look, adds a hover. */
.chip-fitlink {
  text-decoration: none;
}
a.chip.chip-fitlink {
  display: inline-block;
}
a.chip.chip-fitlink:hover {
  background: var(--forest-500);
  border-color: var(--forest-500);
}
a.chip-suggested.chip-fitlink:hover {
  background: #f3ead0;
}

/* Catalogue part numbers - a vertical list, each number a link to a search for it. Replaces the
   old centred chip cloud (the "replaced by" note was unreadable as tiny grey text inside a chip). */
.partnum-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.partnum-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--mist);
}
.partnum-num {
  font-weight: 700;
  font-size: 15px;
  color: var(--forest-700);
  text-decoration: none;
}
.partnum-num:hover {
  text-decoration: underline;
}
.partnum-type {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}
.partnum-note {
  font-size: 13px;
  color: var(--ink-soft);
}
/* A superseded number: dim it and strike the number; the "replaced by" note is readable dark text. */
.partnum-row-old {
  background: transparent;
}
.partnum-row-old .partnum-num {
  color: var(--ink-soft);
  text-decoration: line-through;
}
.partnum-super {
  margin-left: auto;
  font-size: 13px;
  color: var(--ink-soft);
}
.partnum-super a {
  color: var(--forest-700);
  font-weight: 700;
  text-decoration: none;
}
.partnum-super a:hover {
  text-decoration: underline;
}
/* The current number a buyer should order - a readable green pill. */
.partnum-current {
  margin-left: auto;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--forest-700);
  color: #fff;
  padding: 3px 9px;
  border-radius: 3px;
}

/* User-suggested (unverified) fitment: a cream pill with DARK text (the old .chip white-on-cream
   was unreadable), plus a readable amber "Unverified" badge. */
.chip-suggested {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: #fbf6e8;
  border: 1px dashed var(--brass);
  border-radius: 4px;
  padding: 7px 12px;
  font-weight: 700;
  font-size: 13px;
  color: var(--forest-700);
}
.tier-unverified {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: #8a6d1f;
  color: #fff;
  padding: 2px 7px;
  border-radius: 3px;
}

/* ---------------------------------------------------------------------------
   Donor vehicles (34-donor-vehicles.md) - the "Part out this car" hero actions, the start-mode
   picker cards shared by donor_start.html / donor_form.html, the read-only inventory shelf on
   donor_detail.html, and the donor row card on my_donors.html.
   --------------------------------------------------------------------------- */

/* Hero control row, positioned like .page-hero-watch (top-right of the hero) but for a row of
   buttons instead of a single toggle - donor_detail.html's Edit/View-garage-car controls.
   Distinct from .page-hero-actions (the wiki hero's in-flow CTA row) so the two never collide. */
.page-hero-controls {
  position: absolute;
  top: 20px;
  right: 24px;
  z-index: 3;
  display: flex;
  gap: 10px;
}
/* A quiet link in the hero sits on the dark forest band, so it needs light text and a
   translucent outline instead of the chip-link's on-white colours. */
.page-hero-controls .chip-link {
  color: var(--white);
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: 999px;
  padding: 6px 12px;
  background: rgba(255, 255, 255, 0.06);
  text-decoration: none;
}
.page-hero-controls .chip-link:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: var(--brass);
}

/* The two "Start from" cards (full car / already partly stripped) - donor_start.html and
   donor_form.html via marketplace/_donor_start_mode.html. */
.donor-mode-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
@media (max-width: 640px) {
  .donor-mode-cards {
    grid-template-columns: 1fr;
  }
}
.donor-mode-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 12px 14px;
  cursor: pointer;
  background: var(--white);
}
.donor-mode-card:has(input:checked) {
  border-color: var(--forest-500);
  background: var(--mist);
}
.donor-mode-card input {
  margin-top: 3px;
}
.donor-mode-card-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* One donor as a row card on my_donors.html (marketplace/_donor_card.html). */
.donor-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.donor-card {
  display: flex;
  gap: 14px;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 10px;
  background: var(--white);
}
.donor-card-thumb {
  width: 96px;
  height: 96px;
  object-fit: cover;
  border-radius: 4px;
  flex-shrink: 0;
}
.donor-card-placeholder {
  width: 96px;
  height: 96px;
  border-radius: 4px;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--forest-500) 0%, var(--forest-900) 135%);
  display: grid;
  place-items: center;
  color: rgba(255, 255, 255, 0.5);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 28px;
  font-weight: 800;
}
.donor-card-body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.donor-card-title {
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
}
.donor-card-title:hover {
  text-decoration: underline;
}

/* Small muted note - "N followers get an update", "updated N days ago", start-mode explanations. */
.donor-muted {
  color: var(--ink-soft);
  font-size: 13px;
}

/* ---------------------------------------------------------------------------
   Donor page and its inventory shelf (34-donor-vehicles.md, increments 2 and 7).
   The page keeps the listing detail's two-column top (.market-detail-layout): gallery + facts
   left, condition + seller right. The shelf (marketplace/_donor_shelf.html) sits under it at
   full width, with the category roots in two boxed columns (Inventory.root_columns), each row
   collapsible (static/js/donor-shelf.js toggles .is-open).
   --------------------------------------------------------------------------- */

/* Section head: the title's brass rule moves to the flex wrapper so the meta can sit on it. */
.donor-shelf-block {
  margin-top: 36px;
}
.donor-shelf-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 8px 16px;
  margin: 0 0 16px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--brass);
}
.donor-shelf-head .donor-shelf-heading {
  margin: 0;
  padding: 0;
  border-bottom: 0;
}
.donor-shelf-meta {
  margin: 0;
  color: var(--ink-soft);
  font-size: 15px;
}
.donor-shelf-tabs {
  margin-bottom: 12px;
}
.donor-tab-count {
  color: var(--ink-soft);
  font-weight: 400;
}
.donor-tab-quiet {
  opacity: 0.75;
}
.donor-shelf-hint {
  margin: 0 0 12px;
}

/* Two boxed columns of roots; one column on small screens. */
.donor-shelf-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  align-items: start;
}
@media (max-width: 820px) {
  .donor-shelf-columns {
    grid-template-columns: 1fr;
  }
}

/* The tree box and its rows. A row is the line (chevron, name, state, actions) plus, below it,
   the children list - hidden until the row is open. */
.donor-shelf {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--white);
  overflow: hidden;
}
.donor-shelf-row {
  border-bottom: 1px solid var(--line);
}
.donor-shelf > .donor-shelf-row:last-child {
  border-bottom: none;
}
.donor-shelf-children {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--line);
}
.donor-shelf-children > .donor-shelf-row:last-child {
  border-bottom: none;
}
.donor-shelf-row:not(.is-open) > .donor-shelf-children {
  display: none;
}
.donor-shelf-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  padding: 10px 12px;
}
/* Indent by depth: a child's text lines up with its parent's name (past the chevron). */
.donor-depth-1 > .donor-shelf-line {
  padding-left: 44px;
}
.donor-depth-2 > .donor-shelf-line {
  padding-left: 76px;
}
.donor-depth-3 > .donor-shelf-line {
  padding-left: 108px;
}
.donor-depth-4 > .donor-shelf-line {
  padding-left: 140px;
}

/* Chevron toggle (and the same-width spacer on a root with nothing underneath). */
.donor-shelf-toggle {
  flex: 0 0 22px;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
}
.donor-shelf-toggle:hover {
  background: var(--mist);
  color: var(--ink);
}
.donor-shelf-toggle-spacer {
  cursor: default;
}
.donor-shelf-chevron {
  width: 16px;
  height: 16px;
  transition: transform 0.12s ease;
}
.donor-shelf-row.is-open > .donor-shelf-line .donor-shelf-chevron {
  transform: rotate(90deg);
}

/* The name keeps a floor width so it never shrinks under the owner's controls: when the row is
   too narrow for everything, the actions wrap to their own line (right-aligned) instead. */
.donor-shelf-name {
  flex: 1 1 200px;
  min-width: 160px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 6px;
}
.donor-shelf-title {
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
}
a.donor-shelf-title:hover {
  text-decoration: underline;
}
.donor-shelf-hint-inline {
  color: var(--ink-soft);
  font-size: 13px;
}
.donor-shelf-hint-inline::before {
  content: "\00b7";
  margin-right: 4px;
}
.donor-shelf-row-sold > .donor-shelf-line .donor-shelf-title {
  text-decoration: line-through;
  color: var(--ink-soft);
}
.donor-shelf-row-not_available > .donor-shelf-line .donor-shelf-title {
  color: var(--ink-soft);
}

/* Availability label on a row. */
.donor-state {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}
.donor-state-available {
  color: var(--forest-500);
}
.donor-state-sold {
  color: var(--brass-dk);
}
.donor-state-not_available {
  color: var(--ink-soft);
}

/* Row actions: the owner's mark forms, the "+ Add specific parts" opener, the buyer's bundle button. */
.donor-shelf-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}
.donor-mark-form {
  display: inline;
}
.btn-mini {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 5px 10px;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  background: var(--white);
  color: var(--ink);
  cursor: pointer;
}
.btn-mini:hover {
  background: var(--mist);
}
.donor-shelf-addpart {
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 4px 8px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--brass-dk);
  cursor: pointer;
  white-space: nowrap;
}
.donor-shelf-addpart:hover {
  background: #fbf3e2;
}
.donor-shelf-remove {
  padding: 0 6px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--ink-soft);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.donor-shelf-remove:hover {
  background: var(--mist);
  color: var(--ink);
}

/* A named catalogue part row: tinted so it reads as a refinement of the category above it. */
.donor-shelf-part > .donor-shelf-line {
  background: var(--mist-2);
}
.donor-part-badge {
  background: var(--brass);
  color: var(--forest-900);
  font-size: 11px;
  font-weight: 700;
  border-radius: 4px;
  padding: 0 6px;
}
.donor-part-number {
  font-size: 13px;
  color: var(--ink-soft);
}
.donor-part-price {
  font-weight: 700;
  white-space: nowrap;
}
/* The row a ?part= link lands on (an implicit-listing card). */
.donor-shelf-part.is-focus > .donor-shelf-line {
  background: #fbf3e2;
  box-shadow: inset 3px 0 0 var(--brass);
}

/* The one "Add specific parts" panel under the shelf (marketplace/_donor_part_add.html). */
.donor-part-add-panel {
  margin-top: 16px;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--mist-2);
}
.donor-part-add-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.donor-part-add-title {
  margin: 0;
  font-size: 17px;
}
.donor-part-add-form {
  margin: 0;
}
.donor-part-add-row {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 10px;
}
.donor-part-add-row .search-select {
  flex: 1 1 320px;
  min-width: 0;
}
.donor-part-add-price {
  width: 120px;
}
.donor-part-add-form .donor-muted {
  margin: 10px 0 0;
}

/* A one-button POST form sitting among the hero's action links (reopen donor, archive car). */
.page-hero-inline-form {
  display: inline;
  margin: 0;
}

/* Close-donor confirmation: the "Archive this car too" checkbox row. */
.form-field-checkbox label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
}

/* "Ask about a part" form under the seller box (34-donor-vehicles.md increment 3). */
.donor-ask-form {
  margin-top: 12px;
}

/* Register a sale (34-donor-vehicles.md increment 5): the checkbox shelf and the fixed buyer line. */
.donor-sale-list {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  columns: 2;
  column-gap: 24px;
}
.donor-sale-list li {
  break-inside: avoid;
  padding: 3px 0;
  white-space: pre;
}
.donor-sale-list label {
  white-space: pre-wrap;
  font-weight: 400;
}
.donor-sale-rows legend {
  font-weight: 700;
  margin-bottom: 4px;
}
.donor-sale-buyer {
  margin: 4px 0;
  font-weight: 700;
}
@media (max-width: 640px) {
  .donor-sale-list {
    columns: 1;
  }
}

/* Donors in browse (34-donor-vehicles.md increment 6): the implicit-listing card ribbon, the
   "Also available from donors" block and the Listings / Donor cars tab bar. */
.donor-offer-card .gen-card-image {
  position: relative;
}
.donor-offer-ribbon {
  position: absolute;
  top: 8px;
  left: 8px;
  background: var(--brass);
  color: var(--forest-900);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 2px 8px;
  border-radius: 4px;
}
.donor-offers-block {
  margin-top: 28px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}
.browse-tabs {
  margin: 0 0 14px;
}
.donor-tab-controls {
  flex-wrap: wrap;
}
.donor-tab-controls .sort-select-form {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------------------
   Bundle cart (34-donor-vehicles.md increment 7): the "Add to bundle" buttons scattered across
   listing/donor templates, and the cart page's own groups (marketplace/_bundle_groups.html). The
   cart itself is client-side (static/js/bundle.js keeps ids in localStorage) - everything here is
   just presentation, the same way the rest of this file never decides what is on screen.
   --------------------------------------------------------------------------- */

/* The full "Add to bundle" button (listing detail, donor shelf rows) - a plain .btn/.btn-mini
   until it is pressed, then it reads like the watch button's active state. */
.bundle-add-btn[aria-pressed="true"] {
  background: var(--mist);
  border-color: var(--forest-500);
  color: var(--forest-700);
}

/* Compact variant on a card (.gen-card-wrap): a round basket icon pinned bottom-RIGHT of the
   card - the watch heart (.watch-btn-compact) owns the top-right corner. The card body keeps
   room on the right so the tag row never runs under it. */
.bundle-add-compact {
  position: absolute;
  right: 10px;
  bottom: 10px;
  z-index: 2;
  width: 36px;
  height: 36px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--white);
  color: var(--forest-700);
  box-shadow: 0 1px 3px var(--shadow);
  cursor: pointer;
}
.bundle-add-compact .icon {
  width: 18px;
  height: 18px;
}
.bundle-add-compact:hover {
  transform: scale(1.05);
}
.bundle-add-compact[aria-pressed="true"] {
  background: var(--forest-500);
  border-color: var(--forest-500);
  color: #fff;
}
.gen-card-wrap-bundle .gen-card-body {
  padding-right: 56px;
}

/* Text buttons carrying the basket icon (listing detail CTA, donor shelf rows). */
.bundle-add-icon-btn,
.market-cta-bundle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.bundle-add-icon-btn .icon,
.market-cta-bundle .icon {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}

/* Listing detail: "Make an offer" and "Add to bundle" share one row (.market-cta-row). The
   bundle button comes first in the DOM and floats right; the offer control (a <details>
   summary, or the sign-in link) is a block formatting context, so it shrinks to sit beside the
   float instead of running under it, and the offer form clears the float to open full width
   underneath. (display: contents on the <details> was tried first - Chromium keeps the closed
   content laid out that way, so it is not usable here.) */
.market-cta-row {
  display: flow-root;
  margin-bottom: 12px;
}
.market-cta-row .offer-panel {
  margin: 0;
}
.market-cta-row .market-price-cta {
  margin-bottom: 0;
}
.market-cta-row .offer-open-trigger,
.market-cta-row > .market-price-cta:not(.market-cta-bundle) {
  display: flow-root;
  overflow: hidden;
  width: auto;
  min-height: 36px;
  box-sizing: border-box;
}
.market-cta-row .offer-form {
  clear: both;
}
.market-cta-row .offer-form .market-price-cta {
  margin-bottom: 12px;
}
/* The bundle button is the secondary action here: an outline next to the brass offer CTA. */
.market-cta-row .market-cta-bundle {
  float: right;
  width: auto;
  min-height: 36px;
  box-sizing: border-box;
  margin: 0 0 0 10px;
  padding: 0 12px;
  font-size: 12px;
  white-space: nowrap;
  background: var(--white);
  color: var(--forest-700);
  border: 1px solid var(--forest-500);
}
.market-cta-row .market-cta-bundle:hover {
  background: var(--mist);
}
.market-cta-row .market-cta-bundle[aria-pressed="true"] {
  background: var(--forest-500);
  color: #fff;
}
/* Alone in the row (offers off, or the buyer already has a live offer): full width like every
   other CTA in the price card. */
.market-cta-row:not(:has(.offer-panel, .market-price-cta:not(.market-cta-bundle))) .market-cta-bundle {
  float: none;
  display: flex;
  width: 100%;
  margin: 0;
}

/* ---------------------------------------------------------------------------
   Offer cards in the chat stream (templates/messaging/_offer_card_message.html, design
   direction A 2026-09-16): the message that announced an offer, counter or price request draws
   as a card - brass top rule like the listing cards, header line, amount, the bundle's lines,
   the note, the actions. Inside .msg-run-mine it goes dark like the sender's own bubbles. A
   resolved offer collapses to one quiet line (.offer-msg-done).
   --------------------------------------------------------------------------- */
.offer-msg {
  width: min(520px, 100%);
  box-sizing: border-box;
  background: var(--white);
  border: 1px solid var(--line);
  border-top: 4px solid var(--brass);
  border-radius: 8px;
  box-shadow: 0 2px 8px var(--shadow);
  padding: 12px 16px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  color: var(--ink);
  text-align: left;
}
.offer-msg-head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.offer-msg-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--brass-dk);
}
.offer-msg-label {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--brass-dk);
}
.offer-msg-pill {
  margin-left: auto;
}
.offer-msg-amount-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}
.offer-msg-amount {
  font-family: "Arial Narrow", "Segoe UI", Impact, sans-serif;
  font-size: 26px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.offer-msg-for {
  font-size: 13px;
  color: var(--ink-soft);
}
.offer-msg-items {
  list-style: none;
  margin: 2px 0 0;
  padding: 0;
  border-top: 1px solid var(--line);
}
.offer-msg-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.offer-msg-item-label {
  flex: 1;
  min-width: 0;
}
.offer-msg-note {
  margin: 0;
  padding: 8px 12px;
  background: var(--mist-2);
  border-radius: 6px;
  font-size: 13px;
}
.offer-msg-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding-top: 2px;
}
.offer-msg-quiet {
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 7px 4px;
  border: 0;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
}
.offer-msg-quiet:hover {
  color: var(--ink);
}
.offer-msg-expiry {
  margin-left: auto;
  font-size: 12px;
  color: var(--ink-soft);
}
/* The popover inside a card opens to the left edge of the card, not the deal bar's 18px. */
.offer-msg .deal-pop-panel {
  left: 0;
}

/* The sender's own card follows their dark bubbles. */
.msg-run-mine .offer-msg {
  background: var(--forest-900);
  border-color: var(--forest-900);
  border-top-color: var(--brass);
  color: #eef2ef;
}
.msg-run-mine .offer-msg-icon,
.msg-run-mine .offer-msg-label {
  color: var(--brass);
}
.msg-run-mine .offer-msg-for,
.msg-run-mine .offer-msg-expiry,
.msg-run-mine .offer-msg-quiet {
  color: #cdd9d0;
}
.msg-run-mine .offer-msg-quiet:hover {
  color: var(--white);
}
.msg-run-mine .offer-msg-items,
.msg-run-mine .offer-msg-item {
  border-color: rgba(255, 255, 255, 0.14);
}
.msg-run-mine .offer-msg-item-label,
.msg-run-mine .offer-msg a {
  color: #eef2ef;
}
.msg-run-mine .offer-msg-note {
  background: rgba(255, 255, 255, 0.08);
  color: #eef2ef;
}
.msg-run-mine .order-pill-waiting {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.18);
  color: #cdd9d0;
}

/* Resolved: one grey line, no buttons. Same look on both sides of the thread. */
.offer-msg-done,
.msg-run-mine .offer-msg-done {
  flex-direction: row;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  border-top-width: 1px;
  border-color: var(--line);
  background: var(--mist-2);
  box-shadow: none;
  color: var(--ink-soft);
  font-size: 13px;
}
.offer-msg-done .offer-msg-icon,
.msg-run-mine .offer-msg-done .offer-msg-icon {
  width: 16px;
  height: 16px;
  color: var(--ink-soft);
}
.offer-msg-done strong {
  color: var(--ink);
}
.offer-msg-done-text {
  flex: 1;
  min-width: 0;
}

/* The cart page groups (marketplace/_bundle_groups.html): one card per seller. */
.bundle-group {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 12px;
  margin-bottom: 16px;
  overflow: hidden;
}
.bundle-group-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--mist);
}
/* Remove-the-whole-seller trash button, at the far right of the group head. */
.bundle-group-remove {
  margin-left: auto;
}
.bundle-group-title a {
  font-weight: 700;
}
.bundle-items {
  list-style: none;
  margin: 0;
  padding: 0;
}
.bundle-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--line);
}
.bundle-item:last-child {
  border-bottom: 0;
}
.bundle-item-gone .bundle-item-label {
  text-decoration: line-through;
  color: var(--ink-soft);
}
.bundle-item-price {
  font-weight: 700;
}
.bundle-group-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
}
.bundle-offer-form {
  display: flex;
  align-items: center;
  gap: 8px;
}
.bundle-offer-form {
  flex-wrap: wrap;
}
.bundle-offer-form input[type="number"] {
  width: 110px;
}
/* The amount box carries the group's currency as a prefix (shared form-input-group kit). */
.bundle-amount-group {
  width: auto;
}
/* The optional note takes the whole width under the amount row. */
.bundle-offer-form .bundle-message {
  flex-basis: 100%;
  resize: vertical;
}
.bundle-footnote {
  margin-top: 12px;
}

/* ---------------------------------------------------------------------------
   Business back-end (orgs app, spec 35)
   --------------------------------------------------------------------------- */

/* The "free during the testing phase" notice: the limit-notice shape, a calm green accent. */
.org-free-notice {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: var(--mist-2);
  border: 1px solid var(--line);
  border-left: 4px solid var(--forest-300);
  border-radius: 6px;
  padding: 14px 18px;
  margin: 0 0 20px;
  color: var(--ink-soft);
  font-size: 15px;
}
.org-free-notice-icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  color: var(--forest-500);
  margin-top: 1px;
}
.org-free-notice-body strong {
  display: block;
  margin-bottom: 2px;
  color: var(--ink);
}
.org-free-notice-body p {
  margin: 0;
}
/* The "free during testing" part sits under the work-in-progress line, split by a hairline. */
.org-free-notice-body .org-free-notice-free {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.org-free-notice-link {
  font-weight: 600;
  text-decoration: underline;
}
/* Stat row on the dashboard: the hero-meta items, on the white card. */
.org-stats {
  margin: 0;
  color: var(--ink);
}
.org-stats .page-hero-meta-item {
  color: var(--ink);
  text-decoration: none;
}
/* The hero styles these numbers white for the dark hero; on the white card they must be ink. */
.org-stats .page-hero-meta-item strong {
  color: var(--ink);
}
/* The per-row action forms in the members table sit inline like chips. */
.org-inline-form {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 8px 0 0;
}


/* ---------------------------------------------------------------------------
   Content reports (spec 36): the "Report" disclosure + inline form on listing, request and
   comment surfaces, and the standalone /report/ page. The form itself is the shared form-panel
   family; these rules only size the disclosure and the reason radio list.
   --------------------------------------------------------------------------- */
.report-disclosure {
  margin: 12px 0 0;
}
.report-disclosure > summary {
  cursor: pointer;
  list-style: none;
}
.report-disclosure > summary::-webkit-details-marker {
  display: none;
}
.report-disclosure[open] > summary {
  margin-bottom: 10px;
}
.report-box .form-panel {
  max-width: 520px;
}
.report-reasons ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}
.report-reasons label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
}
.report-notice {
  margin: 0 0 10px;
  padding: 8px 12px;
  border-left: 3px solid var(--brass);
  background: var(--mist);
  font-size: 14px;
}
.report-privacy {
  margin: 0 0 10px;
  font-size: 13px;
  color: var(--ink-soft);
}
.report-thanks p {
  margin: 0 0 6px;
  font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Review section (spec 36): the Reports tab rows, target previews and the moderator's
   read-only thread view. The tab bar itself is .section-tabs (twin of .profile-tabs).
   --------------------------------------------------------------------------- */
.review-filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0 0 16px;
}
.review-count {
  margin: 0;
  font-size: 13px;
  color: var(--ink-soft);
}
.review-rows {
  display: grid;
  gap: 14px;
}
.review-row {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 14px 16px;
  background: var(--page);
}
.review-row-hidden {
  border-left: 3px solid var(--brass);
}
.review-row-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 10px;
  font-size: 14px;
  color: var(--ink-soft);
}
.review-row-type {
  font-weight: 700;
  color: var(--ink);
}
.review-badge {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 1px 8px;
}
.review-badge-hidden {
  border-color: var(--brass);
  color: var(--brass);
}
.review-row-when {
  margin-left: auto;
}
.review-preview-body {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.review-preview-thumb {
  flex: 0 0 96px;
}
.review-preview-img {
  width: 96px;
  height: 72px;
  object-fit: cover;
  border-radius: 6px;
}
.review-preview-title {
  margin: 0 0 4px;
  font-weight: 700;
}
.review-preview-meta {
  margin: 0 0 4px;
  font-size: 13px;
  color: var(--ink-soft);
}
.review-preview-text {
  margin: 0;
  font-size: 14px;
}
.review-reasons {
  list-style: none;
  margin: 12px 0 0;
  padding: 10px 0 0;
  border-top: 1px dashed var(--line);
  font-size: 14px;
  display: grid;
  gap: 4px;
}
.review-reason-details {
  margin-left: 8px;
}
.review-reason-when {
  margin-left: 8px;
  color: var(--ink-soft);
  font-size: 12px;
}
.review-row-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 12px 0 0;
}
.review-row-actions form {
  margin: 0;
}
.review-messages {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: grid;
  gap: 10px;
}
.review-message {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 14px;
}
.review-message-removed {
  opacity: 0.7;
}
.review-message-images {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 6px 0;
}
.review-message form {
  margin: 8px 0 0;
}

/* Uncategorised tab rows (spec 36 increment 5): inline category picker + nudge. */
.review-recategorise {
  align-items: flex-end;
}
.review-recategorise-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px;
}
.review-recategorise-label {
  font-size: 13px;
  font-weight: 700;
  width: 100%;
}
.review-recategorise-form select {
  max-width: 320px;
}
.review-row-done {
  border-left: 3px solid var(--forest-500);
}
.review-filed {
  margin: 12px 0 0;
  font-weight: 600;
  color: var(--forest-500);
}

/* Org requests tab: business facts left, decision panel right; stacks on narrow screens. */
.org-request {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: 20px;
}
.org-request-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 16px;
  margin: 0 0 12px;
}
.org-request-grid dt,
.org-request-label {
  margin: 0 0 2px;
  font-size: 12px;
  color: var(--ink-soft);
}
.org-request-grid dd {
  margin: 0;
  font-size: 14px;
  overflow-wrap: anywhere;
}
.org-request-answer {
  margin: 0 0 8px;
  padding: 8px 10px;
  border-radius: 6px;
  background: var(--mist-2);
  font-size: 14px;
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.org-request-panel {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-left: 20px;
  border-left: 1px solid var(--line);
}
.org-request-panel form {
  margin: 0;
}
.org-request-decided {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--forest-500);
}
.org-request-note,
.org-request-reject-form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}
.org-request-note textarea,
.org-request-reject-form textarea {
  width: 100%;
}
.org-request-reject > summary {
  cursor: pointer;
  list-style: none;
}
.org-request-reject > summary::-webkit-details-marker { display: none; }
.org-request-reject > summary::marker { content: ""; }
.org-request-reject-form {
  margin-top: 8px;
}
/* The Held accounts page (review/hold_detail.html): what the account posted in the last 7 days,
   one compact list per kind, held rows carrying the shared "Waiting for review" badge. */
.hold-tier-field {
  width: 100%;
  margin: 0;
}
.hold-content-title {
  margin: 16px 0 8px;
  font-weight: 700;
}
.hold-content-group {
  margin: 0 0 12px;
}
.hold-content-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.hold-content-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  padding: 5px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  overflow-wrap: anywhere;
}
.hold-content-list time {
  margin-left: auto;
  color: var(--ink-soft);
  white-space: nowrap;
}
/* The reviewers' note log reuses the garage compact-timeline rows (.timeline-log*); these only
   let the note text wrap (a log title is one ellipsed line) and fit the narrow panel. */
.org-note-log .timeline-log-summary {
  align-items: flex-start;
  gap: 10px;
  padding: 8px 10px;
}
.org-note-log .timeline-log-date {
  flex-basis: 44px;
  padding-top: 2px;
}
.org-note-body {
  flex: 1 1 auto;
  min-width: 0;
}
.org-note-text {
  margin: 0;
  font-size: 14px;
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.org-note-meta {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--ink-soft);
}
.org-note-log .icon-actions {
  flex: 0 0 auto;
}
.org-note-edit {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 10px;
}
.org-note-edit textarea {
  width: 100%;
}
.org-note-edit-actions {
  display: flex;
  gap: 6px;
}
@media (max-width: 760px) {
  .org-request {
    grid-template-columns: minmax(0, 1fr);
  }
  .org-request-panel {
    padding: 14px 0 0;
    border-left: 0;
    border-top: 1px solid var(--line);
  }
}
@media (max-width: 480px) {
  .org-request-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------------------------------------------------------------------------
   Home page, lower half (2026-09 redesign): roadmap, pricing panels, persona picker,
   trust band + closing strip. All classes are home-* so nothing leaks into other pages.
   Revet pictures are pre-sized static JPGs with a white background, so they always sit on
   white (a medallion, an avatar ring or a white image pane), never straight on green.
   --------------------------------------------------------------------------- */

.home-featured,
.home-roadmap,
.home-pricing,
.home-who {
  padding: 72px 0;
}
.home-pricing {
  background: var(--mist);
}

/* Featured generations: the new block layout on the dark forest band. The eyebrow keeps the
   shared home-eyebrow-dark class but switches to the lighter brass, which stays readable on green. */
.home-featured {
  background: var(--forest-900);
  color: #fff;
}
.home-featured .home-eyebrow-dark {
  color: var(--brass);
}
.home-featured .home-eyebrow-dark::before {
  background: var(--brass);
}
.home-featured .home-center-head h2 .accent {
  color: var(--brass);
}
.home-featured .home-center-head p {
  color: #c3d3c7;
}

/* Shared small parts */
.home-eyebrow-dark {
  color: var(--brass-dk);
}
.home-eyebrow-dark::before {
  background: var(--brass-dk);
}
.home-lead {
  color: var(--ink-soft);
  font-size: 17px;
  margin: 0 0 22px;
}
.home-center-head {
  text-align: center;
  max-width: 44em;
  margin: 0 auto 40px;
}
.home-center-head h2 {
  font-size: 40px;
  line-height: 1.05;
  margin: 10px 0;
}
.home-center-head h2 .accent {
  color: var(--brass-dk);
}
.home-center-head p {
  color: var(--ink-soft);
  font-size: 17px;
  margin: 0;
}
.home-btn-on-dark {
  color: #fff;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35);
}
.home-btn-on-dark:hover {
  background: var(--brass);
  color: var(--forest-900);
  box-shadow: inset 0 0 0 1px var(--brass);
}

/* 1. Roadmap ("Built on the classics") */
.home-roadmap-grid {
  display: grid;
  grid-template-columns: 5fr 7fr;
  gap: 56px;
  align-items: center;
}
.home-roadmap-title {
  font-size: 40px;
  line-height: 1.05;
  margin: 12px 0 14px;
}
.home-roadmap-title .accent {
  color: var(--brass-dk);
}
.home-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
}
.home-stat b {
  display: block;
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 30px;
  line-height: 1;
  color: var(--forest-700);
}
.home-stat span {
  font-size: 12px;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.home-track {
  position: relative;
  padding-left: 34px;
}
.home-track::before {
  content: "";
  position: absolute;
  left: 11px;
  top: 14px;
  bottom: 14px;
  width: 2px;
  background: repeating-linear-gradient(var(--line-strong) 0 6px, transparent 6px 12px);
}
.home-stop {
  position: relative;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 18px 20px;
  margin-bottom: 14px;
  box-shadow: 0 1px 3px var(--shadow);
}
.home-stop::before {
  content: "";
  position: absolute;
  left: -30px;
  top: 22px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  border: 3px solid var(--line-strong);
}
.home-stop.is-now {
  border-color: var(--brass);
  box-shadow: 0 10px 24px rgba(199, 154, 58, 0.15);
}
.home-stop.is-now::before {
  border-color: var(--brass);
  background: var(--brass);
}
.home-stop.is-next::before {
  border-color: var(--forest-500);
}
.home-stop.is-open {
  border-style: dashed;
  background: var(--mist-2);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 0;
}
.home-stop.is-open p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 14px;
}
.home-stop.is-open .btn,
.home-tier-cta,
.home-closer-actions .btn {
  white-space: nowrap;
}
.home-stop.is-open strong {
  display: block;
  color: var(--ink);
  font-size: 15px;
}
.home-stop-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.home-stop-head h3 {
  margin: 0;
  font-size: 22px;
}
.home-tag {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 99px;
  white-space: nowrap;
}
.home-tag-now {
  background: var(--brass);
  color: var(--forest-900);
}
.home-tag-next {
  background: var(--mist);
  color: var(--forest-500);
}
.home-stop-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.home-stop-chip {
  font-size: 13px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 5px;
  background: var(--mist-2);
  border: 1px solid var(--line);
  color: var(--forest-700);
}
.home-stop.is-now .home-stop-chip {
  background: #fbf4e4;
  border-color: #ecd9ae;
  color: var(--brass-dk);
}

/* 2. Pricing panels ("Free for enthusiasts. Tools for the trade.") */
.home-center-head .home-principle {
  display: inline-block;
  margin-top: 16px;
  font-style: italic;
  color: var(--forest-700);
  border-left: 3px solid var(--brass);
  padding: 2px 0 2px 12px;
  text-align: left;
}
.home-tiers {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
}
.home-tier {
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 150px;
  gap: 10px 18px;
  align-content: start;
  padding: 30px 30px 26px;
  border-radius: 14px;
  background: #fff;
  border: 1px solid var(--line);
  box-shadow: 0 12px 30px var(--shadow);
}
.home-tier.is-dark {
  background: linear-gradient(135deg, var(--forest-900), var(--forest-700));
  border-color: var(--forest-900);
  color: #fff;
}
.home-tier-label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--forest-500);
}
.home-tier.is-dark .home-tier-label {
  color: var(--brass);
}
.home-tier h3 {
  font-size: 28px;
  line-height: 1.05;
  margin: 4px 0 2px;
}
.home-tier-price {
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 44px;
  font-weight: 800;
  line-height: 1;
  margin: 10px 0 2px;
}
.home-tier-price small {
  display: block;
  margin-top: 6px;
  font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-soft);
}
.home-tier.is-dark .home-tier-price small {
  color: #c3d3c7;
}
.home-medal {
  grid-column: 2;
  grid-row: 1;
  width: 150px;
  height: 150px;
  border-radius: 50%;
  overflow: hidden;
  background: #fff;
  border: 4px solid var(--mist);
}
.home-tier.is-dark .home-medal {
  border-color: var(--brass);
}
.home-medal img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.home-checklist {
  grid-column: 1 / -1;
  list-style: none;
  padding: 0;
  margin: 14px 0 18px;
  display: grid;
  gap: 9px;
}
.home-checklist li {
  display: flex;
  gap: 10px;
  font-size: 15px;
}
.home-checklist li::before {
  content: "";
  flex: 0 0 18px;
  height: 18px;
  margin-top: 2px;
  border-radius: 50%;
  background: var(--forest-500) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 8.5l2.5 2.5L12 5.5' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 12px no-repeat;
}
.home-tier.is-dark .home-checklist li {
  color: #e4ece6;
}
.home-tier.is-dark .home-checklist li::before {
  background-color: var(--brass);
}
.home-tier-cta {
  grid-column: 1 / -1;
  justify-self: start;
}
.home-tier-ribbon {
  position: absolute;
  top: 18px;
  right: -34px;
  transform: rotate(35deg);
  background: var(--brass);
  color: var(--forest-900);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 4px 40px;
}

/* 3. Persona picker ("Who it's for"). Without JS the list is hidden and all panels stack;
   home-personas.js adds .is-enhanced, which shows the list and hides the inactive panels. */
.home-personas {
  display: grid;
  gap: 26px;
}
.home-personas.is-enhanced {
  grid-template-columns: 4fr 8fr;
  align-items: stretch;
}
.home-persona-list {
  display: none;
}
.home-personas.is-enhanced .home-persona-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.home-persona-tab {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.home-persona-tab:hover {
  border-color: var(--line-strong);
}
.home-persona-tab:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}
.home-persona-tab.is-active {
  border-color: var(--brass);
  background: #fffcf5;
  box-shadow: 0 8px 20px rgba(199, 154, 58, 0.14);
}
.home-avatar {
  flex: 0 0 56px;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  overflow: hidden;
  background: #fff;
  border: 3px solid var(--mist);
}
.home-persona-tab.is-active .home-avatar {
  border-color: var(--brass);
}
.home-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.home-persona-tab-text {
  display: flex;
  flex-direction: column;
}
.home-persona-name {
  font-family: "Arial Narrow", "Segoe UI", Impact, sans-serif;
  text-transform: uppercase;
  font-weight: 800;
  font-size: 18px;
  line-height: 1.2;
}
.home-persona-tagline {
  font-size: 13px;
  color: var(--ink-soft);
}
.home-persona-arrow {
  margin-left: auto;
  color: var(--line-strong);
  font-weight: 700;
}
.home-persona-tab.is-active .home-persona-arrow {
  color: var(--brass-dk);
}
.home-persona-panels {
  display: grid;
  gap: 18px;
}
.home-persona-panel {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-radius: 14px;
  overflow: hidden;
  background: linear-gradient(135deg, var(--forest-900), var(--forest-700));
  color: #fff;
}
/* All panels share one grid cell, so the box is always as tall as the tallest persona and does
   not jump when switching. Inactive panels stay laid out but invisible (visibility also removes
   them from the accessibility tree and the tab order), instead of display: none. */
.home-personas.is-enhanced .home-persona-panel {
  grid-area: 1 / 1;
}
.home-personas.is-enhanced .home-persona-panel[hidden] {
  display: grid;
  visibility: hidden;
}
.home-persona-img {
  background: #fff;
  border: 1px solid var(--line);
  border-right: 0;
  border-radius: 14px 0 0 14px;
  padding: 16px;
}
/* contain, not cover: the pane is taller than wide once all panels share the tallest height, and
   cover would crop wide pictures such as Revet in the car. */
.home-persona-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.home-persona-body {
  display: flex;
  flex-direction: column;
  padding: 32px 30px;
}
.home-persona-kicker {
  color: var(--brass);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.home-persona-body h3 {
  font-size: 32px;
  line-height: 1.05;
  margin: 6px 0 10px;
}
.home-persona-body > p {
  color: #c3d3c7;
  margin: 0 0 18px;
}
.home-persona-bullets {
  list-style: none;
  padding: 0;
  margin: 0 0 24px;
  display: grid;
  gap: 10px;
}
.home-persona-bullets li {
  position: relative;
  padding-left: 20px;
  font-size: 15px;
  color: #e4ece6;
}
.home-persona-bullets li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--brass);
  transform: rotate(45deg);
}
.home-persona-bullets b {
  color: #fff;
}
.home-persona-body .btn {
  margin-top: auto;
  align-self: flex-start;
}

/* 4. Trust band ("No ghosting. No mystery boxes.") + closing strip */
.home-trust {
  background: var(--forest-900);
  color: #fff;
  padding: 76px 0 0;
}
.home-trust-grid {
  display: grid;
  grid-template-columns: 4fr 8fr;
  gap: 56px;
  align-items: start;
}
.home-trust-title {
  font-size: 44px;
  line-height: 1;
  margin: 12px 0 16px;
}
.home-trust-title .accent {
  color: var(--brass);
}
.home-trust-lead {
  color: #c3d3c7;
  font-size: 17px;
  margin: 0 0 24px;
}
.home-trust-mascot {
  width: 210px;
  height: 210px;
  border-radius: 50%;
  overflow: hidden;
  background: #fff;
  border: 5px solid var(--brass);
}
.home-trust-mascot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.home-pillars {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.home-pillar {
  padding: 26px 26px 28px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.home-pillar:nth-child(odd) {
  border-right: 1px solid rgba(255, 255, 255, 0.12);
}
.home-pillar:nth-child(even) {
  padding-left: 26px;
  padding-right: 0;
}
.home-pillar-num {
  font-family: "Arial Narrow", Impact, sans-serif;
  color: var(--brass);
  font-size: 13px;
  letter-spacing: 0.14em;
}
.home-pillar-top {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 8px 0;
}
.home-pillar-icon {
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  border-radius: 9px;
  background: rgba(199, 154, 58, 0.14);
  color: var(--brass);
  display: grid;
  place-items: center;
}
.home-pillar-icon svg {
  width: 22px;
  height: 22px;
}
.home-pillar h3 {
  margin: 0;
  font-size: 21px;
}
.home-pillar p {
  margin: 0;
  color: #c3d3c7;
  font-size: 15px;
}
.home-closer {
  margin-top: 56px;
  background: var(--forest-700);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.home-closer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-top: 26px;
  padding-bottom: 26px;
}
.home-closer-inner p {
  margin: 0;
  font-size: 18px;
}
.home-closer-inner p b {
  font-family: "Arial Narrow", Impact, sans-serif;
  text-transform: uppercase;
  font-size: 22px;
  margin-right: 8px;
}
.home-closer-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

@media (max-width: 900px) {
  .home-roadmap-grid,
  .home-trust-grid,
  .home-tiers,
  .home-personas.is-enhanced {
    grid-template-columns: 1fr;
    gap: 32px;
  }
  .home-trust-mascot {
    width: 150px;
    height: 150px;
  }
}
@media (max-width: 560px) {
  .home-featured,
  .home-roadmap,
  .home-pricing,
  .home-who {
    padding: 52px 0;
  }
  .home-roadmap-title,
  .home-center-head h2,
  .home-trust-title {
    font-size: 32px;
  }
  .home-tier {
    grid-template-columns: minmax(0, 1fr) 84px;
    padding: 24px 20px;
  }
  .home-tier-price {
    font-size: 34px;
  }
  .home-medal {
    width: 84px;
    height: 84px;
    margin-top: 18px;
  }
  .home-stop.is-open,
  .home-closer-inner {
    flex-direction: column;
    align-items: flex-start;
  }
  .home-persona-panel {
    grid-template-columns: 1fr;
  }
  .home-persona-img {
    height: 220px;
    border-right: 1px solid var(--line);
    border-bottom: 0;
    border-radius: 14px 14px 0 0;
  }
  .home-persona-body {
    padding: 24px 20px;
  }
  .home-pillars {
    grid-template-columns: 1fr;
  }
  .home-pillar,
  .home-pillar:nth-child(even) {
    padding: 22px 0;
    border-right: 0;
  }
}

/* Roadmap chips we are further along with (MarqueCluster.advanced_chips): solid forest green,
   so they read apart from both the pale queued chips and the brass "documenting now" chips. */
.home-stop-chip.is-advanced,
.home-stop.is-now .home-stop-chip.is-advanced {
  background: var(--forest-500);
  border-color: var(--forest-500);
  color: #fff;
}
/* An advanced chip with a wiki generation page links to it. */
a.home-stop-chip.is-link {
  text-decoration: none;
  transition: background 0.12s ease, border-color 0.12s ease;
}
a.home-stop-chip.is-link:hover,
a.home-stop-chip.is-link:focus-visible {
  background: var(--forest-700);
  border-color: var(--forest-700);
  color: #fff;
}

/* ---------------------------------------------------------------------------
   How it works page (templates/core/how_it_works.html)

   A guided tour of the four blocks. White intro header, then one chapter per block:
   .hiw-chapter-dark chapters sit on forest-900, .hiw-chapter-flip chapters are white and
   mirrored (preview left, mascot right). Each chapter holds a mascot column (.hiw-who), the copy
   with three numbered steps (.hiw-copy) and a static page preview (.hiw-screen-col).
   Then the "how the blocks connect" band (.hiw-connect) and the closing CTA (.hiw-close).
   The mascot JPGs have a white background, so they always sit on a white circle or card.
   --------------------------------------------------------------------------- */

/* Intro header */
.hiw-intro {
  padding: 56px 0 40px;
  border-bottom: 1px solid var(--line);
}
.hiw-intro-grid {
  display: grid;
  grid-template-columns: 1.3fr 0.7fr;
  gap: 40px;
  align-items: center;
}
.hiw-intro h1 {
  font-size: 54px;
  line-height: 1.02;
  color: var(--forest-900);
  margin: 14px 0 16px;
}
.hiw-intro h1 .accent {
  color: var(--brass);
}
.hiw-intro-lead {
  font-size: 18px;
  color: var(--ink-soft);
  max-width: 560px;
  margin: 0;
}
.hiw-intro-mascot {
  width: 100%;
  max-width: 300px;
  height: auto;
  justify-self: center;
}
.hiw-jump {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 22px;
}
.hiw-jump a {
  font-size: 14px;
  font-weight: 600;
  color: var(--forest-700);
  border: 1px solid var(--line);
  background: var(--mist);
  padding: 7px 14px;
  border-radius: 99px;
}
.hiw-jump a:hover {
  border-color: var(--forest-300);
  text-decoration: none;
}

/* Block chapters */
.hiw-chapter {
  padding: 72px 0;
  scroll-margin-top: 72px; /* clears the sticky site header when jumping to #marketplace etc. */
}
.hiw-chapter-grid {
  display: grid;
  grid-template-columns: 260px 1fr 1fr;
  gap: 36px;
  align-items: start;
}
.hiw-who,
.hiw-screen-col {
  align-self: center;
}
.hiw-who {
  text-align: center;
}
.hiw-who img {
  width: 100%;
  max-width: 240px;
  height: auto;
  border-radius: 50%;
  background: var(--white);
  border: 5px solid var(--white);
  box-shadow: 0 0 0 3px var(--brass), 0 10px 30px rgba(20, 48, 29, 0.12);
}
.hiw-num {
  display: block;
  margin-top: 10px;
  font-family: "Arial Narrow", Impact, sans-serif;
  font-size: 84px;
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 2px var(--forest-900);
}
.hiw-kicker {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brass-dk);
}
.hiw-copy h2 {
  font-size: 40px;
  line-height: 1.05;
  color: var(--forest-900);
  margin: 6px 0 12px;
}
.hiw-copy h2 .accent {
  color: var(--brass-dk);
}
.hiw-copy p {
  color: var(--ink-soft);
  margin: 0 0 18px;
}
.hiw-steps {
  list-style: none;
  padding: 0;
  margin: 0 0 22px;
  counter-reset: hiw-step;
  display: grid;
  gap: 12px;
}
.hiw-steps li {
  counter-increment: hiw-step;
  display: grid;
  grid-template-columns: 30px 1fr;
  gap: 10px;
  font-size: 15px;
}
.hiw-steps li::before {
  content: counter(hiw-step);
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--forest-500);
  color: var(--white);
  font-weight: 700;
  font-size: 13px;
}
.hiw-steps b {
  display: block;
  color: var(--forest-900);
}
.hiw-cta {
  font-size: 15px;
  padding: 10px 18px;
}
.hiw-cta-alt {
  margin-left: 14px;
  color: var(--brass-dk);
  font-size: 14px;
}
.hiw-cta-alt:hover {
  color: var(--forest-700);
}

/* Dark chapter: forest background, light copy, brass accents */
.hiw-chapter-dark {
  background: var(--forest-900);
  color: var(--white);
}
.hiw-chapter-dark .hiw-copy h2,
.hiw-chapter-dark .hiw-steps b {
  color: var(--white);
}
.hiw-chapter-dark .hiw-kicker,
.hiw-chapter-dark .hiw-copy h2 .accent {
  color: var(--brass);
}
.hiw-chapter-dark .hiw-copy p {
  color: #cfdcd3;
}
.hiw-chapter-dark .hiw-num {
  -webkit-text-stroke-color: var(--brass);
}
.hiw-chapter-dark .hiw-cap {
  color: #9fb8a6;
}
.hiw-chapter-dark .hiw-screen {
  border-color: var(--forest-700);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
}

/* Mirrored chapter: preview left, copy middle, mascot right */
.hiw-chapter-flip .hiw-chapter-grid {
  grid-template-columns: 1fr 1fr 260px;
}
.hiw-chapter-flip .hiw-screen-col { order: 1; }
.hiw-chapter-flip .hiw-copy { order: 2; }
.hiw-chapter-flip .hiw-who { order: 3; }

/* Static page preview */
.hiw-screen {
  background: var(--white);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(20, 48, 29, 0.1);
  overflow: hidden;
}
.hiw-screen-bar {
  background: var(--forest-900);
  height: 30px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
}
.hiw-screen-bar i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--forest-500);
}
.hiw-screen-bar span {
  margin-left: 10px;
  color: #9fb8a6;
  font-size: 11px;
}
.hiw-screen-body {
  padding: 16px;
  display: grid;
  gap: 10px;
}
.hiw-screen-body small {
  color: var(--ink-soft);
  font-size: 12px;
  display: block;
}
.hiw-cap {
  font-size: 12px;
  color: var(--ink-soft);
  text-align: center;
  margin: 10px 0 0;
}
.hiw-item {
  display: grid;
  grid-template-columns: 54px 1fr auto;
  gap: 12px;
  align-items: center;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px;
}
.hiw-item img {
  width: 54px;
  height: 54px;
  border-radius: 6px;
  object-fit: cover;
}
.hiw-item b {
  font-size: 14px;
  display: block;
}
.hiw-price {
  font-weight: 700;
  color: var(--forest-900);
  white-space: nowrap;
}
.hiw-badge {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  background: #e3f0e6;
  color: var(--forest-500);
  border-radius: 99px;
  padding: 2px 8px;
  margin-top: 3px;
}
.hiw-badge-brass {
  background: #f6ecd4;
  color: var(--brass-dk);
}
.hiw-spec {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.hiw-spec td {
  border-bottom: 1px solid var(--line);
  padding: 7px 4px;
}
.hiw-spec td:first-child {
  color: var(--ink-soft);
  width: 45%;
}
.hiw-timeline {
  display: grid;
  gap: 8px;
  font-size: 13px;
}
.hiw-timeline div {
  border-left: 3px solid var(--forest-300);
  padding: 2px 0 2px 10px;
}

/* How the blocks connect */
.hiw-connect {
  background: var(--forest-900);
  color: var(--white);
  padding: 64px 0;
  border-top: 1px solid var(--forest-700);
}
.hiw-connect h2 {
  font-size: 36px;
  text-align: center;
  margin: 0;
}
.hiw-connect h2 .accent {
  color: var(--brass);
}
.hiw-connect-sub {
  text-align: center;
  color: #cfdcd3;
  margin: 10px auto 36px;
  max-width: 620px;
}
.hiw-loop {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  align-items: stretch;
}
.hiw-loop li {
  background: var(--forest-700);
  border: 1px solid var(--forest-500);
  border-radius: 12px;
  padding: 16px;
  text-align: center;
  position: relative;
}
.hiw-loop li + li {
  margin-left: 28px;
}
.hiw-loop li + li::before {
  content: "\2192";
  position: absolute;
  left: -24px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--brass);
  font-size: 22px;
  font-weight: 700;
}
.hiw-loop img {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--white);
  border: 3px solid var(--brass);
}
.hiw-loop h3 {
  font-size: 20px;
  margin: 8px 0 4px;
}
.hiw-loop small {
  color: #cfdcd3;
  font-size: 13px;
  display: block;
}
.hiw-loopback {
  text-align: center;
  margin: 18px 0 0;
  color: var(--brass);
  font-size: 14px;
  font-weight: 600;
}

/* Closing call to action */
.hiw-close {
  padding: 56px 0;
  text-align: center;
}
.hiw-close img {
  width: 140px;
  height: auto;
}
.hiw-close h2 {
  font-size: 34px;
  color: var(--forest-900);
  margin: 8px 0;
}
.hiw-close h2 .accent {
  color: var(--brass-dk);
}
.hiw-close p {
  color: var(--ink-soft);
  margin: 0 0 20px;
}
.hiw-close-cta {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
}
.hiw-close-cta .btn {
  font-size: 15px;
  padding: 10px 18px;
}

@media (max-width: 980px) {
  .hiw-chapter-grid {
    grid-template-columns: 200px 1fr;
  }
  .hiw-chapter-flip .hiw-chapter-grid {
    grid-template-columns: 1fr 200px;
  }
  .hiw-chapter-flip .hiw-copy { order: 1; }
  .hiw-chapter-flip .hiw-who { order: 2; }
  .hiw-screen-col,
  .hiw-chapter-flip .hiw-screen-col {
    grid-column: 1 / -1;
    order: 3;
  }
}

@media (max-width: 860px) {
  .hiw-intro-grid,
  .hiw-chapter-grid,
  .hiw-chapter-flip .hiw-chapter-grid {
    grid-template-columns: 1fr;
  }
  .hiw-intro h1 {
    font-size: 40px;
  }
  .hiw-intro-mascot {
    max-width: 200px;
  }
  .hiw-chapter {
    padding: 48px 0;
  }
  .hiw-chapter-flip .hiw-who { order: 0; }
  .hiw-who img {
    max-width: 160px;
  }
  .hiw-num {
    font-size: 56px;
  }
  .hiw-loop {
    grid-template-columns: 1fr;
    gap: 28px;
  }
  .hiw-loop li + li {
    margin-left: 0;
  }
  .hiw-loop li + li::before {
    content: "\2193";
    left: 50%;
    top: -26px;
    transform: translateX(-50%);
  }
}

/* ---------------------------------------------------------------------------
   FAQ page (templates/core/faq.html)

   Reuses the How it works intro header (.hiw-intro) and CTA button (.hiw-cta). Then a dark band
   of topic tiles (.faq-tiles), the question groups (.faq-group with <details class="faq-q">),
   and a closing "Still stuck?" strip (.faq-stuck). The search box and the filtered-out
   questions/groups use the hidden attribute (static/js/faq-search.js); the rules at the end keep
   it winning over any display value.
   --------------------------------------------------------------------------- */

/* Search box in the intro header */
.faq-search {
  margin-top: 22px;
  max-width: 520px;
}
.faq-search input {
  width: 100%;
  font: inherit;
  font-size: 16px;
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--mist);
  color: var(--ink);
}
.faq-search input:focus {
  outline: 2px solid var(--brass);
  outline-offset: 0;
  background: var(--white);
}

/* Topic tiles */
.faq-tiles-band {
  background: var(--forest-900);
  padding: 40px 0;
}
.faq-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
.faq-tile {
  display: grid;
  grid-template-columns: 64px 1fr;
  grid-template-rows: auto 1fr;
  column-gap: 14px;
  background: var(--white);
  border-radius: 12px;
  border-bottom: 4px solid var(--brass);
  padding: 14px 16px;
  color: var(--ink);
  transition: transform 0.15s;
}
.faq-tile:hover {
  text-decoration: none;
  transform: translateY(-3px);
}
.faq-tile img {
  grid-row: 1 / 3;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 2px solid var(--brass);
}
.faq-tile b {
  font-family: "Arial Narrow", Impact, sans-serif;
  text-transform: uppercase;
  font-size: 19px;
  color: var(--forest-900);
  margin: 4px 0 2px;
}
.faq-tile span {
  font-size: 13px;
  color: var(--ink-soft);
}

/* Question groups */
.faq-list {
  max-width: 820px;
  padding-top: 24px;
  padding-bottom: 48px;
}
.faq-group {
  padding: 28px 0 8px;
  scroll-margin-top: 80px; /* clears the sticky site header when jumping from a tile */
}
.faq-group-head {
  display: flex;
  align-items: center;
  gap: 14px;
  border-bottom: 3px solid var(--forest-900);
  padding-bottom: 10px;
}
.faq-group-head img {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 2px solid var(--brass);
}
.faq-group-head h2 {
  font-size: 28px;
  margin: 0;
  color: var(--forest-900);
}
.faq-q {
  border-bottom: 1px solid var(--line);
}
.faq-q summary {
  cursor: pointer;
  list-style: none;
  position: relative;
  padding: 14px 36px 14px 0;
  font-weight: 700;
  font-size: 16px;
  color: var(--forest-900);
}
.faq-q summary::-webkit-details-marker {
  display: none;
}
.faq-q summary::after {
  content: "+";
  position: absolute;
  right: 6px;
  top: 10px;
  font-size: 22px;
  font-weight: 400;
  color: var(--brass-dk);
}
.faq-q[open] summary::after {
  content: "\2212";
}
.faq-q summary:hover {
  color: var(--brass-dk);
}
.faq-q summary:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}
.faq-q > div {
  padding: 0 0 14px;
  color: var(--ink-soft);
}
.faq-q > div p {
  margin: 0;
}
.faq-empty {
  color: var(--ink-soft);
  padding: 20px 0;
}

/* Still stuck strip */
.faq-stuck {
  background: var(--forest-900);
  color: var(--white);
  padding: 40px 0;
}
.faq-stuck-inner {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 24px;
  align-items: center;
}
.faq-stuck img {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  background: var(--white);
  border: 4px solid var(--brass);
}
.faq-stuck h2 {
  font-size: 32px;
  margin: 0;
}
.faq-stuck h2 .accent {
  color: var(--brass);
}
.faq-stuck p {
  color: #cfdcd3;
  margin: 4px 0 0;
}

/* The filter hides with the hidden attribute; keep it winning over the display rules above. */
.faq-search[hidden],
.faq-group[hidden],
.faq-q[hidden],
.faq-empty[hidden] {
  display: none;
}

/* How it works: the "How do deals work?" link on the dark Marketplace chapter */
.hiw-chapter-dark .hiw-cta-alt {
  color: var(--brass);
}
.hiw-chapter-dark .hiw-cta-alt:hover {
  color: var(--white);
}

@media (max-width: 860px) {
  .faq-tiles {
    grid-template-columns: 1fr 1fr;
  }
  .faq-stuck-inner {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
  }
}

@media (max-width: 520px) {
  .faq-tiles {
    grid-template-columns: 1fr;
  }
}

/* ---------------------------------------------------------------------------
   Error pages (templates/errors/base_error.html, 404/403/400, standalone 500)
   A dark forest hero: the status code in brass with the mascot as the middle digit, eyebrow,
   title, lead and an optional search / action row; then a row of section links on white.
   --------------------------------------------------------------------------- */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.error-hero {
  background: var(--forest-900);
  color: var(--white);
  padding: 48px 0 56px;
  text-align: center;
}
.error-hero-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.error-code {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: clamp(88px, 14vw, 160px);
  font-weight: 800;
  line-height: 1;
  color: var(--brass);
}
.error-code-mascot img {
  display: block;
  width: clamp(110px, 16vw, 190px);
  height: auto;
  border-radius: 50%;
  background: var(--white);
  border: 8px solid var(--brass);
}
.error-eyebrow {
  margin-top: 22px;
}
.error-hero h1 {
  font-size: clamp(28px, 3.5vw, 42px);
  line-height: 1.1;
  margin: 8px 0 10px;
  color: var(--white);
}
.error-lead {
  color: #cfdcd3;
  max-width: 580px;
  margin: 0;
}
.error-search {
  display: flex;
  gap: 8px;
  width: 100%;
  max-width: 580px;
  margin: 24px 0 18px;
}
.error-search input {
  flex: 1;
  min-width: 0;
  padding: 13px 16px;
  border: 1px solid transparent;
  border-radius: 8px;
  font: inherit;
  background: var(--white);
  color: var(--ink);
}
.error-search input:focus {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}
.error-search .btn {
  padding: 0 20px;
  font-size: 14px;
}
.error-actions {
  margin-top: 24px;
}
.error-actions .btn {
  padding: 11px 20px;
  font-size: 14px;
}
.error-popular {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 8px;
}
.error-popular-label {
  color: #9fb5a6;
  font-size: 13px;
  margin-right: 4px;
}
.error-chip {
  border: 1px solid var(--forest-500);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 13px;
  color: #e6efe8;
  text-decoration: none;
}
.error-chip:hover {
  border-color: var(--brass);
  color: var(--brass);
  text-decoration: none;
}
.error-nav {
  padding: 28px 0 48px;
  text-align: center;
}
.error-nav-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}
.error-nav-row a {
  padding: 10px 18px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--mist-2);
  color: var(--forest-900);
  font-weight: 600;
  text-decoration: none;
}
.error-nav-row a:hover {
  border-color: var(--forest-300);
  text-decoration: none;
}
.error-nav-row .error-nav-home {
  background: var(--forest-500);
  border-color: var(--forest-500);
  color: var(--white);
}
.error-report {
  margin-top: 24px;
  color: var(--ink-soft);
  font-size: 14px;
}
.error-report a {
  color: var(--forest-500);
}
.error-footer {
  text-align: center;
}

@media (max-width: 560px) {
  .error-search {
    flex-direction: column;
  }
  .error-search .btn {
    padding: 11px 20px;
  }
}
/* The standalone 500 page has no section-link row, so let the dark hero fill down to the footer. */
.error-standalone main {
  background: var(--forest-900);
}

/* ---------------------------------------------------------------------------
   Two-column editor shell (.form-split): the course editor, the garage car form and the
   marketplace listing form. Fields left; photos and a status card (publish checklist,
   visibility) right. One column below 960px, where the side column follows the fields.
   The course side column is sticky (it is short); the car and listing side columns carry
   a growing photo grid, so they use .form-split-side-flow and scroll with the page.
   --------------------------------------------------------------------------- */
.form-split {
  max-width: 1080px;
  margin-inline: auto;
}
.form-split-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}
.form-split-side {
  position: sticky;
  top: 90px;
}
.form-split-side-note {
  padding: 0 4px;
}
.form-split-side-flow {
  position: static;
}
@media (max-width: 960px) {
  .form-split-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
  .form-split-side {
    position: static;
  }
}
.form-split-side .seg-control {
  flex-wrap: wrap;
}
.form-split-side-actions {
  display: flex;
  justify-content: flex-end;
  padding-bottom: 8px;
}

/* Photo grid for the side column (components/_photo_side.html). The same .photo-manage-row
   markup as the wide rows (photo-manage.js moves rows by DOM order), laid out as tiles: the
   first photo spans both columns as the cover, each tile holds the thumbnail with the
   remove control on top, the caption input, and the earlier / later movers. */
.photo-manage-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 10px;
}
.photo-manage-grid .photo-manage-row {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px;
  padding: 6px;
}
.photo-manage-grid .photo-manage-row:first-child {
  grid-column: 1 / -1;
}
.photo-manage-grid .photo-manage-thumbwrap {
  grid-column: 1 / -1;
}
.photo-manage-grid .photo-manage-row img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
}
.photo-manage-grid .photo-manage-caption {
  grid-column: 1 / -1;
}
.photo-manage-grid .photo-manage-remove {
  position: absolute;
  top: 10px;
  right: 10px;
}
.photo-manage-grid .photo-manage-btns {
  grid-column: 1 / -1;
  justify-content: space-between;
}
.form-split-side .dropzone {
  padding: 18px 12px;
}
/* Topic and level side by side; stacked on phones. */
.course-editor-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: 16px;
}
@media (max-width: 600px) {
  .course-editor-pair {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
}
.course-editor-tally {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink-soft);
}

/* Chapter outline rows. */
.chapter-outline {
  gap: 8px;
  margin-bottom: 12px;
}
.chapter-outline-row {
  padding: 8px 10px;
  border-radius: 8px;
  box-shadow: none;
}
.chapter-outline-row.is-empty {
  border-color: var(--brass);
  background: #fdf9f0;
}
.chapter-outline-head {
  margin-bottom: 0;
  flex-wrap: wrap;
}
.chapter-outline-title {
  flex: 1 1 140px;
  min-width: 0;
}
.chapter-outline-title input {
  width: 100%;
  padding: 7px 10px;
  font-size: 14px;
}
.chapter-outline-title.form-field-invalid input {
  border-color: #7a2f2f;
}
.chapter-outline-status {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.chapter-outline-count {
  font-size: 12.5px;
  color: var(--ink-soft);
  white-space: nowrap;
}
.chapter-outline-flag {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--brass-dk);
  white-space: nowrap;
}
.chapter-outline-row > .form-field-error,
.chapter-outline-row > .form-errors {
  margin: 6px 0 2px 38px;
}
/* Type-and-Enter add line under the outline. */
.chapter-quick-add {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 8px;
}
.chapter-quick-add input {
  flex: 1;
  min-width: 0;
  padding: 9px 12px;
  border: 1px dashed var(--line-strong);
  border-radius: 8px;
  background: var(--mist-2);
  font: inherit;
  font-size: 14px;
}
.chapter-quick-add input:focus {
  border-style: solid;
  background: var(--white);
}

/* Current cover row above the dropzone. */
.course-cover-current {
  flex: 1;
  font-size: 13px;
  color: var(--ink-soft);
}
.photo-manage-row:has(input[name$="-clear"]:checked) {
  opacity: 0.5;
  border-color: #7a2f2f;
}
.photo-manage-row:has(input[name$="-clear"]:checked) .photo-manage-x {
  background: #7a2f2f;
  border-color: #7a2f2f;
  color: #fff;
}
.form-split-side .photo-manage {
  margin-bottom: 10px;
}

/* Publish checklist (advisory - Publish is never blocked). */
.form-checklist-title {
  margin: 0 0 10px;
  font-size: 15px;
  font-weight: 800;
  color: var(--forest-700);
}
.form-checklist-list {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.form-checklist-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--ink);
}
.form-checklist-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  border: 2px dashed var(--brass);
  border-radius: 50%;
  font-size: 12px;
  font-weight: 800;
  color: #fff;
}
.form-checklist-item.is-optional .form-checklist-mark {
  border-color: var(--line-strong);
}
.form-checklist-item.is-done .form-checklist-mark {
  border: 0;
  background: var(--forest-500);
}
.form-checklist-opt {
  font-size: 12px;
  color: var(--ink-soft);
}
.form-checklist-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  padding-bottom: 8px;
}

/* ---------------------------------------------------------------------------
   Business storefront (orgs/storefront.html, /org/<slug>/). The member-profile hero and tab
   strip, plus a sidebar (About / Trader details / Parting out now) beside the tab content.
   --------------------------------------------------------------------------- */
.storefront-logo {
  border-radius: 14px;
}

.storefront-stats {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 18px;
  margin-top: 6px;
}

.storefront-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 24px;
  align-items: start;
}

.storefront-aside {
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: sticky;
  top: 16px;
}

.storefront-aside .settings-card {
  margin: 0;
}

.storefront-grid {
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}

.storefront-donors {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.storefront-description p {
  margin: 0 0 8px;
}

.storefront-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 12px;
  margin: 10px 0;
}

.storefront-facts dt {
  color: var(--ink-soft);
}

.storefront-facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.storefront-donor-list {
  list-style: none;
  padding: 0;
  margin: 6px 0 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

@media (max-width: 900px) {
  .storefront-layout {
    grid-template-columns: 1fr;
  }

  .storefront-aside {
    position: static;
  }
}

/* ---------------------------------------------------------------------------
   Inbox side switch (messaging/inbox.html): All / Personal / <business>, shown only to someone
   who also works for a business, plus the "to <business>" tag on business threads.
   --------------------------------------------------------------------------- */
.msg-sides {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.msg-side {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--white);
  color: var(--ink);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}

.msg-side:hover {
  border-color: var(--forest-500);
}

.msg-side.is-on {
  background: var(--forest-700);
  border-color: var(--forest-700);
  color: var(--white);
}

.msg-side-count {
  font-weight: 400;
  opacity: 0.7;
}

.msg-item-side {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--mist);
  color: var(--forest-500);
  font-size: 12px;
  font-weight: 600;
  vertical-align: middle;
}

/* "Replying as <business>" under the composer label on a business thread (messaging/thread.html). */
.msg-composer-as {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--forest-500);
}
/* Business import: the live progress card (orgs/_import_progress.html). The bar reuses the
   restyled native <progress> of the academy; here it spans the card. */
.import-progress-file {
  margin-left: 8px;
  font-size: 15px;
  font-weight: 400;
  color: var(--ink-soft);
}
.import-progress .import-progress-bar {
  display: block;
  width: 100%;
  max-width: none;
  height: 8px;
  margin: 4px 0 8px;
}

/* Business Overview / Listings / Members (orgs/dashboard.html, listings.html, members.html): the
   same .form-split two-column shell as the Export/Import page - the work in .org-main, small
   cards in the sticky .org-side rail. The rail drops under the main column below 960px. */
.org-split {
  padding: 8px 0 72px;
}
.org-main,
.org-side {
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
}
@media (max-width: 960px) {
  .org-side {
    margin-top: 20px;
  }
}
/* Overview: four number tiles, then the actions two by two. */
.org-stat-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}
.org-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 16px 16px 14px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--ink);
  text-decoration: none;
}
a.org-stat:hover {
  border-color: var(--forest-300);
  text-decoration: none;
}
.org-stat strong {
  font-family: "Arial Narrow", "Segoe UI", Impact, sans-serif;
  font-size: 32px;
  line-height: 1.1;
  color: var(--forest-700);
}
.org-stat span {
  font-size: 13px;
  color: var(--ink-soft);
}
.org-stat--alert {
  background: #fdf6e3;
  border-color: #ecd9a6;
}
.org-stat--alert strong {
  color: var(--brass-dk);
}
.org-action-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 640px) {
  .org-stat-grid,
  .org-action-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .org-action-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* Overview rail: the business card and the listing limit meter. */
.org-id-card {
  text-align: center;
}
.org-id-logo {
  display: block;
  width: 64px;
  height: 64px;
  margin: 0 auto 10px;
  border-radius: 8px;
  object-fit: cover;
}
.org-id-logo--initial {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--forest-500);
  color: var(--white);
  font-family: "Arial Narrow", Impact, sans-serif;
  font-weight: 800;
  font-size: 28px;
}
.org-id-name {
  margin: 0;
  font-weight: 700;
  font-size: 17px;
}
.org-id-role {
  margin: 2px 0 8px;
  font-size: 13px;
  color: var(--ink-soft);
}
.org-id-card a.org-id-link,
.org-attention a.org-attention-link {
  color: var(--brass-dk);
  font-weight: 700;
  font-size: 13px;
}
/* Listings: rail status filter (links with a count pill), the attention card, the filter note. */
.org-filter-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.org-filter-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 10px;
  border-radius: 6px;
  color: var(--ink);
  text-decoration: none;
  font-size: 14px;
}
.org-filter-link:hover,
.org-filter-link.is-current {
  background: var(--mist);
  text-decoration: none;
}
.org-filter-link.is-current {
  font-weight: 700;
}
.org-attention {
  border-color: #ecd9a6;
  background: #fdf6e3;
}
.org-filter-note {
  margin: 0;
  font-size: 14px;
  color: var(--ink-soft);
}
.org-filter-note a {
  color: var(--brass-dk);
  font-weight: 700;
}
/* The card grid fills the wider main column three across (two on tablets). */
.org-listing-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 1100px) {
  .org-listing-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 560px) {
  .org-listing-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* Members rail: the invite form, pending invites as a compact list, the roles card. */
.org-invite-form .form-actions {
  margin-top: 4px;
}
.org-invite-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.org-invite-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.org-invite-list li:first-child {
  border-top: 0;
  padding-top: 0;
}
.org-invite-id {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  font-size: 13px;
}
.org-invite-id b {
  overflow-wrap: anywhere;
}
.org-invite-id span {
  color: var(--ink-soft);
  font-size: 12.5px;
}
.org-role-list {
  margin: 0;
  font-size: 13px;
}
.org-role-list dt {
  font-weight: 700;
}
.org-role-list dd {
  margin: 0 0 8px;
  color: var(--ink-soft);
}

/* Business Export/Import page (orgs/import.html): the .form-split shell with the work in the main
   column and the exports, template and limits in the sticky side rail. The column reference is a
   full-width <details> card under both columns, collapsed by default. */
.import-page {
  padding: 8px 0 72px;
}
.import-main,
.import-side {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
@media (max-width: 960px) {
  .import-side {
    margin-top: 20px;
  }
}
.import-card-sub {
  margin: -8px 0 14px;
  font-size: 13.5px;
  color: var(--ink-soft);
}
.import-chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin-top: 4px;
}
.import-chip {
  font-size: 12px;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 10px;
  color: var(--ink-soft);
}
.import-downloads {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.import-download {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--ink);
  text-decoration: none;
}
.import-download:hover,
.import-download:focus-visible {
  border-color: var(--forest-300);
  background: var(--mist-2);
}
.import-download b {
  display: block;
  font-size: 14px;
}
.import-download span span {
  font-size: 13px;
  color: var(--ink-soft);
}
.import-download-ext {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 4px;
  background: var(--forest-500);
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
}
.import-download-ext--zip {
  background: var(--forest-700);
}
.import-limits {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
}
.import-limits li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.import-limits li:last-child {
  border-bottom: 0;
}
.import-limits b {
  font-variant-numeric: tabular-nums;
}
.import-columns {
  margin-top: 24px;
  padding: 0;
}
.import-columns > summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 18px 24px;
  cursor: pointer;
  list-style: none;
}
.import-columns > summary::-webkit-details-marker {
  display: none;
}
.import-columns > summary::after {
  content: "+";
  color: var(--brass-dk);
  font-size: 24px;
  font-weight: 700;
  line-height: 1;
}
.import-columns[open] > summary::after {
  content: "\2212";
}
.import-columns > summary:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: -2px;
}
.import-columns > summary .settings-card-title {
  display: block;
  margin: 0;
}
.import-columns-body {
  padding: 0 24px 24px;
}

/* Import report (orgs/import_batch.html): the problem-rows card header, title left and the CSV
   download right, wrapping under the title on a phone. */
.import-report-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 16px;
  margin-bottom: 8px;
}
.import-report-head .settings-card-title {
  margin: 0;
}
.import-report-count {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 9px;
  border-radius: 999px;
  background: var(--mist);
  color: var(--ink-soft);
  font-size: 13px;
  vertical-align: middle;
}

/* ---------------------------------------------------------------------------
   Staging banner (templates/base.html, shown only when SITE_ENV is "staging").
   Deliberately off-brand - a signal colour outside the forest/brass palette - so a screenshot
   of staging can never pass for the live site.
   --------------------------------------------------------------------------- */
.site-env-banner {
  background: #c2410c;
  color: #ffffff;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-align: center;
  padding: 6px 16px;
}

/* ---------------------------------------------------------------------------
   Garage: Specs "Mileage" row with the owner's quick "Log" form (garage/_mileage_log_form.html).
   The <details> sits inline after the reading while closed; open, it drops the small form on its
   own line under the reading.
   --------------------------------------------------------------------------- */
.garage-mileage-value {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
}
.garage-mileage-log {
  display: inline-block;
}
.garage-mileage-log[open] {
  display: block;
  flex-basis: 100%;
}
.garage-mileage-log-toggle {
  display: inline;
  list-style: none;
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  color: var(--forest-500);
}
.garage-mileage-log-toggle::-webkit-details-marker {
  display: none;
}
.garage-mileage-log-toggle:hover,
.garage-mileage-log-toggle:focus-visible {
  text-decoration: underline;
}
.garage-mileage-log-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
}
.garage-mileage-log-form .form-field {
  margin-bottom: 0;
}
.garage-mileage-log-form .btn {
  align-self: flex-start;
}

/* Checkbox rows (form-field-checkbox): the generic .form-field input rule would stretch the box
   full-width, so pin it to a plain checkbox. Nested inside a .form-field (edit-car "Visitors can
   see") the labels are options, not bold field titles. */
.form-field .form-field-checkbox label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
  font-weight: 400;
}
.form-field-checkbox input[type="checkbox"] {
  width: 16px;
  height: 16px;
  margin: 0;
  flex-shrink: 0;
  accent-color: var(--forest-500);
}

/* Delete-car confirmation: the "Archive instead" alternative above the delete question. */
.garage-archive-instead {
  padding: 16px 20px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--forest-500);
  border-radius: 0;
  background: #fff;
}
.garage-archive-instead .wiki-section-title {
  margin-top: 0;
}

/* ---------------------------------------------------------------------------
   Cookie consent bar (components/_cookie_bar.html, shown only while
   NON_ESSENTIAL_SCRIPTS_ENABLED is on and the visitor has not answered).
   Fixed to the bottom, dark like the header and footer, brass top edge. Sits
   above the back-to-top button and feedback tab (900) and below the flash
   toasts and lightbox (1000). The two choice buttons get equal weight in size;
   refusing must be as easy as accepting.
   --------------------------------------------------------------------------- */
.cookie-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 950;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 56px 14px 20px;
  background: var(--forest-900);
  border-top: 3px solid var(--brass);
  color: #d9e3dc;
}
.cookie-bar-badge {
  flex: none;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 2px var(--brass);
}
.cookie-bar-text {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  line-height: 1.5;
}
.cookie-bar-text p {
  margin: 0;
}
.cookie-bar-title {
  margin: 0;
  font-size: 15px;
  color: #fff;
}
.cookie-bar a {
  color: var(--brass);
  text-decoration: underline;
}
.cookie-bar-actions {
  flex: none;
  display: flex;
  gap: 8px;
  margin: 0;
}
.cookie-bar-actions .btn {
  padding: 8px 16px;
}
.cookie-bar-btn-required {
  background: transparent;
  color: #fff;
  box-shadow: inset 0 0 0 1px var(--forest-300);
}
.cookie-bar-btn-required:hover {
  background: var(--forest-700);
}
.cookie-bar-close {
  position: absolute;
  top: 8px;
  right: 10px;
  padding: 6px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: #d9e3dc;
  font-size: 18px;
  line-height: 0;
  cursor: pointer;
}
.cookie-bar-close:hover {
  background: var(--forest-700);
  color: #fff;
}
.cookie-bar :focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}
/* Phones: badge and text on one row, the two choices as equal halves below. */
@media (max-width: 720px) {
  .cookie-bar {
    flex-wrap: wrap;
    gap: 12px;
    padding: 14px 16px 16px;
  }
  .cookie-bar-badge {
    width: 48px;
    height: 48px;
  }
  .cookie-bar-text {
    flex: 1 1 0;
    padding-right: 28px;
  }
  .cookie-bar-actions {
    flex: 1 1 100%;
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}

/* Footer "Cookie settings": a form button (it clears the stored answer) styled like the
   footer links around it. */
.footer-link-button {
  padding: 0;
  border: 0;
  background: none;
  color: #eef4ef;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.footer-link-button:hover {
  color: var(--white);
  text-decoration: underline;
}

/* ---------------------------------------------------------------------------
   Generation buying guide (48-seo-content-plan.md section 2a)
   The guide page (taxonomy/wiki/buying_guide.html, layout E2 of the 2026-10-20 design round)
   reads like an inspection sheet you take to a viewing: plain sentence-case headings, ruled lines
   and a table with tick boxes, no boxes or coloured stripes. The card on the generation page
   (_buying_guide_card.html) is a wide .card with the button on the right.
   --------------------------------------------------------------------------- */

.guide { padding-top: 28px; padding-bottom: 56px; max-width: 940px; }
.guide-head {
  display: flex;
  gap: 24px;
  align-items: flex-end;
  justify-content: space-between;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 14px;
}
.guide-head h1 { margin: 0; font-size: 36px; color: var(--ink); line-height: 1.05; }
.guide-head .wiki-badge { vertical-align: middle; }
.guide-byline { margin: 8px 0 0; color: var(--ink-soft); font-size: 14px; }
.guide-photo { flex: none; display: block; }
.guide-photo img {
  display: block;
  width: 210px;
  height: 120px;
  object-fit: cover;
  border-radius: 3px;
}

/* The bare <section> rule elsewhere in this file pads every section; the guide sets its own. */
.guide-section { margin-top: 40px; padding: 0; }
.guide-section-first { margin-top: 24px; }
.guide-section h2 {
  text-transform: none;
  letter-spacing: 0;
  font-size: 21px;
  margin: 0 0 8px;
  color: var(--ink);
}
.guide-section > p { max-width: 46em; margin: 0 0 10px; }
.guide-section .guide-lead { font-size: 19px; line-height: 1.55; margin: 4px 0 12px; }
.guide-section .guide-forag { margin: 4px 0; max-width: 52em; }

/* The inspection sheet. */
.guide-sheet-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
}
.guide-sheet { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 15px; }
.guide-sheet th,
.guide-sheet td {
  text-align: left;
  vertical-align: top;
  padding: 9px 10px 9px 0;
  border-bottom: 1px solid var(--line-strong);
}
.guide-sheet thead th {
  font-size: 13px;
  color: var(--ink-soft);
  font-weight: 600;
  border-bottom: 2px solid var(--ink);
}
.guide-sheet-group th {
  padding-top: 18px;
  font-size: 15px;
  font-weight: 700;
  border-bottom: 1px solid var(--ink);
}
.guide-sheet-tick { width: 30px; }
.guide-sheet-box {
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--ink);
  border-radius: 2px;
  margin-top: 3px;
}
.guide-sheet-sev { white-space: nowrap; width: 90px; }
.guide-sheet-scope { color: var(--ink-soft); }
.guide-more { margin-top: 12px; font-weight: 600; }

.guide-engine-table { margin-top: 12px; }

.guide-foot {
  margin-top: 44px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 14px;
  color: var(--ink-soft);
}

/* The card on the generation page (_buying_guide_card.html): a wide .card with the button on the
   right. No coloured top edge (the .card default is a 4px green one that turns brass on hover), and
   no lift on hover: the card holds links, it is not one. */
.guide-card {
  display: flex;
  gap: 24px;
  align-items: center;
  border-top: 1px solid var(--line);
  padding: 22px 24px;
}
.guide-card:hover {
  transform: none;
  border-top-color: var(--line);
  box-shadow: 0 1px 3px var(--shadow);
}
.guide-card-main { flex: 1; min-width: 0; }
.guide-card .guide-card-title { margin: 0 0 6px; font-size: 20px; }
.guide-card-title a { color: var(--ink); text-decoration: none; }
.guide-card-title a:hover { color: var(--brass-dk); }
.guide-card-checks { list-style: none; margin: 12px 0 0; padding: 0; }
.guide-card-checks li {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 4px 0;
  font-size: 15px;
}
.guide-card-checks .icon { width: 18px; height: 18px; color: var(--forest-500); flex: none; }
.guide-card .guide-card-meta { margin-top: 12px; font-size: 13px; }
.guide-card-side { flex: none; }
@media (max-width: 760px) {
  .guide-card { flex-direction: column; align-items: stretch; }
}
@media (max-width: 640px) {
  .guide-head { flex-direction: column-reverse; align-items: stretch; }
  .guide-head h1 { font-size: 30px; }
  .guide-photo img { width: 100%; height: 170px; }
  /* The sheet stacks per check on a phone: the tick box beside the check, its issue and its
     severity. */
  .guide-sheet thead { display: none; }
  .guide-sheet-group { display: block; }
  .guide-sheet-group th { display: block; }
  .guide-sheet tbody tr:not(.guide-sheet-group) {
    display: grid;
    grid-template-columns: 30px 1fr;
    padding: 8px 0;
    border-bottom: 1px solid var(--line-strong);
  }
  .guide-sheet tbody tr:not(.guide-sheet-group) td { border: 0; padding: 1px 0; width: auto; }
  .guide-sheet td.guide-sheet-tick { grid-row: span 3; }
  /* Four engine columns fit a phone without a sideways scroll once the cell padding is halved. */
  .guide-engine-table th,
  .guide-engine-table td { padding-left: 7px; padding-right: 7px; }
}

/* Printing: the guide prints without the site chrome; "Print this list" (print-button.js sets
   html.printing-sheet) prints the inspection sheet alone. */
@media print {
  .site-header,
  .site-footer,
  .wiki-breadcrumb,
  .back-to-top,
  .cookie-bar,
  .guide-print,
  .guide-photo { display: none; }
  .printing-sheet .guide-section:not(.guide-print-area),
  .printing-sheet .guide-foot,
  .printing-sheet .guide-more { display: none; }
  .printing-sheet .guide-print-area { margin-top: 12px; }
  .guide-sheet a { color: var(--ink); }
}
