:root{
  --canvas:#FBFBFC; --surface:#FFF; --surface2:#F5F5F7; --surface3:#EEEEF1;
  --border:#EAEAEE; --border2:#DCDCE2;
  --text:#0A0A0C; --t2:#61616B; --t3:#95959F;
  --accent:#EA580C; --accent-fg:#C2410C; --accent-soft:#FFF3EB; --accent-line:#FAD4BC;
  /* The count badge is deliberately NOT the accent. It sits two inches from an
     orange Create button and an orange rail, and a third orange thing in that
     span stops being a signal and becomes decoration. Blue is the only hue in
     the header that means exactly one thing: there are N of these waiting. */
  --badge:#1B4FD8; --badge-fg:#FFFFFF;
  /* The ink that goes ON an accent fill — every one of them, in 43 places that
     each used to spell it `#fff` for themselves.
     It is WHITE, which is the house look: an orange button with white on it.
     It is a token anyway, and that is the point of this change. The operator
     sets the accent from the Appearance screen, and white is only safe on a
     colour dark enough to carry it — pick a pastel and forty-three hard-coded
     #fff turn into forty-three invisible labels at once. Settings::inkFor()
     decides per accent in views/app.php; this is what an untouched install
     uses, and it agrees with what that function returns for the default. */
  --accent-ink:#FFFFFF;
  /* The same ink under a name no page shell shadows. .su and .mdp each
     redefine --accent-ink locally to mean the OPPOSITE thing — the accent used
     as TEXT on a wash — which is right for the fourteen places each uses it for
     and wrong for the one that matters, so the settings screen's primary button
     was painting C2410C on EA580C. A button fill reads this instead. */
  --accent-on:var(--accent-ink);
  /* The brand's hexagon, as a clip. The mark, the badge and anything else cut
     to this shape read the same because they ARE the same six points. */
  --hex:polygon(25% 0%,75% 0%,100% 50%,75% 100%,25% 100%,0% 50%);
  --green:#15A34A; --green-soft:#F0FDF4; --green-line:#BBF7D0;
  --violet:#7C3AED; --violet-soft:#F5F1FE; --violet-line:#DDD0FB;
  --sh-sm:0 1px 2px rgba(12,12,16,.05);
  --sh:0 1px 2px rgba(12,12,16,.04),0 8px 20px -12px rgba(12,12,16,.16);
  --sh-lg:0 2px 6px rgba(12,12,16,.05),0 20px 44px -20px rgba(12,12,16,.24);
  --sh-btn:0 1px 2px rgba(12,12,16,.16),inset 0 1px 0 rgba(255,255,255,.09);
  --r:10px; --r-lg:14px; --r-xl:20px;
  /* The button ladder's SHAPE, as tokens. Four ported page shells (#pg-vehicle,
     .mdp, #pg-vehicles, .su) each wrote these seven numbers out for themselves,
     so a button was the same size on five pages by coincidence rather than by
     rule. They read these now and keep only their own palette; css/00b-buttons.php
     is the treatment. To move a button, move a number here — not five. */
  --btn-h:32px; --btn-h-sm:28px; --btn-h-lg:44px;
  --btn-pad:12px; --btn-r:6px; --btn-gap:6px;
  --btn-fs:12.5px; --btn-fs-sm:12px; --btn-fs-lg:14px;
  --navh:60px;
  /* The page frame — three tokens, one ladder, every page (CONVENTIONS §11).
     --pad      the left/right gutter
     --pad-top  where content starts under the nav
     --col      how wide the content column may grow — the ONLY cap on the site
     What the eye sees is the SUM of these with the column's auto margins, so
     they move together on the same breakpoints and no page adds a term.

     THERE IS ONE COLUMN AND EVERY PAGE IS IN IT. There used to be three rungs:
     --col for most pages, --col-feed (1040px) for the feed and the profile, and
     --col-read (760px) for a long-form reading column. Each was a defensible
     local decision about ONE screen, and together they were the §11 trap all
     over again one term along — the gutter and the top pad were unified and the
     cap was not, so /feed's edge landed 90px inside /mods' on the same window
     and walking between them read as the page shifting under you. A rung that
     only one section stands on is not a ladder, it is that section's private
     number wearing a token's name. To move a page's edge, move --col. */
  --pad:18px; --pad-top:27px; --col:1220px;
  --ui:"Inter","Inter Tight",system-ui,-apple-system,"Segoe UI",sans-serif;
  --dis:"Inter Tight","Inter",system-ui,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,Menlo,monospace;
  --ease:cubic-bezier(.32,.72,0,1);
  --grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='.17'/%3E%3C/svg%3E");
}
/* The pre-paint boot (views/app/theme-boot.php) puts the class on <html> as
   well, because <body> does not exist yet when the head script runs. This is
   the rule that keeps the canvas, the overscroll gutter and the scrollbars
   from coming up white for a frame on a dark member's cold load — the token
   ladder below cannot do it, since it hangs off body. Same value as --canvas.
   Move that and move this. */
html.dark{background:#08080A;color-scheme:dark}
body.dark{
  --canvas:#08080A; --surface:#111114; --surface2:#1A1A1E; --surface3:#232329;
  --border:#25252B; --border2:#33333B;
  --text:#FAFAFA; --t2:#9F9FAA; --t3:#6B6B76;
  --accent:#FB923C; --accent-fg:#FDBA74; --accent-soft:rgba(251,146,60,.11); --accent-line:rgba(251,146,60,.28);
  --badge:#3B76E8; --badge-fg:#FFFFFF;
  --accent-ink:#FFFFFF; --accent-on:var(--accent-ink);
  --green:#4ADE80; --green-soft:rgba(74,222,128,.1); --green-line:rgba(74,222,128,.26);
  --violet:#A78BFA; --violet-soft:rgba(167,139,250,.1); --violet-line:rgba(167,139,250,.26);
  --sh-sm:0 1px 2px rgba(0,0,0,.4);
  --sh:0 1px 2px rgba(0,0,0,.3),0 8px 20px -12px rgba(0,0,0,.7);
  --sh-lg:0 2px 6px rgba(0,0,0,.35),0 20px 44px -20px rgba(0,0,0,.85);
  color-scheme:dark;
}

/* THE DRAWER'S NAV PALETTE — ON <body>, AND THAT IS THE WHOLE OF WHY IT WORKS.
   It is the same chrome as the bar above it, so each of these is the theme
   token it should always have been, not one of the six hard-coded greys the old
   always-dark left rail carried. They sat in the :root block above under a comment saying body.dark flipped
   them for free. IT DOES NOT: a custom property is substituted where it is
   DECLARED, not where it is read, so `--sb-bg:var(--surface)` written on :root
   takes :root's LIGHT --surface — every dark token is redefined one element
   down, on body.dark — and inherits that finished white to the drawer. A member
   on dark got a white menu over a black page, and the token names all looked
   right. Declared here they resolve against the element carrying the dark
   values. Any alias of a themed token belongs on body for the same reason. */
body{
  --sb-bg:var(--surface); --sb-line:var(--border); --sb-text:var(--t2); --sb-dim:var(--t3);
  --sb-hover:var(--surface2); --sb-active-bg:var(--accent-soft);
  --sb-active:var(--accent-fg); --sb-strong:var(--text);
}
*,*::before,*::after{box-sizing:border-box}
body{margin:0;background:var(--canvas);color:var(--text);font:400 15px/1.6 var(--ui);letter-spacing:-.008em;
  -webkit-font-smoothing:antialiased;transition:background .25s var(--ease),color .25s var(--ease)}
a{color:inherit;text-decoration:none}
button,select,input,textarea{font:inherit;color:inherit}
button{background:none;border:0;cursor:pointer}
h1,h2,h3,h4{margin:0;font-family:var(--dis);font-weight:600;line-height:1.2;letter-spacing:-.028em}
p{margin:0}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}
/* The frame ladder. Two steps, shared by every page — a page does not get to
   pick its own breakpoints for the edge, because that is what made /vehicle
   (28px) sit a nudge wider than /garage (24px) on the same screen, and /events
   open flush against the nav while /groups opened 36px below it. */
@media(max-width:860px){:root{--pad:14px; --pad-top:23px}}
@media(max-width:600px){:root{--pad:12px; --pad-top:20px}}
.wrap{max-width:var(--col);margin:0 auto;padding:0 var(--pad)}
.mono{font-family:var(--mono);font-size:.92em}
/* Said to a screen reader and to nobody else. Three pages had already grown a
   private copy of these six declarations under their own id; this is the one
   every surface can reach, so the next one does not make a fourth. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
.muted{color:var(--t2)} .small{font-size:13px}
.row{display:flex;align-items:center;gap:10px}
.spread{display:flex;align-items:center;justify-content:space-between;gap:16px}
.stack{display:flex;flex-direction:column}
.hide-d{display:none}

/* The buttons moved out to css/00b-buttons.php — the ladder is a screenful on
   its own and this file was at the 600-line cap (§10). The name stays because
   the TOKENS above are still what a button is cut from. */

/* ---------- bits ---------- */
.card{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);box-shadow:var(--sh-sm)}
.pad{padding:20px}
.pill{display:inline-flex;align-items:center;gap:5px;height:24px;padding:0 10px;border:1px solid var(--border);
  border-radius:999px;background:var(--surface2);font-size:12px;font-weight:500;color:var(--t2);white-space:nowrap}
.pill-a{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent-fg)}
.pill-g{background:var(--green-soft);border-color:var(--green-line);color:var(--green)}
.pill-v{background:var(--violet-soft);border-color:var(--violet-line);color:var(--violet)}
.pill-c{background:var(--violet-soft);border-color:var(--violet-line);color:var(--violet)}
.pill-d{background:var(--surface2);border-color:var(--border);color:var(--t2)}
.pill i{width:5px;height:5px;border-radius:50%;background:currentColor;flex:none}

/* ---- events: map + location picker ---- */
.ev-mapwrap{margin:0 0 24px;border:1px solid var(--border);border-radius:16px;overflow:hidden;background:var(--surface2)}
.ev-maptools{display:flex;align-items:center;gap:12px;padding:11px 14px}
.ev-maptools .small{margin-right:auto}
.ev-map{height:340px;width:100%;background:var(--surface3)}
.ev-map-sm{height:220px;border-radius:12px;overflow:hidden;border:1px solid var(--border)}

/* ============ The stats page's section head ============
   All that is left of the old My Garage card grid. That page is
   views/app/css/08d-garage.php now — a different layout with a gg- prefix —
   and its ggr- rules went with the renderer they styled.

   These three stayed because they were never the garage's alone: /stats draws
   the same section head (views/app/page-stats.php) and render-stats.php emits
   .ggr-up in its comments tile. They keep the ggr- name for that reason —
   renaming them would be a rename across two files that do not mention this
   one, to tidy somebody else's deletion.

   .ggr-up gained #pg-stats. It was scoped to #pg-garage and the only thing
   that ever drew it inside #pg-garage was garageStatbar(), in the bundle,
   which is deleted — so the one live user, the stats tile's delta arrow, was
   already inheriting nothing and rendering as plain body text. Found by
   checking who still needed each rule before cutting it, which is the point of
   doing that rather than deleting the block wholesale. */
#pg-garage .ggr-sect,#pg-stats .ggr-sect{display:flex;align-items:center;gap:12px;margin:0 0 14px}
#pg-garage .ggr-sect h2,#pg-stats .ggr-sect h2{font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--t3);font-weight:600;margin:0}
#pg-garage .ggr-rule,#pg-stats .ggr-rule{flex:1;height:1px;background:var(--border)}
#pg-garage .ggr-up,#pg-stats .ggr-up{color:var(--green);font-size:11.5px;display:inline-flex;align-items:center;gap:3px;margin-left:2px}

/* ============ Full stats page ============ */
#pg-stats .st-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:1px;background:var(--border);border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;margin-bottom:20px}
#pg-stats .st-tile{background:var(--surface);padding:16px 18px}
#pg-stats .st-v{font-family:ui-monospace,'IBM Plex Mono',SFMono-Regular,Menlo,monospace;font-size:26px;font-weight:600;letter-spacing:-.02em;line-height:1.05;font-variant-numeric:tabular-nums}
#pg-stats .st-l{font-size:12.5px;color:var(--t3);margin-top:5px;display:flex;align-items:center}
#pg-stats .st-panel{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);padding:16px 18px 18px;margin-bottom:16px}
#pg-stats .st-t{font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--t3);font-weight:600;margin:0 0 14px}
#pg-stats .st-cols{display:grid;grid-template-columns:1fr 1fr;gap:16px}
#pg-stats .st-cols .st-panel{margin-bottom:0}
#pg-stats .st-chart{display:flex;align-items:flex-end;gap:8px;height:130px;padding-top:6px}
#pg-stats .st-col{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;gap:6px;min-width:0}
#pg-stats .st-colbar{width:100%;max-width:34px;background:var(--accent);border-radius:3px 3px 0 0;min-height:2px;opacity:.85;transition:opacity .15s}
#pg-stats .st-col:hover .st-colbar{opacity:1}
#pg-stats .st-collab{font-size:10.5px;color:var(--t3);white-space:nowrap}
#pg-stats .st-hbars{display:flex;flex-direction:column;gap:11px}
#pg-stats .st-hbar{display:grid;grid-template-columns:120px 1fr auto;align-items:center;gap:10px}
#pg-stats .st-hl{font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--t2)}
#pg-stats .st-htrack{height:8px;background:var(--surface3);border-radius:99px;overflow:hidden}
#pg-stats .st-htrack i{display:block;height:100%;background:var(--accent);border-radius:99px}
#pg-stats .st-hv{font-size:12.5px;color:var(--text);font-variant-numeric:tabular-nums;min-width:56px;text-align:right}
#pg-stats .st-vehs{display:flex;flex-direction:column}
#pg-stats .st-veh{border-top:1px solid var(--border)}
#pg-stats .st-veh:first-child{border-top:0}
#pg-stats .st-vsum{display:flex;align-items:center;gap:12px;padding:11px 0;cursor:pointer;list-style:none}
#pg-stats .st-vsum::-webkit-details-marker{display:none}
#pg-stats .st-veh:hover .st-vehmeta b{color:var(--accent)}
#pg-stats .st-vehimg{width:64px;height:44px;flex:none;border-radius:8px;background:var(--surface3) center/cover no-repeat;border:1px solid var(--border)}
#pg-stats .st-vehmeta{min-width:0;flex:1}
#pg-stats .st-vehmeta b{font-weight:600;font-size:14px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#pg-stats .st-vehmeta .muted{font-size:12.5px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#pg-stats .st-vehspent{font-size:14px;font-weight:600;flex:none;font-variant-numeric:tabular-nums}
#pg-stats .st-vcaret{color:var(--t3);flex:none;transition:transform .15s}
#pg-stats .st-veh[open] .st-vcaret{transform:rotate(180deg)}
#pg-stats .st-spend{padding:2px 0 10px 76px}
#pg-stats .st-spitem{display:grid;grid-template-columns:1fr auto 66px;align-items:center;gap:10px;padding:5px 0}
#pg-stats .st-sptitle{font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--t2)}
#pg-stats .st-sptag{font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--t3);background:var(--surface3);border-radius:99px;padding:2px 8px;white-space:nowrap}
#pg-stats .st-spamt{font-size:13px;font-variant-numeric:tabular-nums;text-align:right}
#pg-stats .st-spnote{padding:0 0 10px 76px;margin:0;font-size:12.5px}
#pg-stats .st-vlink{display:inline-block;margin:0 0 12px 76px;font-size:12.5px;color:var(--accent);text-decoration:none}
@media (max-width:640px){
  #pg-stats .st-spend,#pg-stats .st-spnote,#pg-stats .st-vlink{padding-left:0;margin-left:0}
}
@media (max-width:640px){
  #pg-stats .st-cols{grid-template-columns:1fr}
  #pg-stats .st-hbar{grid-template-columns:90px 1fr auto}
}

/* the "Vehicles going" line-up on an event page */
.ev-vehgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
.ev-vehcard{display:flex;flex-direction:column;border:1px solid var(--border);border-radius:12px;overflow:hidden;background:var(--surface2);transition:border-color .15s ease}
.ev-vehcard:hover{border-color:var(--t3)}
.ev-vehphoto{display:block;width:100%;aspect-ratio:4/3;background:var(--surface3) center/cover no-repeat}
.ev-vehmeta{padding:8px 10px;min-width:0}
.ev-vehmeta b{display:block;font-weight:500;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ev-vehmeta .muted{display:block;font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.emap-canvas{height:240px;margin-top:10px;border-radius:12px;overflow:hidden;border:1px solid var(--border);background:var(--surface3)}
.emap-tools{display:flex;gap:9px;margin-top:10px;flex-wrap:wrap}
.eorigin-seg{display:inline-flex;border:1px solid var(--border);border-radius:10px;overflow:hidden;margin-bottom:2px}
.eorigin-seg button{background:var(--surface2);border:0;border-right:1px solid var(--border);padding:9px 16px;
  font-size:13.5px;font-weight:500;color:var(--t2);cursor:pointer;font-family:inherit}
.eorigin-seg button:last-child{border-right:0}
.eorigin-seg button.on{background:var(--accent);color:var(--accent-ink)}
.eorigin-comm{margin-top:13px}
.eorigin-prev{margin-top:10px}
.eorigin-prevcard{display:flex;gap:12px;align-items:center;border:1px solid var(--border);border-radius:12px;padding:9px;background:var(--surface2)}
.eorigin-prevcard img{width:88px;height:66px;object-fit:cover;border-radius:8px;flex:none;background:var(--surface3)}
.eorigin-prevcard b{display:block;font-size:13px;margin-bottom:2px}
.eorigin-prevcard .btn{margin-top:7px}
/* Leaflet tiles must sit above the card background but below app overlays */
.leaflet-container{font:inherit}
.leaflet-pane,.leaflet-top,.leaflet-bottom{z-index:2}
.pill.lg{height:28px;font-size:12.5px;padding:0 12px}
.av{width:32px;height:32px;border-radius:999px;flex:none;display:grid;place-items:center;font-size:11.5px;
  font-weight:600;color:#fff;background:#3F3F49;position:relative}
.av-sm{width:24px;height:24px;font-size:9.5px}
.av-lg{width:72px;height:72px;font-size:24px;border-radius:22px}
.av-xs{width:20px;height:20px;font-size:9px}
/* The bubble's own image fills it and inherits its shape. It must be taken out
   of flow: .av is display:grid, so an in-flow <img> lands in a SECOND grid cell
   and the initials end up sitting beside the photo instead of behind it. */
.av>.av-img{width:100%;height:100%;object-fit:cover;border-radius:inherit;display:block;
  position:absolute;inset:0}
/* presence dot — hidden by default, shown when the bubble is .is-online. Sits on
   the bottom-right edge with a ring the colour of the surface behind it. Scales
   with the bubble so it reads on a 20px chip and a 72px hero alike. */
.av>/* An icon that LEADS a line of text in a button. It replaces an inline style
   (`vertical-align:-2px;margin-right:5px`) that the icon helper has no field
   for — and should not grow one, or every call site starts carrying its own
   geometry again. */
.ic-lead{vertical-align:-2px;margin-right:5px}
.av-pres{position:absolute;right:-1px;bottom:-1px;width:34%;height:34%;min-width:8px;min-height:8px;
  max-width:15px;max-height:15px;border-radius:50%;background:var(--green);
  box-shadow:0 0 0 2px var(--surface);display:none}
.av.is-online>.av-pres{display:block}
.av-lg>.av-pres{right:2px;bottom:2px}
.avstack{display:flex}
.avstack .av{margin-left:-7px;box-shadow:0 0 0 2px var(--surface)}
.avstack .av:first-child{margin-left:0}
.live{position:relative;width:7px;height:7px;border-radius:50%;background:var(--green);flex:none}
.live::after{content:"";position:absolute;inset:-4px;border-radius:50%;border:1.5px solid var(--green);
  opacity:.6;animation:ping 2s var(--ease) infinite}
@keyframes ping{0%{transform:scale(.6);opacity:.7}100%{transform:scale(1.5);opacity:0}}
.input{width:100%;height:40px;padding:0 13px;border:1px solid var(--border2);border-radius:var(--r);
  font:400 14px var(--ui);background:var(--surface);transition:border-color .16s,box-shadow .16s}
.input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
textarea.input{height:auto;padding:11px 13px;min-height:88px;resize:vertical;line-height:1.6}
select.input{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--t3) 50%),linear-gradient(135deg,var(--t3) 50%,transparent 50%);
  background-position:calc(100% - 17px) 17px,calc(100% - 12px) 17px;background-size:5px 5px;background-repeat:no-repeat;padding-right:34px}
label.lbl{display:block;font-size:13px;font-weight:500;margin:0 0 7px}
hr{border:0;border-top:1px solid var(--border);margin:0}
.sect-t{font-size:12px;font-weight:600;color:var(--t3);margin:0 0 13px;font-family:var(--ui)}

/* ---------- PHOTO (slot for real photography) ---------- */
.photo{position:relative;overflow:hidden;border-radius:12px;background:#141418;isolation:isolate;
  background-image:var(--img,none);background-size:cover;background-position:center}
.photo::before{content:"";position:absolute;inset:0;z-index:1;
  background-image:var(--grain),
    radial-gradient(85% 75% at 22% 18%,var(--p1,#5A6472),transparent 62%),
    radial-gradient(75% 85% at 82% 86%,var(--p2,#2A2F38),transparent 64%),
    linear-gradient(158deg,var(--p3,#454C58),var(--p4,#14161A));
  background-size:120px 120px,auto,auto,auto}
.photo::after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  background:radial-gradient(125% 105% at 50% 32%,transparent 46%,rgba(0,0,0,.44))}
/* A real uploaded photo is set as the element's own background-image, which
   paints BELOW the ::before placeholder gradient (z-index:1) and so was hidden.
   When .hasimg is present, drop both pseudo-elements so the photo shows. */
.photo.hasimg::before,.photo.hasimg::after{content:none!important}

/* vehicle photo gallery tiles: cover badge + owner controls (delete / set cover) */
.vphoto{cursor:zoom-in}
.pgrid .vphoto .tagp{opacity:1;background:rgba(234,88,12,.9);border-color:rgba(255,255,255,.3)}
/* controls reveal on hover (and on keyboard focus, so touch/keyboard users
   can still reach them) */
.vph-acts{position:absolute;top:7px;right:7px;z-index:6;display:flex;gap:5px;
  opacity:0;transition:opacity .15s var(--ease)}
.vphoto:hover .vph-acts,.vphoto:focus-within .vph-acts{opacity:1}
/* there is no hover on a phone — the owner's controls are simply always up */
@media(hover:none){.vph-acts{opacity:1}}
.vph-btn{height:28px;padding:0 10px;border-radius:8px;border:1px solid rgba(255,255,255,.28);
  background:rgba(10,10,12,.66);color:#fff;font:600 11px var(--ui);cursor:pointer;backdrop-filter:blur(5px)}
.vph-btn:hover{background:rgba(10,10,12,.85)}
/* delete is a red circular trash icon */
.vph-del{width:28px;height:28px;padding:0;display:grid;place-items:center;border-radius:50%;
  background:rgba(220,38,38,.92);border-color:rgba(255,255,255,.4);color:#fff}
.vph-del:hover{background:#B91C1C;border-color:#fff}
.vph-del svg{display:block}
/* owner-only visibility chip on the hero (unlisted / private) */
.pmeta2 a{color:var(--accent-fg,var(--accent));text-decoration:none}
.pmeta2 a:hover{text-decoration:underline}
.vis-chip{display:inline-block;margin-left:8px;padding:2px 9px;border-radius:999px;
  font:600 10.5px/1.5 var(--ui);letter-spacing:.04em;text-transform:uppercase;vertical-align:middle;
  background:rgba(255,255,255,.14);color:#fff;border:1px solid rgba(255,255,255,.28)}

/* inline vehicle-detail editor (in-page panel under the hero, not a modal) */
.veh-edit{border-bottom:1px solid var(--border);background:var(--surface2);
  animation:in .22s var(--ease)}
.veh-edit .wrap{padding:18px var(--pad)}
.veh-edit-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.veh-edit label{display:block;font-size:12.5px;font-weight:600;color:var(--t2)}
.veh-edit label .input{margin-top:6px;font-weight:400}
.veh-edit-foot{display:flex;align-items:center;justify-content:flex-end;gap:9px;margin-top:16px}
.veh-edit-foot .amsmodal-err{margin-right:auto;color:#E5484D;font-size:12.5px}
.ve-top{margin:0 0 16px;padding:0 0 16px;border-bottom:1px solid var(--border)}
.ve-head{margin:0 0 9px;font-size:12.5px;font-weight:600;color:var(--t2);
  display:flex;align-items:center;gap:9px}
.ve-head b{color:var(--text);font-weight:600}
.ve-gen{font-size:11px;font-weight:600;color:var(--t3,var(--t2));background:var(--card2,rgba(127,127,127,.12));
  border:1px solid var(--border);border-radius:999px;padding:1px 9px}
.ve-ymm{display:grid;grid-template-columns:88px 1fr 1fr;gap:12px}
.ve-note{margin:10px 0 0;font-size:11.5px;line-height:1.5;color:var(--t3,var(--t2));opacity:.85}
.ve-catwrap{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.ve-wide{grid-column:1/-1}
.veh-edit label .ve-suf{font-weight:400;color:var(--t3,var(--t2));opacity:.7;font-size:11px}
.ve-inline{display:flex;gap:8px;margin-top:6px}
.ve-inline .input{margin-top:0}
.ve-unit{flex:none;width:66px}
.ve-color{display:flex;gap:9px;align-items:center;margin-top:6px}
.ve-color .input{margin-top:0}
.ve-swatch{flex:none;width:38px;height:38px;padding:0;border:1px solid var(--border);
  border-radius:9px;background:none;cursor:pointer}
.ve-swatch::-webkit-color-swatch-wrapper{padding:3px}
.ve-swatch::-webkit-color-swatch{border:0;border-radius:6px}
.ve-swatch::-moz-color-swatch{border:0;border-radius:6px}
@media(max-width:760px){.veh-edit-grid,.ve-catwrap{grid-template-columns:1fr 1fr}.veh-edit .wrap{padding:16px var(--pad)}}
@media(max-width:520px){.veh-edit-grid,.ve-catwrap{grid-template-columns:1fr}.ve-ymm{grid-template-columns:72px 1fr 1fr}}
.photo .ph-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:2;
  opacity:0;transition:opacity .6s var(--ease);display:block}
.photo .ph-img.on{opacity:1}
body.nophoto .photo .ph-img{display:none}
.ph-garage{--p1:#8A7454;--p2:#20242C;--p3:#5C5344;--p4:#111318}
.ph-engine{--p1:#6E7A88;--p2:#2A2018;--p3:#49525E;--p4:#15171B}
.ph-road{--p1:#5D6B8A;--p2:#241E2E;--p3:#3E4661;--p4:#101218}
.ph-shop{--p1:#9A8F7E;--p2:#252A2E;--p3:#63615A;--p4:#14161A}
.ph-paint{--p1:#4E7D78;--p2:#1E2630;--p3:#3A5E5C;--p4:#101519}
.ph-dirt{--p1:#9C7B52;--p2:#2B2A22;--p3:#6B5B41;--p4:#15150F}
.ph-night{--p1:#4A5A94;--p2:#1A1626;--p3:#333C63;--p4:#0C0D14}
.photo .cap{position:absolute;left:10px;right:10px;bottom:10px;z-index:4;
  font-size:12px;font-weight:500;color:rgba(255,255,255,.94);text-shadow:0 1px 6px rgba(0,0,0,.6)}
.photo .tl{position:absolute;left:10px;top:10px;z-index:4}
.photo .pill{background:rgba(10,10,12,.55);border-color:rgba(255,255,255,.16);color:rgba(255,255,255,.92);
  backdrop-filter:blur(6px)}

/* ---------- nav ----------
   ONE bar. The dark left rail is gone and its 248px went back to the page, so
   this is the whole of the site's navigation on a desktop: the brand, the bar,
   search, and the member's own controls. What used to be three lists of the
   same destinations (rail, drawer, phone tab bar) is now one table in
   views/app/chrome.php rendered twice — the bar here, the drawer below. */
.nav{position:sticky;top:0;z-index:80;background:color-mix(in srgb,var(--canvas) 86%,transparent);
  backdrop-filter:blur(14px) saturate(1.6);border-bottom:1px solid var(--border)}
.nav .wrap{display:flex;align-items:center;gap:0;height:var(--navh);max-width:none;padding:0 var(--pad)}
/* the brand, a hairline, then the bar — so the mark reads as a mark and not as
   the first nav item */
.nav .logo{flex:none;position:relative;padding-right:16px;margin-right:10px}
.nav .logo::after{content:"";position:absolute;right:0;top:50%;transform:translateY(-50%);
  width:1px;height:24px;background:var(--border2)}
/* No overflow:hidden here. The mark's frame carries transparent padding that
   keeps its points off the boundary (see .hexmark below), and the negative
   margin that cancels that padding from the layout puts it back OUTSIDE this
   box — so clipping here would cut away exactly the margin the points need and
   flatten them again. The truncation this rule was for belongs to the wordmark,
   which is text and can be cut and still read as itself; see .logo .wm in
   css/06-settings-and-mod.php. */
.logo{display:flex;align-items:center;gap:9px;font-family:var(--dis);font-weight:600;font-size:15.5px;
  letter-spacing:-.03em;flex:0 1 auto;min-width:0}
/* THE HEXAGON'S POINTS ARE ITS VIEWBOX EDGE, so the frame is padded — 20 units
   on every side (viewBox "-20 -20 240 214" against a 200x174 drawing). Without
   it the left and right vertices sit exactly on the boundary and render flat:
   that is the bug 75648e5 fixed and 608e261 undid, and it is why nothing here
   may go back to "0 0 200 174".
   608e261 undid it because padding the frame shrinks the drawing inside a fixed
   height and widens its box, which moved the lockup. Both are arithmetic, so
   both are answered here rather than by dropping the padding:
     --hxh  is the BOX height = the ink height you want x 214/174
     margin cancels the padding from the layout = box height x 20/214
   Set --hxh and the mark keeps its old size and its old footprint exactly. */
.hexmark{height:var(--hxh,25px);width:auto;margin-inline:calc(var(--hxh,25px) * -0.09346)}
.logo .hexmark{--hx-ink:#201E1D;--hx-hot:#EE7016;--hxh:30.75px;flex:none;display:block}
body.dark .logo .hexmark{--hx-ink:#F4F4F5}
.logo .hexmark path{transition:fill .22s var(--ease)}
.logo .hexmark .hx-out{fill:var(--hx-ink)}
.logo .hexmark .hx-in{fill:var(--hx-hot)}
/* hover inverts the mark: ring goes orange, socket goes ink */
.logo:hover .hexmark .hx-out,.logo:focus-visible .hexmark .hx-out{fill:var(--hx-hot)}
.logo:hover .hexmark .hx-in,.logo:focus-visible .hexmark .hx-in{fill:var(--hx-ink)}

/* ---------- the bar ----------
   Words only up here. The glyphs are still drawn — in the dropdowns, in the
   drawer and in the account menu, where a row has the height to carry one; a
   17px brand silhouette beside 14px type read as a smudge and made six items
   look like twelve. */
.navbar{display:flex;align-items:stretch;align-self:stretch;gap:6px;flex:1 1 auto;min-width:0}

/* A TAB, NOT A PILL.
   The bar used to draw each item as a 34px rounded chip that filled with
   accent-soft when it was the current one. Two chips of different colours
   floating in a 60px bar read as two buttons rather than as one row of tabs,
   and the current one read as "selected" the way a filter chip does — a state
   you could clear — rather than as "you are here".
   These are full-height tabs with a 2px rail on the header's own bottom edge:
   the rail is the header's, so the marker belongs to the bar rather than to a
   shape sitting inside it. Grey rail on hover, BRAND rail on the section you
   are standing in, and nothing at all otherwise — one mark, three states, no
   background anywhere. */
.nb-item{position:relative;display:inline-flex;align-items:center;gap:7px;height:100%;padding:0 13px;
  color:var(--t2);font-size:14px;font-weight:490;letter-spacing:-.006em;white-space:nowrap;
  transition:color .14s}
.nb-item::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;
  background:transparent;transition:background .14s}
.nb-item:hover,.nb-dd.open>.nb-item{color:var(--text)}
.nb-item:hover::after,.nb-dd.open>.nb-item::after{background:color-mix(in srgb,var(--text) 42%,transparent)}
/* The current one wins in every state, hover included — a brand rail must not
   turn grey because the pointer happens to be resting on it. */
.nb-item.on,.nb-dd.here>.nb-item{color:var(--text);font-weight:600}
.nb-item.on::after,.nb-item.on:hover::after,
.nb-dd.here>.nb-item::after,.nb-dd.here>.nb-item:hover::after{background:var(--accent)}
/* The rail sits ON the header's hairline, so a focus ring drawn outside the tab
   is clipped by it — draw it inside instead. */
.nb-item:focus-visible{outline-offset:-6px}
.nb-chev{opacity:.5;margin:1px -4px 0 -2px;transition:transform .16s var(--ease)}
.nb-dd.open .nb-chev{transform:rotate(180deg)}
/* .nb-item sets display:inline-flex, which outranks the generic .member-only
   hide (equal specificity, declared earlier) — scope the gate so it wins. */
.nb-item.member-only{display:none}
body.member .nb-item.member-only{display:inline-flex}

/* ---------- a dropdown ---------- */
.nb-dd{position:relative;display:inline-flex;align-self:stretch}
.nb-menu{position:absolute;top:calc(100% + 8px);left:-4px;min-width:250px;z-index:90;display:none;
  background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:6px;
  box-shadow:var(--sh-lg)}
.nb-menu.wide{min-width:300px}
/* The 8px between the button and its menu is a gap on screen and must not be a
   gap to the pointer: cross it and mouseleave fires on the way to the thing you
   were reaching for. This bridges it — invisible, no hit target of its own
   beyond the width of the menu it belongs to. */
.nb-menu::before{content:"";position:absolute;left:0;right:0;top:-10px;height:10px}
.nb-menu.right{left:auto;right:-4px}
.nb-dd.open>.nb-menu{display:block;animation:nbpop .15s var(--ease)}
/* Hover opens a menu, and js/01-nav is what does it — on a pointer that can
   actually rest on something, with a grace period on the way out. This rule is
   the same behaviour for a browser with no working bundle at all, plus keyboard
   focus, so every link inside a menu stays reachable either way (CONVENTIONS
   §12). The bundle stamps .js on <html> at the moment it binds its handlers, so
   the CSS and the JS can never both be driving. */
html:not(.js) .nb-dd:hover>.nb-menu,html:not(.js) .nb-dd:focus-within>.nb-menu{display:block}
@keyframes nbpop{from{opacity:0;transform:translateY(-5px)}}
/* A ROW IN A NAV MENU, WHETHER IT IS A LINK OR A BUTTON. Every row here used
   to be an <a>, so this rule never had to say what a row is not: no border, no
   background, the menu's own font, aligned left. "Log a mod" became a <button>
   when the composer stopped having an address, and a bare <button> takes the
   UA's border, grey fill, centred system-font text and shrink-to-fit width —
   one row in the Create menu suddenly looking like a form control. The reset
   belongs on the row, not on a second class beside it: the two shapes are the
   same row and have to render identically. */
.nb-mi{display:flex;align-items:flex-start;gap:11px;padding:9px 10px;border-radius:10px;color:var(--t2);
  width:100%;border:0;background:none;font:inherit;text-align:left;cursor:pointer;
  transition:background .12s,color .12s}
.nb-mi:hover{background:var(--surface2)}
/* WHICH PAGE, not just which section. The tab's rail says you are somewhere
   under Discover; this says you are on Groups. A filled row said it too, but it
   said it in the same accent-soft the hover state used two pixels away, so the
   row you were ON and the row you were POINTING AT looked alike. A 2px brand
   rail down the left edge is not a fill, cannot be confused with hover, and
   leaves the hover highlight free to do its own job — including on the current
   row, which still highlights when you point at it.
   .on is what the nav lighter toggles; aria-current is what a screen reader
   reads. Both are on the row, and this styles the pair together so neither can
   be the one that got forgotten. */
.nb-mi.on,.nb-mi[aria-current="page"]{position:relative;font-weight:540}
.nb-mi.on::before,.nb-mi[aria-current="page"]::before{content:"";position:absolute;
  left:0;top:9px;bottom:9px;width:2px;border-radius:1px;background:var(--accent)}
.nb-mi.on strong,.nb-mi[aria-current="page"] strong{color:var(--text)}
.nb-mi-i{width:19px;height:19px;flex:none;margin-top:2px;color:var(--t3)}
.nb-mi:hover .nb-mi-i{color:var(--t2)}
.nb-mi.on .nb-mi-i,.nb-mi[aria-current="page"] .nb-mi-i{color:var(--accent-fg)}
.nb-mi strong{display:block;font-size:14px;font-weight:550;color:var(--text)}
.nb-mi small{display:block;font-size:12px;line-height:1.35;color:var(--t3);margin-top:1px}
.nb-mi.member-only{display:none}
body.member .nb-mi.member-only{display:flex}
/* The spill's rows are single-line: it is a list of links, not a menu of
   destinations with something to say about each. */
#nb-more-menu .nb-mi small{display:none}
.nb-grouplabel{font:600 10px/1 var(--ui);letter-spacing:.1em;text-transform:uppercase;
  color:var(--t3);padding:12px 10px 5px}

/* Search results. They used to be a dropdown hung under the header field with
   its own border, shadow and absolute offset; the field is a dialog now, so the
   list is simply that dialog's second row and owns none of that chrome. */
.sres{overflow-y:auto;padding:6px;-webkit-overflow-scrolling:touch}
.sres-row{display:flex;align-items:center;gap:9px;width:100%;box-sizing:border-box;text-align:left;padding:7px 9px;border:0;border-radius:8px;
  background:none;cursor:pointer;color:var(--text);text-decoration:none;font:inherit}
.sres-row:hover,.sres-row:focus,.sres-row.cur{background:var(--surface2);color:var(--text);text-decoration:none;outline:none}
/* result thumbnail — a cover/avatar/logo (an <img>), or a tinted placeholder
   glyph (a <span>). object-fit keeps the <img> variant cropped, not squashed. */
.sres-th{flex:none;width:34px;height:34px;border-radius:7px;overflow:hidden;object-fit:cover;
  background:var(--surface2) center/cover no-repeat;
  display:flex;align-items:center;justify-content:center;font-size:16px;line-height:1}
/* close (✕) for the mobile full-screen search — desktop never shows it */
.srch-close{display:none;position:absolute;top:6px;right:6px;width:36px;height:36px;
  align-items:center;justify-content:center;border:0;border-radius:9px;background:none;
  color:var(--t2);cursor:pointer}
.srch-close:hover{background:var(--surface2);color:var(--text)}
.sres-th-round{border-radius:50%}
.sres-th-ph{color:var(--t3);background:var(--surface2)}
.sres-k{flex:none;font:600 9.5px/1 var(--ui);letter-spacing:.06em;text-transform:uppercase;color:var(--t3);
  min-width:52px}
.sres-l{font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sres-l em{color:var(--t3);font-style:normal;font-size:12px;margin-left:5px}
.sres-empty{padding:12px 11px;font-size:13px;color:var(--t3)}
/* ---------- buttons ----------
   ONE ladder, and every button on the site is cut from it.

   The GEOMETRY is tokens, not numbers, and that is the change that makes this
   file worth existing. Four ported page shells — #pg-vehicle, .mdp,
   #pg-vehicles and .su — each carried a full private copy of the shape
   (height, padding, radius, size, weight, gap, transition), so the site had
   five buttons that happened to look similar and five places to miss when one
   of them moved. They keep their own PALETTE, which is the only thing
   genuinely local to a ported design, and read the shape from here (§1).

   The TREATMENT, in one sentence: a button is a bordered label, not a slab.
   - Flat. No shadow at rest, on any variant. A row of six controls with a
     shadow under each reads as six objects stacked on the page; the same row
     with a hairline round each reads as one row.
   - The label sits at --t2 until you reach for it. HOVER DARKENS THE BORDER
     AND THE TEXT rather than washing a grey in behind — the button does not
     change size, colour or weight, it just comes forward.
   - The press is a millimetre DOWN, not a shrink. A button that scales tugs
     at its neighbours; one that sinks reads as the thing you pushed.
   - 600 weight at 12.5px. Small and bold beats large and light at this
     height: the label has to survive being the shortest word on the screen.

   Four variants and no more. --primary is the site's ink fill (the one
   irreversible action in a form), --accent the orange one (the one thing this
   screen is FOR), --acc the same orange said quietly, --ghost no frame at all.
   Anything else is a fifth answer to "how important is this button". */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--btn-gap);
  height:var(--btn-h);padding:0 var(--btn-pad);border:1px solid var(--border2);
  border-radius:var(--btn-r);background:var(--surface);color:var(--t2);
  font-size:var(--btn-fs);font-weight:600;letter-spacing:-.004em;white-space:nowrap;box-shadow:none;cursor:pointer;
  transition:background .13s var(--ease),color .13s var(--ease),border-color .13s var(--ease),
    transform .06s var(--ease)}
.btn:hover{background:var(--surface);border-color:var(--t3);color:var(--text)}
.btn:active{transform:translateY(1px)}
/* Both shapes AMSR.icon() can return: an <svg class="ic">, and the <span
   class="ic"> placeholder it draws for a name the registry does not carry.
   Sizing only the svg leaves a missing glyph at whatever width it was born
   with, which is how a broken icon becomes a broken LAYOUT. Pass null as the
   size at the call site — that is what it is for — and the ladder decides. */
.btn svg,.btn > .ic{width:14px;height:14px;flex:none}
.btn[disabled],.btn:disabled,.btn[aria-disabled="true"]{opacity:.45;pointer-events:none}

/* The ink fill. `opacity:.88` used to be the hover, which fades the LABEL as
   well as the fill and reads as the button switching off at the moment it is
   reached for. Mixing toward the page is a real colour and works in both
   themes without being written twice: it lightens black ink and darkens white. */
.btn-primary{background:var(--text);border-color:var(--text);color:var(--canvas)}
.btn-primary:hover{background:color-mix(in srgb,var(--text) 85%,var(--surface));
  border-color:color-mix(in srgb,var(--text) 85%,var(--surface));color:var(--canvas)}

.btn-accent{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.btn-accent:hover{background:color-mix(in srgb,var(--accent) 86%,#000);
  border-color:color-mix(in srgb,var(--accent) 86%,#000);color:var(--accent-ink)}

/* The accent, said quietly: the action a screen is for when it is not the only
   thing on the screen. Orange on the frame and in the label, and the wash only
   arrives on hover — a filled orange button that is one of four is four
   buttons shouting. */
.btn-acc{color:var(--accent-fg);border-color:var(--accent-line);background:var(--surface)}
.btn-acc:hover{color:var(--accent-fg);border-color:var(--accent);background:var(--accent-soft)}

.btn-ghost{border-color:transparent;background:transparent}
.btn-ghost:hover{border-color:transparent;background:var(--surface2);color:var(--text)}

/* A held-down control is GREEN, not orange, and that is deliberate: orange is
   what this screen is for, green is what is true. Saved, Following, Filtered —
   the button is reporting a state, not offering an action, and it must not read
   as the loudest thing in the row while it does. */
.btn[aria-pressed="true"]{background:var(--green-soft);border-color:var(--green-line);color:var(--green)}
.btn[aria-pressed="true"]:hover{border-color:var(--green);color:var(--green)}

.btn-sm{height:var(--btn-h-sm);padding:0 9px;font-size:var(--btn-fs-sm);gap:5px}
.btn-sm svg,.btn-sm > .ic{width:13px;height:13px}
.btn-lg{height:var(--btn-h-lg);padding:0 20px;font-size:var(--btn-fs-lg);border-radius:8px;gap:8px}
.btn-lg svg,.btn-lg > .ic{width:16px;height:16px}
.btn-block{width:100%}

/* The rung the ladder was missing: a button that is ONLY a glyph. Every one of
   them was a labelled button with the label left out, so it kept the 12px of
   side padding meant to sit either side of a word and drew a 40x32 pill around
   a 14px dot — the ··· on the profile header being the one everybody sees.
   Square, and the glyph a size up, because at 14px alone in a 32px frame it
   reads as a speck rather than a control. */
.btn-icon{width:var(--btn-h);padding:0;flex:none}
.btn-icon svg,.btn-icon > .ic{width:16px;height:16px}
.btn-sm.btn-icon{width:var(--btn-h-sm)}
.btn-sm.btn-icon svg,.btn-sm.btn-icon > .ic{width:15px;height:15px}
.btn-lg.btn-icon{width:var(--btn-h-lg)}

/* A count riding inside a button, behind a hairline. It is the dimmest thing on
   the control at rest and comes up with the label, because it is part of the
   same word — "Comments 12", not a badge stuck to a button. */
.btn .ct{color:var(--t3);border-left:1px solid var(--border);margin-left:2px;padding-left:9px;font-variant-numeric:tabular-nums}
.btn:hover .ct{color:var(--t2)}
.btn-primary .ct,.btn-accent .ct{color:rgba(255,255,255,.55);border-color:rgba(255,255,255,.2)}
body.dark .btn-primary .ct{color:rgba(0,0,0,.45);border-color:rgba(0,0,0,.2)}
/* THE FAMILY MUST NOT CROP ARTWORK DRAWN TO THE EDGE OF ITS OWN GRID.
   An <svg> clips to its viewport by UA default, and ams_icon() supplies the
   wrapper — viewBox "0 0 24 24" — so that clip belongs to the FAMILY, not to
   the glyph (migration 313: the wrapper is applied at render time from the
   family tokens, and the artwork is only ever the inner markup).

   Every glyph the registry held was drawn INSIDE the box with a margin, so in
   82 names across 306 surfaces nothing had ever met the boundary. The five
   brand marks (355) are the first that FILL the grid they were drawn on, edge
   to edge — that is simple-icons' convention and it is legitimate artwork —
   and at the footer's 19px a point at x=24 lands exactly on the clip line, so
   the antialiased edge was shaved and a circle came back with a flat right
   side. Instagram, Reddit, GitHub and YouTube each had one; X was spared only
   because its ink stops 0.26 units short of the edge, which is what made this
   look like four broken glyphs rather than one broken wrapper.

   Measured over the whole registry, NO glyph has ink outside 0..24, so this
   spills nothing today. What it changes is the failure mode for the next one
   that does: a visible overhang instead of a silent crop. That is the trade
   this codebase keeps making on purpose — a missing icon renders a visible
   placeholder for the same reason. */
.ic{overflow:visible}

/* HOW BIG A CATEGORY GLYPH IS — the one answer, for every surface that draws one.
   A cat-* mark appears on a My mods card, that page's filter panel, a garage
   row, the build sheet, the /parts rail, a parts card, a listing tag, the sell
   form and the mod composer's dropdown. Every one of them used to decide for
   itself, mostly by accident: 13px from a rule about a card's footer, 16px from
   a rule about a DIFFERENT panel icon, 17px, 12px, and a literal at the rest.
   So the size of a category glyph had no answer and no place to change it.
   ams_icon()/AMSR.icon() stamp AMS_CAT_IC on the svg and pass no size, and this
   sizes it.

   TWO CLASSES ON PURPOSE. The rules that were catching these glyphs by accident
   are one class plus an element (`.mm-opt-i svg`, `.vpro-sysl__th svg`), which
   this outranks — so the mark wins wherever it lands without !important and
   without depending on which partial loaded first. A rule that would still beat
   it is a rule sizing a category glyph on purpose, and there is exactly one
   left to delete rather than argue with. */
.ic.cat-ic{width:22px;height:22px}
/* ---------- the search palette ----------
   ONE search. There used to be two: a wide field wired into the header on a
   desktop, and a full-screen takeover on a phone that reused the same input but
   was styled by an entirely separate block under a media query. They drifted —
   the phone sheet grew big touch rows, a thumbnail size and an empty state the
   desktop dropdown never got.

   The field is a dialog now at every width: centred over the page on a desktop,
   full-screen on a phone, opened by the one trigger in the bar (or ⌘K). Same
   node, same ids, same typeahead in js/07-live-data — the only thing the media
   query changes is where it sits and how big the rows are.

   .search is closed by default and opened by body.searching, which is also
   what locks the page behind it. The header keeps a .pal class of its own
   purely so the JS has one place to ask whether the palette is up.

   That state class used to be .msearch, for "mobile search" — a name that had
   stopped being true and, worse, was already taken: .msearch is also the
   marketplace's search label on /parts, and its "position:absolute on any svg
   inside" was landing on this sheet's magnifier from three stylesheets away.
   The phone rules happened to override it and the centred palette did not, so
   the glyph floated into the middle of the results. One state, one name. */
.search{display:none}
body.searching{overflow:hidden}
.pal-scrim{display:none;position:fixed;inset:0;z-index:2147483000;
  background:rgba(6,6,10,.5);backdrop-filter:blur(3px);animation:fadein .16s}
body.searching .pal-scrim{display:block}
body.searching .search{
  display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  grid-template-rows:auto minmax(0,1fr) auto;
  position:fixed;top:11vh;left:50%;transform:translateX(-50%);
  width:min(600px,94vw);max-height:min(70vh,620px);
  z-index:2147483002;overflow:hidden;
  background:var(--surface);border:1px solid var(--border2);border-radius:16px;
  box-shadow:var(--sh-lg);animation:nbpop .16s var(--ease)}
body.searching .search .mag{grid-column:1;grid-row:1;align-self:center;margin-left:16px;color:var(--t3)}
body.searching .search .input{grid-column:2;grid-row:1;height:52px;border:0;background:none;padding:0 12px;
  font-size:15.5px;box-shadow:none}
body.searching .search .input:focus{outline:none;box-shadow:none}
body.searching .search>kbd{grid-column:3;grid-row:1;align-self:center;margin-right:14px;height:20px;padding:0 6px;
  border:1px solid var(--border2);border-radius:5px;background:var(--surface2);
  font:500 10.5px/19px var(--mono);color:var(--t3)}
body.searching .search .sres{grid-column:1 / -1;grid-row:2;border-top:1px solid var(--border)}
body.searching .search .sfoot{grid-column:1 / -1;grid-row:3;display:flex;gap:18px;padding:9px 15px;
  border-top:1px solid var(--border);font-size:11.5px;color:var(--t3)}
body.searching .search .sfoot kbd{display:inline-block;min-width:17px;margin-right:3px;padding:1px 4px;
  border:1px solid var(--border2);border-radius:4px;background:var(--surface2);
  font:500 10px/14px var(--mono);text-align:center}
/* the ✕ is the phone's way out; a desktop has the scrim and ESC */
.srch-close{display:none;grid-column:3;grid-row:1;align-self:center;margin-right:10px;
  width:40px;height:40px;align-items:center;justify-content:center;border:0;border-radius:11px;
  background:var(--surface2);color:var(--t2);cursor:pointer}
.srch-close:hover{background:var(--surface3);color:var(--text)}
@media(max-width:760px){
  body.searching .search{
    top:0;left:0;transform:none;width:100vw;max-height:none;
    height:calc(100vh - var(--floor,0px));height:calc(100dvh - var(--floor,0px));
    border:0;border-radius:0;box-shadow:none;animation:none;
    grid-template-rows:auto minmax(0,1fr);background:var(--canvas);
    padding-top:env(safe-area-inset-top,0px)}
  body.searching .search .input{height:56px;font-size:16px}
  body.searching .search>kbd,body.searching .search .sfoot{display:none}
  body.searching .srch-close{display:flex}
  /* bigger rows, thumbnails and text for touch */
  body.searching .search .sres-row{padding:11px 10px;gap:13px;border-radius:12px}
  body.searching .search .sres-th{width:50px;height:50px;border-radius:11px;font-size:22px}
  body.searching .search .sres-k{min-width:0;font-size:10px}
  body.searching .search .sres-l{font-size:15.5px;white-space:normal}
  body.searching .search .sres-l em{font-size:13px}
  body.searching .search .sres-empty{padding:20px 6px;font-size:15px}
}

.navauth{display:flex;align-items:center;gap:6px;flex:none;margin-left:10px}
.wsw{display:flex;align-items:center;gap:7px;height:32px;padding:0 9px;white-space:nowrap;flex:none;
  border:1px solid var(--border);
  border-radius:9px;background:var(--surface2);font-size:13px;font-weight:500}
.wsw .sq{width:16px;height:16px;border-radius:5px;background:var(--violet);flex:none}
.wsw svg{color:var(--t3)}
/* The burger only exists once the bar has handed its links to the drawer. */
.burger{display:none;width:36px;height:36px;border-radius:10px;align-items:center;justify-content:center;
  color:var(--t2);margin-left:-4px;margin-right:6px}
.burger:hover{background:var(--surface2);color:var(--text)}

.member-only{display:none}
body.member .member-only{display:var(--d,inline-flex)}
body.member .visitor-only{display:none!important}
/* Two of them set their own display, from a LATER stylesheet, and the generic
   gate above is the same specificity — so it lost the tie and a signed-out
   visitor got the messages icon, the notification bell and an empty "?" avatar
   bubble sitting next to the Sign in button. Same trap as .sn-link.member-only
   and .sn-group.member-only below; same fix, which is to out-specify rather
   than to hope about order. */
.nb-dd.member-only,.usermenu-wrap.member-only{display:none}
body.member .nb-dd.member-only,body.member .usermenu-wrap.member-only{display:inline-flex}

/* ---------- the drawer ----------
   The bar's links, as a list, for every width the bar cannot hold them at. It
   renders from the SAME $NAV table the bar does (views/app/chrome.php), which
   is the whole reason it can be trusted to be complete: on a phone it is the
   navigation, and a destination missing from it is a destination with no door.
   It slides from the left because that is where the burger is. */
.drawer{position:fixed;inset:0;z-index:100;display:none}
.drawer.open{display:block}
.drawer .scrim{position:absolute;inset:0;background:rgba(6,6,10,.5);backdrop-filter:blur(2px);animation:fadein .2s}
.drawer .sheet{position:absolute;top:0;left:0;bottom:0;width:min(310px,86vw);
  background:var(--sb-bg);color:var(--sb-text);
  border-right:1px solid var(--sb-line);padding:14px;overflow-y:auto;display:flex;flex-direction:column;
  animation:slidein .26s var(--ease)}
@keyframes fadein{from{opacity:0}to{opacity:1}}
@keyframes slidein{from{transform:translateX(-100%)}to{transform:none}}
.drawer .sheet .logo,.drawer .sheet .wm i{color:var(--sb-strong)}
.drawer .sheet .sidenav{display:flex;flex-direction:column;gap:14px}
.drawer .sheet .sn-close{background:transparent;border:0;color:var(--sb-dim);width:38px;height:38px;border-radius:10px;
  cursor:pointer;display:flex;align-items:center;justify-content:center}
.drawer .sheet .sn-close:hover{background:var(--sb-hover);color:var(--sb-strong)}

.sidenav{display:flex;flex-direction:column;gap:14px;flex:1 1 auto}
.sn-group{display:flex;flex-direction:column;gap:2px}
.sn-label{margin:0 0 4px;padding:0 10px;font:600 10.5px/1 var(--ui);letter-spacing:.11em;
  text-transform:uppercase;color:var(--sb-dim)}
.sn-link{position:relative;display:flex;align-items:center;gap:12px;height:44px;padding:0 10px;
  border-radius:10px;font-size:15px;font-weight:500;color:var(--sb-text);
  transition:background .15s,color .15s}
.sn-link .sn-i{width:22px;height:22px;flex:none;color:var(--sb-dim);transition:color .15s}
.sn-link:hover{background:var(--sb-hover);color:var(--sb-strong)}
.sn-link:hover .sn-i{color:var(--sb-text)}
.sn-link.on{background:var(--sb-active-bg);color:var(--sb-active);font-weight:600}
.sn-link.on .sn-i{color:var(--sb-active)}
/* .sn-link sets display:flex, which would outrank the generic .member-only
   hide (equal specificity, declared earlier) — scope the gate to win. */
.sn-link.member-only{display:none}
body.member .sn-link.member-only{display:flex}
/* Same trap one level up: .sn-group sets display:flex, so a group that is
   member-only as a WHOLE needs the same scoped gate — else a signed-out
   visitor gets the "You" heading standing over an empty box. */
.sn-group.member-only{display:none}
body.member .sn-group.member-only{display:flex}
.sn-foot{margin-top:14px;padding-top:12px;border-top:1px solid var(--sb-line)}
.sn-foot.visitor-only{display:none}
body:not(.member) .sn-foot.visitor-only{display:block}
.sn-theme{width:100%;text-align:left}

/* ---------- the drawer, on a phone: A SCREEN, NOT A SLIDE-OUT ----------
   At the desktop-tablet fold the drawer IS the navigation — the bar has handed
   it every link and the burger or the thumb zone's Menu is the only way to
   them. A 310px panel over a dimmed page says "a menu is open in front of what
   you were reading"; going somewhere is the whole reason it is open, so it
   reads as the destination instead, the way the account menu and every page on
   this site do at this width.

   It is the SAME 1040px step the rest of the chrome folds at (the navbar goes
   and the burger arrives in css/06, the thumb zone arrives in css/21) — the nav
   does not get a breakpoint of its own, so there is no width at which the
   drawer is the whole navigation and still a 310px sliver.

   FULL SCREEN HERE MEANS DOWN TO THE FLOOR, not to the bottom of the window
   (docs/CONVENTIONS.md §6). --floor is what the bottom edge is worth
   altogether — the thumb zone, the operator's admin bar, the home indicator —
   and stopping at it is what every page on the site already does. It is also
   what keeps Menu pressable while the menu is open: the tab that opened this
   is the tab that closes it, and a drawer painted over its own trigger leaves
   the × as the only way out. The whole element stops there, not just the sheet,
   or the transparent box over the tab bar would swallow the press. */
@media(max-width:1040px){
  /* AND IT IS --floor HERE, DELIBERATELY, not --floor-modal. Everything else
     that dims the page ends at the admin bar and covers the tab bar, because
     a scrimmed tab bar is a control the reader cannot press anyway. This one
     drops its scrim entirely at this width (below) and leaves the thumb zone
     LIVE — Menu is both the way in and the way out — so the tab bar here is
     not dimmed navigation, it is the navigation, and the drawer stops above
     it for the reason stated in the block above. */
  .drawer{bottom:var(--floor,0px)}
  /* Nothing is behind it any more, so there is nothing to dim — and the scrim
     is the one part that would still be over the thumb zone. */
  .drawer .scrim{display:none}
  .drawer .sheet{inset:0;width:auto;border-right:0;overscroll-behavior:contain;
    padding:calc(14px + env(safe-area-inset-top)) max(16px,env(safe-area-inset-right))
            20px max(16px,env(safe-area-inset-left));
    animation:drawerup .2s var(--ease)}
  /* It arrives rather than sliding in from the left: there is no left edge for
     it to have come from once it is the whole screen. */
  @keyframes drawerup{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
  /* A tablet is 1040px wide and a list of 44px rows stretched across it is a
     column of very long targets. The rows keep phone width and centre, which is
     what .tb-in already does for the thumb zone at the same fold. Direct
     children, because the member's Sign out is appended to the sheet itself. */
  .drawer .sheet > *{width:100%;max-width:520px;margin-left:auto;margin-right:auto}
}

/* ---------- page shell ---------- */
.page{display:none;padding:var(--pad-top) 0 88px}
.page.on{display:block;animation:in .3s var(--ease)}
/* A page whose first block is a full-bleed cover opens flush under the nav —
   the picture IS the top of the page. That is the ONLY reason to lose the top
   pad, it is declared here by class, and it never travels as an inline style
   (CONVENTIONS §11). Everything after the cover resumes at var(--pad-top). */
.page.bleeds{padding-top:0}
/* home closes on a full-width band, so it gives up the bottom pad as well */
#pg-home{padding-bottom:0}
/* Messages is a full-height, self-contained surface (a shadow-DOM host), so it
   drops the page padding and fills the content column below the sticky top bar. */
#pg-messages{padding:0}
#pg-messages.on{animation:none}
#msg-host{display:block;height:calc(100dvh - var(--navh) - var(--floor,0px));overflow:hidden}
/* --floor already carries the tab bar AND the home-indicator pad at this
   width; the 64px + inset + --abh this used to say counted the inset twice for
   an operator and guessed the bar's height for everyone else. */
@media(max-width:760px){ #msg-host{height:calc(100dvh - var(--navh) - var(--floor,0px))} }
/* =========================================================
   Friends page — self-contained visual system, all classes
   prefixed .fr-. The palette maps onto the app theme tokens
   so light/dark follow body.dark automatically; a few extra
   surfaces (buttons, danger, ok, dark chip) are defined here.
   ========================================================= */
.fr{
  --fr-orange:var(--accent); --fr-orange-hover:var(--accent); --fr-orange-press:var(--accent-fg);
  --fr-panel:var(--surface); --fr-fill:var(--surface2);
  --fr-line:var(--border); --fr-line-strong:var(--border2);
  --fr-ink:var(--text); --fr-ink-2:var(--t2); --fr-ink-3:var(--t3);
  --fr-dark:#2A2A2E; --fr-on-dark:#FFFFFF; --fr-ok:var(--green); --fr-ok-bg:var(--green-soft);
  --fr-danger:#C62828; --fr-danger-bg:#FDEDED;
  --fr-photo:var(--surface3);
  --fr-btn:var(--surface2); --fr-btn-hover:var(--surface3); --fr-btn-press:var(--border2);
  --fr-h:36px; --fr-h-sm:30px; --fr-r:8px; --fr-r-sm:7px;
  --fr-shadow:var(--sh);
  color:var(--fr-ink);font-size:15px;line-height:1.5;padding-bottom:40px;
}
body.dark .fr{
  --fr-dark:#F4F4F5; --fr-on-dark:#18181B;
  --fr-danger:#F27171; --fr-danger-bg:#2E1618;
}
.fr *{box-sizing:border-box}
/* No width/height here any more: these are registry glyphs now and every call
   site names its own size, which a class rule would silently overrule. */
.fr-ic{flex:none;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
/* .fr-sr hid the private <symbol> sprite this page used to define. The glyphs
   are registry names now, so there is nothing left to hide — kept as the
   visually-hidden helper it always was in case the class is still on markup. */
.fr-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0)}

/* ---- buttons: one geometry, four levels of emphasis ---- */
.fr-btn{display:inline-flex;align-items:center;justify-content:center;height:var(--fr-h);padding:0 14px;
  border:none;border-radius:var(--fr-r);font:500 14px/1 var(--ui);letter-spacing:-.005em;
  color:var(--fr-ink);background:var(--fr-btn);white-space:nowrap;position:relative;cursor:pointer;isolation:isolate;
  transition:background .13s ease,color .13s ease,box-shadow .13s ease,transform .07s ease}
.fr-btn:hover{background:var(--fr-btn-hover)}
.fr-btn:active{background:var(--fr-btn-press);transform:translateY(1px)}
.fr-btn:focus-visible{outline:none;box-shadow:0 0 0 2px var(--fr-panel),0 0 0 4px var(--fr-orange)}
.fr-lbl{display:inline-flex;align-items:center;gap:6px;transition:opacity .12s}
.fr-btn svg{width:16px;height:16px;flex:none}
.fr-btn--sm{height:var(--fr-h-sm);padding:0 11px;font-size:13px;border-radius:var(--fr-r-sm)}
.fr-btn--sm .fr-lbl{gap:5px}
.fr-btn--sm svg{width:15px;height:15px}
.fr-btn--primary{background:var(--fr-orange);color:#fff}
.fr-btn--primary:hover{background:var(--fr-orange-hover);opacity:.92}
.fr-btn--primary:active{background:var(--fr-orange-press);opacity:1}
.fr-btn--quiet{background:transparent;color:var(--fr-ink);box-shadow:inset 0 0 0 1px var(--fr-line)}
.fr-btn--quiet:hover{background:var(--fr-btn);box-shadow:inset 0 0 0 1px var(--fr-line-strong)}
.fr-btn--quiet:active{background:var(--fr-btn-press)}
.fr-btn--quiet:focus-visible{box-shadow:0 0 0 2px var(--fr-panel),0 0 0 4px var(--fr-orange)}
.fr-btn--ghost{background:transparent;color:var(--fr-ink-2)}
.fr-btn--ghost:hover{background:var(--fr-btn);color:var(--fr-ink)}
.fr-btn--danger:hover{background:var(--fr-danger-bg);color:var(--fr-danger)}
.fr-btn--danger:active{background:var(--fr-danger-bg);color:var(--fr-danger)}
.fr-btn--icon{width:var(--fr-h);padding:0}
.fr-btn--sm.fr-btn--icon{width:var(--fr-h-sm)}
.fr-btn--block{flex:1 1 0;min-width:0}
.fr-btn--block .fr-lbl{min-width:0}
.fr-btn--block .fr-lbl span{overflow:hidden;text-overflow:ellipsis}
.fr-spin{position:absolute;inset:0;display:grid;place-items:center;opacity:0;pointer-events:none;transition:opacity .12s}
.fr-spin i{width:14px;height:14px;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;animation:fr-rot .62s linear infinite}
.fr-btn[data-busy="1"]{pointer-events:none}
.fr-btn[data-busy="1"] .fr-lbl{opacity:0}
.fr-btn[data-busy="1"] .fr-spin{opacity:1}
@keyframes fr-rot{to{transform:rotate(360deg)}}

/* ---- header ---- */
.fr-head{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;flex-wrap:wrap;margin:0 0 6px}
.fr-head h1{font-size:30px;font-weight:700;letter-spacing:-.03em;margin:0;line-height:1.15}
.fr-head p{color:var(--fr-ink-2);font-size:15px;margin:8px 0 0}
/* the controls stay one unit and drop under the title together rather than
   splitting "Find people" onto a line of its own — min-width is what makes the
   header wrap instead of squashing them */
.fr-actions{display:flex;align-items:center;gap:10px;flex-wrap:nowrap;justify-content:flex-end;flex:1 1 380px;min-width:min(380px,100%)}
.fr-field{display:flex;align-items:center;gap:9px;flex:1 1 210px;min-width:168px;max-width:320px;height:var(--fr-h);background:var(--fr-btn);border-radius:var(--fr-r);padding:0 13px;box-shadow:inset 0 0 0 1px transparent;transition:background .13s,box-shadow .13s}
.fr-field:focus-within{background:var(--fr-panel);box-shadow:inset 0 0 0 1px var(--fr-orange),0 0 0 3px var(--accent-soft)}
.fr-field svg{color:var(--fr-ink-3);width:17px;height:17px}
.fr-field input{flex:1;min-width:0;border:none;background:none;font-size:14px;outline:none;color:inherit}
.fr-field input::placeholder{color:var(--fr-ink-3)}
.fr-field .fr-btn{display:none;width:22px;height:22px;border-radius:6px;padding:0}
.fr-field[data-full="1"] .fr-btn{display:inline-flex}
.fr-seg{display:flex;gap:2px;height:var(--fr-h);background:var(--fr-btn);border-radius:var(--fr-r);padding:3px}
.fr-seg button{display:grid;place-items:center;width:32px;border:none;border-radius:6px;background:transparent;color:var(--fr-ink-3);cursor:pointer;transition:background .13s,color .13s,box-shadow .13s}
.fr-seg button:hover{color:var(--fr-ink)}
.fr-seg button:focus-visible{outline:none;box-shadow:0 0 0 2px var(--fr-orange)}
.fr-seg button[aria-pressed="true"]{background:var(--fr-panel);color:var(--fr-ink);box-shadow:var(--sh-sm)}

/* ---- sections & grid ----
   Each section head is a disclosure button: the whole title strip toggles the
   body, so "Sent requests" can sit collapsed out of the way without hiding its
   count. The filter/sort popover hangs off the right of the friends head. */
.fr-sec{margin-top:34px}
.fr-sec__head{display:flex;align-items:center;gap:9px;margin-bottom:14px;flex-wrap:wrap}
.fr-sec__head h2{font-size:18px;font-weight:600;letter-spacing:-.015em;margin:0}
.fr-sectoggle{display:flex;align-items:center;gap:9px;margin-left:-7px;padding:4px 8px 4px 7px;border:none;background:none;border-radius:8px;cursor:pointer;color:inherit;font:inherit}
.fr-sectoggle:hover{background:var(--fr-btn)}
.fr-sectoggle:focus-visible{outline:2px solid var(--fr-orange);outline-offset:1px}
/* carries .fr-ic too, so it strokes in currentColor — a bare <svg> would fill
   black and vanish against the dark theme */
.fr-chev{width:17px;height:17px;color:var(--fr-ink-2);transition:transform .18s ease;flex:none}
.fr-sectoggle[aria-expanded="false"] .fr-chev{transform:rotate(-90deg)}
.fr-secright{margin-left:auto;display:flex;align-items:center;gap:8px;position:relative}
.fr-secbody[hidden]{display:none}
.fr-count{font-size:12.5px;font-weight:500;color:var(--fr-ink-2);background:var(--fr-fill);border-radius:999px;padding:2px 9px;min-width:24px;text-align:center}
.fr-livechip{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:500;color:var(--fr-ok);background:var(--fr-ok-bg);border-radius:999px;padding:2px 10px}
.fr-livechip::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--fr-ok)}
.fr-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(196px,1fr));gap:16px}

/* ---- filter + sort popover ---- */
.fr-pop{position:absolute;top:calc(100% + 6px);right:0;z-index:50;width:226px;background:var(--fr-panel);border:1px solid var(--fr-line);border-radius:10px;box-shadow:var(--fr-shadow);padding:6px}
.fr-popgrp{font-size:10.5px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--fr-ink-3);padding:9px 10px 5px}
.fr-popitem{display:flex;align-items:center;gap:9px;width:100%;padding:7px 10px;border:none;background:none;border-radius:6px;font-size:13.5px;color:var(--fr-ink);cursor:pointer;text-align:left;font-family:inherit}
.fr-popitem:hover{background:var(--fr-btn)}
.fr-popitem svg{width:15px;height:15px;flex:none;color:var(--fr-orange);opacity:0}
.fr-popitem[aria-checked="true"]{font-weight:500}
.fr-popitem[aria-checked="true"] svg{opacity:1}
.fr-pop hr{border:none;border-top:1px solid var(--fr-line);margin:5px 0}
.fr-btn--on{box-shadow:inset 0 0 0 1px var(--fr-orange);color:var(--fr-orange);background:transparent}
.fr-btn--on:hover{background:var(--accent-soft)}
.fr-btn--on svg{color:var(--fr-orange)}

/* ---- card ----
   The whole card is the profile link (role="link"): the buttons inside it stop
   the click first, so the big target does the obvious thing and the small ones
   still win. Text is left-aligned with the avatar hung off the cover's bottom
   edge, which leaves the full card width for a name that needs two lines. */
.fr-card{display:flex;flex-direction:column;background:var(--fr-panel);border:1px solid var(--fr-line);border-radius:12px;position:relative;cursor:pointer;transition:border-color .16s,box-shadow .16s,transform .16s,opacity .18s}
.fr-card:hover{border-color:var(--fr-line-strong);box-shadow:var(--fr-shadow);transform:translateY(-2px)}
.fr-card.is-open{z-index:30}
.fr-card.is-exiting{opacity:0;transform:scale(.97)}
.fr-card:focus-visible,.fr-row:focus-visible{outline:2px solid var(--fr-orange);outline-offset:-2px;border-radius:12px}
.fr-card:focus-visible{outline-offset:1px}
.fr-photo{height:78px;border-radius:11px 11px 0 0;overflow:hidden;background:var(--fr-photo);position:relative;display:block}
.fr-photo img{display:block;width:100%;height:100%;object-fit:cover;transition:transform .5s cubic-bezier(.2,.6,.2,1)}
.fr-card:hover .fr-photo img{transform:scale(1.05)}
.fr-more{position:absolute;top:8px;right:8px;z-index:2;width:28px;height:28px;border:none;border-radius:50%;background:rgba(255,255,255,.94);color:#3F3F46;display:grid;place-items:center;cursor:pointer;backdrop-filter:blur(6px);opacity:0;transition:opacity .14s,transform .14s,background .14s}
.fr-card:hover .fr-more,.fr-more:focus-visible,.fr-card.is-open .fr-more{opacity:1}
.fr-more:hover{transform:scale(1.08);background:#fff}
.fr-more:focus-visible{outline:2px solid var(--fr-orange);outline-offset:2px}
.fr-body{flex:1;display:flex;flex-direction:column;padding:26px 12px 12px;min-width:0}
.fr-av{width:46px;height:46px;border-radius:50%;background:var(--fr-dark);color:var(--fr-on-dark);display:grid;place-items:center;font:600 15px/1 var(--dis);border:3px solid var(--fr-panel);position:relative;flex:none;overflow:hidden}
.fr-card > .fr-av{position:absolute;left:12px;top:54px;z-index:3;margin:0}
.fr-av img{width:100%;height:100%;object-fit:cover;border-radius:inherit}
/* presence: a green "active now" dot. is-online lifts the clip so the dot can
   sit on the avatar edge; the image keeps its own round crop via border-radius. */
.fr-av.is-online{overflow:visible}
.fr-pres{position:absolute;right:1px;bottom:1px;width:14px;height:14px;border-radius:50%;
  background:var(--fr-ok);border:2.5px solid var(--fr-panel);box-sizing:border-box}
.fr-row .fr-av.is-online{overflow:visible}
.fr-row .fr-pres{width:12px;height:12px;border-width:2px;right:-1px;bottom:-1px}
/* A display name gets two lines, and steps down a size as it gets longer, so
   "SuperchargedChevelleRestomod1972" still lands whole in a 196px card. */
.fr-card h3{font-size:14.5px;font-weight:600;letter-spacing:-.012em;margin:0;line-height:1.28;max-width:100%;min-width:0;
  overflow-wrap:anywhere;word-break:normal;hyphens:auto;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
/* the clamp lives on the h3 so the Verified pill stays inline after the name
   instead of being pushed onto a line of its own */
.fr-card h3 .fr-nm{display:inline}
.fr-card h3.is-long{font-size:13.2px;letter-spacing:-.016em;line-height:1.26}
.fr-card h3.is-vlong{font-size:12.3px;letter-spacing:-.02em;line-height:1.25}
.fr-card h3 .pill,.fr-rowmain h3 .pill{flex:none}
.fr-rowmain h3{display:flex;align-items:center;min-width:0}
.fr-rowmain h3 .fr-nm{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fr-handle{font-size:12.5px;color:var(--fr-ink-2);margin:1px 0 0;line-height:1.35;max-width:100%;white-space:nowrap;overflow:hidden;min-width:0}
.fr-sub{display:flex;align-items:center;gap:4px;font-size:12px;color:var(--fr-ink-3);margin:3px 0 0;line-height:1.4;min-width:0;min-height:18px}
.fr-txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.fr-dot{flex:none;opacity:.55}
.fr-sub--wait{font-size:10.5px;font-weight:600;letter-spacing:.09em;text-transform:uppercase}
.fr-acts{display:flex;gap:6px;width:100%;margin-top:auto;padding-top:12px}
/* the garage count doubles as the link to it — one fewer button on the card */
/* padding is cancelled by an equal negative margin: the hover pill gets room to
   breathe without the chip taking more space than the "·" separators around it */
.fr-garage{display:inline-flex;align-items:center;gap:5px;flex:none;padding:1px 3px;margin:0 -3px;border:none;background:none;font:500 12px/1.3 inherit;color:var(--fr-ink-2);cursor:pointer;border-radius:5px;transition:color .12s,background .12s}
.fr-garage:hover{color:var(--fr-orange);background:var(--fr-btn)}
.fr-garage svg{width:14px;height:14px;color:var(--fr-ink-3);transition:color .12s}
.fr-garage:hover svg{color:var(--fr-orange)}
.fr-garage:focus-visible{outline:2px solid var(--fr-orange);outline-offset:1px}
.fr-live{color:var(--fr-ok);font-weight:500;flex:none}

/* ---- list ---- */
.fr-list{background:var(--fr-panel);border:1px solid var(--fr-line);border-radius:12px}
.fr-row{display:grid;grid-template-columns:46px minmax(0,1fr) auto;gap:14px;align-items:center;padding:11px 14px;border-top:1px solid var(--fr-line);position:relative;cursor:pointer;transition:background .12s,opacity .18s}
.fr-row:first-child{border-top:none}
.fr-row:hover{background:var(--fr-fill)}
.fr-row.is-open{z-index:30}
.fr-row.is-exiting{opacity:0}
.fr-row .fr-av{width:46px;height:46px;margin:0;font-size:15px;border-width:0}
.fr-rowmain{min-width:0}
.fr-rowmain h3{font-size:15px;font-weight:600;letter-spacing:-.01em;margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fr-rowsub{display:flex;align-items:center;gap:5px;font-size:13px;color:var(--fr-ink-2);margin:2px 0 0;min-width:0}
.fr-rowsub b{font-weight:400;color:var(--fr-ink-3)}
.fr-rowsub .fr-garage{font-size:13px}
.fr-rowsub .fr-txt{font-size:13px}
.fr-rowacts{display:flex;align-items:center;gap:6px}

/* ---- overflow menu ---- */
.fr-menu{position:absolute;z-index:40;min-width:184px;background:var(--fr-panel);border:1px solid var(--fr-line);border-radius:10px;box-shadow:var(--fr-shadow);padding:5px;text-align:left}
.fr-card .fr-menu{top:42px;right:10px}
.fr-row .fr-menu{top:44px;right:14px}
.fr-menu .fr-btn{width:100%;justify-content:flex-start;height:34px;padding:0 10px;border-radius:6px;background:transparent;color:var(--fr-ink);font-size:13.5px}
.fr-menu .fr-btn:hover{background:var(--fr-btn)}
.fr-menu .fr-btn--danger{color:var(--fr-danger)}
.fr-menu hr{border:none;border-top:1px solid var(--fr-line);margin:5px 0}

/* ---- empty state ---- */
.fr-empty{border:1px solid var(--fr-line);border-radius:12px;padding:38px 24px;text-align:center;background:var(--fr-panel)}
.fr-empty__ic{width:40px;height:40px;border-radius:50%;background:var(--fr-fill);display:grid;place-items:center;margin:0 auto 12px;color:var(--fr-ink-3)}
.fr-empty__ic svg{width:19px;height:19px}
.fr-empty h3{font-size:15.5px;font-weight:600;margin:0}
.fr-empty p{font-size:14px;color:var(--fr-ink-2);margin:6px auto 0;max-width:340px}
.fr-empty .fr-btn{margin-top:16px}

/* ---- toast (clears whatever owns the bottom edge, via --floor) ---- */
.fr-toast{position:fixed;left:50%;bottom:calc(26px + var(--floor,0px));transform:translateX(-50%) translateY(8px);z-index:60;display:flex;align-items:center;gap:10px;background:var(--fr-dark);color:var(--fr-on-dark);border-radius:10px;padding:8px 8px 8px 16px;box-shadow:var(--fr-shadow);font-size:14px;opacity:0;pointer-events:none;transition:opacity .16s,transform .16s}
.fr-toast.is-up{opacity:1;transform:translateX(-50%) translateY(0);pointer-events:auto}
.fr-toast .fr-btn{height:28px;padding:0 10px;font-size:13px;background:transparent;color:var(--fr-orange)}
.fr-toast .fr-btn:hover{background:rgba(128,128,128,.24)}
.fr-toast .fr-btn:focus-visible{box-shadow:0 0 0 2px var(--fr-dark),0 0 0 4px var(--fr-orange)}

@media(max-width:900px){
  .fr-head h1{font-size:26px}
  .fr-actions{width:100%;flex-wrap:wrap;min-width:0}
  .fr-field{flex:1;width:auto;max-width:none}
  .fr-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
  .fr-photo{height:74px}
  /* two-up cards are too narrow for "3 mutual · 2 vehicles" on one line, and
     half a word ("3 mut…") is worse than a second line — stack the meta */
  .fr-sub{flex-direction:column;align-items:flex-start;gap:1px}
  .fr-sub .fr-dot{display:none}
  .fr-row{grid-template-columns:44px minmax(0,1fr);gap:12px;padding:12px}
  .fr-rowacts{grid-column:1/-1}
  .fr-rowacts .fr-btn{flex:1 1 0}
}
@media (prefers-reduced-motion:reduce){.fr *{transition:none!important}.fr-spin i{animation-duration:1.4s}}
/* nav pending-requests badge — the drawer's Friends row and the account
   menu's, filled by the same [data-friend-badge] writer */
.sn-badge,.um-badge{margin-left:auto;font:600 10px/1 var(--mono);background:var(--accent);color:var(--accent-ink);
  border-radius:99px;padding:2px 6px;min-width:16px;text-align:center}
@keyframes in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.page-head{margin:0 0 26px}
.page-head h1{font-size:28px}
.page-head p{color:var(--t2);margin-top:7px;font-size:14.5px}
.cols{display:grid;grid-template-columns:minmax(0,1fr) 310px;gap:36px;align-items:start}
.cols-l{display:grid;grid-template-columns:210px minmax(0,1fr);gap:36px;align-items:start}
.sticky{position:sticky;top:84px}

/* ---------- HERO ---------- */
.hero{position:relative;padding:60px 0 0;overflow:hidden}
.hero::before{content:"";position:absolute;inset:-30% -20% auto -20%;height:110%;pointer-events:none;
  background:radial-gradient(45% 45% at 30% 25%,var(--accent-soft),transparent 70%)}
.hero .wrap{position:relative;z-index:1}
.hero-grid{display:grid;grid-template-columns:minmax(0,1.02fr) minmax(0,1fr);gap:48px;align-items:center}
.hero h1{font-size:clamp(36px,4.6vw,54px);letter-spacing:-.042em;line-height:1.05}
.hero .lede{font-size:17.5px;color:var(--t2);max-width:48ch;margin-top:20px;line-height:1.6}
.eyebrow{display:inline-flex;align-items:center;gap:9px;height:30px;padding:0 12px;border-radius:999px;
  border:1px solid var(--border2);background:var(--surface);box-shadow:var(--sh-sm);font-size:13px;color:var(--t2)}
.eyebrow b{font-weight:500;color:var(--text)}

/* vehicle search */
.vsearch{margin-top:26px;border:1px solid var(--border2);border-radius:14px;background:var(--surface);
  box-shadow:var(--sh);padding:6px;display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.vsearch input{flex:1;min-width:170px;height:40px;border:0;background:none;padding:0 12px;font-size:14.5px}
.vsearch input:focus{outline:none}
.chips{display:flex;gap:6px;flex-wrap:wrap;margin-top:12px;align-items:center}
.chips .lbl2{font-size:12.5px;color:var(--t3);margin-right:2px}
.chip{height:28px;padding:0 11px;border-radius:999px;border:1px solid var(--border);background:var(--surface);
  font-size:12.5px;font-weight:450;color:var(--t2);display:inline-flex;align-items:center;transition:all .16s}
.chip:hover{border-color:var(--accent-line);background:var(--accent-soft);color:var(--accent-fg)}

/* hero mosaic */
.mosaic{display:grid;grid-template-columns:repeat(3,1fr);grid-auto-rows:96px;gap:9px}
.mosaic .photo{display:block;
  transition:transform .2s var(--ease),box-shadow .2s var(--ease)}
.mosaic .photo:hover{transform:translateY(-2px);box-shadow:var(--sh)}
.mosaic .cap{font-size:11.5px;line-height:1.35}
/* The tiles fade in — but a tile is CONTENT, so it is visible by default and
   the animation is what asks for the fade, never what grants the visibility.
   It used to be the other way round: opacity:0 with `animation:tilein forwards`
   to bring it back. 06-settings-and-mod.php ends with the usual blanket
   `@media(prefers-reduced-motion:reduce){*{animation:none!important}}`, which
   killed tilein and left every tile parked at opacity:0 — the hero was a blank
   column for anyone with Reduce Motion on, images loaded and links live
   underneath. Nothing else on the page needs an animation to be seen, which is
   why only the hero went. Gate the entrance on no-preference instead: motion
   off simply means the tiles are already there. */
@media (prefers-reduced-motion:no-preference){
  .mosaic .photo{opacity:0;animation:tilein .5s var(--ease) forwards}
  @keyframes tilein{to{opacity:1}}
}
.mosaic .t1{grid-column:1/3;grid-row:1/3}
.mosaic .t2{grid-column:3;grid-row:1}
.mosaic .t3{grid-column:3;grid-row:2}
.mosaic .t4{grid-column:1;grid-row:3/5}
.mosaic .t5{grid-column:2/4;grid-row:3}
.mosaic .t6{grid-column:2;grid-row:4}
.mosaic .t7{grid-column:3;grid-row:4}
.swap{transition:opacity .5s var(--ease),transform .5s var(--ease)}
.swap.out{opacity:0;transform:scale(1.03)}

/* live ticker */
.ticker{margin-top:44px;border-top:1px solid var(--border);border-bottom:1px solid var(--border);
  background:var(--surface);overflow:hidden}
.ticker .wrap{display:flex;align-items:center;gap:16px;height:52px}
.ticker .now{display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;color:var(--t2);
  flex:none;padding-right:16px;border-right:1px solid var(--border);height:100%;}
.ticker .feed{flex:1;min-width:0;position:relative;height:100%}
.ticker .ev{position:absolute;inset:0;display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--t2);
  opacity:0;transform:translateY(8px);transition:opacity .4s var(--ease),transform .4s var(--ease)}
.ticker .ev.on{opacity:1;transform:none}
.ticker .ev b{color:var(--text);font-weight:500}
.ticker .ev .t{margin-left:auto;font-size:12px;color:var(--t3);flex:none}

.band{padding:60px 0;border-bottom:1px solid var(--border)}
.band-t{font-size:24px;letter-spacing:-.032em}
.band-s{color:var(--t2);font-size:15px;margin-top:8px}
.stats{display:grid;grid-template-columns:repeat(4,1fr);border-bottom:1px solid var(--border)}
.stats div{padding:26px 0}
.stats b{display:block;font-family:var(--dis);font-size:28px;font-weight:600;letter-spacing:-.035em;font-variant-numeric:tabular-nums}
.stats span{font-size:13.5px;color:var(--t2)}

/* ---------- cards ---------- */
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.grid-4{grid-template-columns:repeat(4,1fr)}
.grid-2{grid-template-columns:repeat(2,1fr)}
.pcard{border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);
  box-shadow:var(--sh-sm);display:block;transition:transform .22s var(--ease),box-shadow .22s var(--ease),border-color .22s}
.pcard:hover{transform:translateY(-3px);box-shadow:var(--sh);border-color:var(--border2)}
.pcard .photo{border-radius:0;aspect-ratio:16/10}
.pcard .body{padding:14px 16px 16px}
.pcard h3{font-size:15.5px}
.pcard .desc{font-size:13.5px;color:var(--t2);line-height:1.5;margin-top:6px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pcard .meta{display:flex;align-items:center;gap:12px;margin-top:14px;font-size:12.5px;color:var(--t3)}
.pcard .meta .avstack{margin-right:auto}
/* events reuse .pcard / .grid / .bhero / .cols; only the date line is bespoke */
.evcard .photo{aspect-ratio:16/9}
.evdate{font:600 13.5px/1.3 var(--dis);letter-spacing:-.01em;color:var(--accent-fg);margin-top:2px}
.tags{display:flex;gap:6px;flex-wrap:wrap;margin-top:12px}

/* vehicle card */
.vcard{border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);
  box-shadow:var(--sh-sm);display:block;transition:transform .22s var(--ease),box-shadow .22s var(--ease)}
.vcard:hover{transform:translateY(-3px);box-shadow:var(--sh)}
.vcard .photo{border-radius:0;aspect-ratio:16/9}
.vcard .body{padding:13px 15px 15px}
.vcard h3{font-size:15px}
.vcard .sub{font-size:12.5px;color:var(--t3);margin-top:3px}
.vcard .m{display:flex;gap:12px;margin-top:11px;font-size:12.5px;color:var(--t2)}

/* mod card */
.mcard{border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);
  box-shadow:var(--sh-sm);display:flex;flex-direction:column;transition:transform .22s var(--ease),box-shadow .22s var(--ease)}
.mcard:hover{transform:translateY(-3px);box-shadow:var(--sh)}
.mcard .photo{border-radius:0;aspect-ratio:16/10}
.mcard .body{padding:14px 16px 16px;flex:1;display:flex;flex-direction:column}
.mcard h3{font-size:15px;line-height:1.35}
.mcard .spec{display:flex;gap:14px;margin-top:12px;font-size:12.5px;color:var(--t2)}
.mcard .spec b{display:block;font-family:var(--dis);font-size:14px;font-weight:600;color:var(--text)}
.mcard .spec span{font-size:11px;color:var(--t3)}
.mcard .foot{display:flex;align-items:center;gap:8px;margin-top:14px;padding-top:12px;border-top:1px solid var(--border);
  font-size:12.5px;color:var(--t3)}

/* ---------- vehicle page ---------- */
.vhero{position:relative;border-bottom:1px solid var(--border)}
.vhero .photo{border-radius:0;height:280px}
.vhero .over{position:absolute;left:0;right:0;bottom:0;padding:26px 0;
  background:linear-gradient(180deg,transparent,rgba(6,6,10,.82))}
.vhero .over .wrap{color:#fff}
.vhero h1{font-size:clamp(26px,3.6vw,38px);color:#fff}
.vhero .sub{color:rgba(255,255,255,.78);font-size:14.5px;margin-top:6px}
.vhero .pill{background:rgba(10,10,12,.5);border-color:rgba(255,255,255,.18);color:#fff;backdrop-filter:blur(6px)}
.vstats{display:grid;grid-template-columns:repeat(4,1fr);border-bottom:1px solid var(--border);background:var(--surface)}
.vstats div{padding:18px 0;text-align:center;border-right:1px solid var(--border)}
.vstats div:last-child{border-right:0}
.vstats b{display:block;font-family:var(--dis);font-size:20px;font-weight:600}
.vstats span{font-size:12.5px;color:var(--t2)}

/* tabs */
.tabs{display:flex;gap:2px;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.tabs::-webkit-scrollbar{display:none}
.tab{padding:12px 13px;font-size:14px;font-weight:450;color:var(--t2);border-bottom:2px solid transparent;white-space:nowrap}
.tab .n{font-size:11.5px;color:var(--t3);margin-left:7px;background:var(--surface2);border-radius:999px;padding:2px 6px}
.tab:hover{color:var(--text)}
.tab.on{color:var(--text);border-bottom-color:var(--accent);font-weight:500}
.pane{display:none} .pane.on{display:block;animation:in .28s var(--ease)}
.tabwrap{border-bottom:1px solid var(--border);background:var(--surface)}

/* ---------- project page ---------- */
.phead{border-bottom:1px solid var(--border);padding:28px 0 0;background:var(--surface)}
.phead .crumb{font-size:13px;color:var(--t2);margin-bottom:12px}
.phead h1{font-size:30px}
.phead .sub{color:var(--t2);font-size:15px;margin-top:10px;max-width:62ch;line-height:1.55}
.phead .facts{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px}
.entry{border:1px solid var(--border);border-radius:var(--r-lg);margin-bottom:18px;overflow:hidden;background:var(--surface);box-shadow:var(--sh-sm)}
.entry-h{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:14px 18px;border-bottom:1px solid var(--border)}
.entry-h .id{font:500 12px var(--mono);color:var(--t2)}
.entry-b{padding:20px}
.entry-b h3{font-size:19px;margin-bottom:11px}
.entry-b p{font-size:14.5px;color:var(--t2);margin-bottom:13px;max-width:70ch;line-height:1.65}
.entry-b p:last-child{margin-bottom:0}
.entry-b strong{color:var(--text);font-weight:500}
.note{border:1px solid var(--accent-line);background:var(--accent-soft);border-radius:12px;padding:14px 16px;margin-bottom:16px}
.note b{display:block;font-size:12.5px;font-weight:600;color:var(--accent-fg);margin-bottom:4px}
.note p{font-size:14px;color:var(--accent-fg);margin:0;opacity:.92;max-width:none}
.shots{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:16px}
.shots .photo{aspect-ratio:16/10}
.files{display:flex;gap:8px;flex-wrap:wrap}
.file{display:inline-flex;align-items:center;gap:8px;height:34px;padding:0 12px;border:1px solid var(--border);
  border-radius:999px;font-size:13px;background:var(--surface)}
.file:hover{background:var(--surface2)}
.file .ext{font:500 10px var(--mono);color:var(--t2)}
.file .sz{color:var(--t3);font-size:12px}
.entry-f{display:flex;gap:6px;padding:10px 14px;border-top:1px solid var(--border);background:var(--surface2)}
.entry-f a{font-size:13px;color:var(--t2);padding:5px 10px;border-radius:8px}
.entry-f a:hover{color:var(--text);background:var(--surface3)}

.list{border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);box-shadow:var(--sh-sm)}
.list-row{display:flex;align-items:center;gap:14px;padding:14px 16px;border-bottom:1px solid var(--border)}
.list-row:last-child{border-bottom:0}
.list-row:hover{background:var(--surface2)}
.fname{font:500 13.5px var(--mono);display:flex;align-items:center;gap:9px;min-width:0}
.fname em{font-style:normal;font-family:var(--ui);font-size:13px;color:var(--t2);font-weight:400}
.fmt{font:500 10px var(--mono);border:1px solid var(--border2);border-radius:5px;padding:3px 6px;color:var(--t2);flex:none}
.rt{margin-left:auto;display:flex;align-items:center;gap:16px;flex:none;font-size:13px;color:var(--t2)}
.repo{border:1px solid var(--border);border-radius:var(--r-lg);padding:20px;margin-bottom:14px;background:var(--surface);box-shadow:var(--sh-sm)}
.repo h3{font:500 16px var(--mono);letter-spacing:-.02em}
.repo h3 span{color:var(--t3)}
.repo p{font-size:14px;color:var(--t2);margin-top:8px;max-width:70ch;line-height:1.6}
.repo .m{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px}
.lang i{width:8px;height:8px;border-radius:50%;display:block;background:currentColor}
pre{margin:16px 0 0;padding:16px 18px;background:#0C0C0F;border:1px solid var(--border);border-radius:12px;overflow-x:auto;
  font:400 12.5px/1.75 var(--mono);color:#D4D4D8}
pre .c{color:#71717A}pre .k{color:#93C5FD}pre .s{color:#86EFAC}pre .f{color:#FDBA74}

.thread{display:flex;gap:14px;padding:17px 16px;border-bottom:1px solid var(--border)}
.thread:last-child{border-bottom:0}
.thread:hover{background:var(--surface2)}
.thread h3{font-size:15.5px;font-weight:500;line-height:1.4}
.thread:hover h3{color:var(--accent-fg)}
.thread .by{font-size:13px;color:var(--t3);margin-top:5px}
.thread .by b{color:var(--t2);font-weight:500}
.thread .ex{font-size:13.5px;color:var(--t2);margin-top:9px;max-width:74ch;line-height:1.55}
.thread .rt{align-self:center;text-align:center;display:block}
.thread .rt b{display:block;font-family:var(--dis);font-size:17px;font-weight:600;color:var(--text)}
.thread .rt span{font-size:11px;color:var(--t3)}

/* feed scope toggle: Everything (weighted) vs Following */
.feedscope{display:inline-flex;gap:2px;padding:3px;margin:0 0 18px;border:1px solid var(--border);
  border-radius:11px;background:var(--surface2)}
.feedscope button{height:32px;padding:0 16px;border-radius:8px;font-size:13.5px;font-weight:500;
  color:var(--t2);background:transparent;border:0;cursor:pointer;
  transition:background .15s var(--ease),color .15s var(--ease)}
.feedscope button:hover{color:var(--text)}
.feedscope button.on{background:var(--surface);color:var(--text);box-shadow:var(--sh-sm);font-weight:600}
body.dark .feedscope button.on{background:var(--surface3)}
@media(max-width:760px){.feedscope{display:flex;margin-bottom:14px}.feedscope button{flex:1;height:38px}}

/* ═══ Getting-started setup card (feed) — ported inline-editing workbench.
   Prototype design tokens are mapped onto the app's own theme vars here, so
   the whole card themes light/dark with everything else. Scoped under .su. ═══ */
.su{--panel:var(--surface);--sunken:var(--surface2);--line:var(--border);--line-strong:var(--border2);
  --ink:var(--text);--ink-2:var(--t2);--ink-3:var(--t3);
  --accent-hover:color-mix(in srgb,var(--accent) 88%,#000);--accent-press:color-mix(in srgb,var(--accent) 78%,#000);
  --accent-ink:var(--accent-fg);--accent-wash:var(--accent-soft);
  --ok-wash:color-mix(in srgb,var(--ok) 13%,transparent);
  --danger-wash:color-mix(in srgb,var(--danger) 12%,transparent);
  --shadow:var(--sh-sm);--pop-shadow:var(--sh-lg,0 12px 34px rgba(0,0,0,.16));
  --r:14px;--r-ctl:8px;--r-pill:999px;--ctl-sm:32px;--ctl:40px;
  --t-fast:.08s;--t-base:.14s;--t-slow:.24s;
  --focus-ring:0 0 0 3px color-mix(in srgb,var(--accent) 22%,transparent);
  color:var(--ink);margin:0 0 18px}
.su h2,.su h3,.su h4{color:var(--ink)}
/* per-tile dismiss — a task crossed off here never returns (server-persisted).
   Sits over the time chip and swaps in on hover so it isn't visual clutter. */
.su .tl-time{transition:opacity var(--t-base) var(--ease)}
.su .tl-x{position:absolute;top:6px;right:6px;z-index:2;height:20px;padding:0 9px;border:1px solid var(--line);
  border-radius:var(--r-pill);display:inline-flex;align-items:center;color:var(--ink-3);background:var(--panel);
  font-size:10.5px;font-weight:600;letter-spacing:.01em;opacity:0;
  transition:opacity var(--t-base) var(--ease),background var(--t-base) var(--ease),color var(--t-base) var(--ease),border-color var(--t-base) var(--ease)}
.su .tl:hover .tl-x,.su .tl:focus-within .tl-x{opacity:1}
.su .tl:hover .tl-time{opacity:0}
.su .tl-x:hover{background:var(--sunken);color:var(--ink);border-color:var(--line-strong)}
.su .tl.is-next .tl-x{background:var(--accent-wash);color:var(--accent-ink);border-color:var(--accent-line)}
.su .tl.is-next .tl-x:hover{background:var(--panel)}
.su .wb-foot .su-dismiss{color:var(--ink-3);margin-left:-2px}
.su .wb-foot .su-dismiss:hover{color:var(--danger);background:var(--danger-wash)}
.su .btn:focus-visible,.su .tl:focus-visible,.su .opt:focus-visible,.su .chip:focus-visible,.su .wb-item:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.su .mono{font-family:"JetBrains Mono",monospace}
.su .eyebrow{font-family:"JetBrains Mono",monospace;font-size:10.5px; letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
/* Palette only — the shape is the site's one ladder (css/00b-buttons.php, §1).
   This shell is where the ladder's hover came from: border and label forward,
   no wash. It kept a private copy of the geometry anyway. */
.su .btn{background:var(--panel);border-color:var(--line-strong);color:var(--ink-2)}
.su .btn:hover{background:var(--panel);border-color:var(--ink-3);color:var(--ink)}
.su .btn-primary{background:var(--accent);border-color:var(--accent);color:var(--accent-on)}
.su .btn-primary:hover{background:var(--accent-hover);border-color:var(--accent-hover);color:var(--accent-on)}
.su .btn-primary:active{background:var(--accent-press);border-color:var(--accent-press)}
.su .btn-secondary{background:var(--panel);border-color:var(--line-strong);color:var(--ink)}
.su .btn-secondary:hover{border-color:var(--ink-3);background:var(--sunken);color:var(--ink)}
.su .btn-ghost{border-color:transparent;background:transparent;color:var(--ink-2)}
.su .btn-ghost:hover{border-color:transparent;background:var(--sunken);color:var(--ink)}
.su .btn-ghost.on{background:var(--accent-wash);border-color:transparent;color:var(--accent-ink)}
.su .input, .su .select, .su .textarea{width:100%;height:var(--ctl);padding:0 12px; background:var(--panel);border:1px solid var(--line-strong);border-radius:var(--r-ctl); font-size:14.5px;color:var(--ink);outline:none; transition:border-color var(--t-base) var(--ease),box-shadow var(--t-base) var(--ease)}
.su .textarea{height:auto;min-height:84px;padding:9px 12px;resize:vertical;line-height:1.55}
.su .input::placeholder, .su .textarea::placeholder{color:var(--ink-3)}
.su .input:hover, .su .select:hover, .su .textarea:hover{border-color:var(--ink-3)}
.su .input:focus, .su .select:focus, .su .textarea:focus{border-color:var(--accent);box-shadow:var(--focus-ring)}
.su .select{appearance:none;background-image: linear-gradient(45deg,transparent 50%,var(--ink-3) 50%), linear-gradient(135deg,var(--ink-3) 50%,transparent 50%); background-position:calc(100% - 17px) 50%,calc(100% - 12px) 50%; background-size:5px 5px;background-repeat:no-repeat;padding-right:34px}
.su .field{display:flex;flex-direction:column;gap:5px}
.su .field-label{font-family:"JetBrains Mono",monospace;font-size:10px;letter-spacing:.14em; text-transform:uppercase;color:var(--ink-2);font-weight:500}
.su .field-help{font-size:12px;color:var(--ink-3)}
.su .pill{display:inline-flex;align-items:center;gap:5px;height:20px;padding:0 9px; border-radius:var(--r-pill);font-family:"JetBrains Mono",monospace;font-size:9.5px; letter-spacing:.1em;text-transform:uppercase;font-weight:500; background:var(--sunken);border:1px solid var(--line-strong);color:var(--ink-2)}
.su .pill-ok{background:var(--ok-wash);border-color:color-mix(in srgb,var(--ok) 30%,transparent);color:var(--ok)}
.su .pill-accent{background:var(--accent-wash);border-color:var(--accent-line);color:var(--accent-ink)}
.su .pill .dot{width:4px;height:4px;border-radius:50%;background:currentColor}
.su .chip{display:inline-flex;align-items:center;gap:6px;height:27px;padding:0 11px; border-radius:var(--r-pill);border:1px solid var(--line-strong);background:var(--panel); font-size:12.5px;font-weight:500;color:var(--ink-2); transition:border-color var(--t-base) var(--ease),background var(--t-base) var(--ease),color var(--t-base) var(--ease)}
.su .chip:hover{border-color:var(--ink-3);color:var(--ink)}
.su .chip.is-on{background:var(--accent-wash);border-color:var(--accent);color:var(--accent-ink)}
.su .chip .n{font-family:"JetBrains Mono",monospace;font-size:10.5px;opacity:.75}.su{background:var(--panel);border:1px solid var(--line);border-radius:var(--r); box-shadow:var(--shadow);overflow:hidden}
.su .su-head{display:flex;align-items:center;gap:14px;padding:14px 16px 0}
.su .su-head-tx{flex:1;min-width:0}
.su .su-head h2{font-size:16px;font-weight:650;letter-spacing:-.02em}
.su .su-head p{font-size:12.5px;color:var(--ink-2);margin-top:1px}
.su .su-head p b{color:var(--ink);font-weight:600}
.su .su-x{width:27px;height:27px;flex:0 0 auto;border-radius:6px;display:grid;place-items:center; color:var(--ink-3);transition:background var(--t-base) var(--ease),color var(--t-base) var(--ease)}
.su .su-x:hover{background:var(--sunken);color:var(--ink)}
.su .su-x svg{width:15px;height:15px}
.su .gauge{display:flex;align-items:center;gap:9px;flex:0 0 auto}
.su .gauge-n{font-family:"JetBrains Mono",monospace;font-size:11.5px;font-weight:500; color:var(--ink-2);font-variant-numeric:tabular-nums;white-space:nowrap}
.su .gauge-n b{color:var(--accent-ink);font-weight:600}
.su .segs{display:flex;gap:3px}
.su .seg{width:12px;height:4px;border-radius:2px;background:var(--line); transition:background var(--t-slow) var(--ease)}
.su .seg.on{background:var(--accent)}
.su .su-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(196px,1fr)); gap:9px;padding:12px 16px}
.su .su-grid+.su-grid{padding-top:0}
.su .tl{position:relative;display:flex;flex-direction:column;text-align:left; background:var(--panel);border:1px solid var(--line);border-radius:var(--r); padding:11px 12px 10px;min-height:112px;overflow:hidden; transition:border-color var(--t-base) var(--ease),background var(--t-base) var(--ease)}
.su .tl::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:transparent; transition:background var(--t-base) var(--ease)}
.su .tl:hover{border-color:var(--line-strong);background:var(--sunken)}
.su .tl:hover::before{background:var(--line-strong)}
.su .tl.is-next{border-color:var(--accent-line);background:var(--accent-wash)}
.su .tl.is-next::before{background:var(--accent)}
.su .tl.is-next:hover{border-color:var(--accent)}
.su .tl-top{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.su .tl-ico{width:26px;height:26px;flex:0 0 auto;border-radius:7px;display:grid;place-items:center; background:var(--sunken);border:1px solid var(--line);color:var(--ink-2)}
.su .tl.is-next .tl-ico{background:var(--panel);border-color:var(--accent-line);color:var(--accent-ink)}
.su .tl-ico svg{width:14px;height:14px}
.su .tl-time{margin-left:auto;font-family:"JetBrains Mono",monospace;font-size:9.5px; letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3)}
.su .tl h3{font-size:13.5px;font-weight:600;letter-spacing:-.01em;line-height:1.3}
.su .tl-why{font-size:12px;color:var(--ink-2);line-height:1.45;margin-top:3px}
.su .tl-why em{font-style:normal;color:var(--ink);font-weight:500}
.su .tl-go{margin-top:auto;padding-top:9px;display:flex;align-items:center;gap:5px; font-size:12px;font-weight:600;color:var(--ink-2); transition:color var(--t-base) var(--ease),gap var(--t-base) var(--ease)}
.su .tl.is-next .tl-go{color:var(--accent-ink)}
.su .tl:hover .tl-go{color:var(--ink);gap:8px}
.su .tl.is-next:hover .tl-go{color:var(--accent-ink)}
.su .tl-go svg{width:12px;height:12px}
.su .tl.is-open{grid-column:1/-1;min-height:0;border-color:var(--accent);background:var(--panel); box-shadow:var(--pop-shadow);cursor:default;padding:13px 14px 12px}
.su .tl.is-open::before{background:var(--accent)}
.su .tl.is-open:hover{background:var(--panel)}
.su .wb{margin-top:11px;padding-top:12px;border-top:1px solid var(--line)}
.su .wb-body{display:flex;flex-direction:column;gap:11px}
.su .wb-row{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.su .wb-foot{display:flex;align-items:center;gap:9px;margin-top:13px;flex-wrap:wrap}
.su .wb-foot .sp{flex:1}
.su .wb-note{font-size:12px;color:var(--ink-3)}
.su .wb-err{margin-top:9px;font-size:12px;color:var(--danger);font-weight:500}
.su .count{font-family:"JetBrains Mono",monospace;font-size:10.5px;color:var(--ink-3); font-variant-numeric:tabular-nums}
.su .count.over{color:var(--danger)}
.su .wb-list{display:flex;flex-direction:column;border:1px solid var(--line); border-radius:var(--r);overflow:hidden}
.su .wb-item{display:flex;align-items:center;gap:10px;padding:9px 11px;width:100%;text-align:left; border-bottom:1px solid var(--line);transition:background var(--t-base) var(--ease)}
.su .wb-item:last-child{border-bottom:0}
.su .wb-item:hover{background:var(--sunken)}
.su .wb-item.done{background:var(--ok-wash)}
.su .wb-item.pick{background:var(--accent-wash)}
.su .wb-thumb{width:38px;height:28px;flex:0 0 auto;border-radius:5px;display:grid;place-items:center; border:1px solid var(--line);color:rgba(255,255,255,.9)}
.su .wb-thumb svg{width:22px;height:22px}
.su .wb-item-tx{flex:1;min-width:0}
.su .wb-item-tx b{display:block;font-size:13px;font-weight:600;white-space:nowrap; overflow:hidden;text-overflow:ellipsis}
.su .wb-item-tx span{font-family:"JetBrains Mono",monospace;font-size:10.5px;color:var(--ink-2)}
.su .wb-item .input{width:104px;height:var(--ctl-sm);font-size:12.5px; font-family:"JetBrains Mono",monospace;text-align:right}
.su .wb-q{padding:11px;border:1px solid var(--line);border-radius:var(--r);background:var(--sunken); transition:border-color var(--t-base) var(--ease),background var(--t-base) var(--ease)}
.su .wb-q.on{border-color:var(--accent);background:var(--accent-wash)}
.su .wb-q h4{font-size:13px;font-weight:600;line-height:1.4}
.su .wb-q .who{font-family:"JetBrains Mono",monospace;font-size:10.5px;color:var(--ink-2);margin-top:4px}
.su .wb-q .textarea{margin-top:9px;min-height:70px;font-size:13.5px}
.su .drop{width:100%;border:1px dashed var(--line-strong);border-radius:var(--r);background:var(--sunken); padding:18px;text-align:center;color:var(--ink-2);font-size:12.5px; transition:border-color var(--t-base) var(--ease),background var(--t-base) var(--ease)}
.su .drop:hover{border-color:var(--accent);background:var(--accent-wash);color:var(--accent-ink)}
.su .drop b{display:block;color:var(--ink);font-size:13.5px;margin-bottom:2px}
.su .drop.filled{border-style:solid;border-color:var(--ok);background:var(--ok-wash);color:var(--ok)}
.su .shots{display:flex;gap:6px;justify-content:center;margin-top:9px;flex-wrap:wrap}
.su .shot{width:44px;height:34px;border-radius:5px;border:1px solid var(--line-strong)}
.su .opts{display:flex;gap:7px;flex-wrap:wrap}
.su .opt{display:inline-flex;align-items:center;height:32px;padding:0 12px; border:1px solid var(--line-strong);border-radius:7px;background:var(--panel); font-size:12.5px;font-weight:500;color:var(--ink-2); transition:border-color var(--t-base) var(--ease),background var(--t-base) var(--ease),color var(--t-base) var(--ease)}
.su .opt:hover{border-color:var(--ink-3);color:var(--ink)}
.su .opt.on{background:var(--accent-wash);border-color:var(--accent);color:var(--accent-ink)}
.su .opt.on.ok{background:var(--ok-wash);border-color:var(--ok);color:var(--ok)}
.su .opt.on.no{background:var(--danger-wash);border-color:var(--danger);color:var(--danger)}
.su .band{display:flex;align-items:baseline;gap:10px;padding:12px 16px 0}
.su .band .lb{font-family:"JetBrains Mono",monospace;font-size:10px;letter-spacing:.14em; text-transform:uppercase;color:var(--ink-2)}
.su .band .nt{font-size:11.5px;color:var(--ink-3);flex:1}
.su .band .ct{font-family:"JetBrains Mono",monospace;font-size:10px;letter-spacing:.1em; text-transform:uppercase;color:var(--ink-3)}
.su .band .ct.acc{color:var(--accent-ink)}
.su .su-foot{display:flex;align-items:center;gap:10px;padding:9px 16px; border-top:1px solid var(--line);background:var(--sunken)}
.su .su-foot .tick{width:16px;height:16px;flex:0 0 auto;border-radius:50%;background:var(--ok); color:#fff;display:grid;place-items:center}
.su .su-foot .tick svg{width:9px;height:9px}
.su .su-foot .lb{font-size:12.5px;color:var(--ink-2)}
.su .su-foot .lb b{color:var(--ink);font-weight:600}
.su .su-foot .caret{color:var(--ink-3);display:grid;place-items:center; transition:transform var(--t-base) var(--ease)}
.su .su-foot .caret svg{width:13px;height:13px}
.su .su-foot .donebtn{display:flex;align-items:center;gap:8px;border-radius:6px;padding:3px 6px; margin:-3px -6px;transition:background var(--t-base) var(--ease)}
.su .su-foot .donebtn:hover{background:var(--line)}
.su .su-foot .donebtn[aria-expanded="true"] .caret{transform:rotate(180deg)}
.su .su-foot .sp{flex:1}
.su .dlist{display:flex;flex-wrap:wrap;gap:6px;padding:0 16px 12px;background:var(--sunken)}
.su .dlist[hidden]{display:none}
.su .dchip{display:inline-flex;align-items:center;gap:6px;height:25px;padding:0 10px; border-radius:var(--r-pill);background:var(--panel);border:1px solid var(--line); font-size:12px;color:var(--ink-2)}
.su .dchip svg{width:11px;height:11px;color:var(--ok);flex:0 0 auto}
.su .su-rest{display:flex;align-items:center;gap:12px;padding:11px 16px}
.su .su-rest-ico{width:32px;height:32px;flex:0 0 auto;border-radius:8px;display:grid;place-items:center; background:var(--accent-wash);border:1px solid var(--accent-line);color:var(--accent-ink)}
.su .su-rest-ico svg{width:16px;height:16px}
.su .su-rest-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.su .su-rest-tx b{font-size:13px;font-weight:650;letter-spacing:-.01em}
.su .su-rest-sub{font-size:12px;color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.su .su-rest-sub b{color:var(--accent-ink);font-weight:600}
.su .su-rest-segs{flex:0 0 auto}
@media (max-width:520px){.su .su-rest{flex-wrap:wrap;padding:12px 13px}.su .su-rest-segs{display:none}.su .su-rest [data-resume]{flex:1 1 auto}}
@media (max-width:520px){.su .su-head{flex-wrap:wrap;padding:13px 13px 0}.su .gauge{order:3;width:100%}.su .su-grid{grid-template-columns:1fr;padding:11px 13px}.su .band, .su .su-foot, .su .dlist{padding-left:13px;padding-right:13px}.su .wb-row{grid-template-columns:1fr}}

.feed-item{display:flex;gap:13px;padding:18px 0;border-bottom:1px solid var(--border)}
.feed-item:last-child{border-bottom:0}
.feed-item .txt{font-size:14px;color:var(--t2);min-width:0;flex:1}
.feed-item .txt b{color:var(--text);font-weight:500}
.feed-item .feed-by{margin-top:8px;font-size:12.5px;color:var(--t3,var(--t2))}
.feed-item .prev{margin-top:11px;border:1px solid var(--border);border-radius:12px;padding:14px 16px;
  background:var(--surface);display:block}
.feed-item .prev:hover{border-color:var(--border2);box-shadow:var(--sh-sm)}
.feed-item .prev h4{font-size:14.5px}
.feed-item .prev p{font-size:13.5px;color:var(--t2);margin-top:5px;line-height:1.55}
.feed-item .prev .photo{display:block;aspect-ratio:16/6.5;margin:-14px -16px 13px;border-radius:11px 11px 0 0}
.when{margin-left:auto;font-size:12.5px;color:var(--t3);white-space:nowrap;flex:none}
/* "going to an event": the car they said they're bringing, under the event
   preview. A chip rather than a second big card — the event is the news, the
   car is the detail. One renderer (ams_feed_item / feedCardLive). */
.feed-item .feed-bring{display:inline-flex;align-items:center;gap:9px;max-width:100%;margin-top:9px;
  padding:4px 12px 4px 4px;border:1px solid var(--border);border-radius:var(--r-pill);
  background:var(--surface);font-size:12.5px;color:var(--t2);line-height:1.2}
.feed-item .feed-bring:hover{border-color:var(--border2);box-shadow:var(--sh-sm)}
.feed-item .feed-bring .photo{width:26px;height:26px;flex:none;border-radius:50%}
.feed-item .feed-bring b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* a photo-only feed card (from "added a photo") */
.feed-item .prev.feed-photo{padding:0;overflow:hidden}
.feed-item .prev.feed-photo .photo{display:block;aspect-ratio:16/9;margin:0;border-radius:12px}
/* "added a vehicle" feed tile: the profile hero cropped to a feed — the
   photograph and the name, nothing else. One renderer (ams_vehicle_tile in PHP,
   vehTileHtml in JS); fields: image=cover else newest photo else drafting
   sheet, name=nickname else Y/M/M, ym=Y/M/M (or the model when the name already
   carries it), who=@owner shown only when it isn't yours, add control only on
   your own photoless car. */
a.vt{display:block;position:relative;margin-top:11px;overflow:hidden;
  border:1px solid var(--border);border-radius:13px;background:var(--surface2);box-shadow:var(--sh-sm);
  aspect-ratio:2.4/1;transition:box-shadow .2s var(--ease),transform .2s var(--ease)}
a.vt:hover{box-shadow:var(--sh);transform:translateY(-2px)}
/* The home page shows these in a grid instead of one per feed card. The feed's
   top margin exists to space the tile under a card's text and has nothing to
   sit under here, and a banner aspect wastes the row — so the container adjusts
   the tile rather than the tile growing a second set of rules. */
.vtgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:14px}
.vtgrid a.vt{margin-top:0;aspect-ratio:16/11}
@media(max-width:1080px){.vtgrid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media(max-width:720px){.vtgrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:11px}}
a.vt:hover .vt-img{transform:scale(1.03)}
.vt-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .5s cubic-bezier(.2,.7,.3,1)}
/* no photo yet: a drafting sheet with the silhouette, not a grey rectangle */
.vt-empty{position:absolute;inset:0;display:grid;place-items:center;
  background:
    repeating-linear-gradient(0deg,rgba(12,13,15,.045) 0 1px,transparent 1px 14px),
    repeating-linear-gradient(90deg,rgba(12,13,15,.045) 0 1px,transparent 1px 14px),
    linear-gradient(160deg,#FAFAFB,#EDEDF0)}
body.dark .vt-empty{background:
    repeating-linear-gradient(0deg,rgba(255,255,255,.05) 0 1px,transparent 1px 14px),
    repeating-linear-gradient(90deg,rgba(255,255,255,.05) 0 1px,transparent 1px 14px),
    linear-gradient(160deg,#1b1b20,#141418)}
.vt-empty svg{width:64px;height:64px;color:var(--t3);opacity:.42}
.vt-id{position:absolute;left:0;right:0;bottom:0;padding:44px 20px 16px;
  background:linear-gradient(180deg,transparent,rgba(6,7,9,.84))}
.vt-id .nm{font:600 23px/1.1 var(--dis);letter-spacing:-.034em;color:#fff;
  text-shadow:0 1px 14px rgba(0,0,0,.34);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* ---- sharing ------------------------------------------------------------
   A share is one feed item: the sharer's line, an optional caption, and the
   subject card. The card is ONE renderer (ams_share_subject in PHP,
   AMSR.shareSubject in JS) so it looks the same in the site feed, in a profile
   feed and inside the share sheet's preview. */
.feed-item .share-cap{margin-top:9px;font-size:14.5px;line-height:1.6;color:var(--text)}
/* the subject card is an ordinary feed preview — same frame and photo crop as
   every other .prev, so a share doesn't read as a different kind of object */
.share-kind{display:inline-block;margin-bottom:7px;padding:2px 8px;border-radius:999px;
  border:1px solid var(--border2);background:var(--surface2);
  font:600 10.5px/1.7 var(--ui);letter-spacing:.06em;text-transform:uppercase;color:var(--t3)}
.share-by{display:block;margin-top:9px;font-size:12.5px;color:var(--t3)}
/* remove control on your own share — quiet until the item is hovered. The
   author line is ordinary flowing text, not a flex row, so this is pinned to
   the item rather than pushed to the end of the line. */
.feed-item[data-shareitem]{position:relative}
.share-rm{position:absolute;right:0;top:16px;width:22px;height:22px;border:0;border-radius:6px;
  background:transparent;color:var(--t3);font-size:15px;line-height:1;cursor:pointer;opacity:0;
  transition:opacity .16s,background .16s,color .16s}
.feed-item:hover .share-rm,.share-rm:focus-visible{opacity:1}
.share-rm:hover{background:var(--surface3,var(--surface2));color:var(--text)}
/* the actions under a feed card — one row, drawn by ams_feed_acts /
   AMSR.feedActs, present only on cards that are actually shareable */
.feed-acts{display:flex;align-items:center;gap:8px;margin-top:11px}
.feed-act{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 11px;
  border:1px solid var(--border);border-radius:8px;background:transparent;
  color:var(--t3);font:500 12.5px var(--ui);cursor:pointer;
  transition:color .16s,border-color .16s,background .16s}
.feed-act:hover{color:var(--text);border-color:var(--border2);background:var(--surface)}
.feed-act svg{flex:none}
/* the share sheet (inside amsModal) */
.share-sheet .share-prev{border:1px dashed var(--border2);border-radius:12px;padding:12px}
.share-sheet .share-prev .prev.share-sub{margin-top:0}
.share-sheet .amsfield span{display:block;margin-bottom:6px;font-size:12.5px;color:var(--t3)}
/* the profile's own feed column — narrower than the site feed, it sits in a
   section rather than a page */
.pf-feed{max-width:640px}
/* a section header's count and its action ride together on the right, so
   adding a button doesn't strand the count in the middle */
.gx .gsec-h .gsec-r{margin-left:auto;display:flex;align-items:center;gap:12px}

.vt-id .ym{font-size:13px;color:rgba(255,255,255,.8);margin-top:4px;
  text-shadow:0 1px 10px rgba(0,0,0,.34);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vt-id .who{color:rgba(255,255,255,.62)}
.vt-id .who::before{content:"·";margin:0 6px;opacity:.6}
/* on the pale drafting sheet the type flips to dark */
.vt-id.on-sheet{background:linear-gradient(180deg,transparent,rgba(255,255,255,.5))}
body.dark .vt-id.on-sheet{background:linear-gradient(180deg,transparent,rgba(6,7,9,.6))}
.vt-id.on-sheet .nm{color:var(--text);text-shadow:none}
.vt-id.on-sheet .ym{color:var(--t2);text-shadow:none}
.vt-id.on-sheet .who{color:var(--t3)}
/* the one control, only on your own photoless car */
.vt-add{position:absolute;right:12px;top:11px;display:inline-flex;align-items:center;gap:5px;
  height:26px;padding:0 11px;border-radius:999px;border:1px solid var(--border2);
  background:rgba(255,255,255,.9);color:var(--t2);font:500 11.5px var(--ui);
  transition:background .18s,color .18s,border-color .18s}
a.vt:hover .vt-add{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
@media(max-width:620px){
  a.vt{aspect-ratio:1.7/1}
  .vt-id{padding:36px 15px 13px}
  .vt-id .nm{font-size:19px}
  .vt-id .ym{font-size:12px}
  .vt-empty svg{width:48px;height:48px}
}
.newpill{position:sticky;top:76px;z-index:20;display:flex;justify-content:center;margin:-6px 0 10px;pointer-events:none}
.newpill button{pointer-events:auto;opacity:0;transform:translateY(-8px);transition:all .3s var(--ease)}
.newpill.show button{opacity:1;transform:none}

.seg{display:inline-flex;padding:3px;background:var(--surface2);border:1px solid var(--border);border-radius:10px;gap:2px}
.seg button{padding:5px 12px;border-radius:7px;font-size:13px;font-weight:450;color:var(--t2);transition:all .16s var(--ease)}
.seg button.on{background:var(--surface);color:var(--text);font-weight:500;box-shadow:var(--sh-sm)}

.phero{display:flex;gap:24px;align-items:flex-start;padding-bottom:28px;border-bottom:1px solid var(--border);flex-wrap:wrap}
.phero h1{font-size:26px}
.phero .handle{font:400 14px var(--mono);color:var(--t2);margin-top:4px}
.phero .bio{margin-top:14px;font-size:14.5px;color:var(--t2);max-width:60ch;line-height:1.6}
.phero .m{display:flex;gap:8px;margin-top:16px;flex-wrap:wrap}

.filter{margin-bottom:24px}
.filter h4{font-size:12px;font-weight:600;color:var(--t3);margin-bottom:9px;font-family:var(--ui)}
.filter a{display:flex;align-items:center;gap:8px;padding:6px 9px;border-radius:8px;font-size:14px;color:var(--t2)}
.filter a:hover{background:var(--surface2);color:var(--text)}
.filter a.on{background:var(--surface2);color:var(--text);font-weight:500}
.filter a .c{margin-left:auto;font-size:12px;color:var(--t3);font-variant-numeric:tabular-nums}

.auth{max-width:400px;margin:0 auto}
.auth h1{font-size:24px;text-align:center}
.auth .s{text-align:center;color:var(--t2);font-size:14.5px;margin-top:9px;margin-bottom:28px}
.auth .f{margin-bottom:16px}
/* The "or" between the OAuth buttons and the password form. .auth is an empty
   box the bundle fills on both auth screens now, so the divider lives outside
   it in .gatewrap or the first render would wipe it. The .auth copy stays for
   any host that still renders the divider inside — one definition, either way. */
.auth .or,.gatewrap .or{display:flex;align-items:center;gap:12px;margin:22px 0;color:var(--t3);font-size:12.5px}
.auth .or::before,.auth .or::after,
.gatewrap .or::before,.gatewrap .or::after{content:"";flex:1;height:1px;background:var(--border)}
.auth .foot{text-align:center;font-size:14px;color:var(--t2);margin-top:22px}
.auth .foot a{color:var(--text);font-weight:500}
.gate{border:1px dashed var(--border2);border-radius:var(--r-lg);padding:24px;background:var(--surface2);text-align:center}
.gate h4{font-size:16px;margin-bottom:6px}
.gate p{font-size:14px;color:var(--t2);margin-bottom:16px;max-width:44ch;margin-left:auto;margin-right:auto}

.steps{counter-reset:s}
.step{display:flex;gap:16px;padding:18px 0;border-bottom:1px solid var(--border)}
.step:last-child{border-bottom:0}
.step .n{counter-increment:s;flex:none;width:28px;height:28px;border-radius:999px;background:var(--surface2);
  border:1px solid var(--border);display:grid;place-items:center;font-size:12.5px;font-weight:600;color:var(--t2)}
.step .n::before{content:counter(s)}
.step h4{font-size:15.5px;margin-bottom:6px}
.step p{font-size:14px;color:var(--t2);line-height:1.6;max-width:70ch}

.foot{border-top:1px solid var(--border);padding:34px 0;background:var(--surface)}
.foot .wrap{display:flex;gap:24px;flex-wrap:wrap;align-items:center}
.foot p{font-size:13px;color:var(--t3)}
.foot nav{margin-left:auto;display:flex;gap:6px;flex-wrap:wrap}
.foot nav a{font-size:13px;color:var(--t2);padding:5px 9px;border-radius:7px}
.foot nav a:hover{color:var(--text);background:var(--surface2)}

/* ---------- YMM finder ---------- */
.finder{margin-top:24px}
.finder .seg{margin-bottom:10px}
.ymm{border:1px solid var(--border2);border-radius:14px;background:var(--surface);box-shadow:var(--sh);
  padding:6px;display:flex;gap:4px;align-items:stretch;flex-wrap:wrap}
.ymm-f{flex:1 1 130px;min-width:0;display:flex;flex-direction:column;justify-content:center;
  padding:7px 13px;border-radius:10px;position:relative;cursor:pointer;transition:background .16s}
.ymm-f:hover{background:var(--surface2)}
.ymm-f+.ymm-f::before{content:"";position:absolute;left:-2px;top:9px;bottom:9px;width:1px;background:var(--border)}
.ymm-f>span:first-child{font-size:11px;font-weight:600;color:var(--t3)}
.ymm-f select{appearance:none;border:0;background:none;padding:0;margin-top:2px;width:100%;
  font:500 14.5px var(--ui);color:var(--text);cursor:pointer;text-overflow:ellipsis}
.ymm-f select:focus{outline:none}
.ymm-f.off{opacity:.55;pointer-events:none}
.ymm .go{align-self:stretch;min-height:48px;flex:0 0 auto}
.uni{border:1px solid var(--border2);border-radius:14px;background:var(--surface);box-shadow:var(--sh);padding:15px 16px}
.uni h5{font-family:var(--dis);font-size:14.5px;font-weight:600;margin:0 0 3px}
.uni .sub2{font-size:13px;color:var(--t2);margin-bottom:12px}
.uni .g{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:14px}
.dice{display:inline-flex;align-items:center;gap:7px}
.resolved{display:flex;gap:11px;align-items:center;flex-wrap:wrap;margin-top:11px;
  animation:in .28s var(--ease)}
.ymm .go.dim{opacity:.45;pointer-events:none}

/* ---------- amsCombo: themed, searchable dropdown (replaces native <select>) ---------- */
.combo{position:relative}
.combo-lbl{font-size:11px;font-weight:600;color:var(--t3)}
.combo-field{display:flex;align-items:center;gap:6px;width:100%;background:none;border:0;padding:0;margin-top:2px;
  font:500 14.5px var(--ui);color:var(--text);cursor:pointer;text-align:left}
.combo-val{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.combo-val.ph{color:var(--t3);font-weight:450}
.combo-chev{flex:none;color:var(--t3);display:inline-flex;transition:transform .18s var(--ease)}
.combo.open .combo-chev{transform:rotate(180deg)}
.combo.off{opacity:.55;pointer-events:none}
.combo-pop{position:absolute;top:calc(100% + 8px);left:-4px;z-index:300;min-width:max(100%,190px);
  background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:var(--sh-lg);
  padding:6px;animation:in .16s var(--ease)}
.combo-search{padding:2px 2px 6px}
.combo-in{width:100%;height:34px;padding:0 11px;border:1px solid var(--border2);border-radius:8px;
  background:var(--surface2);color:var(--text);font:450 13.5px var(--ui);outline:none}
.combo-in:focus{border-color:var(--accent);background:var(--surface);box-shadow:0 0 0 3px var(--accent-soft)}
.combo-list{max-height:262px;overflow-y:auto}
.combo-list .combo-opt+.combo-opt{margin-top:1px}
.combo-opt{display:block;width:100%;text-align:left;padding:8px 10px;border:0;border-radius:8px;background:none;
  color:var(--text);font:450 14px var(--ui);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.combo-opt:hover,.combo-opt.active{background:var(--surface2)}
.combo-opt.sel{color:var(--accent-fg);font-weight:600}
.combo-empty{padding:10px 11px;color:var(--t3);font-size:13px}
/* marketplace toolbar variant: a bordered pill like the old select */
.fsel .combo-field{height:34px;margin-top:0;padding:0 12px;border:1px solid var(--border2);border-radius:9px;
  background:var(--surface);font-size:13.5px}
.fsel .combo.off{opacity:1}
.fsel .combo-pop{left:0;right:auto}
/* native selects that remain (composer/edit) follow the theme's colour-scheme */
select.input,.fsel select{color-scheme:light}
body.dark select.input,body.dark .fsel select{color-scheme:dark}

/* ---------- brands ---------- */
.brandgrid{display:grid;grid-template-columns:repeat(6,1fr);gap:12px}
.brand{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);box-shadow:var(--sh-sm);
  padding:17px 12px;text-align:center;display:block;
  transition:transform .2s var(--ease),box-shadow .2s var(--ease),border-color .2s}
.brand:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--border2)}
.brand b{display:block;font-family:var(--dis);font-size:15px;font-weight:600;letter-spacing:-.024em}
.brand span{display:block;font-size:11.5px;color:var(--t3);margin-top:4px}
.brandstrip{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:22px}

/* ---------- parent company ---------- */
.parent{border-top:1px solid var(--border);background:var(--surface2);padding:38px 0}
.parent .in{display:flex;gap:24px;align-items:center;flex-wrap:wrap}
/* Both footer marks (MPL and AMS) share one fixed-width, centered box so the
   two rows' text columns line up despite the logos' different proportions. */
.parent .mk{flex:none;color:var(--text);opacity:.92;width:68px;display:flex;align-items:center;justify-content:center}
.parent .mk svg{fill:currentColor}
.parent .mk svg{height:56px;width:auto;display:block}
.parent .tx{flex:1;min-width:260px}
.parent .kicker{font-size:11px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--t3)}
.parent h4{font-family:var(--dis);font-size:21px;letter-spacing:-.026em;margin-top:6px}
.parent p{font-size:14px;color:var(--t2);margin-top:8px;max-width:60ch;line-height:1.6}
/* the AMS tagline lead: bolded and in the stronger ink so it reads above the body */
.parent .footer-lead{color:var(--text);margin-top:10px}
/* AMS block mirrors the MPL layout: logo (left) · text with the social row
   (fills the middle) · nav links (far right). Separated from the MPL block
   above by a hairline rule. */
.parent .in.second{margin-top:30px;padding-top:30px;border-top:1px solid var(--border)}
/* Social brand logos live in the "Free to use" text column, under the blurb. */
.parent .tx .social-icons{display:inline-flex;gap:13px;margin-top:16px;align-items:center}
.parent .tx .social-icons a{color:var(--t2);display:inline-flex;transition:color .16s var(--ease),transform .16s var(--ease)}
.parent .tx .social-icons a:hover{color:var(--accent);transform:translateY(-1px)}
.parent .tx .social-icons svg{width:19px;height:19px;display:block;fill:currentColor}
/* AMS mark: same rendering as the header logo — dark outer ring, orange inner hex */
.parent .mk-ams .hexmark{--hx-ink:#201E1D;--hx-hot:#EE7016;--hxh:68.87px;display:block}  /* 56px of ink x 214/174 */
body.dark .parent .mk-ams .hexmark{--hx-ink:#F4F4F5}
.parent .mk-ams .hx-out{fill:var(--hx-ink)}
.parent .mk-ams .hx-in{fill:var(--hx-hot)}
.parent-copy{margin-top:26px;padding-top:18px;border-top:1px solid var(--border);display:flex;flex-wrap:wrap;gap:10px 18px;align-items:center;justify-content:space-between}
.parent-copy span{font-size:12.5px;color:var(--t3)}
.parent .lk{display:flex;gap:4px;flex-wrap:wrap;margin-left:auto;flex:none}
.parent .lk a{font-size:13px;font-weight:500;color:var(--t2);padding:7px 11px;border-radius:8px;transition:all .16s}
.parent .lk a:hover{color:var(--text);background:var(--surface)}


/* powered by */
.powered{margin-top:26px;padding-top:20px;border-top:1px solid var(--border);
  display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.mpl{display:inline-flex;align-items:center;gap:11px;color:var(--t3);transition:color .18s var(--ease)}
.mpl:hover{color:var(--text)}
.mpl svg{height:30px;width:auto;display:block;flex:none}
.mpl .lbl3{font-size:13px;letter-spacing:-.005em;line-height:1.3}
.mpl .lbl3 b{display:block;font-family:var(--dis);font-size:14.5px;font-weight:600;
  letter-spacing:-.022em;color:var(--t2);transition:color .18s var(--ease)}
.mpl:hover .lbl3 b{color:var(--text)}
.powered .small{color:var(--t3)}
.mpl2{margin-left:auto;font-size:13px;font-weight:500;color:var(--t2)}
.mpl2:hover{color:var(--text)}

.vsw{position:fixed;left:16px;bottom:calc(16px + var(--floor,0px));z-index:95;display:flex;align-items:center;gap:3px;
  background:color-mix(in srgb,var(--surface) 90%,transparent);backdrop-filter:blur(12px);
  border:1px solid var(--border2);border-radius:12px;padding:4px;box-shadow:var(--sh-lg)}
.vsw span{font-size:11px;color:var(--t3);padding:0 8px 0 6px}
.vsw button{padding:7px 12px;border-radius:8px;font-size:12.5px;font-weight:500;color:var(--t2);transition:all .16s var(--ease)}
.vsw button.on{background:var(--text);color:var(--canvas)}
.vsw .sep{width:1px;height:20px;background:var(--border);margin:0 3px}
.vsw .thm{padding:7px 9px;color:var(--t2)}

/* ================= pro components ================= */
.crumbs{display:flex;align-items:center;gap:7px;font-size:13px;color:var(--t3);margin-bottom:12px;flex-wrap:wrap}
.crumbs a{color:var(--t2)} .crumbs a:hover{color:var(--text)}
.crumbs em{font-style:normal;opacity:.5}

.toolbar{position:sticky;top:60px;z-index:40;background:color-mix(in srgb,var(--canvas) 88%,transparent);
  backdrop-filter:blur(12px);border-bottom:1px solid var(--border);margin-bottom:22px}
.toolbar .in{display:flex;align-items:center;gap:8px;padding:12px 0;flex-wrap:wrap}
.tsearch{position:relative;flex:1 1 220px;min-width:180px;max-width:340px}
.tsearch .input{height:34px;padding-left:32px;font-size:13.5px;background:var(--surface2);border-color:transparent}
.tsearch .input:focus{background:var(--surface);border-color:var(--accent)}
.tsearch svg{position:absolute;left:11px;top:10px;color:var(--t3)}
.fsel{position:relative}
.fsel select{appearance:none;height:34px;padding:0 30px 0 12px;border:1px solid var(--border2);border-radius:9px;
  background:var(--surface);font:500 13px var(--ui);color:var(--t2);cursor:pointer;box-shadow:var(--sh-sm)}
.fsel select:focus{outline:none;border-color:var(--accent)}

.tcount{margin-left:auto;font-size:13px;color:var(--t3);white-space:nowrap;font-variant-numeric:tabular-nums}
.vtog{display:inline-flex;padding:2px;background:var(--surface2);border:1px solid var(--border);border-radius:9px;gap:2px}
.vtog button{width:28px;height:28px;border-radius:7px;display:grid;place-items:center;color:var(--t3)}
.vtog button.on{background:var(--surface);color:var(--text);box-shadow:var(--sh-sm)}

/* ---- atlas split view ---- */
.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.06fr);gap:0;
  border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);box-shadow:var(--sh-sm)}
.split .left{max-height:76vh;overflow-y:auto;border-right:1px solid var(--border)}
.split .right{position:relative;background:var(--surface2);min-height:420px}
.mapwrap{position:sticky;top:0;height:76vh;display:flex;flex-direction:column}
.mapwrap svg{flex:1;width:100%;height:100%;display:block}
.map-land{fill:var(--surface3);stroke:var(--border2);stroke-width:1.2}
body.dark .map-land{fill:#1E1E24;stroke:#33333B}
.map-grid{stroke:var(--border);stroke-width:.6;opacity:.65}
.map-ring{fill:var(--accent);opacity:.07;stroke:var(--accent);stroke-width:1;stroke-dasharray:5 4}
.pin{cursor:pointer}
.pin circle.d{fill:var(--accent);stroke:#fff;stroke-width:1.6}
body.dark .pin circle.d{stroke:#111114}
.pin circle.h{fill:var(--accent);opacity:0;transition:opacity .2s}
.pin:hover circle.h,.pin.on circle.h{opacity:.22}
.pin.you circle.d{fill:var(--text)}
.pin text{font:600 9px var(--mono);fill:var(--text);opacity:0;transition:opacity .2s}
.pin:hover text,.pin.on text{opacity:1}
.mapbar{display:flex;align-items:center;gap:10px;padding:10px 14px;border-top:1px solid var(--border);
  background:var(--surface);font-size:12.5px;color:var(--t3);flex-wrap:wrap}
.scalebar{display:inline-flex;align-items:center;gap:6px}
.scalebar i{display:block;width:46px;height:1px;background:var(--t3);position:relative}
.scalebar i::before,.scalebar i::after{content:"";position:absolute;top:-3px;width:1px;height:7px;background:var(--t3)}
.scalebar i::before{left:0}.scalebar i::after{right:0}

/* live vendor map (Leaflet) — replaces the schematic SVG on the vendors page */
.mapwrap .vendors-map{flex:1;width:100%;min-height:420px;background:var(--surface3)}
.mapwrap .vendors-map.empty{display:flex;align-items:center;justify-content:center;
  text-align:center;color:var(--t3);font-size:13px;padding:24px}
.leaflet-popup-content{font:inherit;margin:11px 13px;line-height:1.5}
.leaflet-popup-content b{font-weight:600}
.leaflet-popup-content a{color:var(--accent-fg);font-weight:500}
.vpin-you{background:var(--text);border:2px solid var(--surface);border-radius:50%;
  width:14px;height:14px;box-shadow:0 0 0 3px rgba(0,0,0,.15)}

/* reusable link preview / image scraper card (Facebook-style) */
.linkprev{margin-top:10px}
.linkprev-card{display:flex;flex-direction:column;position:relative;overflow:hidden;
  border:1px solid var(--border);border-radius:12px;background:var(--surface2)}
.linkprev-img{width:100%;aspect-ratio:1.91/1;background:var(--surface3) center/cover no-repeat}
.linkprev-img.none{aspect-ratio:auto;height:0}
.linkprev-body{display:flex;flex-direction:column;gap:3px;padding:11px 13px;min-width:0}
.linkprev-site{font:600 10.5px var(--mono);text-transform:uppercase;letter-spacing:.04em;color:var(--t3)}
.linkprev-title{font-size:14px;font-weight:600;line-height:1.35;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.linkprev-desc{font-size:12.5px;color:var(--t3);line-height:1.45;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.linkprev-tag{font-size:11.5px;color:var(--accent-fg);font-weight:500;margin-top:3px}
.linkprev-x{position:absolute;top:8px;right:8px;width:26px;height:26px;border-radius:50%;
  border:none;background:rgba(0,0,0,.55);color:#fff;font-size:13px;cursor:pointer;
  display:grid;place-items:center;line-height:1}
.linkprev-x:hover{background:rgba(0,0,0,.75)}
.linkprev-loading{display:flex;align-items:center;gap:10px;padding:14px;
  border:1px dashed var(--border2);border-radius:12px}
.linkprev-loading .ams-spin{width:18px;height:18px;border-width:2.5px;border-top-color:var(--accent)}
.linkprev-note{padding:12px 13px;border:1px dashed var(--border2);border-radius:12px}

/* vendor "look up the business" (OpenStreetMap) results */
.vfind-res{margin-top:9px;display:flex;flex-direction:column;gap:6px}
.vfind-item{display:block;width:100%;text-align:left;padding:9px 11px;border:1px solid var(--border2);
  border-radius:9px;background:var(--surface);font:inherit;font-size:12.5px;line-height:1.4;
  color:var(--t2);cursor:pointer}
.vfind-item:hover{border-color:var(--accent);background:var(--accent-soft);color:var(--text)}

/* ── Vendors filter bar: clean, aligned, grouped (scoped to #pg-vendors) ── */
#pg-vendors .vbar{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:12px 0}
#pg-vendors .vbar-2{border-top:1px solid var(--border)}
#pg-vendors .vbar .tsearch{flex:0 1 240px;min-width:180px;max-width:280px;margin:0}
#pg-vendors .vbar .tsearch .input{border:1px solid var(--border2)}
#pg-vendors .vbar .tsearch svg{top:11px}
#pg-vendors .vbar-spring{flex:1 1 auto}
#pg-vendors .vbar-sep{width:1px;height:24px;background:var(--border);margin:0 2px}
#pg-vendors .tcount{font-weight:500;color:var(--t2);background:var(--surface2);
  border:1px solid var(--border);border-radius:999px;padding:0 13px;height:36px;
  display:inline-flex;align-items:center;font-size:12.5px;white-space:nowrap;margin:0}
#pg-vendors .vbar-sort{margin-left:auto}
#pg-vendors .fsel select,#pg-vendors .fsel .selbtn,#pg-vendors .fsel .combo-field,
#pg-vendors .vbar .tsearch .input,#pg-vendors .tog{height:36px}
#pg-vendors .miniymm{align-self:center}
#pg-vendors .miniymm .mf{padding:5px 13px}
#pg-vendors .miniymm .mf>span:first-child{text-transform:uppercase;letter-spacing:.05em}
@media(max-width:760px){
  #pg-vendors .vbar-spring{display:none}
  #pg-vendors .vbar-sep{display:none}
  #pg-vendors .vbar .tsearch{flex:1 1 100%;max-width:none}
  #pg-vendors .vbar .fsel{flex:1 1 100%}
  #pg-vendors .vbar .fsel select,#pg-vendors .vbar .fsel .sel,#pg-vendors .vbar .fsel .selbtn{width:100%}
  #pg-vendors .tog{flex:1 1 calc(50% - 5px);justify-content:flex-start}
  #pg-vendors .miniymm{width:100%}
  #pg-vendors .tcount{flex:1 1 100%;justify-content:center;margin-left:0}
  #pg-vendors .vbar-sort{margin-left:0}
}

/* ---- vendor row ---- */
.vrow{display:flex;gap:14px;padding:16px;border-bottom:1px solid var(--border);cursor:pointer;transition:background .16s}
.vrow:last-child{border-bottom:0}
.vrow:hover,.vrow.on{background:var(--surface2)}
.vrow .photo{width:78px;height:78px;flex:none;border-radius:10px}
.vrow .bd{min-width:0;flex:1}
.vrow h3{font-size:15.5px;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
.vrow .loc{font-size:13px;color:var(--t2);margin-top:4px;display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.vrow .tg{display:flex;gap:5px;flex-wrap:wrap;margin-top:9px}
.vrow .dist{flex:none;text-align:right}
.vrow .dist b{display:block;font-family:var(--dis);font-size:16px;font-weight:600}
.vrow .dist span{font-size:10.5px;color:var(--t3)}
.stars{display:inline-flex;align-items:center;gap:4px;font-size:12.5px;color:var(--t2)}
.stars b{color:var(--text);font-weight:600}
.stars svg{color:var(--accent)}
.vtype{font-size:11px;font-weight:600;color:var(--accent-fg);background:var(--accent-soft);
  border:1px solid var(--accent-line);border-radius:6px;padding:2px 7px}

/* ---- parts marketplace ---- */
/* your listings (seller-owned) on the marketplace */
.mylist{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);box-shadow:var(--sh-sm);padding:14px 18px 6px}
.mlrow{display:flex;align-items:center;gap:14px;padding:11px 0;border-top:1px solid var(--border)}
.mlrow:first-of-type{border-top:0}
.mlrow .photo{width:56px;height:42px;border-radius:8px;flex:none;background:#e9e9ee}
.mlrow .photo.noimg{width:56px!important;height:42px!important;flex:none!important;display:block!important}
.mlbody{min-width:0;flex:1}
.mltitle{display:block;font-weight:600;font-size:14.5px;color:var(--text);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mltitle:hover{text-decoration:underline}
.mlmeta{display:flex;align-items:center;gap:9px;margin-top:4px}
.mlacts{display:flex;gap:8px;flex:none}
@media(max-width:640px){.mlrow{flex-wrap:wrap}.mlacts{width:100%;justify-content:flex-end;margin-top:2px}}
.plist{border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);box-shadow:var(--sh-sm)}
.phead2{display:grid;grid-template-columns:74px minmax(0,1fr) 112px 128px 100px;gap:14px;padding:10px 16px;
  background:var(--surface2);border-bottom:1px solid var(--border);font-size:11.5px;font-weight:600;color:var(--t3)}
.prow{display:grid;grid-template-columns:74px minmax(0,1fr) 112px 128px 100px;gap:14px;padding:14px 16px;
  border-bottom:1px solid var(--border);align-items:center;transition:background .16s;cursor:pointer}
.prow:last-child{border-bottom:0}
.prow:hover{background:var(--surface2)}
.prow .photo{width:74px;height:56px;border-radius:8px}
.prow h4{font-size:14.5px;font-weight:500;line-height:1.35}
.prow .pn{font:400 12px var(--mono);color:var(--t3);margin-top:4px}
.prow .price{font-family:var(--dis);font-size:17px;font-weight:600;letter-spacing:-.02em}
.prow .ship{font-size:11.5px;color:var(--t3);margin-top:2px}
.prow .sell{font-size:13px;color:var(--t2);min-width:0}
.prow .sell b{display:block;font-weight:500;color:var(--text);font-size:13px}
.fit{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:600;
  color:var(--green);background:var(--green-soft);border:1px solid var(--green-line);border-radius:6px;padding:2px 7px}
.fitbar{display:flex;align-items:center;gap:10px;padding:12px 16px;border:1px solid var(--green-line);
  background:var(--green-soft);border-radius:var(--r-lg);margin-bottom:18px;flex-wrap:wrap}
.fitbar b{font-size:14px}

/* ---- marketplace: card gallery (content area only) ---- */
.msec{margin-bottom:26px}
/* No top margin: the wraps above the first section head are empty until data
   lands, so a top margin collapses through them and pushes the whole page down
   past the 36px every other section opens with. `.msec`'s 26px bottom margin
   already does the separating. */
.msechead{display:flex;align-items:center;gap:11px;margin:0 0 16px}
.msechead .tick{width:3px;height:16px;border-radius:2px;background:var(--accent);flex:none}
.msechead h2{font-family:var(--dis);font-weight:600;font-size:17px;letter-spacing:-.02em;white-space:nowrap}
.msechead .rule{flex:1;height:1px;background:var(--border)}
.msechead .n{font:500 12px var(--mono);color:var(--t3)}
.msearch{position:relative;flex:0 1 300px;min-width:150px}
.msearch svg{position:absolute;left:11px;top:50%;transform:translateY(-50%);color:var(--t3);pointer-events:none}
.msearch input{width:100%;height:34px;padding:0 12px 0 33px;border:1px solid var(--border2);border-radius:var(--r);
  background:var(--surface);font-size:13.5px;color:var(--text);box-shadow:var(--sh-sm)}
.msearch input::placeholder{color:var(--t3)}
.msearch input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
@media(max-width:640px){.msearch{flex:1 1 100%;order:3}.msechead{flex-wrap:wrap}}

.msell{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-top:26px;padding:16px 20px;
  border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);box-shadow:var(--sh-sm)}
.msell b{font-family:var(--dis);font-weight:600;font-size:15px;display:block;margin-bottom:2px}
.msell .btn{margin-left:auto}

/* ---- marketplace Browse ⇄ Selling toggle ---- */
.mkt-viewtog{display:inline-flex;background:var(--surface2);border:1px solid var(--border);border-radius:10px;padding:3px;gap:2px}
.mkt-viewtog button{border:0;background:none;cursor:pointer;color:var(--t2);font:inherit;font-size:13.5px;font-weight:500;padding:7px 16px;border-radius:7px;transition:.15s}
.mkt-viewtog button.on{background:var(--surface);color:var(--text);box-shadow:var(--sh-sm)}

/* 'Only mine' toggle + browse card ownership */
.minetog{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border:1px solid var(--border2);border-radius:999px;
  background:var(--surface);font-size:12.5px;font-weight:500;color:var(--t2);box-shadow:var(--sh-sm);white-space:nowrap;cursor:pointer}
.minetog:hover{color:var(--text);border-color:var(--t3)}
.minetog.on{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.plcard{position:relative}
.plcard.own{border-color:var(--accent-line)}
.plcard.own:hover{border-color:var(--accent)}
.plyours{position:absolute;top:9px;right:9px;z-index:2;display:inline-flex;align-items:center;gap:4px;padding:3px 9px;border-radius:999px;
  background:rgba(255,255,255,.94);color:var(--accent-fg);font-family:var(--dis);font-size:10.5px;font-weight:700;letter-spacing:.06em;box-shadow:var(--sh-sm)}
.pledit{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;margin-top:10px;padding:7px 12px;
  border:1px solid var(--accent-line);border-radius:var(--r);background:var(--accent-soft);color:var(--accent-fg);
  font-family:var(--dis);font-weight:600;font-size:13px;cursor:pointer;transition:.16s var(--ease)}
.pledit:hover{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}

/* ---- Selling console ---- */
.sell-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap;margin-bottom:16px}
.sell-head h1{font-family:var(--dis);font-weight:700;font-size:24px;letter-spacing:-.03em}
.sell-acts{margin-left:auto;display:flex;gap:8px}
.sell-stats{display:grid;grid-template-columns:repeat(5,1fr);border:1px solid var(--border);border-radius:var(--r-xl);overflow:hidden;background:var(--surface);box-shadow:var(--sh-sm)}
.sell-stats .scell{padding:15px 18px;border-right:1px solid var(--border)}
.sell-stats .scell:last-child{border-right:none}
.scell .k{display:block;font-size:11px;font-weight:500;color:var(--t3);margin-bottom:3px}
.scell .v{font-family:var(--mono);font-size:19px;letter-spacing:-.03em}
.sell-nudge{display:flex;align-items:center;gap:11px;margin-top:16px;padding:11px 15px;border-radius:var(--r-lg);background:var(--accent-soft);border:1px solid var(--accent-line);font-size:13.5px;color:var(--accent-fg)}
.sell-nudge svg{flex:none}
.sell-nudge .btn{margin-left:auto}
.sell-tabs{display:flex;gap:2px;border-bottom:1px solid var(--border);margin-top:22px}
.stab{position:relative;padding:11px 14px;font-size:13.5px;font-weight:500;color:var(--t2);border:0;background:none;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px}
.stab:hover{color:var(--text)}
.stab.on{color:var(--accent-fg);border-bottom-color:var(--accent)}
.stab .c{font-family:var(--mono);font-size:11.5px;color:var(--t3);margin-left:6px}
.stab.on .c{color:var(--accent-fg)}
.sell-table{background:var(--surface);border:1px solid var(--border);border-top:none;border-radius:0 0 var(--r-xl) var(--r-xl);overflow:hidden;box-shadow:var(--sh-sm)}
.strow{display:grid;grid-template-columns:34px minmax(200px,2.4fr) 118px 96px 66px 66px 70px 96px 34px;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--border)}
.strow:last-child{border-bottom:0}
.strow.sthead{background:var(--surface2);font-size:11.5px;font-weight:600;color:var(--t3)}
.strow:not(.sthead):hover{background:var(--surface2)}
.strow.picked{background:var(--accent-soft)}
.strow.ended{opacity:.62}
.schk{width:16px;height:16px;accent-color:var(--accent);cursor:pointer}
.sitem{display:flex;align-items:center;gap:11px;min-width:0;text-align:left;background:none;border:0;cursor:pointer;padding:0}
.sth{width:52px;height:40px;flex:none;border-radius:8px;background:var(--surface3);background-size:cover;background-position:center}
.sth.none{background:#e9e9ee center/cover url(/assets/vehicle-placeholder.svg) no-repeat}
.stt{min-width:0}
.stt b{display:block;font-family:var(--dis);font-weight:600;font-size:14px;letter-spacing:-.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--text)}
.stt small{color:var(--t3);font-size:11.5px;font-family:var(--mono)}
.spricecell{display:flex;justify-content:flex-end}
.sprice{width:92px;padding:5px 8px;border:1px solid transparent;border-radius:8px;background:transparent;font-family:var(--mono);font-size:14px;text-align:right;color:var(--text)}
.sprice:hover:not(:disabled){border-color:var(--border2);background:var(--surface)}
.sprice:focus{outline:none;border-color:var(--accent);background:var(--surface);box-shadow:0 0 0 3px var(--accent-soft)}
.sprice:disabled{color:var(--t3)}
.scond{font-size:12.5px;color:var(--t2)}
.smetric{font-family:var(--mono);font-size:13.5px;color:var(--t2)}
.smetric.hot{color:var(--accent-fg);font-weight:500}
.skebab{width:28px;height:28px;border-radius:8px;display:grid;place-items:center;color:var(--t3);font-size:17px;line-height:1;cursor:pointer;background:none;border:0}
.skebab:hover{background:var(--surface3);color:var(--text)}
.smenu{position:fixed;z-index:200;min-width:184px;background:var(--surface);border:1px solid var(--border2);border-radius:var(--r);box-shadow:var(--sh-lg,var(--sh));padding:5px}
.smenu button{display:block;width:100%;padding:8px 10px;border-radius:7px;font-size:13.5px;text-align:left;background:none;border:0;cursor:pointer;color:var(--text)}
.smenu button:hover{background:var(--surface2)}
.smenu button.d{color:var(--red,#DC2626)}
.smenu button.d:hover{background:var(--red-soft,rgba(220,38,38,.08))}
.smenu hr{border:0;border-top:1px solid var(--border);margin:4px 0}
.sell-bulk{position:fixed;left:24px;right:24px;bottom:calc(20px + var(--floor,0px));z-index:120;display:none;align-items:center;gap:10px;padding:10px 14px;background:var(--text);color:var(--canvas);border-radius:var(--r-lg);box-shadow:var(--sh-lg,var(--sh))}
.sell-bulk.on{display:flex}
.sell-bulk b{font-family:var(--mono);font-size:14px}
.sell-bulk .sp{flex:1}
.sell-bulk button{padding:7px 13px;border-radius:8px;font-size:13px;font-weight:500;background:rgba(128,128,128,.22);color:inherit;border:0;cursor:pointer}
.sell-bulk button:hover{background:rgba(128,128,128,.34)}
.sell-bulk button.x{background:none;opacity:.7}
@media(max-width:1000px){
  .sell-stats{grid-template-columns:repeat(3,1fr)}
  .sell-stats .scell:nth-child(3n){border-right:none}
  .strow{grid-template-columns:32px minmax(160px,1fr) 110px 34px}
  .s-hide{display:none}
}
@media(max-width:640px){
  .sell-stats{grid-template-columns:repeat(2,1fr)}
  .sell-stats .scell:nth-child(2n){border-right:none}
  .sell-bulk{left:12px;right:12px;bottom:76px}
}

/* ---- vehicles: weighted-feed mosaic + selection + garage grid ----
   NB: tile classes are prefixed .vf* to avoid the legacy a.vt component
   (which carries its own aspect-ratio and would squash these tiles). */
.vh-topline{display:flex;align-items:center;gap:12px;margin:4px 0 16px}
.vh-topline h1{font-size:22px;font-weight:600;letter-spacing:-.02em}
.vh-count{font-size:13.5px;color:var(--t3)}
.vh-spacer{flex:1}
.vh-linka{font-size:13.5px;font-weight:500;color:var(--accent-fg)}
.vh-linka:hover{text-decoration:underline}

.vh-mosaic{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:187px;gap:12px;margin-bottom:14px}
/* fewer than 5 in the feed — an even row instead of a 2×2 lead with a gap */
.vh-mosaic.vh-row{grid-auto-rows:236px}
.vh-mosaic.vh-row.m1{grid-template-columns:minmax(0,760px)}
.vh-mosaic.vh-row.m2{grid-template-columns:repeat(2,1fr)}
.vh-mosaic.vh-row.m3{grid-template-columns:repeat(3,1fr)}
.vh-mosaic.vh-row.m4{grid-template-columns:repeat(4,1fr)}
.vft{position:relative;overflow:hidden;border-radius:12px;background:#1f2937;box-shadow:var(--sh-sm);display:block;
  min-height:0;transition:transform .2s var(--ease),box-shadow .2s var(--ease)}
.vft:hover{transform:translateY(-3px);box-shadow:var(--sh)}
.vft.lead{grid-column:span 2;grid-row:span 2}
.vf-photo{position:absolute;inset:0;background-size:cover;background-position:center;transform:scale(1.02);
  transition:transform .55s var(--ease)}
.vf-photo.noimg{background:#e9e9ee center/cover url(/assets/vehicle-placeholder.svg) no-repeat}
.vft:hover .vf-photo{transform:scale(1.07)}
.vf-scrim{position:absolute;inset:0;background:linear-gradient(to top,rgba(8,11,16,.88) 0%,rgba(8,11,16,.34) 42%,rgba(8,11,16,0) 72%)}
.vf-cap{position:absolute;left:16px;right:16px;bottom:14px;color:#fff}
.vf-cap h3{font-size:16px;font-weight:600;letter-spacing:-.01em;text-shadow:0 1px 3px rgba(0,0,0,.45)}
.vf-cap p{margin:2px 0 0;font-size:12.5px;color:rgba(255,255,255,.82)}
.vft.lead .vf-cap h3{font-size:26px}
.vft.lead .vf-cap p{font-size:14px;margin-top:4px}
.vf-meta{display:flex;align-items:center;gap:8px;margin-top:12px;color:rgba(255,255,255,.9);font-size:13px}
/* size + border only: the bubble itself is AMSR.avatar, which supplies its own
   background inline. Setting one here would be a second palette. */
.vf-av{width:24px;height:24px;border-radius:50%;border:1px solid rgba(255,255,255,.35);
  color:#fff;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:600;flex:none}
.vf-badge{position:absolute;top:12px;left:12px;background:rgba(255,255,255,.16);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,.28);color:#fff;border-radius:6px;padding:3px 9px;font-size:11.5px;font-weight:600}
.vf-flag{position:absolute;top:12px;right:12px;background:var(--accent);color:var(--accent-ink);border-radius:6px;padding:3px 9px;font-size:11.5px;font-weight:600}
.vh-mosaic-foot{display:flex;align-items:center;gap:10px;margin-bottom:34px}
.vh-mosaic-foot .dots{display:flex;gap:5px}
.vh-mosaic-foot .dots i{width:6px;height:6px;border-radius:50%;background:var(--border2)}
.vh-mosaic-foot .dots i:first-child{background:var(--accent);width:16px;border-radius:3px}

/* ---- Shop by vehicle / My Garage bar (theme-aware; overflow visible for combo popovers) ---- */
.vg-bar{position:relative;background:var(--surface);border:1px solid var(--border);border-radius:14px;box-shadow:var(--sh);margin-bottom:34px}
.vg-row{display:flex;align-items:center;gap:14px;padding:13px 16px;flex-wrap:wrap}
.vg-brand{display:flex;align-items:center;gap:9px;padding-right:2px}
.vg-brand svg{width:21px;height:21px;color:var(--accent);flex:none}
.vg-brand-label{font-family:var(--dis);font-weight:600;font-size:14px;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap;color:var(--t2)}
.vg-picker{display:flex;align-items:center;gap:10px;flex:1 1 auto;min-width:0;flex-wrap:wrap}
/* themed comboboxes, sized to the bar */
.vg-combo{flex:1 1 120px;min-width:108px}
.vg-combo .combo-field{height:44px;margin-top:0;padding:0 13px;border:1px solid var(--border2);border-radius:9px;
  background:var(--surface);font-size:14px;font-weight:500;transition:border-color .15s,box-shadow .15s}
.vg-combo .combo-val.ph{font-weight:450;color:var(--t3)}
.vg-combo.open .combo-field{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.vg-combo.off{opacity:1}
.vg-combo.off .combo-field{background:var(--surface2);color:var(--t3);cursor:not-allowed}
.vg-combo .combo-pop{left:0;right:auto}
/* fitment tell-tale lights — one segment lights per completed step */
.vg-lights{display:flex;gap:5px;padding:0 2px;flex:none}
.vg-light{width:16px;height:5px;border-radius:3px;background:var(--border2);opacity:.7;transition:opacity .16s,background .16s,box-shadow .16s}
.vg-light.on{background:var(--accent);opacity:1;box-shadow:0 0 8px var(--accent-soft)}
/* primary button — ignites when all three lights are on */
.vg-go{font-family:var(--dis);font-weight:700;font-size:14px;letter-spacing:.08em;text-transform:uppercase;color:var(--t3);
  background:transparent;border:1px solid var(--border2);border-radius:9px;padding:11px 18px;cursor:not-allowed;flex:none;transition:all .16s var(--ease)}
.vg-go.ready{color:var(--accent-ink);background:var(--accent);border-color:var(--accent);cursor:pointer;box-shadow:0 0 14px var(--accent-soft)}
.vg-go.ready:hover{filter:brightness(1.06)}
/* active-vehicle state */
.vg-active{display:none;align-items:center;gap:12px;flex:1 1 auto;min-width:0;flex-wrap:wrap}
.vg-active.show{display:flex}
.vg-dot{width:8px;height:8px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent-soft);flex:none}
.vg-active-name{font-family:var(--dis);font-weight:600;font-size:18px;letter-spacing:.03em;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vg-active-note{font-size:13px;color:var(--t3);white-space:nowrap}
.vg-active .btn{margin-left:2px}
.vg-textbtn{font:500 13px/1 var(--ui);color:var(--accent-fg);background:none;border:0;padding:6px 2px;cursor:pointer;text-decoration:underline;text-underline-offset:3px}
.vg-textbtn:hover{opacity:.85}
.vg-textbtn.dim{color:var(--t3)}
/* garage button + count */
.vg-garage-btn{display:flex;align-items:center;gap:8px;font:500 14px/1 var(--ui);color:var(--text);background:transparent;
  border:1px solid var(--border2);border-radius:9px;padding:10px 13px;cursor:pointer;flex:none;margin-left:auto;transition:.16s}
.vg-garage-btn:hover{border-color:var(--t3);background:var(--surface2)}
.vg-garage-btn svg{width:17px;height:17px;color:var(--t3)}
.vg-count{font:600 11px/1 var(--ui);color:var(--accent-ink);background:var(--accent);border-radius:9px;min-width:18px;height:18px;
  display:inline-flex;align-items:center;justify-content:center;padding:0 5px}
.vg-count.zero{background:var(--surface3);color:var(--t3)}
.vg-caption{font-size:12px;color:var(--t3);padding:0 16px 12px;margin:-2px 0 0}
/* garage popover */
.vg-pop{position:absolute;top:calc(100% + 8px);right:14px;width:290px;background:var(--surface);border:1px solid var(--border2);
  border-radius:12px;box-shadow:var(--sh-lg,var(--sh));padding:6px;z-index:80;opacity:0;transform:translateY(-4px);pointer-events:none;transition:opacity .14s,transform .14s}
.vg-pop.open{opacity:1;transform:none;pointer-events:auto}
.vg-pop-title{font-family:var(--dis);font-weight:600;font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--t3);padding:8px 10px 6px}
.vg-pop-list{list-style:none;margin:0;padding:0;max-height:220px;overflow:auto}
.vg-pop-item{display:flex;align-items:center;gap:8px;border-radius:8px;padding:2px 4px 2px 10px}
.vg-pop-item:hover{background:var(--surface2)}
.vg-pop-pick{display:flex;align-items:center;gap:10px;flex:1;min-width:0;background:none;border:0;color:var(--text);font:500 14px/1.2 var(--ui);text-align:left;padding:9px 0;cursor:pointer}
.vg-pop-pick .dot{width:8px;height:8px;border-radius:50%;border:1.5px solid var(--t3);flex:none}
.vg-pop-item.active .dot{background:var(--accent);border-color:var(--accent);box-shadow:0 0 6px var(--accent-soft)}
.vg-pop-pick .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.vg-pop-remove{background:none;border:0;color:var(--t3);font-size:17px;line-height:1;padding:8px 9px;cursor:pointer;border-radius:6px;flex:none}
.vg-pop-remove:hover{color:var(--red,#DC2626);background:var(--red-soft,rgba(220,38,38,.08))}
.vg-pop-empty{font-size:13px;color:var(--t3);padding:4px 10px 10px;line-height:1.45}
.vg-pop-add{width:100%;font:500 13px/1 var(--ui);color:var(--accent-fg);background:none;border:0;border-top:1px solid var(--border);margin-top:4px;padding:11px 10px 9px;text-align:left;cursor:pointer}
.vg-pop-add:hover{opacity:.85}
@media(max-width:880px){ .vg-picker,.vg-active{order:5;flex-basis:100%} .vg-go{flex:1 1 auto} }
@media(max-width:520px){ .vg-combo{flex:1 1 100%} .vg-lights{display:none} }

.vh-sechead{display:flex;align-items:center;gap:12px;margin-bottom:14px}
.vh-sechead h2{font-size:16px;font-weight:600;letter-spacing:-.01em}
.vh-filterbar{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:16px}
.vh-fchip{font:inherit;font-size:13px;font-weight:500;color:var(--t2);cursor:pointer;background:var(--surface);border:1px solid var(--border2);border-radius:999px;padding:6px 14px;transition:.15s}
.vh-fchip:hover{border-color:var(--t3)}
.vh-fchip .n{color:var(--t3);font-size:12px;margin-left:5px}
.vh-fchip[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.vh-fchip[aria-pressed="true"] .n{color:rgba(255,255,255,.8)}
.vh-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
.vcard2{position:relative;background:var(--surface);border:1px solid var(--border);border-radius:10px;overflow:hidden;box-shadow:var(--sh-sm);display:flex;flex-direction:column;
  transition:border-color .18s,box-shadow .18s,transform .18s}
.vcard2:hover{border-color:var(--border2);box-shadow:var(--sh);transform:translateY(-3px)}
.vc-thumb{position:relative;aspect-ratio:4/3;overflow:hidden;background:#1f2937;display:block}
.vcard2 .vf-photo{transition:transform .5s var(--ease)}
.vcard2:hover .vf-photo{transform:scale(1.08)}
.vc-thumb .vf-cap{left:13px;right:13px;bottom:11px}
.vc-thumb .vf-cap h3{font-size:15px}
.vc-body{padding:11px 13px 13px;display:flex;flex-direction:column;gap:10px;flex:1}
.vc-owner{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--t2)}
/* size only — background comes from AMSR.avatar, inline (see .vf-av above) */
.vc-av{width:21px;height:21px;border-radius:50%;color:#fff;flex:none;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:600}
.vc-dot{color:var(--border2)}
.vc-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:auto}
.vc-chips span{font-size:11.5px;color:var(--t2);background:var(--surface2);border-radius:5px;padding:3px 7px}
@media(max-width:1080px){.vh-grid{grid-template-columns:repeat(3,1fr)}.vh-mosaic{grid-auto-rows:158px}}
@media(max-width:820px){
  .vh-mosaic{grid-template-columns:repeat(2,1fr);grid-auto-rows:150px}
  .vft.lead{grid-column:span 2;grid-row:span 2}
  .vh-grid{grid-template-columns:repeat(2,1fr)}
  .vh-filters{grid-template-columns:1fr 1fr}
  .vh-filters .btn{grid-column:1/-1}
}
@media(max-width:520px){
  .vh-mosaic{grid-template-columns:1fr;grid-auto-rows:150px}
  .vft.lead{grid-column:span 1;grid-row:span 2}
  .vft:nth-child(n+4){display:none}
  .vh-grid{grid-template-columns:1fr}
  .vh-filters{grid-template-columns:1fr}
}

/* featured spotlight */
.mhero{border:1px solid var(--border);border-radius:var(--r-xl);overflow:hidden;background:var(--surface);box-shadow:var(--sh);margin-bottom:22px}
.mhero-frame{position:relative;aspect-ratio:21/8;min-height:220px;background:var(--surface3)}
.mhero-frame .photo{position:absolute;inset:0;border-radius:0;width:100%;height:100%}
.mhero-frame::after{content:"";position:absolute;inset:0;z-index:4;
  background:linear-gradient(90deg,rgba(8,8,10,.86) 0%,rgba(8,8,10,.6) 40%,rgba(8,8,10,.08) 74%,transparent 100%);pointer-events:none}
.mhero-text{position:absolute;inset:0;z-index:5;display:flex;flex-direction:column;justify-content:flex-end;
  padding:clamp(18px,3vw,38px);color:#fff;max-width:min(620px,74%)}
.mflag{align-self:flex-start;background:var(--accent);color:var(--accent-ink);border-radius:99px;padding:4px 11px;
  font-family:var(--dis);font-size:10.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;margin-bottom:13px}
.mhero-text h2{font-family:var(--dis);font-weight:700;font-size:clamp(24px,3.4vw,42px);line-height:1.04;letter-spacing:-.03em;color:#fff;text-wrap:balance}
.mhero-text h2 span{display:block;font-weight:400;font-size:.5em;color:rgba(255,255,255,.72);margin-top:8px;letter-spacing:-.01em}
.mhero-by{display:flex;align-items:center;gap:9px;margin-top:15px;font-size:13.5px;color:rgba(255,255,255,.85)}
.mhero-by .av{width:26px;height:26px;border-radius:8px;background:rgba(255,255,255,.16);display:grid;place-items:center;
  font-family:var(--dis);font-weight:700;font-size:11px;color:#fff}
.mstrip{display:grid;grid-template-columns:repeat(4,1fr) auto;border-top:1px solid var(--border)}
.mcell{padding:13px 18px;border-right:1px solid var(--border);min-width:0}
.mcell .k{display:block;font-size:11px;font-weight:500;color:var(--t3);letter-spacing:.04em;margin-bottom:3px}
.mcell .v{font-family:var(--mono);font-size:15px;letter-spacing:-.02em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}
.mcell.act{display:flex;align-items:center;gap:12px;border-right:none;background:var(--accent-soft);padding-right:clamp(16px,3vw,38px)}
.mcell.act .ask .v{color:var(--accent-fg);font-size:19px}

/* featured reel */
.mreel{display:flex;gap:14px;overflow-x:auto;padding:2px 2px 10px;scroll-snap-type:x proximity}
.mreel .plcard{flex:0 0 262px;scroll-snap-align:start}
.mreel::-webkit-scrollbar{height:6px}
.mreel::-webkit-scrollbar-thumb{background:var(--border2);border-radius:99px}

/* condition chips */
.mchips{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:18px}
.mchip{padding:6px 13px;border:1px solid var(--border2);border-radius:99px;background:var(--surface);
  font-size:13px;font-weight:500;color:var(--t2);box-shadow:var(--sh-sm);transition:.16s var(--ease);cursor:pointer}
.mchip:hover{color:var(--text);border-color:var(--t3)}
.mchip.on{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}

/* listing cards */
.plgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:16px}
.plcard{display:block;text-align:left;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  overflow:hidden;box-shadow:var(--sh-sm);text-decoration:none;color:var(--text);
  transition:box-shadow .22s var(--ease),transform .22s var(--ease),border-color .22s var(--ease)}
.plcard:hover{box-shadow:var(--sh);transform:translateY(-3px);border-color:var(--border2)}
.plcard>.photo{border-radius:0;aspect-ratio:4/3;display:block}
.plcard .ph-img{transition:transform .5s var(--ease)}
.plcard:hover .ph-img{transform:scale(1.045)}
.plbody{padding:12px 13px 14px}
.plcat{font-size:11.5px;font-weight:500;color:var(--accent-fg)}
.plbody h3{font-family:var(--dis);font-weight:600;font-size:15.5px;line-height:1.25;letter-spacing:-.015em;margin:3px 0 5px}
.plfit{font-size:12.5px;color:var(--t2);line-height:1.4;min-height:1.4em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.plfit.mono{font-family:var(--mono);font-size:12px;color:var(--t3)}
.plfoot{display:flex;align-items:flex-end;justify-content:space-between;gap:10px;margin-top:11px;padding-top:10px;border-top:1px solid var(--border)}
.plprice{font-family:var(--dis);font-size:18px;font-weight:600;letter-spacing:-.03em}
.plship{font-size:11.5px;color:var(--t3);text-align:right;line-height:1.3}
.plempty{grid-column:1/-1;padding:44px 24px;text-align:center;color:var(--t2);
  background:var(--surface);border:1px dashed var(--border2);border-radius:var(--r-lg)}
.plempty b{font-size:15px;color:var(--text)}
@media(max-width:820px){
  .mstrip{grid-template-columns:repeat(2,1fr)}
  .mcell:nth-child(2n){border-right:none}
  .mcell{border-bottom:1px solid var(--border)}
  .mcell.act{grid-column:1/-1;border-bottom:none}
  .mhero-frame{aspect-ratio:16/10}
  .mhero-frame::after{background:linear-gradient(0deg,rgba(8,8,10,.9) 0%,rgba(8,8,10,.5) 46%,rgba(8,8,10,.1) 100%)}
  .mhero-text{max-width:100%}
}

/* ---- auth gate ---- */
/* The column both auth screens stand in: the gate at /join and the sign-in
   screen at /signin. They are the same page with a different headline — PHP
   draws the words, the OAuth buttons and the way through to /login, and the
   bundle fills one empty .auth host with the form — so they share the wrapper
   rather than keeping two sets of selectors true to each other. */
.gatewrap{max-width:430px;margin:0 auto}
.gatectx{display:flex;gap:12px;align-items:flex-start;padding:14px 16px;border:1px solid var(--accent-line);
  background:var(--accent-soft);border-radius:12px;margin-bottom:20px}
.gatectx .ic2{width:30px;height:30px;border-radius:8px;background:var(--accent);color:var(--accent-ink);display:grid;place-items:center;flex:none}
.gatectx .kx{font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--accent-fg)}
.gatectx b{display:block;font-size:14.5px;margin-top:3px}
.gh{text-align:center;margin-bottom:22px}
.gh h1{font-size:23px}
.gh p{font-size:14px;color:var(--t2);margin-top:8px}
.oauth{display:grid;gap:8px}
.oauth .btn{height:42px;justify-content:center}
.gsmall{font-size:12px;color:var(--t3);text-align:center;margin-top:16px;line-height:1.55}
/* The way back for somebody who already has an account. It is the one thing in
   this block anybody clicks, so it does not get the muted colour the
   reassurance around it wears. */
.gsmall a{color:var(--text);font-weight:500;text-decoration:none}
.gsmall a:hover{text-decoration:underline}
.gsmall .gsignin{display:inline-block;font-size:13px;margin-bottom:10px}

/* ---- toast ---- */
.toast{position:fixed;left:50%;bottom:calc(26px + var(--floor,0px));transform:translate(-50%,20px);z-index:120;
  display:flex;align-items:flex-start;gap:10px;padding:12px 18px;border-radius:14px;max-width:min(560px,90vw);
  line-height:1.5;text-align:left;
  background:var(--text);color:var(--canvas);font-size:13.5px;font-weight:500;
  box-shadow:var(--sh-lg);opacity:0;pointer-events:none;transition:all .3s var(--ease)}
.toast.on{opacity:1;transform:translate(-50%,0)}
.toast svg{color:var(--green)}
/* THE TOAST THAT WAITS (toastHold, js/04-composer-detail/00-*). An upload takes
   real time and toast()'s 2.8 seconds are shorter than the thing they describe,
   so the one place on this site that says "still going" is the same strip with
   a spinner in place of the tick. Its own colours, because the toast is dark in
   both themes and .ams-spin's default border is drawn for a photo tile. */
.toast .ams-spin{width:15px;height:15px;flex:none;margin-top:2px;border-width:2px;
  border-color:color-mix(in srgb,var(--canvas) 30%,transparent);border-top-color:var(--canvas)}

/* ---- kpi strip ---- */
.kpi{display:grid;grid-template-columns:repeat(4,1fr);border:1px solid var(--border);border-radius:var(--r-lg);
  overflow:hidden;background:var(--surface);box-shadow:var(--sh-sm)}
.kpi div{padding:16px 18px;border-right:1px solid var(--border)}
.kpi div:last-child{border-right:0}
.kpi b{display:block;font-family:var(--dis);font-size:20px;font-weight:600;letter-spacing:-.03em}
.kpi span{font-size:12.5px;color:var(--t2)}

@media(max-width:1040px){
  .split{grid-template-columns:1fr}
  .split .left{max-height:none;border-right:0;border-bottom:1px solid var(--border);order:2}
  .split .right{order:1}
  .mapwrap{position:static;height:340px}
  .phead2{display:none}
  .prow{grid-template-columns:74px minmax(0,1fr);grid-auto-rows:auto;row-gap:8px}
  .prow .price,.prow .sell,.prow .act2{grid-column:2}
  .kpi{grid-template-columns:1fr 1fr}
  .kpi div:nth-child(2){border-right:0}
  .kpi div:nth-child(-n+2){border-bottom:1px solid var(--border)}
}
@media(max-width:680px){
  .vsw{bottom:76px;max-width:calc(100vw - 96px);padding:3px}
  .vsw span{display:none}
  .vsw button{padding:7px 10px;font-size:12px}
  .vsw .thm{padding:7px 8px}
  body:not(.member) .vsw{bottom:16px}
  .toolbar .in{padding:10px 0}
  .tcount{margin-left:0;width:100%}
  .vrow{flex-wrap:wrap}
  .vrow .photo{width:56px;height:56px}
  .vrow .dist{text-align:left}
}

/* ---------- vendor filters ---------- */
.trow{display:flex;align-items:center;gap:8px;padding:11px 0;flex-wrap:wrap}
.trow+.trow{border-top:1px solid var(--border)}
.miniymm{display:flex;border:1px solid var(--border2);border-radius:10px;
  background:var(--surface);box-shadow:var(--sh-sm)}
.miniymm .mf{display:flex;flex-direction:column;justify-content:center;padding:4px 11px;
  border-right:1px solid var(--border);cursor:pointer;min-width:98px}
.miniymm .mf:last-child{border-right:0}
.miniymm .mf>span:first-child{font-size:10px;font-weight:600;color:var(--t3)}
.miniymm select{appearance:none;border:0;background:none;padding:0;margin-top:1px;
  font:500 13px var(--ui);color:var(--text);cursor:pointer;width:100%}
.miniymm select:focus{outline:none}
.miniymm .mf.off{opacity:.45;pointer-events:none}
.tog{display:inline-flex;align-items:center;gap:8px;height:34px;padding:0 12px;border:1px solid var(--border2);
  border-radius:9px;background:var(--surface);font-size:13px;font-weight:500;color:var(--t2);
  cursor:pointer;box-shadow:var(--sh-sm);transition:all .16s}
.tog.on{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent-fg)}
.tog i{width:15px;height:15px;border:1.5px solid var(--border2);border-radius:4px;display:grid;place-items:center;flex:none;color:transparent}
.tog.on i{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.covnote{display:flex;align-items:center;gap:11px;padding:13px 15px;border:1px solid var(--border);
  border-radius:12px;background:var(--surface2);margin-bottom:18px;font-size:13.5px;color:var(--t2);flex-wrap:wrap}
.covnote b{color:var(--text);font-weight:500}
.vrow.nofit{opacity:.6}
.vrow.nofit .photo{filter:grayscale(1)}
.nofitb{font-size:11px;font-weight:600;color:#B91C1C;background:#FEF2F2;border:1px solid #FECACA;border-radius:6px;padding:2px 7px}
body.dark .nofitb{color:#FCA5A5;background:rgba(248,113,113,.1);border-color:rgba(248,113,113,.26)}
.covbox{display:grid;grid-template-columns:1fr 1fr;gap:0;border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface)}
.covbox>div{padding:15px 17px}
.covbox>div:first-child{border-right:1px solid var(--border)}
.covbox h5{font-size:11px;font-weight:600;color:var(--t3);margin:0 0 9px}
@media(max-width:680px){.miniymm{width:100%}.miniymm .mf{flex:1;min-width:0}.covbox{grid-template-columns:1fr}
  .covbox>div:first-child{border-right:0;border-bottom:1px solid var(--border)}}

/* ================= themed dropdowns ================= */
[hidden]{display:none!important}
.selnative{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;clip:rect(0 0 0 0)}
.sel{position:relative;display:inline-flex;min-width:0}
.selbtn{display:flex;align-items:center;gap:8px;width:100%;min-width:0;cursor:pointer;
  font:500 13px var(--ui);color:var(--t2);transition:border-color .16s,background .16s}
.selbtn .v{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left}
.selbtn .cv{flex:none;width:9px;height:9px;border-right:1.5px solid var(--t3);border-bottom:1.5px solid var(--t3);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .18s var(--ease)}
.sel.open .selbtn .cv{transform:rotate(-135deg) translate(-3px,-3px)}
.selbtn .ph{color:var(--t3);font-weight:400}

/* boxed variant (filter bars) */
.sel--box .selbtn{height:34px;padding:0 12px;border:1px solid var(--border2);border-radius:9px;
  background:var(--surface);box-shadow:var(--sh-sm)}
.sel--box .selbtn:hover{background:var(--surface2)}
.sel.open.sel--box .selbtn{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}

/* field variant (forms) */
.sel--field{width:100%}
.sel--field .selbtn{height:40px;padding:0 13px;border:1px solid var(--border2);border-radius:var(--r);
  background:var(--surface);font-size:14px;color:var(--text)}
.sel--field .selbtn:hover{border-color:var(--border2);background:var(--surface2)}
.sel.open.sel--field .selbtn{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft);background:var(--surface)}

/* bare variant (YMM cells) */
.sel--bare{width:100%}
.sel--bare .selbtn{padding:0;border:0;background:none;font:500 14.5px var(--ui);color:var(--text);margin-top:2px}
.miniymm .sel--bare .selbtn{font-size:13px}
.sel--bare .selbtn .cv{width:7px;height:7px;border-width:1.4px}

/* popover */
.pop{position:absolute;z-index:200;top:calc(100% + 6px);left:0;min-width:100%;
  background:var(--surface);border:1px solid var(--border2);border-radius:12px;
  box-shadow:var(--sh-lg);padding:5px;max-height:290px;overflow-y:auto;overscroll-behavior:contain;
  animation:popin .16s var(--ease)}
.pop.right{left:auto;right:0}
/* Select popovers are positioned in JS as fixed, so an ancestor with
   overflow:hidden (the hero) can never clip them and they always sit on top. */
.sel .pop{position:fixed;z-index:1200;top:auto;left:auto;right:auto;min-width:0}
@keyframes popin{from{opacity:0;transform:translateY(-4px) scale(.985)}to{opacity:1;transform:none}}
.pop::-webkit-scrollbar{width:9px}
.pop::-webkit-scrollbar-thumb{background:var(--border2);border-radius:99px;border:3px solid var(--surface)}
.popopt{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:8px;cursor:pointer;
  font-size:13.5px;color:var(--t2);white-space:nowrap;line-height:1.3}
.popopt:hover,.popopt.cur{background:var(--surface2);color:var(--text)}
.popopt.on{color:var(--text);font-weight:500}
.popopt .ck{width:14px;flex:none;color:var(--accent);opacity:0}
.popopt.on .ck{opacity:1}
.pophead{font-size:10.5px;font-weight:600;letter-spacing:.06em;color:var(--t3);padding:9px 10px 5px}
.popsep{height:1px;background:var(--border);margin:5px 0}

/* workspace menu */
.wsw{cursor:pointer;position:relative}
.wsw:hover{background:var(--surface3)}
.wsmenu{min-width:262px}
.wsrow{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:8px;cursor:pointer}
.wsrow:hover{background:var(--surface2)}
.wsrow .sq{width:26px;height:26px;border-radius:7px;flex:none;display:grid;place-items:center;
  font:600 10px var(--mono);color:#fff}
.wsrow .nm{font-size:13.5px;font-weight:500;line-height:1.25}
.wsrow .mt{font-size:11.5px;color:var(--t3)}
.wsrow .ck{margin-left:auto;color:var(--accent);opacity:0}
.wsrow.on .ck{opacity:1}

/* The account menu moved to 18-header-controls.php with the rest of the bar's
   controls. It used to be a `.pop` — the select code's popover — and kept a
   block here that sized it, anchored it and styled its rows. It is a `.nb-menu`
   now, and two stylesheets anchoring the same element is how it ended up four
   pixels past the right edge of a phone: this one still said `right:0` against
   a wrapper the other one had already offset. */
.usermenu-wrap{position:relative;display:inline-flex;flex:none}

/* ================= composer ================= */
/* the step tracker sticks under the nav so it stays on screen while you scroll
   the form for the current step */
.steps2{display:flex;overflow-x:auto;scrollbar-width:none;
  position:sticky;top:var(--navh,60px);z-index:15;margin:0 0 4px;padding:16px 0 2px;
  background:color-mix(in srgb,var(--canvas) 92%,transparent);backdrop-filter:blur(9px) saturate(1.4);
  border-bottom:1px solid var(--border)}
.steps2::-webkit-scrollbar{display:none}
.stp{display:flex;align-items:center;gap:9px;padding:0 0 16px;color:var(--t3);font-size:13.5px;font-weight:500;white-space:nowrap}
.stp .n2{width:24px;height:24px;border-radius:999px;border:1.5px solid var(--border2);display:grid;place-items:center;font-size:11.5px;flex:none}
.stp.on{color:var(--text)}
.stp.on .n2{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.stp.done{color:var(--t2)}
.stp.done .n2{background:var(--green);border-color:var(--green);color:#fff}
.stp::after{content:"";width:30px;height:1px;background:var(--border2);margin:0 14px}
.stp:last-child::after{display:none}
.cmp-body{display:block;padding:22px 0 0}
/* /post two-column layout: composer on the left, drafts + preview on the right */
.post-grid{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:28px;align-items:start;margin-top:6px}
.post-main{min-width:0}
.post-rail{position:sticky;top:76px;display:flex;flex-direction:column;gap:16px}
.post-rail-card{border:1px solid var(--border);border-radius:14px;background:var(--surface);padding:16px}
.draft-row{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:9px;cursor:pointer;transition:background .12s var(--ease)}
.draft-row:hover{background:var(--surface2)}
.draft-row.on{background:var(--accent-soft,var(--surface2))}
.draft-row-b{min-width:0;flex:1;display:flex;flex-direction:column;gap:1px}
.draft-row-b b{font-size:13px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.draft-row-b span{font-size:11.5px;color:var(--t3)}
.draft-x{flex:none;display:flex;align-items:center;justify-content:center;width:26px;height:26px;border:0;border-radius:6px;background:none;color:var(--t3);cursor:pointer;line-height:1;opacity:.5;transition:opacity .12s var(--ease),background .12s var(--ease),color .12s var(--ease)}
.draft-row:hover .draft-x,.draft-row:focus-within .draft-x{opacity:.85}
.draft-x:hover{background:var(--surface2);color:#E5484D}
@media(max-width:900px){.post-grid{grid-template-columns:1fr}.post-rail{position:static}}
.fgrid{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.fld.full{grid-column:1/-1}
.fld .hint{font-size:12.5px;color:var(--t3);margin-top:7px;line-height:1.5}
.fld .req{color:var(--accent);margin-left:3px}
.fsec{margin-bottom:26px}
.fsec>h3{font-size:16px;margin-bottom:4px}
.fsec>p.sub3{font-size:13.5px;color:var(--t2);margin-bottom:18px}
.drop{border:1.5px dashed var(--border2);border-radius:12px;padding:30px 20px;text-align:center;
  background:var(--surface2);cursor:pointer;transition:all .18s var(--ease)}
.drop:hover{border-color:var(--accent);background:var(--accent-soft)}
.drop b{display:block;font-size:14.5px}
.drop span{display:block;font-size:13px;color:var(--t2);margin-top:5px}
.dropgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-top:10px}
.dropgrid .photo{aspect-ratio:1;border-radius:9px}
.dropgrid .rm{position:absolute;top:5px;right:5px;z-index:5;width:20px;height:20px;border-radius:999px;
  background:rgba(8,8,10,.66);color:#fff;display:grid;place-items:center;font-size:12px;line-height:1}
/* the Back / Continue actions stay pinned to the bottom of the viewport so the
   next step is always one reach away, no scrolling back down */
.cmp-foot{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  position:sticky;bottom:0;z-index:14;margin-top:28px;padding:16px 0;
  border-top:1px solid var(--border);
  background:color-mix(in srgb,var(--canvas) 92%,transparent);backdrop-filter:blur(9px) saturate(1.4)}
.draft{font-size:12.5px;color:var(--t3);display:inline-flex;align-items:center;gap:7px}
.draft .dt{width:6px;height:6px;border-radius:50%;background:var(--green)}
/* `.cmp-types` and `.tcard` were the /post chooser's own card, drawn in JS from
   a list that lived there too. Both are gone: the chooser is PHP now
   (views/app/page-submit.php -> CreateMenu::tiles) and wears the tile every
   Create surface wears, in views/app/css/30-create-modal.php. A rule with no
   markup left under it is the shape the next chooser gets built out of. */
.prevcard{border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);box-shadow:var(--sh-sm)}
.prevcard .photo{border-radius:0;aspect-ratio:16/10}
.prevcard .bd2{padding:14px 16px 16px}
.prevcard h4{font-size:15px;line-height:1.35}
.prevempty{color:var(--t3)}
/* vehicle tile picker — the visual "which car is this mod on" grid */
.vtiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(158px,1fr));gap:12px}
.vtile{position:relative;border:1px solid var(--border);border-radius:12px;background:var(--surface);
  padding:0;overflow:hidden;cursor:pointer;text-align:left;box-shadow:var(--sh-sm);
  transition:transform .16s var(--ease),box-shadow .16s var(--ease),border-color .16s var(--ease)}
.vtile:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--accent-line)}
.vtile.on{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}
.vtile-ph{position:relative;display:block;aspect-ratio:16/10;background:#e9e9ee 50%/cover no-repeat}
.vtile-noimg{position:absolute;inset:0;background:#e9e9ee 50%/cover url(/assets/vehicle-placeholder.svg) no-repeat}
.vtile-ck{position:absolute;top:8px;right:8px;width:22px;height:22px;border-radius:999px;background:var(--accent);
  color:var(--accent-ink);display:grid;place-items:center;opacity:0;transform:scale(.7);
  transition:opacity .14s var(--ease),transform .14s var(--ease)}
.vtile.on .vtile-ck{opacity:1;transform:scale(1)}
.vtile-b{display:block;padding:9px 11px 11px}
.vtile-b b{display:block;font-size:13.5px;font-weight:600;letter-spacing:-.01em;line-height:1.3;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vtile-b span{display:block;font-size:12px;color:var(--t3);margin-top:2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vtiles-empty{border:1.5px dashed var(--border2);border-radius:12px;padding:22px;text-align:center;background:var(--surface2)}
.vtile-add{border-style:dashed;background:var(--surface2)}
.vtile-add .vtile-b b{color:var(--t1)}
.vtile-add .vtile-b span{color:var(--t3)}
.vtile-add-ph{display:grid;place-items:center;background:var(--surface2);border-bottom:1px solid var(--border)}
.vtile-add-ic{width:42px;height:42px;border-radius:11px;display:grid;place-items:center;
  background:var(--accent-soft);border:1px solid var(--accent-line);color:var(--accent-fg)}
@media(max-width:1040px){.cmp-body{grid-template-columns:1fr;gap:28px}}
@media(max-width:680px){.fgrid{grid-template-columns:1fr}.dropgrid{grid-template-columns:repeat(3,1fr)}.vtiles{grid-template-columns:repeat(2,1fr)}}

/* ================= vehicle spine ================= */
.vsec{margin-bottom:36px}
.vsec-h{display:flex;align-items:flex-end;justify-content:space-between;gap:14px;margin-bottom:16px;flex-wrap:wrap}
.vsec-h h3{font-size:19px}
.vsec-h p{font-size:13.5px;color:var(--t2);margin-top:5px}
.empty{text-align:center;padding:40px 24px;border:1.5px dashed var(--border2);border-radius:var(--r-lg);background:var(--surface2)}
.empty b{display:block;font-size:15.5px;font-family:var(--dis);letter-spacing:-.022em}
.empty p{font-size:13.5px;color:var(--t2);margin:7px auto 15px;max-width:42ch;line-height:1.55}
.gaps{border:1px solid var(--accent-line);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);box-shadow:var(--sh-sm)}
.gaps .gh2{padding:16px 18px;border-bottom:1px solid var(--border);background:var(--accent-soft)}
.gaps .gh2 h3{font-size:16px;color:var(--accent-fg)}
.gaps .gh2 p{font-size:13.5px;color:var(--accent-fg);opacity:.85;margin-top:4px}
.gap{display:flex;align-items:center;gap:14px;padding:13px 18px;border-bottom:1px solid var(--border)}
.gap:last-child{border-bottom:0}
.gap .gi{width:30px;height:30px;border-radius:8px;background:var(--surface2);border:1px solid var(--border);
  display:grid;place-items:center;color:var(--t3);flex:none;font-size:12px;font-weight:600}
.gap.has .gi{background:var(--green-soft);border-color:var(--green-line);color:var(--green)}
.gap .gt{flex:1;min-width:0}
.gap .gt b{font-size:14px;font-weight:500}
.gap .gt span{display:block;font-size:12.5px;color:var(--t3);margin-top:2px}
.gapbar{height:6px;background:var(--surface3);border-radius:99px;overflow:hidden;margin-top:12px}
.gapbar i{display:block;height:100%;background:var(--accent);border-radius:99px;transition:width .6s var(--ease)}
.oplabel{font-size:10.5px;font-weight:600;color:var(--t3);border:1px solid var(--border2);border-radius:5px;
  padding:2px 6px;cursor:help}

/* ================= featured placement ================= */
.slabel{display:flex;align-items:center;gap:9px;padding:9px 16px;background:var(--accent-soft);
  border-bottom:1px solid var(--accent-line);font-size:11px;font-weight:600;color:var(--accent-fg)}
.slabel .why{margin-left:auto;font-weight:500;font-size:11.5px;color:var(--accent-fg);
  text-decoration:underline;text-underline-offset:2px;cursor:pointer;opacity:.8}
.slabel .why:hover{opacity:1}
.slabel2{padding:9px 16px;background:var(--surface2);border-top:1px solid var(--border);
  border-bottom:1px solid var(--border);font-size:11px;font-weight:600;color:var(--t3)}
.prow.promo,.vrow.promo{background:linear-gradient(90deg,var(--accent-soft),transparent 60%);
  box-shadow:inset 3px 0 0 var(--accent)}
.prow.promo:hover,.vrow.promo:hover{background:linear-gradient(90deg,var(--accent-soft),var(--surface2) 60%)}
.ftag{display:inline-flex;align-items:center;gap:4px;font-size:10.5px;font-weight:600;color:var(--accent-fg);
  background:var(--surface);border:1px solid var(--accent-line);border-radius:5px;padding:2px 6px}
.oplabel{font-size:10.5px;font-weight:600;color:var(--t3);border:1px solid var(--border2);border-radius:5px;
  padding:2px 6px;cursor:help}

/* ================= part detail ================= */
.pdp{display:grid;grid-template-columns:minmax(0,1fr) 348px;gap:40px;align-items:start}
.gal .main{aspect-ratio:4/3;border-radius:14px}
.galthumbs{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin-top:8px}
.galthumbs .photo{aspect-ratio:1;border-radius:9px;cursor:pointer;outline:2px solid transparent;outline-offset:-2px;transition:outline-color .16s}
.galthumbs .photo.on{outline-color:var(--accent)}
.pdp h1{font-size:27px;line-height:1.25;margin-top:12px}
.pmeta{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:13px}
.pstat{display:flex;gap:18px;margin-top:14px;font-size:12.5px;color:var(--t3)}

.buybox{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);box-shadow:var(--sh);overflow:hidden}
.buybox .top{padding:20px}
.bprice{font-family:var(--dis);font-size:34px;font-weight:600;letter-spacing:-.036em;line-height:1}
.bship{font-size:13px;color:var(--t2);margin-top:6px}
.qty{display:inline-flex;border:1px solid var(--border2);border-radius:9px;overflow:hidden;background:var(--surface)}
.qty button{width:34px;height:36px;font-size:15px;color:var(--t2)}
.qty button:hover{background:var(--surface2);color:var(--text)}
.qty span{width:42px;display:grid;place-items:center;font-weight:500;font-size:14px;
  border-left:1px solid var(--border);border-right:1px solid var(--border)}
.trust{display:flex;align-items:flex-start;gap:10px;padding:14px 20px;border-top:1px solid var(--border);
  background:var(--surface2);font-size:12.5px;color:var(--t2);line-height:1.5}
.trust svg{flex:none;margin-top:1px;color:var(--green)}

.fitcheck{border:1px solid var(--green-line);background:var(--green-soft);border-radius:var(--r-lg);padding:18px;margin:24px 0}
.fitcheck.warn{border-color:var(--accent-line);background:var(--accent-soft)}
.fitcheck h4{font-size:16px;display:flex;align-items:center;gap:9px}
.fitcheck .fc-sub{font-size:13.5px;color:var(--t2);margin-top:6px;line-height:1.55}
.fitcheck .fc-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:14px}

.spectab{width:100%;border-collapse:collapse}
.spectab td{padding:11px 0;border-bottom:1px solid var(--border);font-size:14px;vertical-align:top}
.spectab tr:last-child td{border-bottom:0}
.spectab td:first-child{color:var(--t2);width:200px;padding-right:16px}
.spectab td:last-child{font-family:var(--mono);font-size:13px}
.grade{display:flex;gap:4px;margin-top:11px;max-width:260px}
.grade i{flex:1;height:6px;border-radius:99px;background:var(--surface3)}
.grade i.on{background:var(--green)}
.flaw{display:flex;gap:13px;padding:13px 0;border-bottom:1px solid var(--border);align-items:flex-start}
.flaw:last-child{border-bottom:0}
.flaw .photo{width:66px;height:52px;border-radius:8px;flex:none}
.flaw b{font-size:14px;font-weight:500}
.flaw p{font-size:13px;color:var(--t2);margin-top:3px;line-height:1.5}

.cmp2{width:100%;border-collapse:collapse}
.cmp2 th{text-align:left;font-size:11px;font-weight:600;color:var(--t3);padding:0 12px 10px}
.cmp2 td{padding:13px 12px;border-top:1px solid var(--border);font-size:13.5px;vertical-align:middle}
.cmp2 tr.this td{background:var(--accent-soft)}
.cmp2 .pr{font-family:var(--dis);font-size:16px;font-weight:600}

.qa{border-bottom:1px solid var(--border);padding:16px 0}
.qa:last-of-type{border-bottom:0}
.qa .q{display:flex;gap:11px}
.qa .q b{font-size:14.5px;font-weight:500;line-height:1.45}
.qa .a{display:flex;gap:11px;margin:11px 0 0 30px;padding:12px 14px;background:var(--surface2);border-radius:10px}
.qa .a p{font-size:13.5px;color:var(--t2);line-height:1.55}
.qbadge{width:20px;height:20px;border-radius:6px;background:var(--surface3);color:var(--t2);
  display:grid;place-items:center;font-size:10px;font-weight:700;flex:none}

.buybar{position:fixed;left:0;right:0;bottom:var(--floor,0px);z-index:85;display:none;gap:12px;align-items:center;
  /* --floor above already carries the home indicator (§6); adding it to the
     padding as well counted it twice and floated the Buy row off the bar. */
  padding:10px 16px;background:var(--surface);
  border-top:1px solid var(--border);box-shadow:0 -8px 24px -14px rgba(0,0,0,.35)}
.buybar .bp{font-family:var(--dis);font-size:20px;font-weight:600}

@media(max-width:1040px){.pdp{grid-template-columns:1fr;gap:28px}}
@media(max-width:680px){
  .galthumbs{grid-template-columns:repeat(4,1fr)}
  .spectab td:first-child{width:135px}
  body.onpart .buybar{display:flex}
  body.onpart main{padding-bottom:70px}
}

/* ================= vehicle gallery ================= */
.vgal{position:relative;display:grid;grid-template-columns:1.62fr 1fr 1fr;grid-template-rows:1fr 1fr;
  gap:8px;height:410px;margin-bottom:22px}
.vgal .photo{border-radius:0;cursor:pointer;transition:opacity .18s}
.vgal .photo:hover{opacity:.9}
.vgal .photo:nth-child(1){grid-row:span 2;border-radius:16px 0 0 16px}
.vgal .photo:nth-child(3){border-radius:0 16px 0 0}
.vgal .photo:nth-child(5){border-radius:0 0 16px 0}
.showall{position:absolute;right:14px;bottom:14px;z-index:6}
.showall .btn{background:rgba(255,255,255,.94);color:#0A0A0C;border-color:rgba(255,255,255,.6);
  backdrop-filter:blur(8px);font-weight:600}
.showall .btn:hover{background:#fff}
.vtitle h1{font-size:clamp(28px,3.8vw,40px)}
.vtitle .sub{color:var(--t2);font-size:15.5px;margin-top:10px;max-width:66ch;line-height:1.6}

.pgrid2{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
.pgrid2 .photo{aspect-ratio:1;cursor:pointer;border-radius:11px;transition:transform .18s var(--ease)}
.pgrid2 .photo:hover{transform:scale(1.015)}
.pgrid2 .photo .src{position:absolute;left:8px;top:8px;z-index:4;opacity:0;transition:opacity .18s}
.pgrid2 .photo:hover .src{opacity:1}
.pgrid2 .photo .by2{position:absolute;left:9px;bottom:8px;z-index:4;font-size:11px;font-weight:500;
  color:rgba(255,255,255,.94);text-shadow:0 1px 5px rgba(0,0,0,.7);opacity:0;transition:opacity .18s}
.pgrid2 .photo:hover .by2{opacity:1}
.srcpill{font-size:10.5px;font-weight:600;padding:3px 7px;border-radius:6px;
  background:rgba(10,10,12,.62);color:#fff;backdrop-filter:blur(6px)}

/* lightbox */
.lb{position:fixed;inset:0;z-index:300;background:rgba(6,6,9,.95);backdrop-filter:blur(6px);
  display:none;flex-direction:column;animation:fadein .18s}
.lb.on{display:flex}
.lb-top{display:flex;align-items:center;gap:14px;padding:15px 20px;color:#fff;flex:none}
.lb-top .ct2{font:500 13px var(--mono);color:rgba(255,255,255,.6)}
.lb-x{margin-left:auto;width:36px;height:36px;border-radius:999px;background:rgba(255,255,255,.12);
  color:#fff;display:grid;place-items:center}
.lb-x:hover{background:rgba(255,255,255,.22)}
.lb-stage{flex:1;display:flex;align-items:center;justify-content:center;padding:0 66px;min-height:0;position:relative}
.lb-stage .photo{width:100%;max-width:1080px;aspect-ratio:4/3;max-height:100%;border-radius:12px}
.lb-nav{position:absolute;top:50%;transform:translateY(-50%);width:46px;height:46px;border-radius:999px;
  background:rgba(255,255,255,.13);color:#fff;display:grid;place-items:center;backdrop-filter:blur(6px)}
.lb-nav:hover{background:rgba(255,255,255,.24)}
.lb-nav.prev{left:12px}.lb-nav.next{right:12px}
.lb-bot{flex:none;padding:16px 22px 24px;color:#fff;display:flex;gap:16px;align-items:flex-end;flex-wrap:wrap}
.lb-bot h4{font-size:16px;color:#fff}
.lb-bot p{font-size:13px;color:rgba(255,255,255,.62);margin-top:5px}
.lb-bot .btn{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.22);color:#fff;box-shadow:none}
.lb-bot .btn:hover{background:rgba(255,255,255,.24)}

@media(max-width:900px){
  .vgal{grid-template-columns:1fr 1fr;grid-template-rows:180px 110px;height:auto;gap:6px}
  .vgal .photo:nth-child(1){grid-column:span 2;border-radius:14px 14px 0 0}
  .vgal .photo:nth-child(3){border-radius:0}
  .vgal .photo:nth-child(4){border-radius:0 0 0 14px}
  .vgal .photo:nth-child(5){border-radius:0 0 14px 0}
  .pgrid2{grid-template-columns:repeat(3,1fr);gap:7px}
  .lb-stage{padding:0 12px}
  .lb-nav{width:38px;height:38px}
}
@media(max-width:560px){.pgrid2{grid-template-columns:repeat(2,1fr)}}

/* ================= command palette ================= */
.cmdk{position:fixed;inset:0;z-index:400;background:rgba(6,6,9,.5);backdrop-filter:blur(3px);
  display:none;padding:12vh 18px 18px}
.cmdk.on{display:block;animation:fadein .14s}
.cmdk-box{max-width:640px;margin:0 auto;background:var(--surface);border:1px solid var(--border2);
  border-radius:16px;box-shadow:var(--sh-lg);overflow:hidden;animation:popin .17s var(--ease)}
.cmdk-in{display:flex;align-items:center;gap:12px;padding:16px 18px;border-bottom:1px solid var(--border)}
.cmdk-in input{flex:1;border:0;background:none;font:400 16px var(--ui);color:var(--text)}
.cmdk-in input:focus{outline:none}
.cmdk-res{max-height:52vh;overflow-y:auto;padding:6px}
.cres{display:flex;align-items:center;gap:12px;padding:9px 12px;border-radius:9px;cursor:pointer}
.cres.cur{background:var(--surface2)}
.cres .ci{width:30px;height:30px;border-radius:8px;background:var(--surface2);border:1px solid var(--border);
  display:grid;place-items:center;flex:none;font-size:11px;font-weight:600;color:var(--t2)}
.cres .ct3{flex:1;min-width:0}
.cres b{font-size:14px;font-weight:500;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cres span{font-size:12.5px;color:var(--t3)}
.cres .kind{font-size:10.5px;font-weight:600;color:var(--t3);border:1px solid var(--border);border-radius:5px;padding:2px 6px;flex:none}
.cgroup{font-size:10.5px;font-weight:600;color:var(--t3);padding:11px 12px 5px}
.cmdk-foot{padding:10px 16px;border-top:1px solid var(--border);background:var(--surface2);
  font-size:11.5px;color:var(--t3);display:flex;gap:16px;flex-wrap:wrap}
.cmdk-foot kbd{font:500 10.5px var(--mono);border:1px solid var(--border2);border-radius:4px;padding:1px 5px;background:var(--surface)}

/* ================= thread ================= */
.post{display:flex;gap:16px;padding:20px 0;border-bottom:1px solid var(--border)}
.votes{display:flex;flex-direction:column;align-items:center;gap:3px;flex:none;width:42px}
.votes button{width:30px;height:26px;border-radius:7px;color:var(--t3);display:grid;place-items:center}
.votes button:hover{background:var(--surface2);color:var(--text)}
.votes b{font-family:var(--dis);font-size:16px;font-weight:600}
.pbody p{font-size:15px;line-height:1.7;color:var(--t2);margin-bottom:13px;max-width:72ch}
.pbody p:last-child{margin-bottom:0}
.pbody strong{color:var(--text);font-weight:500}
.pauth{display:flex;align-items:center;gap:9px;margin-bottom:11px;flex-wrap:wrap;font-size:13px;color:var(--t3)}
.pauth b{color:var(--text);font-weight:500;font-size:13.5px}
.accepted{border:1px solid var(--green-line);background:var(--green-soft);border-radius:12px;padding:18px;margin:16px 0}
.accepted .abadge{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:600;
  color:var(--green);margin-bottom:11px}

/* ================= guide ================= */
.toc a{display:block;padding:6px 11px;border-radius:0;font-size:13.5px;color:var(--t2);
  border-left:2px solid var(--border);line-height:1.4}
.toc a:hover{color:var(--text);border-left-color:var(--accent);background:var(--surface2)}
.gbody h2{font-size:21px;margin:34px 0 12px;scroll-margin-top:90px}
.gbody p{font-size:15.5px;line-height:1.75;color:var(--t2);margin-bottom:14px;max-width:72ch}
.gbody strong{color:var(--text);font-weight:500}
.gbody ol,.gbody ul{color:var(--t2);font-size:15.5px;line-height:1.75;max-width:70ch;padding-left:22px}
.gbody li{margin-bottom:9px}
.warn{border-left:3px solid #DC2626;background:#FEF2F2;border-radius:0 10px 10px 0;padding:15px 17px;margin:20px 0}
.warn b{display:block;font-size:12.5px;font-weight:600;color:#B91C1C;margin-bottom:5px}
.warn p{font-size:14.5px;color:#7F1D1D;margin:0;max-width:none;line-height:1.6}
body.dark .warn{background:rgba(220,38,38,.11)}
body.dark .warn b{color:#FCA5A5} body.dark .warn p{color:#FCA5A5;opacity:.9}

/* ================= chat dock ================= */
.chatdock{position:fixed;right:16px;bottom:var(--floor,0px);z-index:110;display:none;gap:12px;align-items:flex-end;pointer-events:none}
body.member .chatdock{display:flex}
.chatdock>*{pointer-events:auto}
.cwin{width:330px;height:436px;background:var(--surface);border:1px solid var(--border2);
  border-bottom:0;border-radius:14px 14px 0 0;box-shadow:var(--sh-lg);display:flex;flex-direction:column;
  overflow:hidden;animation:cwin .22s var(--ease)}
@keyframes cwin{from{transform:translateY(14px);opacity:0}to{transform:none;opacity:1}}
.cwin.min{height:48px}
.cwin.min .cw-body,.cwin.min .cw-foot{display:none}
.cw-head{display:flex;align-items:center;gap:10px;padding:9px 12px;border-bottom:1px solid var(--border);
  background:var(--surface);cursor:pointer;flex:none}
.cw-head .nm2{font-size:13.5px;font-weight:600;line-height:1.25;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cw-head .st2{font-size:11px;color:var(--t3)}
.cw-head .acts{margin-left:auto;display:flex;gap:2px;flex:none}
.cw-head .acts button{width:26px;height:26px;border-radius:7px;color:var(--t3);display:grid;place-items:center;font-size:14px}
.cw-head .acts button:hover{background:var(--surface2);color:var(--text)}
.cw-body{flex:1;overflow-y:auto;padding:14px 12px;display:flex;flex-direction:column;gap:8px;background:var(--canvas)}
.msg{display:flex;gap:8px;align-items:flex-end}
.msg.me{flex-direction:row-reverse}
.bub{max-width:78%;padding:8px 12px;border-radius:16px;font-size:13.5px;line-height:1.5}
.msg.me .bub{background:var(--accent);color:var(--accent-ink);border-bottom-right-radius:5px}
.msg.them .bub{background:var(--surface2);color:var(--text);border-bottom-left-radius:5px;border:1px solid var(--border)}
.msg .tm{font-size:10px;color:var(--t3);flex:none;margin-bottom:2px}
.cdate{text-align:center;font-size:10.5px;font-weight:600;color:var(--t3);margin:6px 0}
.cattach{border:1px solid var(--border);border-radius:11px;overflow:hidden;background:var(--surface);max-width:78%;cursor:pointer}
.cattach .photo{aspect-ratio:16/9;border-radius:0}
.cattach .ct4{padding:9px 11px}
.cattach b{font-size:12.5px;font-weight:500;display:block;line-height:1.35}
.cattach span{font-size:11.5px;color:var(--t3)}
.typing{display:inline-flex;gap:3px;align-items:center;padding:10px 13px}
.typing i{width:5px;height:5px;border-radius:50%;background:var(--t3);animation:tp 1.2s infinite}
.typing i:nth-child(2){animation-delay:.15s}.typing i:nth-child(3){animation-delay:.3s}
@keyframes tp{0%,60%,100%{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}
.cw-foot{display:flex;align-items:flex-end;gap:8px;padding:9px 10px;border-top:1px solid var(--border);background:var(--surface);flex:none}
.cw-foot textarea{flex:1;border:1px solid var(--border2);border-radius:18px;padding:8px 13px;font:400 13.5px var(--ui);
  background:var(--surface2);resize:none;height:36px;max-height:90px;line-height:1.4}
.cw-foot textarea:focus{outline:none;border-color:var(--accent);background:var(--surface)}
.cw-foot .snd{width:34px;height:34px;border-radius:999px;background:var(--accent);color:var(--accent-ink);display:grid;place-items:center;flex:none}
.cw-foot .snd:hover{opacity:.9}
.pres{width:9px;height:9px;border-radius:50%;position:absolute;right:-1px;bottom:-1px;border:2px solid var(--surface)}
.pres.on{background:var(--green)} .pres.away{background:#F59E0B} .pres.off{background:var(--t3)}
.avwrap{position:relative;flex:none}

.chatlaunch{position:relative;width:54px;height:54px;border-radius:999px;background:var(--text);color:var(--canvas);
  box-shadow:var(--sh-lg);display:grid;place-items:center;margin-bottom:18px;transition:transform .18s var(--ease)}
.chatlaunch:hover{transform:scale(1.06)}
.chatlaunch .cbadge{position:absolute;top:-2px;right:-2px;min-width:20px;height:20px;padding:0 5px;border-radius:999px;
  background:var(--accent);color:var(--accent-ink);font:600 11px var(--ui);display:grid;place-items:center;border:2px solid var(--canvas)}

.cpanel{width:330px;height:470px;background:var(--surface);border:1px solid var(--border2);border-bottom:0;
  border-radius:14px 14px 0 0;box-shadow:var(--sh-lg);display:flex;flex-direction:column;overflow:hidden;animation:cwin .22s var(--ease)}
.cpanel .ph3{display:flex;align-items:center;gap:10px;padding:13px 14px;border-bottom:1px solid var(--border)}
.cpanel .ph3 b{font-size:15px}
.cpanel .srch{padding:10px 12px;border-bottom:1px solid var(--border)}
.cpanel .srch input{width:100%;height:32px;border:0;border-radius:999px;background:var(--surface2);padding:0 13px;font:400 13px var(--ui)}
.cpanel .srch input:focus{outline:none}
.cpanel .lst{flex:1;overflow-y:auto}
.crow{display:flex;gap:11px;padding:10px 13px;cursor:pointer;align-items:center}
.crow:hover{background:var(--surface2)}
.crow .cm{flex:1;min-width:0}
.crow .cn{font-size:13.5px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.crow .cl{font-size:12.5px;color:var(--t3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.crow.un .cl{color:var(--text);font-weight:500}
.crow .cr{flex:none;text-align:right}
.crow .cr .cw2{font-size:10.5px;color:var(--t3)}
.crow .dot2{width:9px;height:9px;border-radius:999px;background:var(--accent);margin-left:auto;margin-top:5px}

@media(max-width:680px){
  .chatdock{right:0;left:0;bottom:0;justify-content:flex-end;padding-right:12px}
  .cwin,.cpanel{position:fixed;inset:0;width:100%;height:100%;border-radius:0;border:0;z-index:130}
  .cwin.min{position:static;width:auto;height:48px;inset:auto;border-radius:12px 12px 0 0;border:1px solid var(--border2);border-bottom:0}
  .cwin.min .cw-head{padding-right:8px}
  .chatlaunch{margin-bottom:74px}
  body:not(.member) .chatlaunch{margin-bottom:18px}
}

/* ================= mobile feed =================
   The cards this styled are gone: FMODES / feedItems / renderFeed and the five
   card renderers built a feed out of the sample arrays into #mfeed / #mfeed2,
   was blanked by blankForLive() a moment after it drew, and has been removed.
   .mfeed-end survives on its own below — page-feed.php uses it for the REAL
   feed's empty state, which is the one thing here that was never demo. */
.mfeed-end{padding:26px 18px 34px;text-align:center}
.mfeed-end b{display:block;font-family:var(--dis);font-size:15px}
.mfeed-end p{font-size:13px;color:var(--t3);margin-top:5px}

@media(max-width:760px){
  .mfilter{display:flex;gap:7px;overflow-x:auto;scrollbar-width:none;padding:10px 14px;
    position:sticky;top:56px;z-index:35;background:color-mix(in srgb,var(--canvas) 93%,transparent);
    backdrop-filter:blur(12px);border-bottom:1px solid var(--border)}
  .mfilter::-webkit-scrollbar{display:none}
  .mfilter .chip{flex:none;height:32px}
  .mfilter .chip.on{background:var(--text);border-color:var(--text);color:var(--canvas)}

  /* home on a phone: tighter, not emptier.
     This block used to read "home becomes: compact finder, then feed" and hid
     the lede, the hero, the chips, the stats, every band and the ticker, so the
     mobile feed above could have the whole screen. That feed was built out of
     the sample arrays and is gone (see .mfeed-end below), and / is a public
     splash for anybody signed out — there is no feed underneath to fall through
     to. Hiding all of it left a phone visitor a headline and a search box.
     Everything below 1040px already stacks the hero and shortens the mosaic
     rows; the page only needed the top of it pulled in. */
  #pg-home .hero{padding:16px 0 0}
  #pg-home .hero::after,#pg-home .hero::before{display:none}
  #pg-home .hero h1{font-size:24px;letter-spacing:-.03em;max-width:none}
  #pg-home .finder{margin-top:14px;margin-bottom:16px}

  /* member home: the real feed is the whole column, sidebar drops away */
  #pg-feed .cols>aside{display:none}
  #pg-feed .page-head{margin-bottom:14px}
  /* the feed used to go edge-to-edge here (wrap padding:0, head re-padded by
     hand) — it now keeps the one gutter like every other page (§11) */

  /* photos tab can switch between grid and feed */
  .pgrid2.asfeed{display:block}
  .pgrid2.asfeed .photo{aspect-ratio:4/3;border-radius:12px;margin-bottom:10px}
  .pgrid2.asfeed .photo .src,.pgrid2.asfeed .photo .by2{opacity:1}
}

/* ================= profile ================= */
.pcover{height:210px;border-radius:0;position:relative}
.pcover .photo{border-radius:0;height:210px}
.pwrap{position:relative;z-index:2;margin-top:-56px}
.pav{width:116px;height:116px;border-radius:28px;font-size:36px;box-shadow:0 0 0 4px var(--canvas);flex:none}
.phead3{display:flex;gap:22px;align-items:flex-end;flex-wrap:wrap}
.phead3 .pn2{flex:1;min-width:220px;padding-bottom:4px}
.phead3 h1{font-size:28px;display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.phead3 .hd2{font:400 14px var(--mono);color:var(--t2);margin-top:4px}
.pbio{font-size:15px;color:var(--t2);max-width:64ch;line-height:1.65;margin-top:16px}
.pmeta2{display:flex;gap:16px;flex-wrap:wrap;margin-top:14px;font-size:13.5px;color:var(--t3)}
.pmeta2 span{display:flex;align-items:center;gap:6px}
.pstats{display:grid;grid-template-columns:repeat(6,1fr);border:1px solid var(--border);border-radius:var(--r-lg);
  background:var(--surface);box-shadow:var(--sh-sm);margin:22px 0;overflow:hidden}
.pstats div{padding:14px 16px;border-right:1px solid var(--border)}
.pstats div:last-child{border-right:0}
.pstats b{display:block;font-family:var(--dis);font-size:19px;font-weight:600;letter-spacing:-.03em}
.pstats span{font-size:11.5px;color:var(--t3)}
.badge2{display:flex;gap:11px;align-items:center;padding:12px 14px;border:1px solid var(--border);
  border-radius:11px;background:var(--surface)}
.badge2 .bi{width:32px;height:32px;border-radius:9px;display:grid;place-items:center;flex:none;font-size:14px}
.badge2 b{font-size:13.5px;font-weight:500;display:block;line-height:1.3}
.badge2 span{font-size:11.5px;color:var(--t3)}
.ptab{display:flex;gap:2px;border-bottom:1px solid var(--border);margin:6px 0 24px;overflow-x:auto;scrollbar-width:none}
.ptab::-webkit-scrollbar{display:none}
.ptab button{padding:11px 13px;font-size:14px;font-weight:450;color:var(--t2);border-bottom:2px solid transparent;white-space:nowrap}
.ptab button.on{color:var(--text);border-bottom-color:var(--accent);font-weight:500}
[data-user]{cursor:pointer}

/* ================= settings ================= */
.setgrid{display:grid;grid-template-columns:230px minmax(0,1fr);gap:38px;align-items:start}
.setnav{position:sticky;top:84px}
.setnav button{display:flex;align-items:center;gap:10px;width:100%;padding:9px 11px;border-radius:9px;
  font-size:14px;color:var(--t2);text-align:left;margin-bottom:2px}
.setnav button:hover{background:var(--surface2);color:var(--text)}
.setnav button.on{background:var(--surface2);color:var(--text);font-weight:500}
.spanel{display:none} .spanel.on{display:block;animation:in .24s var(--ease)}
.spanel>h2{font-size:21px;margin-bottom:5px}
.spanel>p.lead2{font-size:14px;color:var(--t2);margin-bottom:22px}
.srow{display:flex;gap:22px;padding:18px 0;border-bottom:1px solid var(--border);align-items:flex-start;flex-wrap:wrap}
.srow:last-child{border-bottom:0}
.srow .sl{width:215px;flex:none}
.srow .sl b{font-size:14px;font-weight:500;display:block}
.srow .sl span{font-size:12.5px;color:var(--t3);display:block;margin-top:4px;line-height:1.5}
.srow .sc{flex:1;min-width:220px}
.switch{width:44px;height:25px;border-radius:999px;background:var(--border2);position:relative;flex:none;
  cursor:pointer;transition:background .18s;border:0}
.switch::after{content:"";position:absolute;top:2.5px;left:2.5px;width:20px;height:20px;border-radius:999px;
  background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.25);transition:transform .2s var(--ease)}
.switch.on{background:var(--accent)}
.switch.on::after{transform:translateX(19px)}
/* inline reveal-forms in the Account panel (change email / password / delete).
   :not([hidden]) so the `hidden` attribute always wins when collapsed. */
.set-form{max-width:380px;margin:2px 0 6px}
.set-form:not([hidden]){display:grid;gap:9px}
.set-form .row{display:flex;gap:10px;flex-wrap:wrap}
.set-err{color:#DC2626;font-size:12.5px;margin:0;min-height:0}
body.dark .set-err{color:#FCA5A5}
.danger{border:1px solid #FECACA;background:#FEF2F2;border-radius:var(--r-lg);padding:18px}
body.dark .danger{border-color:rgba(248,113,113,.28);background:rgba(248,113,113,.08)}
.danger h4{font-size:15px;color:#B91C1C} body.dark .danger h4{color:#FCA5A5}
.danger p{font-size:13.5px;color:#7F1D1D;margin:6px 0 13px;line-height:1.55}
body.dark .danger p{color:#FCA5A5;opacity:.85}
.btn-danger{background:#DC2626;border-color:#DC2626;color:#fff}
.btn-danger:hover{background:#B91C1C;border-color:#B91C1C}
.avedit{position:relative;width:86px;height:86px}
.avedit .av{width:86px;height:86px;border-radius:22px;font-size:28px}
.avedit .pen{position:absolute;right:-4px;bottom:-4px;width:30px;height:30px;border-radius:999px;
  background:var(--surface);border:1px solid var(--border2);display:grid;place-items:center;box-shadow:var(--sh-sm)}
@media(max-width:900px){.pstats{grid-template-columns:repeat(3,1fr)}
  .pstats div:nth-child(3n){border-right:0}.pstats div:nth-child(-n+3){border-bottom:1px solid var(--border)}
  .setgrid{grid-template-columns:1fr;gap:22px}.setnav{position:static;display:flex;gap:6px;overflow-x:auto}
  .setnav button{width:auto;white-space:nowrap;margin:0}}
@media(max-width:560px){.pstats{grid-template-columns:repeat(2,1fr)}.pav{width:88px;height:88px;font-size:28px}
  .pwrap{margin-top:-40px}}

/* ================= seller branding ================= */
.brandmark{width:auto;flex:none;display:block;fill:currentColor}
.slabel .brandmark{height:15px;margin-right:2px}
.prow .brandmark,.vrow .brandmark{height:14px}
.bmono{display:inline-grid;place-items:center;border-radius:6px;font:700 9.5px var(--ui);
  letter-spacing:.02em;color:#fff;flex:none;height:17px;padding:0 5px}
.block2{display:flex;align-items:center;gap:9px}
.block2 .brandmark{height:26px}
.block2 .bmono{height:26px;border-radius:8px;font-size:12px;padding:0 9px}
.block2 .bn{font-family:var(--dis);font-weight:600;font-size:15px;letter-spacing:-.02em;line-height:1.2}
.block2 .bt{font-size:11.5px;color:var(--t3)}
.tierpill{font-size:10px;font-weight:700;letter-spacing:.06em;padding:2px 6px;border-radius:5px;
  background:var(--accent);color:var(--accent-ink)}
.tierpill.brand{background:var(--violet)}

/* ================= build page ================= */
.bhero{position:relative}
.bhero .photo{border-radius:0;aspect-ratio:21/8;min-height:300px}
.bhero .ov2{position:absolute;left:0;right:0;bottom:0;padding:34px 0 26px;
  background:linear-gradient(180deg,transparent,rgba(6,6,10,.55) 42%,rgba(6,6,10,.88))}
.bhero h1{font-size:clamp(30px,4.6vw,48px);color:#fff;letter-spacing:-.038em;line-height:1.04}
.bhero .bsub{color:rgba(255,255,255,.82);font-size:15.5px;margin-top:10px;max-width:62ch;line-height:1.55}
.bhero .pill{background:rgba(8,8,12,.5);border-color:rgba(255,255,255,.22);color:#fff;backdrop-filter:blur(8px)}
.bhero .pill-g{background:rgba(21,163,74,.34);border-color:rgba(134,239,172,.45);color:#DCFCE7}
.bhero .who2{display:flex;align-items:center;gap:9px;margin-top:16px;color:rgba(255,255,255,.86);font-size:13.5px}
.bhero .avstack .av{box-shadow:0 0 0 2px rgba(8,8,12,.6)}
.bacts{position:absolute;right:0;top:22px;display:flex;gap:8px;flex-wrap:wrap}
.bacts .btn{background:rgba(12,12,16,.52);border-color:rgba(255,255,255,.24);color:#fff;backdrop-filter:blur(8px);box-shadow:none}
.bacts .btn:hover{background:rgba(12,12,16,.72)}
.bacts .btn-primary{background:#fff;color:#0A0A0C;border-color:#fff}
.bacts .btn .ct{color:rgba(255,255,255,.6);border-color:rgba(255,255,255,.28)}
.bacts .btn-primary .ct{color:rgba(10,10,12,.5);border-color:rgba(10,10,12,.2)}

.bstrip{display:grid;grid-template-columns:repeat(6,1fr);gap:6px;margin:6px 0 22px}
.bstrip .photo{aspect-ratio:4/3;border-radius:9px;cursor:zoom-in}
.bstrip .more3{display:grid;place-items:center;background:var(--surface2);border:1px solid var(--border);
  border-radius:9px;font-size:12px;font-weight:600;color:var(--t2);aspect-ratio:4/3;text-align:center;padding:6px;line-height:1.35}
.bstrip .more3:hover{border-color:var(--border2);color:var(--text)}

.bspec{display:grid;grid-template-columns:repeat(6,1fr);border:1px solid var(--border);border-radius:var(--r-lg);
  background:var(--surface);overflow:hidden;box-shadow:var(--sh-sm)}
.bspec>div{padding:14px 16px;border-right:1px solid var(--border)}
.bspec>div:last-child{border-right:0}
.bspec dt{font-size:10.5px;font-weight:600;color:var(--t3);margin:0 0 5px}
.bspec dd{margin:0;font-family:var(--mono);font-size:13.5px;color:var(--text);line-height:1.35}

.bphase{display:flex;margin-top:16px;border:1px solid var(--border);border-radius:var(--r-lg);
  overflow:hidden;background:var(--surface);box-shadow:var(--sh-sm)}
.bphase>div{flex:1;padding:13px 15px;border-right:1px solid var(--border);min-width:0}
.bphase>div:last-child{border-right:0}
.bphase .ph-done{background:var(--green-soft)}
.bphase .ph-now{background:var(--accent-soft)}
.bphase b{font-size:12.5px;font-weight:600;display:block;line-height:1.3}
.bphase span{font-size:11px;color:var(--t3);display:block;margin-top:3px}
.bphase .ph-done b{color:var(--green)}
.bphase .ph-now b{color:var(--accent-fg)}
.bphase .ph-todo b{color:var(--t3)}

@media(max-width:900px){
  .bspec{grid-template-columns:repeat(3,1fr)}
  .bspec>div:nth-child(3n){border-right:0}
  .bspec>div:nth-child(-n+3){border-bottom:1px solid var(--border)}
  .bstrip{grid-template-columns:repeat(4,1fr)}
  .bphase{flex-wrap:wrap}.bphase>div{flex:1 1 33%;border-bottom:1px solid var(--border)}
  .bacts{position:static;margin-top:16px}
}
@media(max-width:600px){
  .bspec{grid-template-columns:repeat(2,1fr)}
  .bstrip{grid-template-columns:repeat(3,1fr)}
  .bhero .photo{aspect-ratio:4/3;min-height:0}
  .bhero .ov2{padding:24px 0 18px}
}

/* ================= header ================= */
:root{--navh:60px}
.nav{padding-top:env(safe-area-inset-top);transition:transform .26s var(--ease)}
.toolbar{top:var(--navh)}
/* The wordmark is what gives when the bar is tight — .logo used to carry the
   overflow:hidden for this, but it cannot any more: it would clip the mark's
   frame padding and flatten its points (see .logo in css/00). Text can be cut
   and still read as itself; a hexagon missing a point cannot. */
.logo .wm{display:flex;gap:.3em;font-family:var(--dis);font-weight:600;font-size:15.5px;letter-spacing:-.03em;
  min-width:0;overflow:hidden}
.logo .wm i{font-style:normal;white-space:nowrap}
/* Header wordmark stacks the name over a small BETA tag, right-aligned so the
   two share a flush right edge. Scoped to .nav so the drawer wordmark (same
   .wm class) keeps its plain single-line lockup. */
.nav .logo .wm{flex-direction:column;align-items:flex-end;gap:0;line-height:1}
.nav .logo .wm .wm-name{display:flex;gap:.3em}
.nav .logo .wm .wm-beta{font-size:9px;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:#8A8880;margin-top:4px;margin-right:-.16em;transition:color .18s var(--ease)}
.nav .logo:hover .wm-beta,.nav .logo:focus-visible .wm-beta{color:var(--accent)}
.navback{display:none;width:36px;height:36px;border-radius:10px;align-items:center;justify-content:center;
  color:var(--text);margin-right:-6px}
.navback:hover{background:var(--surface2)}
.navtitle{display:none;font-family:var(--dis);font-weight:600;font-size:16px;letter-spacing:-.024em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}

@media(max-width:760px){
  :root{--navh:54px}
  body.navhide .nav{transform:translateY(calc(-100% - 2px))}
  .nav .wrap{height:54px;gap:10px}
  .logo{gap:8px}
  .logo .hexmark{--hxh:34.44px}   /* 28px of ink x 214/174 — see .hexmark in css/00 */
  /* Phones show the mark alone — the two-line uppercase lockup was the densest
     thing in a tight bar. The full name still greets in the drawer header,
     which is why this is scoped to .nav: unscoped it hid that one too, and the
     comment promising it had been wrong for as long as it had been there. */
  .nav .logo .wm{display:none}
  .navauth .btn-ghost{display:none!important}
  .navauth{gap:2px}
  /* the burger drops its box on phones so all header controls read as one set of
     quiet icon buttons rather than one boxed button beside four bare ones */
  .burger{border:0;background:transparent;color:var(--t2)}
  .burger:hover{background:var(--surface2);color:var(--text)}
  /* detail pages swap the wordmark for back + title, like a native app */
  body.deep .logo{display:none}
  body.deep .navback{display:flex}
  body.deep .navtitle{display:block}
}

/* ================= owned vehicle profile =================
   Deliberately close to a person profile, but a car is not a person:
   rectangular portrait instead of an avatar, a plate instead of a handle,
   an odometer instead of a follower count. */
.vp-cover .photo{border-radius:0;height:230px}
.vp-wrap{position:relative;z-index:2;margin-top:-74px}
.vp-head{display:flex;gap:24px;align-items:flex-end;flex-wrap:wrap}
.vp-card{width:250px;aspect-ratio:16/10;border-radius:14px;flex:none;
  box-shadow:0 0 0 4px var(--canvas),var(--sh-lg)}
.vp-id{flex:1;min-width:240px;padding-bottom:6px}
.vp-id h1{font-size:30px;letter-spacing:-.032em}
.vp-ymm{font-size:15px;color:var(--t2);margin-top:6px}
.plate{display:inline-flex;align-items:center;justify-content:center;height:36px;padding:0 15px;
  border-radius:6px;background:#F4F4EE;border:2px solid #1D1D22;color:#1D1D22;
  font:700 17px/1 var(--mono);letter-spacing:.14em;box-shadow:inset 0 -3px 0 rgba(0,0,0,.09);
  margin-top:14px}
.plate small{font:600 8px/1 var(--ui);letter-spacing:.14em;margin-right:9px;opacity:.55;align-self:center}
body.dark .plate{background:#EAEAE3;border-color:#111114;color:#1D1D22}
.vp-owner{display:flex;align-items:center;gap:10px;margin-top:18px;font-size:13.5px;color:var(--t2);flex-wrap:wrap}
.vp-stats{display:grid;grid-template-columns:repeat(6,1fr);border:1px solid var(--border);
  border-radius:var(--r-lg);background:var(--surface);box-shadow:var(--sh-sm);margin:24px 0;overflow:hidden}
.vp-stats>div{padding:15px 16px;border-right:1px solid var(--border)}
.vp-stats>div:last-child{border-right:0}
.vp-stats b{display:block;font-family:var(--mono);font-size:19px;font-weight:600;letter-spacing:-.01em}
.vp-stats .odo b{color:var(--accent-fg)}
.vp-stats span{font-size:11.5px;color:var(--t3)}
.tline{position:relative;padding-left:30px}
.tline::before{content:"";position:absolute;left:9px;top:6px;bottom:6px;width:2px;background:var(--border)}
.tev{position:relative;padding:0 0 22px}
.tev::before{content:"";position:absolute;left:-26px;top:5px;width:12px;height:12px;border-radius:999px;
  background:var(--surface);border:2px solid var(--border2)}
.tev.hot::before{background:var(--accent);border-color:var(--accent)}
.tev .td{font:500 11.5px var(--mono);color:var(--t3);letter-spacing:.04em}
.tev h4{font-size:15.5px;margin:4px 0 5px}
.tev p{font-size:13.5px;color:var(--t2);line-height:1.55;max-width:66ch}
.tev .tm2{display:flex;gap:7px;flex-wrap:wrap;margin-top:9px}
.expand{position:absolute;right:8px;top:8px;z-index:5;width:28px;height:28px;border-radius:8px;
  background:rgba(10,10,12,.6);color:#fff;display:none;align-items:center;justify-content:center;backdrop-filter:blur(6px)}
.photo:hover .expand{display:flex}
.expand:hover{background:rgba(10,10,12,.85)}
@media(max-width:900px){.vp-stats{grid-template-columns:repeat(3,1fr)}
  .vp-stats>div:nth-child(3n){border-right:0}
  .vp-stats>div:nth-child(-n+3){border-bottom:1px solid var(--border)}}
@media(max-width:600px){.vp-stats{grid-template-columns:repeat(2,1fr)}
  .vp-card{width:180px}.vp-wrap{margin-top:-52px}.vp-cover .photo{height:170px}
  .expand{display:flex}}

/* ================= the numbers ================= */
.tagline{font-size:15.5px;color:var(--t2);margin-top:12px;max-width:56ch;line-height:1.55;font-style:italic}
.numbers{display:grid;grid-template-columns:repeat(6,1fr);gap:1px;background:var(--border);
  border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;margin:24px 0 0}
.numbers>div{background:var(--surface);padding:16px 18px 15px}
.numbers .lab{font-size:10.5px;font-weight:600;color:var(--t3);margin-bottom:7px}
.numbers .big{font-family:var(--dis);font-size:30px;font-weight:600;letter-spacing:-.04em;line-height:1;
  font-variant-numeric:tabular-nums}
.numbers .big u{text-decoration:none;font-size:14px;font-weight:500;color:var(--t3);margin-left:3px;letter-spacing:0}
.numbers .was{font-size:11.5px;color:var(--t3);margin-top:7px;font-family:var(--mono)}
.delta{display:inline-flex;align-items:center;gap:3px;font:600 11px var(--ui);padding:2px 6px;border-radius:5px;
  background:var(--accent-soft);color:var(--accent-fg);border:1px solid var(--accent-line);margin-top:7px}
.delta.down{background:var(--surface2);color:var(--t2);border-color:var(--border)}
.delta.flat{background:var(--surface2);color:var(--t3);border-color:var(--border)}

.dynowrap{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);
  box-shadow:var(--sh-sm);padding:20px 22px 14px;margin-top:18px}
.dynowrap .dh{display:flex;align-items:flex-end;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-bottom:6px}
.dynowrap h3{font-size:16px}
.dynokey{display:flex;gap:16px;font-size:12px;color:var(--t3)}
.dynokey i{display:inline-block;width:16px;height:2px;margin-right:6px;vertical-align:3px}
.dyno svg{width:100%;height:auto;display:block;overflow:visible}
.dyno .grid2{stroke:var(--border);stroke-width:1}
.dyno .ax{font:500 10px var(--mono);fill:var(--t3)}
.dyno .stockline{fill:none;stroke:var(--t3);stroke-width:1.8;stroke-dasharray:5 4;opacity:.75}
.dyno .nowline{fill:none;stroke:var(--accent);stroke-width:2.6;stroke-linejoin:round;stroke-linecap:round}
.dyno .nowfill{fill:var(--accent);opacity:.09}
.dyno .peak{fill:var(--accent)}
.dyno .peaktx{font:600 11px var(--ui);fill:var(--text)}

.modbar{display:flex;flex-direction:column;gap:9px}
.modrow{display:flex;align-items:center;gap:12px;font-size:13.5px}
.modrow .mn{width:132px;flex:none;color:var(--t2)}
.modrow .mt{flex:1;height:9px;border-radius:99px;background:var(--surface2);overflow:hidden}
.modrow .mt i{display:block;height:100%;border-radius:99px;background:var(--accent)}
.modrow .mc{width:22px;text-align:right;font-family:var(--mono);font-size:12.5px;color:var(--text);flex:none}

.patches{display:flex;gap:9px;flex-wrap:wrap}
.patch{display:flex;align-items:center;gap:9px;padding:9px 13px 9px 10px;border-radius:999px;
  border:1px solid var(--border);background:var(--surface);box-shadow:var(--sh-sm)}
.patch .pi2{width:26px;height:26px;border-radius:999px;display:grid;place-items:center;font-size:12px;flex:none}
.patch b{font-size:12.5px;font-weight:600;display:block;line-height:1.2}
.patch span{font-size:11px;color:var(--t3)}
@media(max-width:1040px){.numbers{grid-template-columns:repeat(3,1fr)}}
@media(max-width:600px){.numbers{grid-template-columns:repeat(2,1fr)}.numbers .big{font-size:25px}
  .modrow .mn{width:96px;font-size:12.5px}}

/* ---- show first, numbers light ---- */
.tagline{font-size:19px;color:var(--text);margin-top:16px;max-width:52ch;line-height:1.45;
  font-family:var(--dis);font-weight:500;letter-spacing:-.022em}
.statline{display:flex;flex-wrap:wrap;border-top:1px solid var(--border);border-bottom:1px solid var(--border);
  margin:22px 0 0}
.statline>div{flex:1;min-width:118px;padding:15px 0}
.statline b{font-family:var(--dis);font-size:27px;font-weight:600;letter-spacing:-.038em;display:block;
  font-variant-numeric:tabular-nums;line-height:1}
.statline b u{text-decoration:none;font-size:13px;font-weight:500;color:var(--t3);margin-left:3px;letter-spacing:0}
.statline b em{font-style:normal;font-size:12.5px;font-weight:600;color:var(--accent-fg);margin-left:7px;letter-spacing:0}
.statline .lab2{font-size:11.5px;color:var(--t3);margin-top:6px}
.showcase{display:grid;grid-template-columns:1.7fr 1fr;gap:10px;margin:24px 0 0}
.showcase .col2{display:grid;gap:10px;grid-template-rows:1fr 1fr}
.showcase .photo{border-radius:14px;cursor:pointer}
.showcase .big2{aspect-ratio:16/11}
.mcards{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.mcard2{border:1px solid var(--border);border-radius:14px;overflow:hidden;background:var(--surface);
  box-shadow:var(--sh-sm);transition:transform .2s var(--ease),box-shadow .2s var(--ease)}
.mcard2:hover{transform:translateY(-2px);box-shadow:var(--sh)}
.mcard2 .photo{border-radius:0;aspect-ratio:16/10}
.mcard2 .bd3{padding:13px 15px 15px}
.mcard2 h4{font-size:14.5px;line-height:1.35}
.mcard2 p{font-size:13px;color:var(--t2);margin-top:6px;line-height:1.5}
@media(max-width:900px){.mcards{grid-template-columns:1fr}.showcase{grid-template-columns:1fr}
  .showcase .col2{grid-template-columns:1fr 1fr;grid-template-rows:none}}

/* ================= owned vehicle, photo-led ================= */
.ovhero{position:relative}
.ovhero .photo{border-radius:0;aspect-ratio:16/7;min-height:330px}
/* z-index 5 matches the profile header's .pov: it sits above the cover's
   placeholder gradient layers (.photo::before/::after, z 1 and 3), which reach
   this stacking context now that a .pe-host photo no longer isolates them, and
   below the photo editor's own controls (z 8 and up). */
.ovhero .ov3{position:absolute;left:0;right:0;bottom:0;padding:44px 0 26px;z-index:5;
  background:linear-gradient(180deg,transparent,rgba(6,6,10,.5) 40%,rgba(6,6,10,.9))}
.ovhero h1{font-size:clamp(34px,5vw,54px);color:#fff;letter-spacing:-.042em;line-height:1}
.ovhero .ymm2{color:rgba(255,255,255,.82);font-size:15.5px;margin-top:9px}
.ovhero .ymm2 a{color:#fff;border-bottom:1px solid rgba(255,255,255,.35)}
.ovhero .tag2{color:rgba(255,255,255,.9);font-family:var(--dis);font-weight:500;font-size:17px;
  letter-spacing:-.02em;margin-top:12px;max-width:48ch;line-height:1.4}
.ovhero .hrow{display:flex;align-items:center;gap:18px;margin-top:18px;flex-wrap:wrap}
.ovhero .own2{display:flex;align-items:center;gap:9px;color:rgba(255,255,255,.9);font-size:13.5px}
.ovhero .own2 b{color:#fff;font-weight:500}
.ovhero .qs{display:flex;gap:20px;flex-wrap:wrap}
.ovhero .qs div{color:#fff}
.ovhero .qs b{font-family:var(--dis);font-size:21px;font-weight:600;letter-spacing:-.03em;display:block;line-height:1}
.ovhero .qs b em{font-style:normal;font-size:12px;color:#FDBA74;margin-left:5px;font-weight:600}
.ovhero .qs span{font-size:11px;color:rgba(255,255,255,.6)}
.ovhero .acts2{position:absolute;right:0;top:24px;display:flex;gap:8px;flex-wrap:wrap}
.ovhero .acts2 .btn{background:rgba(12,12,16,.5);border-color:rgba(255,255,255,.25);color:#fff;backdrop-filter:blur(8px);box-shadow:none}
.ovhero .acts2 .btn-primary{background:#fff;color:#0A0A0C;border-color:#fff}
.swatch{display:inline-flex;align-items:center;gap:8px;height:28px;padding:0 12px 0 5px;border-radius:999px;
  background:rgba(12,12,16,.5);border:1px solid rgba(255,255,255,.22);color:#fff;font-size:12.5px;backdrop-filter:blur(8px)}
.swatch i{width:18px;height:18px;border-radius:999px;border:1px solid rgba(255,255,255,.4);flex:none}

.patchbar{display:flex;gap:9px;overflow-x:auto;scrollbar-width:none;padding:18px 0 4px}
.patchbar::-webkit-scrollbar{display:none}
.patchbar .patch{flex:none}

.wall{column-count:3;column-gap:10px;margin-top:4px}
.wall .photo{break-inside:avoid;margin-bottom:10px;border-radius:12px;width:100%;display:block;cursor:pointer}
.wall .cap{font-size:11.5px}
@media(max-width:900px){.wall{column-count:2}}
@media(max-width:760px){
  /* the overlay content is taller than the image on a phone, so it clipped.
     below this width the hero stacks: photo, then the details on the page. */
  .ovhero .photo{aspect-ratio:4/3;min-height:0}
  .ovhero .ov3{position:static;background:none;padding:16px 0 0}
  .ovhero h1{color:var(--text);font-size:30px}
  .ovhero .ymm2{color:var(--t2)}
  .ovhero .ymm2 a{color:var(--accent-fg);border-bottom-color:var(--accent-line)}
  .ovhero .tag2{color:var(--text);font-size:16px}
  .ovhero .own2{color:var(--t2)}
  .ovhero .own2 b{color:var(--text)}
  .ovhero .qs b{color:var(--text)}
  .ovhero .qs b em{color:var(--accent-fg)}
  .ovhero .qs span{color:var(--t3)}
  .ovhero .swatch{background:var(--surface2);border-color:var(--border);color:var(--t2)}
  .ovhero .swatch i{border-color:var(--border2)}
  .ovhero .acts2{position:static;margin-top:16px}
  .ovhero .acts2 .btn{background:var(--surface);color:var(--text);border-color:var(--border2);backdrop-filter:none}
  .ovhero .acts2 .btn-primary{background:var(--text);color:var(--canvas);border-color:var(--text)}
  .ovhero .hrow{gap:14px}
}
@media(max-width:560px){.wall{column-count:2;column-gap:7px}.wall .photo{margin-bottom:7px;border-radius:9px}}

/* ---------- responsive ---------- */
@media(max-width:1040px){
  .cols,.cols-l{grid-template-columns:1fr}
  .sticky{position:static}
  .hero-grid{grid-template-columns:1fr;gap:34px}
  .grid,.grid-4{grid-template-columns:repeat(2,1fr)}
  .brandgrid{grid-template-columns:repeat(4,1fr)}
  .parent .lk{margin-left:0;width:100%}
  .wsw{display:none!important}  /* lives in the drawer on mobile */
  .hide-d{display:inline-flex}
  /* The bar hands its links to the drawer. This is the same 1040px step the
     rest of the chrome already folds at — the nav does not get a breakpoint of
     its own. The brand takes the free space so search and the member's
     controls stay pinned right, and the hairline goes with the bar it was
     separating the brand from. */
  .navbar{display:none}
  .burger{display:flex}
  .nav .logo{margin-right:auto;padding-right:0}
  .nav .logo::after{display:none}
}
@media(max-width:680px){
  .grid,.grid-4,.grid-2,.shots{grid-template-columns:1fr}
  .brandgrid{grid-template-columns:repeat(2,1fr)}
  .ymm-f+.ymm-f::before{display:none}
  .ymm .go{width:100%}
  .parent .mk svg{height:44px}
  .stats,.vstats{grid-template-columns:1fr 1fr}
  .stats div,.vstats div{border-right:0}
  .vstats div:nth-child(-n+2){border-bottom:1px solid var(--border)}
  .hero{padding:36px 0 0}
  .hero h1{font-size:33px}
  .band{padding:44px 0}
  .mosaic{grid-auto-rows:76px;gap:7px}
  .page{padding-bottom:96px}  /* top comes off the --pad-top ladder */
  .vhero .photo{height:200px}
  .phead h1{font-size:25px}
  .entry-b,.pad{padding:16px}
  .ticker .now span{display:none}
  body.member main{padding-bottom:20px}
  body.member .foot{padding-bottom:92px}
  .powered{gap:12px}
  .mpl2{margin-left:0}
}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}


/* ===== NEW OWNED-VEHICLE PROFILE (redesign) ===== */
/* ==========================================================================
   BLOCK B — HEADER. Verbatim from auto-maker-space (17): the owned-vehicle
   photo-led hero. Owner and stats have been lifted out of the overlay into
   their own bar below the image. Sits inside .wrap, so the image is content width.
   ========================================================================== */
.vp-wrap{position:relative;z-index:2;margin-top:-74px}
.av-sm{width:24px;height:24px;font-size:9.5px}
.ovhero{position:relative}
.ovhero .photo{border-radius:0;aspect-ratio:16/7;min-height:330px}
/* z-index 5 matches the profile header's .pov: it sits above the cover's
   placeholder gradient layers (.photo::before/::after, z 1 and 3), which reach
   this stacking context now that a .pe-host photo no longer isolates them, and
   below the photo editor's own controls (z 8 and up). */
.ovhero .ov3{position:absolute;left:0;right:0;bottom:0;padding:44px 0 26px;z-index:5;
  background:linear-gradient(180deg,transparent,rgba(6,6,10,.5) 40%,rgba(6,6,10,.9))}
.ovhero h1{font-size:clamp(34px,5vw,54px);color:#fff;letter-spacing:-.042em;line-height:1}
.ovhero .ymm2{color:rgba(255,255,255,.82);font-size:15.5px;margin-top:9px}
.ovhero .ymm2 a{color:#fff;border-bottom:1px solid rgba(255,255,255,.35)}
.ovhero .tag2{color:rgba(255,255,255,.9);font-family:var(--dis);font-weight:500;font-size:17px;
  letter-spacing:-.02em;margin-top:12px;max-width:48ch;line-height:1.4}
/* stats left, owner right — a bar under the image, on the canvas */
.vbar{display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap;
  padding:16px 24px;border-bottom:1px solid var(--border);
  /* graded from the seam down, with the photo casting onto it, so the plinth
     reads as attached to the image rather than a separate strip */
  background:linear-gradient(180deg,var(--surface3),var(--surface2) 62%);
  box-shadow:inset 0 7px 11px -9px rgba(12,12,16,.5)}
body.dark .vbar{box-shadow:inset 0 7px 12px -9px rgba(0,0,0,.85)}
.vbar .qs{display:flex;gap:26px;flex-wrap:wrap}
.vbar .qs b{font-family:var(--dis);font-size:21px;font-weight:600;letter-spacing:-.03em;
  display:block;line-height:1;font-variant-numeric:tabular-nums}
.vbar .qs b em{font-style:normal;font-size:12px;color:var(--accent-fg);margin-left:5px;font-weight:600}
.vbar .qs span{display:flex;align-items:center;gap:6px;font-size:10.5px;color:var(--t3);
  margin-top:6px;letter-spacing:.04em}
/* owner-defined stat. Number =< 6 chars, label =< 18 chars. */
.vbar .qs .custom b{color:var(--accent-fg)}
.vbar .qs .custom span::before{content:"";width:4px;height:4px;border-radius:50%;
  background:var(--accent);flex:none}
/* high-mileage award, printed against the odometer only */
.klub{display:inline-flex;align-items:center;height:16px;padding:0 6px;border-radius:4px;
  font:600 9.5px/1 var(--ui);letter-spacing:.06em;
  background:#FEF6E7;color:#96660C;border:1px solid #F3DFB4}
body.dark .klub{background:rgba(245,190,80,.13);color:#F2C25B;border-color:rgba(245,190,80,.3)}
.vbar .qs b u{text-decoration:none;font-size:11.5px;font-weight:500;color:var(--t3);
  margin-left:3px;letter-spacing:0}
.vbar .own2{display:flex;align-items:center;gap:9px;color:var(--t2);font-size:13.5px}
.vbar .own2 b{color:var(--text);font-weight:500}
.vbar .own2:hover b{color:var(--accent-fg)}
/* stats that open their tab. The chevron is the affordance — mileage and the
   custom stat have nowhere to go, so they stay plain. */
.vbar .qs .jump{padding:0;text-align:left}
.vbar .qs .jump b,.vbar .qs .jump span{transition:color .16s}
.vbar .qs .jump span::after{content:"\203A";display:inline-block;margin-left:2px;font-size:13px;
  line-height:1;color:var(--t3);transition:transform .16s var(--ease),color .16s}
.vbar .qs .jump:hover b{color:var(--accent-fg)}
.vbar .qs .jump:hover span{color:var(--t2)}
.vbar .qs .jump:hover span::after{color:var(--accent);transform:translateX(2px)}
.ovhero .acts2{position:absolute;right:24px;bottom:2px;display:flex;gap:8px;flex-wrap:wrap}
.ovhero .acts2 .btn{background:rgba(12,12,16,.5);border-color:rgba(255,255,255,.25);color:#fff;backdrop-filter:blur(8px);box-shadow:none}
.ovhero .acts2 .btn-primary{background:#fff;color:#0A0A0C;border-color:#fff}
@media(max-width:760px){
  /* the overlay content is taller than the image on a phone, so it clipped.
     below this width the hero stacks: photo, then the details on the page. */
  .ovhero .photo{aspect-ratio:4/3;min-height:0}
  .ovhero .ov3{position:static;background:none;padding:15px 0 0}
  .ovhero h1{color:var(--text);font-size:29px}
  .ovhero .ymm2{color:var(--t2);font-size:14.5px;margin-top:7px}
  .ovhero .ymm2 a{color:var(--accent-fg);border-bottom-color:var(--accent-line)}
  .ovhero .tag2{color:var(--text);font-size:15.5px;margin-top:10px}
  /* the two actions split the row evenly at a thumb-sized height, rather than
     sitting as two odd-width pills with a gap of dead space after them */
  .ovhero .acts2{position:static;margin-top:15px;gap:9px;flex-wrap:nowrap}
  .ovhero .acts2 .btn{flex:1 1 0;min-width:0;height:44px;padding:0 12px;font-size:14.5px}
  .ovhero .acts2 .btn{background:var(--surface);color:var(--text);border-color:var(--border2);backdrop-filter:none}
  .ovhero .acts2 .btn-primary{background:var(--text);color:var(--canvas);border-color:var(--text)}
  /* the stat bar is a grid on a phone, not a wrapping flex row: paint + mileage
     on top, the three jumps on an even three below a hairline. Wrapping put
     them at whatever widths the text happened to make. */
  .vbar{align-items:flex-start;gap:0;padding:13px 15px}
  .vbar .qs{display:grid;grid-template-columns:repeat(6,1fr);gap:0;width:100%}
  /* one selector per row, and specific enough to beat .vbar .qs .jump{padding:0} */
  .vbar .qs>*{min-width:0}
  .vbar .qs>*:nth-child(-n+2){grid-column:span 3;padding:0 9px 13px 0}
  .vbar .qs>*:nth-child(n+3){grid-column:span 2;padding:12px 9px 0 0;border-top:1px solid var(--border)}
  .vbar .qs b{font-size:19px}
  .vbar .qs .custom b{font-size:14.5px!important;line-height:1.25;
    overflow-wrap:anywhere}          /* a long paint name wraps instead of shoving mileage off */
  .vbar .qs span{font-size:10px;margin-top:5px;flex-wrap:wrap}
  .vbar .own2{width:100%;margin-top:13px;padding-top:13px;border-top:1px solid var(--border)}
  .vtabs-w{margin-top:16px}
  .vtabs-w .ptab button{padding:12px 12px}
  #pg-myvehicle .pane{padding-top:18px}
  .ph-bar{margin-bottom:10px}
  /* the owner's controls are permanently up where there is no hover, so on a
     3-up phone tile they have to be small enough not to be the photo */
  .vph-acts{top:5px;right:5px;gap:4px}
  .vph-btn{height:24px;padding:0 8px;border-radius:7px;font-size:10.5px}
  .vph-del{width:24px;height:24px;padding:0}
}

/* ==========================================================================
   BLOCK D — BADGES. 5 featured medallions, the rest in a scrolling rail.
   Replaces .patchbar / .patch.
   ========================================================================== */
.bdg{padding:20px 0 6px}
.bdg-h{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}
.bdg-h h4{font-size:11px;font-weight:600;color:var(--t3);font-family:var(--ui);letter-spacing:.06em}
.bdg-h a{font-size:12.5px;color:var(--t2)}
.bdg-h a:hover{color:var(--text)}
.bdg-feat{display:grid;grid-template-columns:repeat(4,1fr);gap:9px}
.bdg-card{--bc:#3F3F49;display:flex;align-items:center;gap:11px;padding:10px 13px 10px 10px;
  border-radius:var(--r-lg);min-width:0;box-shadow:var(--sh-sm);
  background:color-mix(in srgb,var(--bc) 8%,var(--surface));
  border:1px solid color-mix(in srgb,var(--bc) 26%,var(--border));
  transition:transform .18s var(--ease),box-shadow .18s var(--ease),
    border-color .18s,background .18s}
.bdg-card:hover{transform:translateY(-2px);
  background:color-mix(in srgb,var(--bc) 13%,var(--surface));
  border-color:color-mix(in srgb,var(--bc) 46%,var(--border));
  box-shadow:0 2px 6px rgba(12,12,16,.05),0 14px 26px -14px color-mix(in srgb,var(--bc) 55%,transparent)}
.hex{width:32px;height:36px;flex:none;display:grid;place-items:center;font-size:14px;color:#fff;
  clip-path:polygon(50% 0,100% 25%,100% 75%,50% 100%,0 75%,0 25%);
  background:linear-gradient(160deg,var(--bc,#3F3F49),color-mix(in srgb,var(--bc,#3F3F49) 58%,#000))}
.bdg-card .bt{min-width:0}
.bdg-card b{display:block;font-size:12.5px;font-weight:600;line-height:1.25;letter-spacing:-.014em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  color:color-mix(in srgb,var(--bc) 74%,var(--text))}
.bdg-card .bt span{display:block;font-size:10.5px;margin-top:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  color:color-mix(in srgb,var(--bc) 26%,var(--t3))}
.bdg-rail-w{position:relative;margin-top:9px}
.bdg-rail-w::after{content:"";position:absolute;right:0;top:0;bottom:0;width:60px;pointer-events:none;
  background:linear-gradient(90deg,transparent,var(--canvas))}
.bdg-rail{display:flex;gap:7px;overflow-x:auto;scrollbar-width:none;padding:1px 60px 2px 1px}
.bdg-rail::-webkit-scrollbar{display:none}
.bdg-chip{--bc:#3F3F49;flex:none;display:flex;align-items:center;gap:8px;height:38px;padding:0 12px 0 7px;
  border-radius:999px;border:1px solid var(--border);background:var(--surface2);
  transition:background .18s,border-color .18s}
.bdg-chip:hover{background:color-mix(in srgb,var(--bc) 9%,var(--surface));
  border-color:color-mix(in srgb,var(--bc) 34%,var(--border))}
.bdg-chip .hex{width:22px;height:25px;font-size:10px;
  filter:saturate(.14) opacity(.78);transition:filter .18s}
.bdg-chip:hover .hex{filter:none}
.bdg-chip b{font-size:12.5px;font-weight:500;white-space:nowrap;color:var(--t2);transition:color .18s}
.bdg-chip:hover b{color:color-mix(in srgb,var(--bc) 68%,var(--text))}
.bdg-chip .dt{font:400 10.5px var(--mono);color:var(--t3)}
@media(max-width:1100px){.bdg-feat{grid-template-columns:repeat(2,1fr)}}
@media(max-width:680px){
  .bdg-feat{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;padding-bottom:2px}
  .bdg-feat::-webkit-scrollbar{display:none}
  .bdg-card{flex:none;width:206px}
}

/* ==========================================================================
   BLOCK E — TABS (sticky under the nav) + PANES
   ========================================================================== */
.vtabs-w{position:sticky;top:60px;z-index:30;margin-top:20px;
  background:color-mix(in srgb,var(--canvas) 88%,transparent);backdrop-filter:blur(12px) saturate(1.4);
  border-bottom:1px solid var(--border)}
.vtabs-w .ptab{margin:0;border-bottom:0}
.ptab button .c{font:400 11.5px var(--mono);color:var(--t3);margin-left:6px}
.ptab button.on .c{color:var(--accent-fg)}
#pg-myvehicle .pane{padding-top:26px}
@media(max-width:760px){.vtabs-w{top:54px}}

/* --- PHOTOS (unified, Instagram-style) --------------------------------- */
.ph-bar{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.ph-filter{display:flex;gap:7px;overflow-x:auto;scrollbar-width:none;flex:1;min-width:0;padding-bottom:2px}
.ph-filter::-webkit-scrollbar{display:none}
.ph-filter button{flex:none;height:30px;padding:0 13px;border-radius:999px;border:1px solid var(--border);
  background:var(--surface);font-size:12.5px;font-weight:500;color:var(--t2);box-shadow:var(--sh-sm);
  transition:background .16s,color .16s,border-color .16s}
.ph-filter button:hover{color:var(--text);border-color:var(--border2)}
.ph-filter button.on{background:var(--text);border-color:var(--text);color:var(--canvas)}
.ph-filter button .n{opacity:.5;margin-left:5px;font-family:var(--mono);font-size:11px}
.pgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:5px;border-radius:var(--r-lg);overflow:hidden}
.pgrid .photo{aspect-ratio:1;border-radius:0;cursor:pointer}
.pgrid .photo .ph-img{transition:opacity .6s var(--ease),transform .5s var(--ease)}
.pgrid .photo:hover .ph-img{transform:scale(1.045)}
.pgrid .ov{position:absolute;inset:0;z-index:5;display:flex;flex-direction:column;justify-content:flex-end;
  padding:12px;opacity:0;transition:opacity .2s var(--ease);
  background:linear-gradient(180deg,transparent 42%,rgba(6,6,10,.8))}
.pgrid .photo:hover .ov{opacity:1}
.pgrid .ov b{font-size:12.5px;font-weight:500;color:#fff;letter-spacing:-.012em;line-height:1.35}
.pgrid .ov span{font-size:10px;color:rgba(255,255,255,.62);margin-top:3px;font-family:var(--mono);letter-spacing:.04em}
.pgrid .tagp{position:absolute;left:9px;top:9px;z-index:4;height:21px;padding:0 8px;border-radius:999px;
  background:rgba(10,10,12,.5);border:1px solid rgba(255,255,255,.16);backdrop-filter:blur(6px);
  font:500 10.5px/20px var(--ui);color:rgba(255,255,255,.92);opacity:0;transition:opacity .2s var(--ease)}
.pgrid .photo:hover .tagp{opacity:1}
@media(max-width:640px){.pgrid{gap:3px;border-radius:0}}


/* --- MY PROJECTS ------------------------------------------------------- */
.pj-lead{display:grid;grid-template-columns:1.2fr 1fr;border:1px solid var(--border);
  border-radius:var(--r-xl);overflow:hidden;background:var(--surface);box-shadow:var(--sh);margin-bottom:16px}
.pj-lead .photo{border-radius:0;min-height:370px}
.pj-lead .bd{padding:26px 30px 24px;display:flex;flex-direction:column}
.pj-lead h3{font-size:25px;letter-spacing:-.034em;margin:13px 0 0}
.pj-lead p{font-size:14.5px;color:var(--t2);line-height:1.6;margin-top:10px;max-width:42ch}
.pj-strip{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-top:18px}
.pj-strip .photo{aspect-ratio:1;border-radius:9px;min-height:0;cursor:pointer}
.pj-bar{height:5px;border-radius:99px;background:var(--surface3);overflow:hidden;margin-top:20px}
.pj-bar i{display:block;height:100%;border-radius:99px;background:var(--accent)}
.pj-pct{display:flex;justify-content:space-between;font-size:11.5px;color:var(--t3);margin-top:8px}
.pj-meta{display:flex;gap:22px;flex-wrap:wrap;margin-top:auto;padding-top:22px}
.pj-meta div b{display:block;font-family:var(--dis);font-size:18px;font-weight:600;letter-spacing:-.03em;line-height:1}
.pj-meta div span{font-size:10px;color:var(--t3);letter-spacing:.05em;margin-top:4px;display:block}
.pj-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.pj-card{position:relative;border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);
  box-shadow:var(--sh-sm);transition:transform .2s var(--ease),box-shadow .2s var(--ease)}
.pj-card:hover{transform:translateY(-3px);box-shadow:var(--sh)}
/* owner edit/delete controls on a project card — reveal on hover/focus */
.pj-acts{position:absolute;top:8px;right:8px;z-index:6;display:flex;gap:6px;
  opacity:0;transition:opacity .15s var(--ease)}
.pj-card:hover .pj-acts,.pj-card:focus-within .pj-acts{opacity:1}
.pj-btn{width:28px;height:28px;padding:0;display:grid;place-items:center;border-radius:8px;
  background:rgba(10,10,12,.66);border:1px solid rgba(255,255,255,.28);color:#fff;cursor:pointer;backdrop-filter:blur(5px)}
.pj-btn:hover{background:rgba(10,10,12,.85)}
.pj-btn.pj-del{border-radius:50%;background:rgba(220,38,38,.92);border-color:rgba(255,255,255,.4)}
.pj-btn.pj-del:hover{background:#B91C1C;border-color:#fff}
.pj-btn svg{display:block}
.pj-card > .photo{border-radius:0;aspect-ratio:16/10}
.pj-card > .nocover{aspect-ratio:16/10;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:8px;background:repeating-linear-gradient(135deg,var(--surface2),var(--surface2) 9px,var(--surface3) 9px,var(--surface3) 18px);
  color:var(--t3);border-bottom:1px solid var(--border)}
.pj-card > .nocover span{font-size:11.5px;font-weight:500;letter-spacing:.02em}
.pj-card:hover > .nocover{color:var(--accent-fg)}
.pj-card .bd{padding:15px 16px 14px}
.pj-card h4{font-size:15.5px;letter-spacing:-.024em}
.pj-card p{font-size:13px;color:var(--t2);line-height:1.5;margin-top:6px}
.pj-card .fm{display:flex;align-items:center;gap:10px;margin-top:13px;font-size:11.5px;color:var(--t3)}
.pj-card .fm em{font-style:normal;margin-left:auto}
.pj-thumbs{display:grid;grid-template-columns:repeat(4,1fr);gap:3px;padding:0 16px 16px}
.pj-thumbs .photo{aspect-ratio:1;border-radius:6px}
/* project logged with nothing shot yet */
.pj-thumbs.none{display:block}
.pj-thumbs.none .noshots{border:1.5px dashed var(--border2);border-radius:8px;background:var(--surface2);
  padding:13px;text-align:center;font-size:11.5px;color:var(--t3);line-height:1.45}
.pj-thumbs.none .noshots b{display:block;font-family:var(--ui);font-size:12px;font-weight:600;
  color:var(--t2);margin-bottom:2px}
@media(max-width:980px){.pj-lead{grid-template-columns:1fr}.pj-lead .photo{min-height:250px}
  .pj-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:640px){.pj-grid{grid-template-columns:1fr}.pj-lead .bd{padding:20px}}

/* --- MY PARTS ---------------------------------------------------------- */
.mp{border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);box-shadow:var(--sh-sm)}
.mprow{display:grid;grid-template-columns:62px minmax(0,1fr) 172px 104px;gap:16px;align-items:center;
  padding:12px 16px;border-bottom:1px solid var(--border);transition:background .14s}
.mprow:last-of-type{border-bottom:0}
.mprow:hover{background:var(--surface2)}
.mprow .photo{width:62px;height:47px;border-radius:8px}
.mprow h4{font-size:14.5px;font-weight:500;letter-spacing:-.016em}
.mprow .pn{font:400 11.5px var(--mono);color:var(--t3);margin-top:4px}
.mprow .fit{font-size:12.5px;color:var(--t3)}
.mprow .fit b{display:block;font-weight:500;color:var(--text);font-size:12.5px;margin-bottom:2px}
.mprow .price{text-align:right;font-family:var(--dis);font-size:16px;font-weight:600;letter-spacing:-.024em}
.mprow .price span{display:block;font:400 10.5px var(--ui);color:var(--t3);margin-top:3px;letter-spacing:0}
/* part logged without a photo. Dashed slot, and for the owner it doubles as
   the upload target — the gap becomes a prompt instead of a hole. */
.noimg{width:62px;height:47px;border-radius:8px;flex:none;display:grid;place-items:center;
  border:1.5px dashed var(--border2);background:var(--surface2);color:var(--t3);
  transition:border-color .16s,background .16s,color .16s}
.noimg .ic{display:block}
.noimg .plus{display:none;font:600 10px var(--ui);letter-spacing:.02em}
.mprow:hover .noimg{border-color:var(--accent-line);background:var(--accent-soft);color:var(--accent-fg)}
.mprow:hover .noimg .ic{display:none}
.mprow:hover .noimg .plus{display:block}
.mprow.nophoto h4{color:var(--t2)}
.mprow .flag{display:inline-flex;align-items:center;height:17px;padding:0 6px;border-radius:4px;margin-left:8px;
  font:600 9.5px/1 var(--ui);letter-spacing:.05em;background:var(--surface3);color:var(--t3);vertical-align:1px}
.mp-foot{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:12px 16px;
  border-top:1px solid var(--border);font-size:12.5px;color:var(--t3)}
.mp-sum{display:flex;gap:28px;flex-wrap:wrap;padding:14px 16px;background:var(--surface2);border-top:1px solid var(--border)}
.mp-sum div b{display:block;font-family:var(--dis);font-size:18px;font-weight:600;letter-spacing:-.03em;line-height:1}
.mp-sum div span{font-size:10px;color:var(--t3);letter-spacing:.05em;margin-top:4px;display:block}
@media(max-width:820px){
  .mprow{grid-template-columns:54px minmax(0,1fr) 88px;gap:12px}
  .mprow .photo{width:54px;height:42px}
  .mprow .fit{display:none}
}

/* --- ABOUT ------------------------------------------------------------- */
.ab{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:44px;align-items:start}
.ab .lead{font-family:var(--dis);font-size:21px;font-weight:500;letter-spacing:-.028em;line-height:1.4;max-width:34ch}
.ab .body p{font-size:15px;color:var(--t2);line-height:1.72;margin-top:17px;max-width:62ch}
.facts{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);box-shadow:var(--sh-sm);overflow:hidden}
.facts div{display:flex;justify-content:space-between;gap:16px;padding:11px 16px;border-bottom:1px solid var(--border);font-size:13.5px}
.facts div:last-child{border-bottom:0}
.facts dt{color:var(--t3);font-size:12.5px}
.facts dd{margin:0;font-weight:500;text-align:right;letter-spacing:-.012em}
.nextlist .n{display:flex;justify-content:space-between;align-items:center;gap:14px;padding:10px 0;
  border-bottom:1px solid var(--border);font-size:13.5px}
.nextlist .n:last-child{border-bottom:0}
@media(max-width:900px){.ab{grid-template-columns:1fr;gap:28px}}

/* ---- editing modal (profile, garage) ---- */
.amsmodal-back{position:fixed;inset:0;z-index:2000;display:flex;align-items:flex-start;justify-content:center;
  padding:6vh 16px 16px;background:rgba(8,8,12,.62);backdrop-filter:blur(3px);overflow:auto}
.amsmodal{width:100%;max-width:520px;background:var(--surface);border:1px solid var(--border2);
  border-radius:16px;box-shadow:var(--sh-lg);overflow:hidden}
.amsmodal-h{display:flex;align-items:center;gap:12px;padding:16px 18px;border-bottom:1px solid var(--border)}
.amsmodal-h h3{margin:0;font-family:var(--dis);font-size:18px;font-weight:600;flex:1}
/* The bare header close button is a 32×32 icon. When .amsmodal-x is added to a
   real .btn (the footer "Cancel"), it is only a close-click hook — keep the .btn
   look and skip the icon-box sizing. */
.amsmodal-x:not(.btn){width:32px;height:32px;border-radius:9px;border:1px solid var(--border2);background:none;
  color:var(--t2);cursor:pointer;font-size:14px;display:grid;place-items:center}
.amsmodal-x:not(.btn):hover{background:var(--surface2);color:var(--text)}
.amsmodal-b{padding:18px}
.amsfield{margin-bottom:14px}
.amsfield>label{display:block;font-size:12.5px;font-weight:600;color:var(--t2);margin-bottom:6px}
.amsfield .hint{font-size:11.5px;color:var(--t3);margin-top:5px}
.amsrow{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.amsmodal-f{display:flex;align-items:center;justify-content:flex-end;gap:9px;margin-top:6px}
.amsmodal-err{color:#F87171;font-size:12.5px;margin-right:auto;align-self:center}

/* ---- floating BUG/CHANGE button (every screen) ----
   BOTTOM-LEFT ON A DESKTOP, AND ON A PHONE IT STACKS ABOVE THE CHAT BUTTON ON
   THE RIGHT. It sat bottom-right until the chat dock took that corner: the fan
   of chat bubbles is anchored to the right edge, and two things fighting over
   one corner is how a button ends up under a panel nobody can move. On a wide
   screen they still own one corner each and neither has to know the other's
   size.

   A PHONE HAS ONLY ONE CORNER WORTH REACHING. Both of these are thumb targets
   and the right one is where the hand already is, so the site's two floating
   buttons are one column there rather than one in each corner — which also
   leaves the bottom-LEFT free for the screens that put something in it (the
   hive's legend, the admin bar's reveal pill), instead of every one of them
   having to lift a button out of the way. They do not fight over the corner,
   because the dock publishes where its top edge is (--cd-top, declared beside
   --cd-bub in css/26-chat-dock.php) and this button stands on that rather than
   on a copy of the dock's height. The two consumers that MEASURE this button
   — the fan's own width and the hive's legend — ask whether it is really in
   their way rather than assuming it, so neither reserves room for a button
   that has moved off their side.

   Two numbers, and they mean different things. --floor is the site's CHROME at
   the bottom edge — the admin bar, the phone's tab bar, the home indicator —
   and every fixed thing on the site clears it. --fab-lift is whatever the
   CURRENT SCREEN puts in this corner (0 on screens with none). Messages is the
   one that made the second necessary: its composer spans the chat column, so
   at phone width the button lands on it whichever side it is on. */
.ams-fab{position:fixed;left:20px;bottom:calc(20px + var(--floor,0px) + var(--fab-lift,0px));z-index:1200;display:inline-flex;align-items:center;gap:8px;
  padding:11px 17px;border:1px solid var(--accent);border-radius:999px;cursor:pointer;
  background:var(--accent);color:var(--accent-ink);font-size:13px;font-weight:600;letter-spacing:-.01em;
  box-shadow:0 6px 20px rgba(234,88,12,.34),0 2px 6px rgba(0,0,0,.14);
  transition:filter .14s var(--ease),transform .12s var(--ease),box-shadow .14s var(--ease)}
.ams-fab:hover{filter:brightness(1.06);transform:translateY(-1px);box-shadow:0 10px 26px rgba(234,88,12,.42),0 3px 8px rgba(0,0,0,.16)}
.ams-fab:active{transform:translateY(0)}
.ams-fab svg{flex:none;color:#fff}
/* busy state: the screen grab starts on click and runs for a couple of seconds,
   so the button itself answers the click — it goes grey and inert, the bug icon
   becomes a spinner, and the label says what is happening. The accent is
   reserved for "you can press this"; a greyed button reads as taken. Cleared
   when the capture settles. (The capture is deliberately started one painted
   frame later, or none of this would ever reach the screen — see captureScreen.) */
.ams-fab .fab-spin{display:none;flex:none;width:16px;height:16px;border-radius:50%;box-sizing:border-box;
  border:2px solid rgba(255,255,255,.4);border-top-color:#fff;animation:ams-spin .7s linear infinite}
.ams-fab .fab-lbl-busy{display:none}
.ams-fab.is-busy{
  background:var(--t3);border-color:var(--t3);color:#fff;
  cursor:progress;pointer-events:none;transform:none;
  box-shadow:0 2px 8px rgba(0,0,0,.14)}
.ams-fab.is-busy:hover{filter:none;transform:none;box-shadow:0 2px 8px rgba(0,0,0,.14)}
.ams-fab.is-busy .fab-ic,.ams-fab.is-busy .fab-lbl{display:none}
.ams-fab.is-busy .fab-spin,.ams-fab.is-busy .fab-lbl-busy{display:inline-block}
@media(prefers-reduced-motion:reduce){ .ams-fab .fab-spin{animation-duration:1.6s} }
/* The staff bar and the phone's tab bar used to be two more rules here, each
   with its own copy of a height — which is how the phone case came to be 70px
   above a 72px bar and sit ON it. Both are in --floor now, so the one `bottom`
   above is the whole answer and cannot go stale when a bar changes height. */
/* WHILE A SHEET OWNS THE SCREEN THIS BUTTON STANDS DOWN. The rule is in
   css/26-chat-dock.php with the dock's — the two corners are one sentence and
   were one bug (a full-width sheet's footer runs under both), so they are one
   rule rather than two that could come to disagree. */
/* Messages: the chat surface publishes its live composer height as --msg-comph
   (js/08-admin-router/08-messages.php), 0 on the screens that have no composer
   — the inbox with nothing open, the friend picker, a public thread whose reply
   box scrolls with the stream. The class is toggled by the router, so leaving
   chat drops the lift with it. */
body.onmsgs{--fab-lift:var(--msg-comph,74px)}
/* An operator who collapses the admin bar gets `.ab-reveal` — a pill fixed
   at left:12px, bottom:12px, z-index 1901. That is this corner, and it
   outranks the button, so without this the FAB is simply underneath it.
   The lift is what --fab-lift is for: the screen says how much room its
   own control takes and the button rides above it. 34px of pill plus a
   12px gap. */
body.ab-collapsed{--fab-lift:46px}
/* PHONES: drop the label — it is the only busy signal there — and move the
   button to the right gutter, directly above the chat dock's New-message
   button. It is the dock's own gutter (--cd-edge) and the dock's own published
   top edge (--cd-top), so the two are one column by construction: change the
   bubble's size and this follows it. `left:auto` is not optional — the base
   rule pins the left edge, and an element with both left and right pinned is
   stretched between them rather than moved.

   --floor is NOT added here: --cd-top already carries it. --fab-lift still is,
   because a screen that puts its own furniture in this corner (the messages
   composer, which spans the column and is there whether or not the dock is)
   is exactly what that number is for. */
@media(max-width:560px){
  .ams-fab .fab-lbl,.ams-fab.is-busy .fab-lbl-busy{display:none}
  .ams-fab{padding:12px;left:auto;right:var(--cd-edge,20px);
    bottom:calc(var(--cd-top) + 12px + var(--fab-lift,0px))}
  /* The 46px above is the reveal pill's, and the pill is at left:12px — the
     corner this button has just left. Owed no longer, and a 46px gap opening
     between it and the chat button is what paying it here would look like.
     The messages composer's lift is a different number for a different reason
     and is deliberately still owed, which is why this is not a flat 0. */
  body.ab-collapsed:not(.onmsgs){--fab-lift:0px}
}
/* One-time onboarding flyout that introduces the Bug button (created in JS,
   positioned off the button's live rect). Sits above the FAB with a caret
   pointing at it; theme-aware; z above the FAB but below modals. */
.ams-bugtip{position:fixed;z-index:1300;max-width:290px;width:calc(100vw - 28px);
  background:var(--surface);color:var(--text);border:1px solid var(--border);border-radius:14px;
  padding:15px 16px 16px;box-shadow:0 16px 42px rgba(0,0,0,.19),0 4px 12px rgba(0,0,0,.10);
  opacity:0;transform:translateY(8px) scale(.98);transform-origin:bottom left;
  transition:opacity .2s var(--ease),transform .2s var(--ease);pointer-events:none}
.ams-bugtip.in{opacity:1;transform:none;pointer-events:auto}
.ams-bugtip.out{opacity:0;transform:translateY(6px) scale(.98)}
/* The caret points DOWN at the button, from whichever side the button is on:
   left on a desktop, right on a phone, where it has moved to the chat dock's
   corner. `.r` is set by placeBugTip() off the button's live rect rather than
   by a media query of its own — the card is pinned to the same edge its caret
   is drawn from, and one of those two deciding on its own is how the caret
   ends up pointing at empty page. */
.ams-bugtip::after{content:"";position:absolute;bottom:-7px;left:26px;width:13px;height:13px;
  background:var(--surface);border-right:1px solid var(--border);border-bottom:1px solid var(--border);
  transform:rotate(45deg)}
.ams-bugtip.r{transform-origin:bottom right}
.ams-bugtip.r::after{left:auto;right:26px}
.ams-bugtip .bt-h{display:flex;align-items:center;gap:10px;margin-bottom:8px;padding-right:22px}
.ams-bugtip .bt-i{flex:none;width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  background:var(--accent-soft);color:var(--accent)}
.ams-bugtip .bt-h b{font-size:14px;font-weight:650;letter-spacing:-.01em;line-height:1.25}
.ams-bugtip p{margin:0 0 13px;font-size:12.75px;line-height:1.5;color:var(--t2)}
.ams-bugtip .bt-ok{width:100%;border:0;border-radius:9px;background:var(--accent);color:var(--accent-ink);
  font-size:13px;font-weight:600;padding:9px 0;cursor:pointer;font-family:inherit;
  transition:filter .14s var(--ease)}
.ams-bugtip .bt-ok:hover{filter:brightness(1.06)}
.ams-bugtip .bt-x{position:absolute;top:9px;right:9px;width:26px;height:26px;border:0;border-radius:7px;
  display:grid;place-items:center;background:none;color:var(--t3);cursor:pointer}
.ams-bugtip .bt-x:hover{background:var(--surface2);color:var(--text)}
@media(max-width:560px){ .ams-bugtip::after{left:20px} .ams-bugtip.r::after{left:auto;right:20px} }
@media(prefers-reduced-motion:reduce){
  .ams-bugtip{transition:opacity .2s linear}
  .ams-bugtip.in,.ams-bugtip.out{transform:none}
}

/* segmented toggle used in the report modal (bug vs change) */
.fbseg{display:flex;gap:4px;padding:4px;border:1px solid var(--border);border-radius:11px;background:var(--surface2)}
.fbseg-b{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:9px 12px;
  border:0;border-radius:8px;background:transparent;color:var(--t2);font-size:13px;font-weight:600;cursor:pointer;
  transition:background .12s var(--ease),color .12s var(--ease)}
.fbseg-b:hover{color:var(--text)}
.fbseg-b.on{background:var(--surface);color:var(--text);box-shadow:0 1px 2px rgba(0,0,0,.09)}
/* condensed layout for the report modal */
.fbmodal .amsmodal-b{padding:15px 18px 16px}
.fbmodal .amsfield{margin-bottom:10px}
.fbmodal .amsfield>label{margin-bottom:4px}
.fbmodal .fbseg{padding:3px}
.fbmodal .fbseg-b{padding:7px 6px;font-size:12.5px;gap:5px}
.fbmodal .amsup-zone{min-height:0;padding:13px}
.fbmodal .amsup-zone .amsup-cta span{display:none}
.fbmodal.amsmodal{max-width:440px}
.fbmodal .amsup-grid{grid-template-columns:repeat(auto-fill,minmax(64px,1fr));margin-top:8px}
.fbmodal [data-fbsend]:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}
/* Screenshot status strip: the capture is the slow half of this modal (script
   fetch → rasterise → encode → upload), so every stage names itself here with a
   live indeterminate bar. Goes green on ready, amber when the grab failed. */
.fbshot{position:relative;display:flex;align-items:flex-start;gap:10px;overflow:hidden;
  padding:10px 12px 11px;margin-bottom:8px;border:1px solid var(--border);border-radius:10px;
  background:var(--surface2)}
.fbshot-ic{flex:none;width:20px;height:20px;display:grid;place-items:center;color:var(--t2)}
.fbshot .ams-spin{width:15px;height:15px;border-width:2px;border-color:var(--border2);border-top-color:var(--accent)}
.fbshot-t{display:flex;flex-direction:column;gap:2px;min-width:0}
.fbshot-t b{font-size:12.5px;font-weight:600;color:var(--text);letter-spacing:-.01em}
.fbshot-sub{font-size:11.5px;line-height:1.4;color:var(--t3)}
.fbshot-bar{position:absolute;left:0;right:0;bottom:0;height:2px;overflow:hidden}
.fbshot-bar i{position:absolute;top:0;height:100%;width:38%;background:var(--accent);border-radius:2px;
  animation:fbshot-slide 1.2s var(--ease) infinite}
@keyframes fbshot-slide{0%{left:-40%}100%{left:100%}}
.fbshot.is-ready{border-color:rgba(34,197,94,.42)}
.fbshot.is-ready .fbshot-ic{color:#22C55E}
.fbshot.is-warn{border-color:rgba(229,162,61,.45)}
.fbshot.is-warn .fbshot-ic{color:#E5A23D}
.fbshot.is-ready .fbshot-bar,.fbshot.is-warn .fbshot-bar{display:none}
/* Marking where it is wrong. Optional and skippable, so it is a quiet block
   under the shot rather than a step in the way: the box is drawn straight onto
   a thumbnail of the capture and stored as percentages, which is what lets the
   lab draw the same region at 46px in a queue row and full width in the item
   pane. */
.fbmark{margin-top:10px}
.fbmark p{margin:0 0 6px}
.fbmark-shot{position:relative;border:1px solid var(--border);border-radius:9px;overflow:hidden;
  background:var(--surface2);cursor:crosshair;touch-action:none;line-height:0}
.fbmark-shot img{width:100%;display:block;pointer-events:none;user-select:none}
.fbmark-box{position:absolute;border:2px solid #E5484D;border-radius:3px;pointer-events:none;
  box-shadow:0 0 0 9999px rgba(10,10,12,.42)}
.fbmark [data-fbmarkclear]{margin-top:7px}
@media(prefers-reduced-motion:reduce){
  .fbshot-bar i{animation:none;left:0;width:100%;opacity:.45}
}


/* =====================================================================
   THE VEHICLE PROFILE — /garage/{owner}/{slug}

   One scroll: a two-column hero — the photograph in a contained frame,
   the car's whole record beside it — then a dark data slab, then
   Photos · Mods · Spec · Owner.

   IT USED TO BE A FULL-BLEED BAND WITH THE RECORD STACKED UNDER IT, and
   the reason it is not any more is what a band is sized by: the WINDOW.
   At 1900px the cover was 620px of a 4:3 photograph squeezed into a
   3:1 letterbox, so a car shot from three-quarters on lost its roof and
   its sills and what survived was a strip of door — and the crop was a
   DIFFERENT crop at every width, so what an owner positioned was not
   what anybody else saw. A 3:2 frame takes 11% off a 4:3 photo on a
   phone and on a 5K display alike.

   It still carries nothing written on it, which is the rule the member
   profile taught (23-profile.php): a car's cover is the one photograph
   on the page its owner chose, and a headline across it is a caption
   nobody asked for sitting exactly where the car is.

   TOKENS ARE THE SITE'S, DELIBERATELY. The design was drawn against its
   own ladder — --panel, --line, --ink-2, --sunken — and every one of those
   is mapped here once (--surface, --border, --t2, --surface2) rather than
   redeclared. A page carrying its own palette is a page that stops moving
   when the palette does; 24-image-picker.php shipped written against
   another page's private names and every declaration was silently dropped
   outside that page, which looked deliberate and survived for it.

   CLASS PREFIX IS vpro-. The mockup's own names (.cover, .card, .sec,
   .row, .chip, .sheet, .pop, .grid2) are what you would call things in a
   file that styles one page; this stylesheet is one document for the whole
   site, and half of those already mean something else in it.

   NOT vp-, WHICH IS TAKEN. That was the obvious prefix and it is already
   worn by seventy classes across the vendor page and the vehicle spine —
   including .vp-card, which is `width:250px;aspect-ratio:16/10`. This
   file's own .vp-card lost to it, so the section cards came out 250px wide
   in a 1220px column with their contents wrapping one word per line, and
   nothing anywhere reported a thing: both rules were valid, both applied,
   and the later one simply lost. Check a prefix against the built
   stylesheet before choosing it.
   ===================================================================== */

/* ---- the hero: photograph and record, side by side ------------------- */
/* The picture gets the larger share because it is the thing somebody came
   for; the record gets enough to set the name at a real size and still
   hold a row of verbs on one line. */
/* The bottom padding is the seam. The slab is meant to be a hard edge under
   the hero, not a collision with it: with none, the filmstrip's last row of
   thumbnails ended exactly on the slab's accent rule, and a border touching
   a border reads as a layout that has run out of room. */
.vpro-hero{max-width:var(--col);margin:0 auto;padding:var(--pad-top) var(--pad) 30px}
.vpro-hero__grid{display:grid;grid-template-columns:minmax(0,1.22fr) minmax(0,1fr);
  gap:44px;align-items:start}
.vpro-hero__left{min-width:0}

/* ---- the frame ------------------------------------------------------- */
/* 3:2, so the crop is the same on every screen. The lift is what separates
   it from the page now that no full-bleed edge does. */
.vpro-cover{position:relative;width:100%;aspect-ratio:3/2;border-radius:var(--r-lg);
  background:var(--surface2);border:1px solid var(--border);box-shadow:var(--sh-lg);
  overflow:hidden;user-select:none}
/* One layer per photo; only the one wearing .on is visible. They are all in
   the document rather than swapped in on demand because the filmstrip is a
   BROWSE — pressing a thumbnail must not wait on a network round trip to
   show a photo the page already has. */
.vpro-shot{position:absolute;inset:0;opacity:0;transition:opacity .4s var(--ease)}
.vpro-shot.on{opacity:1}
.vpro-shot img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
/* The blurred under-layer only exists for "fit the whole photo", where the
   image no longer fills the frame and something has to be behind it. It is
   the photo itself rather than a flat colour, so a portrait shot sits in a
   wash of its own colours instead of two grey bars. */
.vpro-shot__blur{inset:-6% !important;width:112% !important;height:112% !important;
  filter:blur(42px) saturate(1.2) brightness(.9);opacity:0;transition:opacity .3s}
.vpro-cover.is-fit .vpro-shot__blur{opacity:1}
.vpro-cover.is-fit .vpro-shot__fg{object-fit:contain}

/* ---- repositioning --------------------------------------------------- */
/* The drag is mountPhotoEditor's, in both axes (migration 348). What is
   here is only what the owner sees while it is happening. */
.vpro-cover.is-editing{cursor:grab}
.vpro-cover.is-editing.is-drag{cursor:grabbing}
.vpro-cover.is-editing .vpro-shot__fg{transition:none}
/* The accent ring says the frame itself is what is being changed. Inset, so
   it cannot add a pixel to the cover's height and make the page jump when
   repositioning opens. */
.vpro-cover.is-editing::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:5;
  box-shadow:inset 0 0 0 3px var(--accent);border-radius:var(--r-lg)}
/* Thirds, drawn only while repositioning. Two gradients rather than four
   elements: this is a guide that appears for a few seconds and adding DOM
   for it means adding it to both twins. */
.vpro-guide{position:absolute;inset:0;opacity:0;pointer-events:none;transition:opacity .2s;z-index:4}
.vpro-cover.is-editing .vpro-guide{opacity:1}
.vpro-guide::before,.vpro-guide::after{content:"";position:absolute;inset:0}
.vpro-guide::before{background:linear-gradient(to right,
  transparent calc(33.33% - .5px),rgba(255,255,255,.5) calc(33.33% - .5px) calc(33.33% + .5px),
  transparent calc(33.33% + .5px),transparent calc(66.66% - .5px),
  rgba(255,255,255,.5) calc(66.66% - .5px) calc(66.66% + .5px),transparent calc(66.66% + .5px))}
.vpro-guide::after{background:linear-gradient(to bottom,
  transparent calc(33.33% - .5px),rgba(255,255,255,.5) calc(33.33% - .5px) calc(33.33% + .5px),
  transparent calc(33.33% + .5px),transparent calc(66.66% - .5px),
  rgba(255,255,255,.5) calc(66.66% - .5px) calc(66.66% + .5px),transparent calc(66.66% + .5px))}

/* ---- the controls that float over it --------------------------------- */
/* NO EDGE MATHS ANY MORE. Edit cover used to need a max() to line up with
   the content column, because the band it sat on ran wider than the column
   underneath it. The frame IS in the column now, so the button is simply
   inset from the frame — one number, and one that cannot drift out of step
   with the page's padding. */
.vpro-covmenu{position:absolute;z-index:7;top:14px;right:14px}
.vpro-cover.is-editing .vpro-covmenu{display:none}

/* The glass treatment is for a control that sits ON a photograph: it has to
   read against a white sky and a black wheel arch alike, which no page
   colour does. */
.vpro-glass{background:rgba(16,16,20,.5);border-color:rgba(255,255,255,.28);color:#fff;
  backdrop-filter:blur(6px)}
.vpro-glass:hover{background:rgba(16,16,20,.74);border-color:rgba(255,255,255,.42);color:#fff}

.vpro-covmenu__list{position:absolute;top:calc(100% + 6px);right:0;min-width:210px;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  box-shadow:var(--sh-lg);padding:5px;z-index:8}
.vpro-covmenu__list[hidden]{display:none}
.vpro-covmenu__i{display:flex;align-items:center;gap:9px;width:100%;text-align:left;border:0;
  background:transparent;color:var(--text);font:500 13px var(--ui);padding:8px 10px;
  border-radius:6px;cursor:pointer;white-space:nowrap}
.vpro-covmenu__i:hover{background:var(--surface2)}
.vpro-covmenu__i svg{width:15px;height:15px;color:var(--t3);flex:none}
.vpro-covmenu__i:hover svg{color:var(--accent)}
/* The tick is always in the markup and only ever changes opacity, so the row
   does not change width the moment "fit whole photo" is turned on. */
.vpro-covmenu__i .vpro-tick{margin-left:auto;color:var(--accent);opacity:0}
.vpro-covmenu__i.on .vpro-tick{opacity:1}

/* the reposition bar, across the top of the photo while it is being dragged */
.vpro-repos{position:absolute;left:0;right:0;top:0;z-index:7;display:flex;align-items:center;
  justify-content:space-between;gap:14px;padding:13px 14px;flex-wrap:wrap;
  background:linear-gradient(to bottom,rgba(16,16,20,.9),rgba(16,16,20,.34) 70%,transparent)}
.vpro-repos[hidden]{display:none}
.vpro-repos__hint{display:inline-flex;align-items:center;gap:9px;color:#fff;font:600 12.5px var(--ui)}
.vpro-repos__hint svg{width:16px;height:16px;flex:none}
/* The live readout is the only place the stored value is visible. It is mono
   because it is a measurement, and it is here because a drag with no number
   on it cannot be repeated. */
.vpro-repos__n{font:500 11px var(--mono);letter-spacing:.08em;color:rgba(255,255,255,.74)}
.vpro-repos__ac{display:inline-flex;gap:8px}
.vpro-repos__ghost{background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.32);color:#fff;
  backdrop-filter:blur(4px)}
.vpro-repos__ghost:hover{background:rgba(255,255,255,.27);border-color:rgba(255,255,255,.46);color:#fff}

/* ---- the filmstrip --------------------------------------------------- */
/* A BROWSE, NOT A COVER PICKER. Pressing one shows that photo in the frame
   for this visit and saves nothing; "Make cover" on a gallery tile is the
   one thing that sets a cover. Two controls that both looked like they
   changed the cover, one of which silently did, is the worse arrangement —
   an idle click would have been a permanent change to somebody's page.

   IT IS A ROW UNDER THE PHOTOGRAPH, not four stamps over its bottom-right
   corner — which is where a car photographed from three-quarters on
   actually is. The cells divide the frame's width between them, so they
   are large enough to tell two silver cars apart, which is the only thing
   a strip is for; over the picture they had to be small enough not to
   cover it, and were therefore too small to choose between. */
.vpro-strip{display:flex;gap:9px;margin-top:10px}
 /* Every `.vpro-strip button` rule reads `.vpro-strip a` as well, because these
   are real links to the gallery (§12) and not in-memory toggles — the same
   edit the bench's ported stylesheet had to make, for the same reason. */
.vpro-strip button,.vpro-strip .vpro-strip__btn,.vpro-strip__rest{
  flex:1 1 0;min-width:0;aspect-ratio:16/10;border-radius:var(--r);overflow:hidden;
  transition:opacity .16s var(--ease),border-color .16s var(--ease),transform .16s var(--ease)}
.vpro-strip button,.vpro-strip .vpro-strip__btn{padding:0;border:1.5px solid var(--border);
  background:var(--surface2);cursor:pointer;opacity:.72}
.vpro-strip button img,.vpro-strip .vpro-strip__btn img{width:100%;height:100%;object-fit:cover;display:block}
.vpro-strip button:hover,.vpro-strip .vpro-strip__btn:hover{opacity:1;border-color:var(--border2)}
.vpro-strip button.on,.vpro-strip .vpro-strip__btn.on{opacity:1;border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent)}
/* "+5 more" is a LINK to the gallery below, not a button that does nothing.
   It is the rest of the photos, and the rest of the photos are a section on
   this page. Dashed, because it is the one cell that is not a photograph. */
.vpro-strip__rest{border:1.5px dashed var(--border2);display:grid;place-content:center;
  text-align:center;line-height:1.35;font:400 10px var(--mono);color:var(--t3)}
.vpro-strip__rest:hover{border-color:var(--accent);color:var(--accent-fg)}
/* Mid-crop the strip is not a way out: swapping the layer under a drag would
   move the photograph the owner is positioning. */
.vpro-cover.is-editing~.vpro-strip{opacity:.4;pointer-events:none}

/* ---- the phone's filmstrip: dots ---------------------------------------
   Four thumbnails dividing a 390px screen are 90px each — a picture of a
   car small enough that two silver ones are the same picture. Dots say
   what the strip says (how many, and which one) without pretending to
   show it, and the photograph they refer to is full width just above.
   Drawn always and hidden here, because the strip and the dots are one
   control at two sizes and both carry data-vpshot. */
.vpro-dots{display:none;gap:7px;align-items:center;justify-content:center;padding:12px 0 2px}
.vpro-dot{width:8px;height:8px;border-radius:50%;padding:0;border:0;cursor:pointer;
  flex:none;background:var(--border2);transition:.18s var(--ease)}
.vpro-dot.on{background:var(--accent);transform:scale(1.35)}
.vpro-dots__rest{font:400 10px var(--mono);color:var(--t3);margin-left:5px}
.vpro-dots__rest:hover{color:var(--accent-fg)}
.vpro-cover.is-editing~.vpro-dots{opacity:.4;pointer-events:none}

/* ---- the record, beside the photograph --------------------------------
   The crumbs, the name, what the car is, the owner's own phrase, the
   verbs, whose car it is, and what is on it — the whole record, level
   with the picture rather than a scroll below it.

   It was a band UNDER a full-bleed cover, which meant the two halves of
   "what am I looking at" were never on screen together. The name is
   smaller here than it was there and that is the trade: it is set to the
   column it is in, not to the window, so it stops growing past the point
   where it is the loudest thing on a page about a photograph. */
.vpro-id{min-width:0}
/* --dis is Inter Tight, the site's display face. The design asked for Inter
   at 800, which is a weight the site does not load — adding one for a single
   heading is 40kB on every page for one line of type. */
.vpro-name{font:700 clamp(34px,3.6vw,54px)/.94 var(--dis);letter-spacing:-.042em;margin:0;
  overflow-wrap:break-word}

/* the crumbs: where this car sits in the catalogue, in the site's
   small-caps mono — the same treatment every other eyebrow on the page
   wears, because that is what it is */
.vpro-crumbs{display:flex;flex-wrap:wrap;align-items:center;gap:7px;margin-bottom:15px;
  font:400 10.5px var(--mono);letter-spacing:.15em;text-transform:uppercase;color:var(--t3)}
.vpro-crumbs a:hover{color:var(--accent-fg)}
.vpro-crumbs i{font-style:normal;color:var(--border2)}

.vpro-ymm{margin-top:15px;display:flex;flex-wrap:wrap;align-items:center;gap:9px;
  font-size:17px;letter-spacing:-.014em;color:var(--t2)}
.vpro-ymm a{color:var(--text);box-shadow:inset 0 -1px 0 transparent;transition:.14s var(--ease)}
.vpro-ymm a:hover{color:var(--accent-fg);box-shadow:inset 0 -1px 0 var(--accent)}
.vpro-ymm__sep{color:var(--border2)}
.vpro-ymm__col{display:inline-flex;align-items:center;gap:8px;white-space:nowrap}
/* The paint chip. An owner who set a hex gets it; one who only typed a name
   gets the neutral gradient, because a swatch invented from a colour NAME
   would be this page claiming to know what "Reflex silver" looks like. */
.vpro-chip{width:12px;height:12px;border-radius:3px;flex:none;
  background:linear-gradient(140deg,#e4e6e9,#9aa0a8);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.2)}
/* The tagline, set like a decal: mono, tracked out, with a rule off its
   front. It is the one line on this page in the owner's own words, so it is
   given a treatment of its own rather than being another grey paragraph. */
.vpro-tag{margin:15px 0 0;display:inline-flex;align-items:center;gap:12px;
  font:500 11.5px var(--mono);letter-spacing:.2em;text-transform:uppercase;color:var(--t2)}
.vpro-tag::before{content:"";width:26px;height:2px;background:var(--accent);flex:none}
.vpro-acts{display:flex;flex-wrap:wrap;gap:8px;margin-top:24px}

/* ---- the owner --------------------------------------------------------
   They used to be the widest cell on the data slab, which set the one
   PERSON on the page in a row of measured figures — a name reading as a
   fifth statistic beside the odometer. Here they are what they are. */
.vpro-ownerrow{display:flex;align-items:center;gap:13px;margin-top:26px;padding-top:22px;
  border-top:1px solid var(--border)}
.vpro-ownerrow__who{display:flex;align-items:center;gap:13px;min-width:0;flex:1}
.vpro-ownerrow .av{flex:none}
.vpro-ownerrow__tx{min-width:0}
.vpro-ownerrow__tx b{display:block;font-size:15.5px;font-weight:600;letter-spacing:-.022em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vpro-ownerrow__tx span{display:block;margin-top:2px;font:400 11px var(--mono);color:var(--t3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vpro-ownerrow__who:hover .vpro-ownerrow__tx b{color:var(--accent-fg)}
/* Two verbs now — the person and their cars — so the slot is a row rather
   than a single button. gap matches the .vpro-acts strip above it. */
.vpro-ownerrow__go{margin-left:auto;flex:none;display:flex;align-items:center;gap:6px}

/* ---- on the car: the build sheet --------------------------------------
   What has been done to the thing in the photograph, while you are still
   looking at it. The Mods section further down is the writeups; this is
   the answer to the question the picture raises.

   IT WAS A ROW OF CHIPS, and chips could only list what exists — which
   hid the more interesting half of the story and repeated the Mods
   section verbatim. The open slots are here too now, so an empty system
   reads as a gap in the record rather than as a footnote on a card
   nobody scrolled to.

   THE THUMBNAIL IS THE STATUS: a photograph means it is on the car, an
   empty dashed frame means the slot is open. A badge saying which would
   be the same fact twice. Set as a list, with a dotted leader tying each
   entry to its label, the way a parts list does — the mod's own name
   leads, because that is what somebody is looking for, and the system it
   sits on is the label. */
.vpro-onthecar{margin-top:20px;padding-top:17px;border-top:1px solid var(--border)}
.vpro-onthecar__h{display:flex;align-items:baseline;gap:9px;margin-bottom:3px}
.vpro-onthecar__n{margin-left:auto;font:400 10.5px var(--mono);color:var(--t3)}
.vpro-onthecar__n b{color:var(--t2);font-weight:600}
.vpro-sysl{list-style:none;margin:0;padding:0}
.vpro-sysl a{display:flex;align-items:center;gap:11px;padding:6px 0;font-size:13px;
  border-top:1px solid var(--border)}
.vpro-sysl li:first-child a{border-top:none}
.vpro-sysl__th{width:30px;height:30px;flex:none;border-radius:5px;overflow:hidden;
  background:var(--surface2);border:1px solid var(--border);
  display:grid;place-items:center;color:var(--t3);transition:.16s var(--ease)}
.vpro-sysl__th img{width:100%;height:100%;object-fit:cover;display:block}
.vpro-sysl__th svg{width:22px;height:22px}
/* the open slot: a frame with nothing in it, which is what it is */
.vpro-sysl a.is-open .vpro-sysl__th{border-style:dashed;border-color:var(--border2);
  background:none}
.vpro-sysl a:hover .vpro-sysl__th{border-color:var(--accent)}
.vpro-sysl__ti{color:var(--text);font-weight:600;letter-spacing:-.012em;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;transition:color .14s}
.vpro-sysl a.is-open .vpro-sysl__ti{color:var(--t2);font-weight:500}
/* a dotted leader, so the eye can travel from the entry to its label */
.vpro-sysl__ld{flex:1;min-width:16px;height:0;align-self:center;margin-top:3px;
  border-bottom:1px dotted var(--border2);transition:border-color .14s}
.vpro-sysl__sy,.vpro-sysl__lg{font:400 10px var(--mono);letter-spacing:.1em;
  text-transform:uppercase;white-space:nowrap}
/* The label carries the system's own glyph before the words. No width here:
   .ic.cat-ic is the one rule that sizes a category mark, and a local one
   would outrank it silently (test/category-glyph-size.php). */
.vpro-sysl__sy{color:var(--t3);transition:color .14s;
  display:inline-flex;align-items:center;gap:5px}
/* The action appears in place of the state, and only on the row being
   pointed at — six standing "Log it" prompts down the column would nag,
   and the row already says it is empty. */
.vpro-sysl__lg{display:none;color:var(--accent-fg);font-weight:500}
.vpro-sysl a:hover .vpro-sysl__ti{color:var(--accent-fg)}
.vpro-sysl a:hover .vpro-sysl__sy{color:var(--t2)}
.vpro-sysl a:hover .vpro-sysl__ld{border-bottom-color:var(--accent)}
.vpro-sysl a.is-open:hover .vpro-sysl__sy,
.vpro-sysl a.is-open:focus-visible .vpro-sysl__sy{display:none}
.vpro-sysl a.is-open:hover .vpro-sysl__lg,
.vpro-sysl a.is-open:focus-visible .vpro-sysl__lg{display:inline}

@media(max-width:1040px){
  /* One column: the photograph, then the record. Below this width the two
     side by side would leave the name in a 300px gutter. */
  .vpro-hero__grid{grid-template-columns:1fr;gap:26px}
}
@media(max-width:760px){
  /* EDGE TO EDGE. Side gutters on a phone are var(--pad) of nothing either
     side of the one thing the reader came for, and a 3:2 crop of a 4:3
     photograph is tighter than it needs to be when the frame is the full
     width — 4:3 gives the car back its roof and its sills on the screen with
     the least room to spare. */
  .vpro-hero{padding-top:0}
  .vpro-hero__left{margin:0 calc(-1 * var(--pad))}
  .vpro-cover{aspect-ratio:4/3;border-radius:0;border-left:0;border-right:0;
    box-shadow:none;touch-action:pan-y}
  .vpro-cover.is-editing{touch-action:none}
  .vpro-cover.is-editing::after{border-radius:0}
  .vpro-strip{display:none}
  .vpro-dots{display:flex}
  .vpro-covmenu{top:10px;right:10px}
  .vpro-id{padding-top:18px}
  .vpro-name{font-size:clamp(30px,8.6vw,42px)}
  .vpro-crumbs{font-size:9.5px;gap:6px;margin-bottom:12px}
  .vpro-ymm{font-size:15.5px;gap:8px}
  .vpro-tag{font-size:10.5px;letter-spacing:.18em;margin-top:14px}
  .vpro-tag::before{width:20px}
  /* On a phone the actions are the reason the page is open: two up, with the
     primary across the top. A wrapped line of half-width buttons was three
     ragged rows. */
  .vpro-acts{width:100%;margin-top:20px;display:grid;grid-template-columns:1fr 1fr;gap:8px}
  .vpro-acts .btn{width:100%}
  .vpro-acts .btn-primary{grid-column:1/-1}
  .vpro-ownerrow{margin-top:20px;padding-top:18px;gap:11px}
  .vpro-ownerrow__go span{display:none}
  .vpro-onthecar{margin-top:18px;padding-top:16px}
  .vpro-sysl a{font-size:12.5px;gap:10px}
  .vpro-sysl__th{width:30px;height:30px}
  .vpro-sysl__sy,.vpro-sysl__lg{font-size:9.5px;letter-spacing:.08em}
  .vpro-repos{padding:10px 12px}
  .vpro-repos__n{display:none}
  .vpro-repos__ac{width:100%;justify-content:flex-end}
}

/* ---- the data slab ----------------------------------------------------
   The figures sit on a full-bleed dark band — the door-jamb data plate
   every car already carries — so the step from photograph to data is a hard
   edge rather than a fade into white. It is also what stops the numbers
   reading as a second row of navigation, which is what happened when they
   sat on the page in the same greys as everything else.

   IT IS DARK IN BOTH THEMES, and that is the point: it is a plate riveted
   to the page, not a surface that follows it. Its tokens are declared on
   the element itself so a dark member gets a slightly warmer, lower-contrast
   plate rather than the same near-black as the canvas behind it — at which
   point the whole device disappears. */
.vpro-slab{position:relative;
  --slab:#1B1A18; --slab-ink:#F5F3EF; --slab-2:#AAA69D; --slab-3:#7A766E;
  --slab-line:rgba(255,255,255,.13);
  background:var(--slab);color:var(--slab-ink)}
body.dark .vpro-slab{--slab:#211F1C; --slab-ink:#F6F4F0; --slab-2:#B0ACA2; --slab-3:#867F76;
  --slab-line:rgba(255,255,255,.10)}
/* the accent rule along the top edge — the seam between photo and plate */
.vpro-slab::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;background:var(--accent)}
/* FIVE FIGURES, AND THE FIRST IS THE WIDEST — because the first is the
   one the OWNER named. A fixed heading is the site deciding what matters
   about somebody else's car, so the widest column on the page belongs to
   whatever they put there.

   `is-short` is that slot not being drawn at all: unset, it is an
   invitation and only its owner gets one, so for everybody else the band
   is four cells and the wide column goes with it. Written as a modifier on
   the grid rather than `display:none` on the cell, because a hidden cell
   still leaves `:first-child` on it — and that is what carries the band's
   left gutter. */
.vpro-slab__grid{max-width:var(--col);margin:0 auto;padding:0 var(--pad);
  display:grid;grid-template-columns:minmax(0,1.6fr) repeat(4,minmax(0,1fr))}
.vpro-slab__grid.is-short{grid-template-columns:repeat(4,minmax(0,1fr))}
.vpro-cell{padding:26px 18px 28px;border-right:1px solid var(--slab-line);min-width:0;overflow:hidden}
.vpro-cell:first-child{padding-left:0}
.vpro-cell:last-child{border-right:none;padding-right:0}
.vpro-cell__lab{display:block;margin-bottom:14px;font:500 9.5px var(--mono);
  letter-spacing:.19em;text-transform:uppercase;color:var(--slab-3)}
/* Mono, because every one of these is a measured figure. tabular-nums so a
   number that ticks over while you watch does not shift the ones beside it. */
.vpro-cell__n{display:block;font:500 clamp(22px,2vw,29px)/1 var(--mono);letter-spacing:-.04em;
  white-space:nowrap;overflow:hidden;font-variant-numeric:tabular-nums}
.vpro-cell__n em{font-style:normal;font-size:13px;color:var(--slab-2);margin-left:4px;letter-spacing:0}
/* The sub-line is what the figure MEANS — "3 systems empty", "be the first".
   A number with nothing under it is a number nobody can act on. */
.vpro-cell__sub{display:block;margin-top:10px;font:400 11.5px var(--mono);color:var(--slab-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* A count of nothing is dimmed rather than hidden: the row still says the
   thing exists and is empty, which is different from the page not having it. */
.vpro-cell.is-none .vpro-cell__n{color:var(--slab-3)}

/* ---- the two named cells ----------------------------------------------
   The odometer's label, and the one slot that is the owner's outright. An
   unnamed slot is drawn quieter still than an empty one — it is not a
   figure nobody has recorded, it is a question nobody has answered. */
.vpro-cell--tag{position:relative}
.vpro-cell--tag.is-empty .vpro-cell__lab{color:var(--slab-3);opacity:.75}
.vpro-cell--tag.is-empty .vpro-cell__n{color:var(--slab-3);opacity:.5}
/* The pencil appears on the cell you are pointing at — five standing pencils
   down a band would read as five things needing attention. An UNNAMED slot
   keeps its pencil showing, because there is nothing else in the cell to say
   it can be filled in. */
.vpro-tagedit{position:absolute;top:15px;right:14px;width:22px;height:22px;border-radius:5px;
  display:grid;place-items:center;color:var(--slab-3);background:none;cursor:pointer;
  border:1px solid var(--slab-line);opacity:0;transition:.16s var(--ease)}
.vpro-cell--tag:hover .vpro-tagedit,
.vpro-tagedit:focus-visible,
.vpro-cell--tag.is-empty .vpro-tagedit{opacity:1}
.vpro-tagedit:hover{color:var(--slab-ink);border-color:var(--slab-2)}
.vpro-cell:last-child .vpro-tagedit{right:0}
/* a figure that opens its section */
a.vpro-cell:hover .vpro-cell__n{color:var(--accent-fg)}
a.vpro-cell:hover .vpro-cell__sub{color:var(--slab-2)}

/* Two across, and the named slot takes a row of its own. The pairs are
   written with nth-child(2n) rather than by position, so the band reflows
   the same way whether or not the wide cell is drawn — a rule per index
   would put the borders in the wrong places the moment a visitor's band
   was one cell shorter. */
@media(max-width:1040px){
  .vpro-slab__grid,.vpro-slab__grid.is-short{grid-template-columns:repeat(2,minmax(0,1fr))}
  .vpro-cell{padding:18px 16px 20px;border-bottom:1px solid var(--slab-line)}
  .vpro-cell__n{font-size:22px}
  .vpro-cell:first-child{grid-column:1/-1;padding-left:0;padding-right:0;border-right:none}
  .vpro-cell:nth-child(2n){padding-left:0}
  .vpro-cell:nth-child(2n+1){border-right:none;padding-right:0}
  .vpro-cell:nth-last-child(-n+2){border-bottom:none}
  .vpro-tagedit{right:0}
}
@media(max-width:760px){
  .vpro-cell{padding:14px 12px 15px}
  .vpro-cell__lab{font-size:8.5px;letter-spacing:.13em;margin-bottom:8px}
  .vpro-cell__n{font-size:17px;letter-spacing:-.04em}
  .vpro-cell__n em{font-size:10px;margin-left:2px}
  .vpro-cell__sub{font-size:9.5px;margin-top:6px}
  .vpro-tagedit{top:10px;opacity:1}
}

/* ---- the section bar --------------------------------------------------
   Five links to five sections of one page. They are real hrefs to real
   addresses — /garage/{owner}/{slug}/mods is a page the server answers —
   so they middle-click, they survive the bundle throwing, and a link into
   Mods is a link somebody can send (§12). What the bundle adds is the
   scroll instead of the reload.

   IT DOCKS UNDER THE NAV AND STAYS THERE. It used to be transparent at
   rest and sit UNDER the hero, taking on chrome only once it had stuck —
   which meant that for the whole first screen the one thing every part of
   this scroll shares was not on it. It is above the hero now and it always
   has a surface, because it is the page's own chrome rather than something
   that arrives on scroll.

   TABS ON A RULE, NOT ISLANDS. The active tab is marked with a 2px rule
   under its label rather than a filled accent block: the bar is 46px of
   permanent furniture at the top of every screen, and a filled pill on it
   competes with the page it is there to navigate. --vpro-chrome is what
   the nav and the bar are worth together, and every scroll-margin and
   every jump on this page measures from it, so there is one number rather
   than one per caller (§6). */
.vpro-secbar{--vpro-barh:46px;--vpro-chrome:calc(var(--navh) + var(--vpro-barh));
  position:sticky;top:var(--navh);z-index:31;
  background:color-mix(in srgb,var(--canvas) 94%,transparent);
  backdrop-filter:saturate(160%) blur(14px);
  border-bottom:1px solid var(--border);
  transition:box-shadow .2s var(--ease),border-color .2s var(--ease)}
/* Stuck is no longer "has a background" — it is "the title is gone", which
   is when the bar starts carrying the record's name. The shadow is the only
   thing that changes about the bar itself. */
.vpro-secbar.is-stuck{border-bottom-color:var(--border2);
  box-shadow:0 14px 26px -22px rgba(20,18,15,.75)}
body.dark .vpro-secbar.is-stuck{box-shadow:0 14px 26px -18px rgba(0,0,0,.9)}
.vpro-secbar__in{max-width:var(--col);margin:0 auto;padding:0 var(--pad);
  display:flex;align-items:stretch;gap:14px;height:var(--vpro-barh)}
.vpro-secbar__tabs{display:flex;align-items:stretch;gap:1px;min-width:0}
.vpro-secbar a{position:relative;display:flex;align-items:center;gap:8px;padding:0 13px;
  font-size:13.5px;font-weight:500;color:var(--t2);white-space:nowrap;
  transition:color .14s var(--ease),background .14s var(--ease)}
/* pull the first one out to the column edge, so the row starts where the
   name below it starts rather than one tab-padding in */
.vpro-secbar__tabs a:first-child{margin-left:-13px}
/* The rule is drawn always and scaled from nothing, so moving between tabs
   is one transform rather than a border appearing and disappearing. */
.vpro-secbar a::after{content:"";position:absolute;left:10px;right:10px;bottom:-1px;height:2px;
  background:var(--accent);transform:scaleX(0);transform-origin:50% 100%;
  transition:transform .24s var(--ease)}
.vpro-secbar a:hover{color:var(--text);background:var(--surface2)}
.vpro-secbar a[aria-current]{color:var(--text);font-weight:600}
.vpro-secbar a[aria-current]::after{transform:scaleX(1)}
/* THE GLYPH NEEDS A SIZE. Nothing on this bar is inside a .btn, and .btn is
   what sizes every other icon on the page — ams_icon(..., null) leaves an
   svg at the UA's default 300×150 box, which is how Suggest an edit came to
   draw a 40px notepad beside 12.5px type. The name resolved, the registry
   read clean and the markup was right. */
.vpro-secbar__tabs svg{width:15px;height:15px;flex:none;color:var(--t3);transition:color .14s}
.vpro-secbar a:hover svg{color:var(--t2)}
.vpro-secbar a[aria-current] svg{color:var(--accent)}
/* A count is a chip, not a dim number beside a word: at 11px in the same
   colour as the label it read as part of the label. */
.vpro-secbar__n{font:500 10.5px/1.5 var(--mono);padding:1px 5px;border-radius:4px;
  border:1px solid var(--border);background:var(--surface2);color:var(--t3);
  transition:.14s var(--ease)}
.vpro-secbar a:hover .vpro-secbar__n{background:var(--surface)}
.vpro-secbar a[aria-current] .vpro-secbar__n{background:var(--accent-soft);
  color:var(--accent-fg);border-color:transparent}

/* ---- which record you are inside of -----------------------------------
   The cover and the name, at the right end, faded in only once the title
   has scrolled past. A sticky bar four sections down a long page was the
   only chrome on screen and it said nothing about whose car it belonged
   to. It is in the markup from the start and shown by a class, because
   markup that appears mid-scroll announces itself with a reflow. */
.vpro-secbar__now{margin-left:auto;display:flex;align-items:center;gap:9px;min-width:0;
  padding-left:14px;opacity:0;transform:translateY(3px);pointer-events:none;
  transition:opacity .22s var(--ease),transform .22s var(--ease)}
.vpro-secbar.is-stuck .vpro-secbar__now{opacity:1;transform:none;pointer-events:auto}
.vpro-secbar__now img{width:25px;height:25px;border-radius:5px;object-fit:cover;flex:none;
  border:1px solid var(--border2);background:var(--surface2)}
.vpro-secbar__now b{font-size:13px;font-weight:600;letter-spacing:-.016em;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---- the verbs, on the bar --------------------------------------------
   The same jobs as the buttons in the hero, in reach from anywhere on the
   page. They are the hero's own attributes and not one new handler, so a
   second copy of a control is a second TRIGGER and never a second
   implementation (§1). */
.vpro-secbar__act{margin-left:auto;display:flex;align-items:center;gap:6px;
  padding-left:16px;flex:none}
.vpro-secbar__now + .vpro-secbar__act{margin-left:16px}
.vpro-sbtn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:30px;
  padding:0 11px;border-radius:7px;border:1px solid var(--border);background:var(--surface);
  color:var(--t2);font:500 12.5px var(--ui);white-space:nowrap;cursor:pointer;
  transition:.14s var(--ease)}
.vpro-sbtn:hover{background:var(--surface2);border-color:var(--t3);color:var(--text)}
.vpro-sbtn svg{width:13px;height:13px;flex:none}
.vpro-sbtn.is-pri{background:var(--accent);border-color:var(--accent);color:#fff}
.vpro-sbtn.is-pri:hover{background:color-mix(in srgb,var(--accent) 88%,#000);
  border-color:color-mix(in srgb,var(--accent) 88%,#000);color:#fff}
.vpro-sbtn.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent-fg)}

/* ---- a section --------------------------------------------------------
   scroll-margin-top is the nav plus the section bar plus a little air. An
   anchor without it lands with the heading underneath the sticky chrome,
   which reads as the link having gone to the wrong place. */
.vpro-sec{max-width:var(--col);margin:0 auto;padding:46px var(--pad) 0;
  scroll-margin-top:calc(var(--navh) + 46px + 16px)}
/* Details is the hero itself, so the first tab lands on the top of the
   record rather than on a heading — the same margin, measured from the same
   chrome, so no tab drops its target under the bar. */
#details{scroll-margin-top:calc(var(--navh) + 46px + 16px)}
/* The last section pays for the admin bar as well as its own bottom air.
   --floor is what the bottom edge of the window is worth altogether
   (CONVENTIONS §6); measuring from it is what keeps the final card from
   ending behind the bar for an operator. */
.vpro-sec:last-of-type{padding-bottom:calc(64px + var(--floor,0px))}
.vpro-sec__h{display:flex;align-items:flex-end;gap:14px;margin-bottom:20px;
  padding-bottom:14px;border-bottom:1px solid var(--border)}
.vpro-sec__h h2{margin:0;font:600 23px/1 var(--dis);letter-spacing:-.03em}
.vpro-sec__sub{font-size:13.5px;color:var(--t3);line-height:1.2}
.vpro-sec__act{margin-left:auto;display:flex;gap:7px;align-items:center;flex-wrap:wrap}

/* the page's own card, on the site's surface tokens */
.vpro-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--sh-sm)}
/* a card's caption strip — a label on the left, a count on the right */
.vpro-cap{padding:13px 24px;border-bottom:1px solid var(--border);background:var(--surface2);
  border-radius:var(--r-lg) var(--r-lg) 0 0;display:flex;align-items:center;gap:10px}
.vpro-cap__n{margin-left:auto;font:400 11px var(--mono);color:var(--t3)}
.vpro-eyebrow{font:500 10px var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--t3)}

/* Below this width the name is the first thing to go: navigation and the
   verbs both outrank knowing which car you are on, and the hero is only a
   scroll away. */
@media(max-width:1100px){
  .vpro-secbar__now{display:none}
  .vpro-secbar__now + .vpro-secbar__act{margin-left:auto}
  /* the secondary verbs drop to their glyphs; the primary keeps its word */
  .vpro-sbtn:not(.is-pri){width:30px;padding:0}
  .vpro-sbtn:not(.is-pri) span{display:none}
}
@media(max-width:760px){
  /* Five tabs only fit as text. The glyphs come out and the LABELS stay,
     because a label is the half somebody can read at a glance — and the
     tabs share the width evenly rather than scrolling sideways, which is a
     row of navigation whose second half nobody discovers. */
  .vpro-secbar__in{gap:0;padding:0 12px}
  .vpro-secbar__tabs{flex:1;gap:0;min-width:0}
  .vpro-secbar a{flex:1;justify-content:center;padding:0 2px;gap:0;font-size:12.5px;min-width:0}
  .vpro-secbar__tabs a:first-child{margin-left:0}
  .vpro-secbar a span{display:flex;align-items:center;height:100%;position:relative}
  /* the rule sits under the WORD, not under the whole cell it shares */
  .vpro-secbar a::after{display:none}
  .vpro-secbar a span::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;
    background:var(--accent);transform:scaleX(0);transform-origin:50% 100%;
    transition:transform .24s var(--ease)}
  .vpro-secbar a[aria-current] span::after{transform:scaleX(1)}
  .vpro-secbar a:hover{background:none}
  .vpro-secbar__tabs svg,.vpro-secbar__n{display:none}
  /* the verb is not a sixth tab, so it reads on the other side of a rule */
  .vpro-secbar__act{padding-left:11px;margin-left:5px;gap:4px;align-self:center;
    border-left:1px solid var(--border2)}
  .vpro-sbtn{width:32px;height:32px;padding:0}
  .vpro-sbtn span{display:none}
  .vpro-sbtn:not(.is-pri){display:none}
  .vpro-sbtn svg{width:15px;height:15px}
  .vpro-sec{padding-top:34px;scroll-margin-top:calc(var(--navh) + 46px + 10px)}
  #details{scroll-margin-top:calc(var(--navh) + 46px + 10px)}
  .vpro-sec__h{flex-wrap:wrap;gap:8px}
  .vpro-sec__act{width:100%;margin-left:0}
  .vpro-cap{padding-left:16px;padding-right:16px}
}

/* ---- the photo mosaic -------------------------------------------------
   A twelve-column grid with three tile sizes, so a set of photographs reads
   as a wall rather than a contact sheet. The sizes are assigned by POSITION
   (the first is large, then a wide, then two small) and never by anything
   about the photo itself: a rule that gave the "best" picture the big slot
   would need an opinion about which one that is, and the owner has already
   expressed theirs by choosing the cover. */
/* `dense` because the rhythm is fixed and the number of photographs is not:
   a gallery of seven ends its last row with a 3-column hole that reads as a
   missing tile rather than as the end of the set. Dense backfills it with the
   next small one, which is what a wall of photographs does anyway. */
.vpro-gal{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));grid-auto-rows:230px;gap:12px;
  grid-auto-flow:row dense}
.vpro-shotile{position:relative;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--border);
  background:var(--surface2);cursor:zoom-in;box-shadow:var(--sh-sm);padding:0;display:block;width:100%}
.vpro-shotile img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .5s var(--ease)}
.vpro-shotile:hover img{transform:scale(1.03)}
.vpro-shotile--a{grid-column:span 6;grid-row:span 2}
.vpro-shotile--w{grid-column:span 6;grid-row:span 1}
.vpro-shotile--s{grid-column:span 3;grid-row:span 1}
/* A wash on hover, so a tile reads as pressable without a border that would
   change the mosaic's rhythm on the way in. */
.vpro-shotile__z{position:absolute;inset:0;background:rgba(14,12,10,0);
  transition:background .25s var(--ease)}
.vpro-shotile:hover .vpro-shotile__z{background:rgba(14,12,10,.12)}
/* The "this opens" glyph. It appears on hover on a pointer and is simply on
   for touch (below), because a photograph that is clickable and does not say
   so is only discoverable by trying it. */
.vpro-shotile__open{position:absolute;right:11px;bottom:11px;width:28px;height:28px;border-radius:7px;
  display:grid;place-items:center;color:#F4F1EC;background:rgba(14,12,10,.6);
  backdrop-filter:blur(8px);opacity:0;transition:opacity .16s var(--ease)}
.vpro-shotile:hover .vpro-shotile__open,
.vpro-shotile:focus-visible .vpro-shotile__open{opacity:1}

/* The caption sits ON the photo because it is about that photo. Frosted so
   it survives whatever is underneath — the same problem the cover controls
   have and the same answer. */
.vpro-shotile__cap{position:absolute;left:11px;bottom:11px;display:flex;align-items:center;gap:9px;
  padding:6px 10px;border-radius:6px;background:rgba(14,12,10,.6);backdrop-filter:blur(8px);
  max-width:calc(100% - 22px)}
.vpro-shotile__cap i{font-style:normal;font:400 9.5px var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:rgba(255,255,255,.64);flex:none}
.vpro-shotile__cap span{font-size:12.5px;color:#F4F1EC;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
/* How many markers the photograph carries (380). Bottom-right, where the
   "this opens" glyph sits, because it is the same promise — the lightbox has
   more to show — and the glyph yields to it: a count is the more specific of
   the two. Steel rather than the accent, the tool's own colour for a marker,
   so it cannot be mistaken for the orange pins the tool draws ON the picture.
   The two tokens are declared on :root in css/33-photo-notes.php, the tool's
   own partial, which is the one place that colour is chosen. */
.vpro-shotile__pin{position:absolute;right:11px;bottom:11px;z-index:1;font:500 9.5px var(--mono);
  letter-spacing:.06em;color:var(--pn-steel-ink);background:var(--pn-steel);padding:4px 6px;border-radius:5px}
.vpro-shotile__pin~.vpro-shotile__open{bottom:44px}
/* the owner's controls, revealed on the tile they belong to */
.vpro-shotile__acts{position:absolute;right:10px;top:10px;display:flex;gap:6px;z-index:2;
  opacity:0;transition:opacity .16s var(--ease)}
.vpro-shotile:hover .vpro-shotile__acts,.vpro-shotile:focus-within .vpro-shotile__acts{opacity:1}
.vpro-shotile__btn{display:inline-flex;align-items:center;gap:5px;padding:5px 9px;border-radius:6px;
  border:1px solid rgba(255,255,255,.28);background:rgba(14,12,10,.6);backdrop-filter:blur(8px);
  color:#F4F1EC;font:400 9.5px var(--mono);letter-spacing:.11em;text-transform:uppercase;cursor:pointer}
.vpro-shotile__btn:hover{background:var(--accent);border-color:var(--accent);color:#fff}
/* Delete is the one control here that cannot be undone, so it does not share
   the accent every other hover uses — the colour is the warning. */
.vpro-shotile__btn.is-del:hover{background:#B4342C;border-color:#B4342C}

@media(max-width:1040px){
  .vpro-gal{grid-auto-rows:200px}
  .vpro-shotile--a{grid-column:span 12;grid-row:span 2}
  .vpro-shotile--w{grid-column:span 12}
  .vpro-shotile--s{grid-column:span 6}
}
@media(max-width:760px){
  .vpro-gal{grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:140px;gap:8px}
  .vpro-shotile--a{grid-column:span 2;grid-row:span 2}
  .vpro-shotile--w{grid-column:span 2;grid-row:span 1}
  .vpro-shotile--s{grid-column:span 1;grid-row:span 1}
  /* No hover on a touch screen, so the owner's controls — and the glyph
     saying a tile opens — are simply on. */
  .vpro-shotile__acts,.vpro-shotile__open{opacity:1}
  .vpro-shotile__cap{left:8px;bottom:8px;padding:5px 8px}
}

/* ---- the mods on this car ---------------------------------------------
   THE CARDS ARE NOT DEFINED HERE. Every one is ams_mod_card() / AMS.modCard
   — the one mod card, drawn identically on /mods, My mods, a generation
   page and a profile — and it brings its own styles. A vehicle page with
   its own mod-card look is the drift §1 exists to stop: the same mod would
   read one way here and another on /mods, and only one of them would ever
   get fixed. What this owns is the grid they sit in and the card BELOW
   them, which is this page's alone. */
.vpro-modgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}

/* ---- what has nothing logged yet --------------------------------------
   The systems this car has no mod under, from Mods::CATEGORIES — the one
   list, and the one a member actually picks from. It is the work that is
   left, which is the same reason the bench's map draws a screen nobody has
   filed anything against: an empty slot IS the information.

   The line under each is fixed and true of every car. The design's lines
   were somebody reading these particular photographs ("sits noticeably
   lower than stock in both exterior shots") and that is worth more than
   anything generatable — but a generated sentence in that voice would be
   this page inventing an observation about a car it has not looked at. */
.vpro-sys{display:grid;grid-template-columns:200px minmax(0,1fr) auto;gap:20px;align-items:center;
  padding:14px 24px;border-bottom:1px solid var(--border)}
.vpro-sys:last-child{border-bottom:none}
.vpro-sys b{font-size:14px;font-weight:600;letter-spacing:-.018em}
.vpro-sys p{margin:0;font-size:13px;color:var(--t3)}

/* ---- the owner's other work -------------------------------------------
   A quieter row than a mod card, deliberately: these are not on this car,
   and drawn at the same weight as the ones above they read as though they
   were. */
.vpro-orow{display:flex;gap:15px;align-items:center;padding:13px 15px;
  transition:border-color .14s,box-shadow .14s}
.vpro-orow:hover{border-color:var(--border2);box-shadow:var(--sh)}
.vpro-orow__th{width:120px;height:84px;border-radius:var(--r);overflow:hidden;flex:none;
  border:1px solid var(--border);background:var(--surface2)}
.vpro-orow__th img{width:100%;height:100%;object-fit:cover;display:block}
.vpro-orow__tx{flex:1;min-width:0}
.vpro-orow__tx b{display:block;font-size:14.5px;font-weight:600;letter-spacing:-.022em}
/* Two lines and then stop. These are summaries of somebody else's work and
   a long one would push the row past the card beside it. */
.vpro-orow__tx p{margin:4px 0 0;font-size:12.5px;line-height:1.5;color:var(--t3);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.vpro-orow__m{margin-top:9px;display:flex;flex-wrap:wrap;gap:6px}

/* a fact chip — mono, because everything in one is measured */
.vpro-f{display:inline-flex;align-items:center;gap:5px;font:400 11px var(--mono);
  padding:5px 8px;border-radius:6px;border:1px solid var(--border);color:var(--t3)}

/* the line under the owner section, in the site's normal prose colour */
.vpro-note{font-size:12.5px;line-height:1.6;color:var(--t3);margin:14px 0 0;max-width:74ch}

@media(max-width:1040px){
  .vpro-modgrid{grid-template-columns:1fr}
  .vpro-sys{grid-template-columns:160px minmax(0,1fr) auto;padding:14px 18px}
}
@media(max-width:760px){
  .vpro-sys{grid-template-columns:1fr;gap:6px;padding:14px 16px}
  .vpro-sys .btn{justify-self:start}
  .vpro-orow{flex-wrap:wrap}
  .vpro-orow__th{width:88px;height:62px}
}

/* ---- the spec sheet ---------------------------------------------------
   Two cards: what is on record, and what is not set. They are two cards and
   not one list with some rows greyed out, because "what is missing" is a
   different question from "what is this car" and an owner opening this page
   is usually asking the second and occasionally acting on the first.

   THE SPLIT IS MADE IN PHP, once, by Api::vehicleSpecRows(): a row with an
   empty value IS the not-set state. Deciding it here — or in the twin —
   would be the same rule in three places, and the count on each card's
   caption would be a fourth. */
.vpro-sheet{display:grid;grid-template-columns:1fr 1fr;gap:0 44px;margin:0;padding:20px 24px 24px}
.vpro-sheet>div{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  padding:11px 0;border-bottom:1px solid var(--border)}
/* the last row of EACH column, in a two-column grid that fills by row */
.vpro-sheet>div:nth-last-child(-n+2){border-bottom:none}
/* The label does not shrink. In the not-set card the value side carries an
   "add" button and a line of prose, and left to negotiate, flexbox gave that
   side the room and squeezed "Engine code" onto two lines against a value
   reading "Not set". */
.vpro-sheet dt{font-size:14px;color:var(--t3);flex:0 0 auto}
/* Mono on the value because these are the car's figures, and right-aligned
   so a column of them can be read down. */
.vpro-sheet dd{margin:0;font:400 12.5px var(--mono);color:var(--text);text-align:right;min-width:0}
/* A field nobody has filled in is italic and in prose, not mono: it is a
   sentence about the absence, not a measurement. */
.vpro-sheet dd.is-unset{color:var(--t3);font:italic 400 13px var(--ui);
  display:flex;align-items:center;gap:10px;justify-content:flex-end;flex-wrap:wrap}
.vpro-sheet dd.is-unset .vpro-f{font-style:normal}
/* the one line saying WHY this field is worth filling in — it hangs under
   the row rather than beside it, because at 13px in a right-hand column it
   would wrap to four lines */
.vpro-why{flex:1 1 100%;text-align:left;font:400 11.5px/1.5 var(--ui);color:var(--t3);
  font-style:normal;margin-top:2px}

/* ---- the forum signature ----------------------------------------------
   This whole page as one line somebody can paste under a post on a forum.
   Mono on the line itself because every part of it is a figure or a name
   off the record, and it is the string that will be pasted — so what is on
   screen has to be exactly what the button copies, character for
   character. It sits in a sunken strip rather than a card: it is a
   footnote to the spec sheet, not a third card of its own. */
.vpro-sig{display:flex;align-items:center;gap:14px;margin-top:14px;padding:13px 16px;
  background:var(--surface2);border:1px solid var(--border);border-radius:var(--r-lg)}
/* One line, clipped. A signature that wraps to three lines is not a
   signature — and the clip is what says "there is more of this", which the
   Copy button beside it is the answer to. */
.vpro-sig code{flex:1;min-width:0;font:400 12px var(--mono);color:var(--t2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vpro-sig .btn{flex:none}

/* ---- the owner section's grid ----------------------------------------- */
.vpro-orows{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}

/* ---- the empty states -------------------------------------------------
   Each says what the section is FOR, not that it is empty — "no photos yet"
   with nothing after it is a fact the reader can already see. */
.vpro-empty{padding:30px 0;text-align:center;font-size:13.5px;color:var(--t3)}
.vpro-empty b{display:block;font-size:15px;color:var(--text);margin-bottom:5px}
.vpro-empty p{margin:0 auto 14px;max-width:52ch;line-height:1.55}

@media(max-width:1040px){
  .vpro-orows{grid-template-columns:1fr}
}
@media(max-width:760px){
  /* On a phone the line is allowed to wrap: there is no width to clip it
     to that leaves anything readable, and the whole point is that it can be
     read before it is copied. */
  .vpro-sig{flex-wrap:wrap}
  .vpro-sig code{flex:1 1 100%;white-space:normal;line-height:1.6}
  .vpro-sheet{grid-template-columns:1fr;padding:14px 16px 18px}
  .vpro-sheet>div:nth-last-child(-n+2){border-bottom:1px solid var(--border)}
  .vpro-sheet>div:last-child{border-bottom:none}
}

/* ---- edit details: a drawer, not a modal ------------------------------
   It sits beside the page rather than over it, so every keystroke previews
   live on the record behind it — the name, the year/make/model line, the
   paint chip, the slab's figures and the spec sheet all repaint as they are
   typed. A modal covers the one thing the form is about.

   It replaces the inline panel that used to open under the hero, which had
   the opposite problem: it pushed the whole page down, so the fields you
   were filling in and the thing they changed were never on screen together.

   THE BLANKS ARE GROUPED AND LIT. A form of fifteen identical boxes hides
   the four that are empty among the eleven that are not; "not yet recorded"
   is its own group in the accent wash, with a count, at the bottom where it
   is the last thing before Save. */
.vpro-dr__scrim{position:fixed;inset:0;z-index:92;background:rgba(12,12,16,.28);opacity:0;
  pointer-events:none;transition:opacity .28s var(--ease)}
.vpro-dr__scrim.on{opacity:1;pointer-events:auto}
/* IT ENDS ON THE FLOOR, not at the bottom of the window (docs/CONVENTIONS.md
   §6). It was `bottom:0`, which put its action row — Cancel and Save — behind
   the operator's admin bar on every width: the one button this drawer exists
   for was unpressable for anybody carrying that bar. --floor is what the
   bottom edge is worth altogether, so this is the same number every other
   pinned thing on the site measures from. */
/* IT COMES IN FROM THE LEFT, AND THAT IS THE HERO'S DOING. It slid in from
   the right for as long as the record ran full width under a full-bleed
   cover, where whichever side it took it covered the same thing. The hero
   is two columns now — photograph left, record right — and on the right the
   drawer landed squarely on the name, which is the field it opens focused
   on: at 1440 the live preview of what you were typing was behind the form
   you were typing it in. On the left it covers the photograph, and nothing
   in this form changes the photograph. Below 1040 the hero is one column
   and the drawer is the full width of the window, so which side it enters
   from stops meaning anything. */
.vpro-drawer{position:fixed;top:0;left:0;bottom:var(--floor-modal);width:min(470px,100vw);z-index:93;
  background:var(--surface);border-right:1px solid var(--border);box-shadow:var(--sh-lg);
  display:flex;flex-direction:column;transform:translateX(-101%);
  transition:transform .34s var(--ease);visibility:hidden}
.vpro-drawer.on{transform:none;visibility:visible}
.vpro-dr__h{flex:none;padding:16px 20px 15px;border-bottom:1px solid var(--border)}
.vpro-dr__t{display:flex;align-items:center;gap:11px}
.vpro-dr__t h3{margin:0;font:600 17px var(--dis);letter-spacing:-.024em}
.vpro-dr__x{margin-left:auto;width:30px;height:30px;border-radius:8px;display:grid;place-items:center;
  color:var(--t3);border:0;background:none;cursor:pointer}
.vpro-dr__x:hover{background:var(--surface2);color:var(--text)}
/* The completeness meter. One bar per field, so it is a count you can see
   rather than a percentage — "11 of 15" is a number an owner can act on and
   "73%" is not. */
.vpro-dr__bars{display:flex;gap:3px;margin:14px 0 8px}
.vpro-dr__bars i{flex:1;height:4px;border-radius:2px;background:var(--border2);
  transition:background .3s var(--ease)}
.vpro-dr__bars i.on{background:var(--accent)}
.vpro-dr__count{margin:0;font:400 11px var(--mono);color:var(--t3)}
.vpro-dr__b{flex:1;overflow-y:auto;padding:0 20px;overscroll-behavior:contain}

.vpro-grp{padding:18px 0;border-bottom:1px solid var(--border)}
.vpro-grp:last-child{border-bottom:none}
.vpro-grp__h{display:flex;align-items:center;gap:9px;margin-bottom:13px}
.vpro-grp__n{margin-left:auto;font:400 10.5px var(--mono);color:var(--t3)}
/* the blanks, in the accent wash — bled to the drawer's edges so it is a
   band rather than a boxed-in panel inside a column of fields */
.vpro-grp.is-blank{margin:0 -20px;padding:18px 20px;background:var(--accent-soft);border-bottom:none}
.vpro-grp.is-blank .vpro-eyebrow,.vpro-grp.is-blank .vpro-grp__n{color:var(--accent-fg)}
/* the field boxes need to keep contrast against the wash they now sit on */
.vpro-grp.is-blank .vpro-fld input,.vpro-grp.is-blank .vpro-fld select{background:var(--surface)}

.vpro-fld{display:flex;flex-direction:column;gap:6px;min-width:0}
.vpro-fld+.vpro-fld{margin-top:12px}
.vpro-g2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.vpro-g2 .vpro-fld+.vpro-fld{margin-top:0}
.vpro-fld label{font:500 9.5px var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--t3)}
.vpro-fld input,.vpro-fld select{height:37px;padding:0 11px;border:1px solid var(--border2);
  border-radius:8px;background:var(--canvas);color:var(--text);font:400 14px var(--ui);width:100%}
.vpro-fld select{cursor:pointer}
.vpro-fld input:focus,.vpro-fld select:focus{outline:none;border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-soft)}
/* A field the owner cannot change is shown, not hidden: knowing the engine
   code comes from the engine is the point of showing it here at all. */
.vpro-fld input:disabled,.vpro-fld select:disabled{color:var(--t3);cursor:not-allowed;
  background:var(--surface2)}
.vpro-fld .vpro-hint{font-size:11.5px;line-height:1.5;color:var(--t3)}
/* where the drawer was opened by pressing "add" on one specific field */
.vpro-fld.is-spot input,.vpro-fld.is-spot select{border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-soft)}

.vpro-row{display:flex;gap:9px;align-items:center}
.vpro-row input{flex:1}
/* mi / km — a segmented control, because it is a choice of two and a select
   for two options is a menu you have to open to find out what is in it */
.vpro-seg{display:inline-flex;border:1px solid var(--border2);border-radius:8px;overflow:hidden;
  flex:none;height:37px}
.vpro-seg button{padding:0 12px;font:500 12.5px var(--ui);color:var(--t3);border:0;background:none;
  cursor:pointer}
.vpro-seg button+button{border-left:1px solid var(--border2)}
.vpro-seg button.on{background:var(--text);color:var(--canvas)}
/* the paint chip's own colour input, beside the name it belongs to */
.vpro-swatch{width:44px;flex:0 0 44px;height:37px;padding:3px;border:1px solid var(--border2);
  border-radius:8px;background:var(--canvas);cursor:pointer}
.vpro-swatch::-webkit-color-swatch-wrapper{padding:0}
.vpro-swatch::-webkit-color-swatch{border:0;border-radius:5px}

.vpro-dr__f{flex:none;display:flex;gap:9px;align-items:center;padding:12px 20px;
  border-top:1px solid var(--border);background:var(--surface2)}
/* how many changes are unsaved. It is the answer to "can I close this", so
   it sits next to the buttons that close it. */
.vpro-dr__dirty{margin-right:auto;font:400 11px var(--mono);color:var(--t3)}
.vpro-dr__f .btn[disabled]{opacity:.45;cursor:not-allowed}

@media(max-width:760px){
  .vpro-drawer{width:100vw;border-right:0}
  .vpro-dr__b{padding:0 16px}
  .vpro-grp.is-blank{margin:0 -16px;padding:18px 16px}
  .vpro-dr__h,.vpro-dr__f{padding-left:16px;padding-right:16px}
  .vpro-g2{grid-template-columns:1fr;gap:12px}
}
/* The drawer animates in from the side; with Reduce Motion it is simply
   there. `visibility` is what makes that work — a transform-only hide would
   leave a focusable form off-screen for a keyboard. */
@media(prefers-reduced-motion:reduce){
  .vpro-drawer,.vpro-dr__scrim,.vpro-shot{transition:none}
}

/* ---- site-wide announcement banner (published from admin Broadcast) ---- */
.ams-banner{display:flex;align-items:center;gap:12px;padding:10px 22px;font-size:13.5px;
  background:var(--accent-soft);color:var(--text);border-bottom:1px solid var(--accent-line);position:relative;z-index:81}
.ams-banner[data-tone="success"]{background:var(--green-soft);border-bottom-color:var(--green-line)}
.ams-banner[data-tone="warning"]{background:#FBEFD6;border-bottom-color:#E7C77A}
body.dark .ams-banner[data-tone="warning"]{background:rgba(224,168,46,.14);border-bottom-color:rgba(224,168,46,.4)}
.ams-banner .amsb-body{color:var(--t2)}
.ams-banner .amsb-x{margin-left:auto;flex:none;width:28px;height:28px;border-radius:6px;display:grid;place-items:center;color:var(--t2);background:none;border:0;cursor:pointer;font-size:15px}
.ams-banner .amsb-x:hover{background:rgba(0,0,0,.06)}
body.dark .ams-banner .amsb-x:hover{background:rgba(255,255,255,.08)}

/* ============================================================
   Unified admin bar (operators) — the same instrument bar as the /admin
   console, fixed at the bottom of every front-end page. Self-contained: its
   own palette on the component roots, every rule scoped under #adminbar /
   #ams-adrawer so the site's generic classes are never touched.
   ============================================================ */
#adminbar,#ams-adrawer,#ab-labwrap,#ab-labfly{--gr:#15181B;--grl:#22272C;--grr:#2C333A;--sig:#F26B21;--sigink:#F26B21;--sigwash:rgba(242,107,33,.16);--jade:#4FA96A;--jadewash:rgba(79,169,106,.16);--aink:#F2F4F5;--aink2:#A3ADB5;--aink3:#7E858D;--arule:#2C333A;--arulesoft:#242A30;--asurf:#15181B;--amono:"JetBrains Mono",ui-monospace,Menlo,monospace;--adisp:"Inter Tight",system-ui,sans-serif;--abody:"Inter",system-ui,sans-serif;color-scheme:dark}
#ams-adrawer *,#ab-labwrap *,#ab-labfly *{scrollbar-width:thin;scrollbar-color:var(--grr) transparent}
#ams-adrawer ::-webkit-scrollbar{width:10px;height:10px}
#ams-adrawer ::-webkit-scrollbar-thumb{background:var(--grr);border-radius:99px}
#ams-adrawer ::-webkit-scrollbar-track{background:transparent}
/* Admin instrument bar height as ONE variable every full-height pane and fixed
   element keys off. It is 0 when the bar is absent or collapsed, so subtracting
   var(--abh) anywhere is always safe and no page ever hides content behind the
   staff bar. This is the single source for "how much bottom the admin bar eats". */
body{--abh:0px}
body.has-adminbar{--abh:46px}
body.has-adminbar.ab-collapsed{--abh:0px}
/* On a phone the thumb zone owns the bottom edge (css/21-tabbar.php), so this
   bar is a STRIP: one line of status with one way into everything. It used to
   be a 72px four-tile nav, and stacked under a 56px tab bar that was 128px of
   permanent chrome on a 780px screen — a quarter of the phone gone before the
   page got a pixel. The strip is 34px, and the tiles it dropped are all in the
   Tools sheet, which is what that sheet is for now. */
@media(max-width:640px){
  /* ONE number for the strip, because two would drift: --ab-strip is the row you
     can read and press, --abh is the whole bar including the home-indicator pad
     underneath it, and #adminbar's height is that same total (box-sizing is
     border-box site-wide, so a bare height:34px would eat the inset out of the
     row rather than add it). */
  body.has-adminbar:not(.ab-collapsed){--ab-strip:34px;--abh:calc(var(--ab-strip) + env(safe-area-inset-bottom))}
}
/* Except in landscape, where the thumb zone folds away and this bar is the only
   navigation an operator has left — so it goes back to being the four-tile one.
   The height matches the block at the bottom of this file. */
@media(max-width:640px) and (max-height:520px){ body.has-adminbar:not(.ab-collapsed){--abh:calc(72px + env(safe-area-inset-bottom))} }
/* WHERE THE FLOOR IS, for the whole site. --abh is what the ADMIN BAR is worth;
   --floor is what the bottom edge is worth altogether — the admin bar, or the
   phone's thumb zone stacked on top of it, or nothing but the home indicator.
   Every fixed thing that hangs off the bottom of the window measures from this
   one number (a toast, a buy bar, a flyout, a sticky rail's height), so a bar
   that changes height can never leave one of them behind the way the feed's
   rail was left behind "Events coming up". The tab bar's share is added in
   css/21-tabbar.php, which is the only file that knows whether it is on screen.
   It is 0 with no chrome at all, so adding var(--floor) anywhere is safe. */
body{--floor:var(--safe-b,0px)}
body.has-adminbar{--floor:var(--abh)}
/* AND THE OTHER FLOOR, FOR SOMETHING THAT HAS TAKEN THE PAGE.
   --floor is what the PAGE must clear, and on a phone most of it is the tab
   bar. A modal sheet is drawn over the page WITH A SCRIM, so that tab bar is
   dimmed and cannot be pressed — and a sheet that still reserves 56px for it
   is holding a band of unusable navigation open underneath itself. That is
   what the Create chooser looked like on a phone: the sheet stopped, then
   came a strip of scrimmed page, then the scrimmed tab bar, then the admin
   bar. Ninety pixels of nothing under a panel that is supposed to be resting
   on the bottom of the screen.

   What a scrim CANNOT cover is #adminbar, which is z-1900 and above every
   overlay on the site, and the phone's home indicator, which is the device.
   So that is what a modal sheet ends at, and it is one number:

     --floor        the page's bottom edge — admin bar + tab bar + indicator
     --floor-modal  a scrimmed overlay's — admin bar + indicator

   The test for which to use is not the z-index and not the shape: it is
   whether the page underneath is still usable. A toast, the Buy bar, the FAB,
   the chat dock and the feed card's own bottom sheets have no scrim, leave the
   navigation live, and belong on --floor — a toast that covered the tab bar
   would be hiding a control somebody can still press. A panel that dims the
   page has already taken that control away.

   THE TAB BAR STANDS ON EXACTLY THIS NUMBER TOO, which is why it has one name
   rather than two: css/21-tabbar.php reads it to sit on, and then adds its own
   height to --floor for everything else. It used to keep a private --tb-base
   saying the same thing, and a second name for one number is how the two come
   to disagree (§1). */
body{--floor-modal:var(--safe-b,0px)}
body.has-adminbar{--floor-modal:var(--abh)}
/* ONE padding rule, at body specificity, because everything that changes the
   floor changes --floor rather than re-declaring this. */
body{padding-bottom:var(--floor)}
#adminbar{position:fixed;left:0;right:0;bottom:0;height:46px;z-index:1900;background:var(--gr);color:#fff;display:flex;align-items:stretch;border-top:1px solid #000;overflow-x:auto;scrollbar-width:none;font-family:var(--abody)}
#adminbar::-webkit-scrollbar{display:none}
#adminbar .ab-zone{display:flex;align-items:center;gap:6px;padding:0 14px;border-right:1px solid var(--grr);flex:none}
#adminbar .ab-zone.ab-right{margin-left:auto;border-right:0;border-left:1px solid var(--grr)}
#adminbar .ab-btn{background:none;border:1px solid transparent;border-radius:7px;color:var(--aink2);font-size:12.5px;font-weight:500;padding:5px 9px;display:flex;align-items:center;gap:7px;white-space:nowrap;text-decoration:none;font-family:inherit;cursor:pointer}
#adminbar .ab-btn:hover{background:var(--grl);color:var(--aink)}
#adminbar .ab-btn[aria-expanded="true"]{background:var(--sigwash);color:var(--sig);font-weight:600}
#adminbar .ab-count{font-family:var(--amono);font-size:10px;background:#E0553F;color:#fff;border-radius:100px;padding:1px 6px;font-variant-numeric:tabular-nums}
#adminbar .ab-brand{display:flex;align-items:center;gap:7px;padding:0 4px;font-size:11.5px;font-weight:700;letter-spacing:.05em;color:var(--aink2)}
#adminbar .ab-brand .mk{width:15px;height:15px;background:var(--sig);clip-path:polygon(25% 2%,75% 2%,100% 50%,75% 98%,25% 98%,0 50%)}
#adminbar .ab-env{font-size:10px;font-weight:700;letter-spacing:.06em;padding:3px 8px;border-radius:100px;background:var(--jadewash);color:var(--jade)}
#adminbar .ab-env[data-env="Staging"]{background:var(--sigwash);color:var(--sig)}
#adminbar .ab-env[data-env="Local"]{background:rgba(91,147,214,.16);color:#5B93D6}
/* context chip + bell on the left — mirrors the console bar's .barctx/.bell */
#adminbar .ab-ctx{display:flex;align-items:center;gap:7px;padding:5px 10px;border-radius:7px;background:var(--grl);border:1px solid var(--grr);font-size:12.5px;color:var(--aink2);max-width:220px}
#adminbar .ab-ctx .t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#adminbar .ab-dot{width:7px;height:7px;border-radius:50%;background:var(--aink3);flex:none}
#adminbar .ab-bell{padding:5px 8px}
#adminbar .ab-link{flex-direction:column;align-items:flex-start;gap:0;padding:3px 8px}
#adminbar .ab-num{font-family:var(--amono);font-size:12px;color:#fff;line-height:1.2;font-variant-numeric:tabular-nums}
#adminbar .ab-sub{font-family:var(--amono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:#7E858D;line-height:1.3}
#adminbar .ab-ticks{display:flex;gap:2px;align-items:center}
#adminbar .ab-ticks i{width:3px;height:15px;background:var(--grr);border-radius:1px}
#adminbar .ab-ticks i.on{background:var(--sig)}
#adminbar .ab-meta{font-family:var(--amono);font-size:10.5px;color:#7E858D;white-space:nowrap}
#adminbar .ab-quiet{font-family:var(--amono);font-size:10px;color:#7E858D;font-variant-numeric:tabular-nums}
#adminbar .ab-cmd{border-color:var(--grr);color:#9DA4AC;font-family:var(--amono);font-size:11px}
#adminbar kbd{font-family:var(--amono);font-size:9.5px;border:1px solid currentColor;border-radius:2px;padding:0 3px;opacity:.55;margin-left:5px;line-height:1.5}
#adminbar .ab-i{flex:none;display:block}
#adminbar .ab-pulse{width:6px;height:6px;border-radius:50%;background:var(--jade);margin-right:5px;display:inline-block;vertical-align:middle}
#adminbar .ab-hide{color:var(--aink3);padding:5px 7px}
#adminbar .ab-hide:hover{color:var(--aink)}
/* the "More" tile only exists on phones — the full-width bar shows everything inline */
#adminbar .ab-more{display:none}
#adminbar{transition:transform .2s}
/* hide / reveal — mirrors the console bar's ⌘B collapse */
body.ab-collapsed #adminbar{transform:translateY(110%)}
body.ab-collapsed{padding-bottom:0!important}
/* Collapsing the bar takes --abh to 0, but on a phone the thumb zone is still
   down there and --floor still says so — so this measures from --floor like
   everything else pinned to the bottom edge (§6). At 12px + the indicator it
   was the only way BACK to the bar, sitting behind the tab bar. --floor
   carries the indicator, so it is not added again. */
.ab-reveal{position:fixed;left:12px;right:auto;bottom:calc(12px + var(--floor,0px));z-index:1901;height:34px;padding:0 13px;border-radius:100px;border:0;background:#F26B21;color:#fff;font:600 12.5px/1 "Inter",system-ui,sans-serif;display:none;align-items:center;gap:7px;box-shadow:0 6px 18px rgba(0,0,0,.35);cursor:pointer}
.ab-reveal.on{display:flex}
.ab-reveal .mk{width:12px;height:12px;background:#fff;clip-path:polygon(25% 2%,75% 2%,100% 50%,75% 98%,25% 98%,0 50%)}
/* key/value grid — the SEO panel's resolved + live tag readouts */
#ams-adrawer .ab-sysgrid{padding:6px 0}
#ams-adrawer .ab-kv{display:flex;justify-content:space-between;gap:12px;padding:10px 24px;border-bottom:1px solid var(--arulesoft);font-size:13px}
#ams-adrawer .ab-kv:last-child{border-bottom:0}
#ams-adrawer .ab-kvk{color:var(--aink3)}
#ams-adrawer .ab-kvv{color:var(--aink);text-align:right;max-width:62%;overflow-wrap:anywhere}
#ams-adrawer .mono{font-family:var(--amono)}
/* SEO panel: section labels + the per-page health checklist. */
#ams-adrawer .ab-seo-h{padding:12px 24px 4px;font:600 10.5px/1 var(--adisp);letter-spacing:.08em;text-transform:uppercase;color:var(--aink3)}
#ams-adrawer .ab-seo-checks{list-style:none;margin:0;padding:2px 0 6px}
#ams-adrawer .ab-seo-checks li{display:flex;align-items:baseline;gap:9px;padding:8px 24px;border-bottom:1px solid var(--arulesoft);font-size:13px}
#ams-adrawer .ab-seo-checks li:last-child{border-bottom:0}
#ams-adrawer .ab-seo-checks .mk{flex:none;width:15px;font-weight:700}
#ams-adrawer .ab-seo-checks li.ok .mk{color:var(--jade)}
#ams-adrawer .ab-seo-checks li.bad .mk{color:var(--sig)}
#ams-adrawer .ab-seo-checks .lbl{color:var(--aink);flex:none}
#ams-adrawer .ab-seo-checks .nt{color:var(--aink3);font-size:11.5px;margin-left:auto;text-align:right;overflow-wrap:anywhere}
/* PHONES: THE STRIP. The navigation is the thumb zone below this bar now, so
   what is left for the staff bar is the one thing the thumb zone cannot say —
   which build you are looking at — plus one control that opens every tool.
   Four tiles under five tabs was two bottom navs stacked.

   Everything the tiles used to reach is in the Tools sheet (see the `more`
   panel in js/08-admin-router/01-*), which is why this is a collapse and not a
   removal: New, Lab and Admin moved into it the same day this rule landed. */
@media(max-width:640px){
  #adminbar{height:var(--abh);min-height:0;flex-wrap:nowrap;overflow-x:hidden;
    align-items:center;gap:9px;padding:0 12px env(safe-area-inset-bottom)}
  /* The zones were three bordered groups across a 46px bar. At 34px there is
     one row, so they stop being boxes and just let their contents sit in it. */
  #adminbar .ab-zone{display:contents}
  /* What a strip cannot hold. The bell, the command button, the hide chevron
     and every tool tile are all in the Tools sheet, which is now the whole bar
     rather than its overflow. */
  #adminbar .ab-btn,#adminbar .ab-cmd,#adminbar .ab-hide,#adminbar .ab-bell{display:none}
  /* The context chip goes too, and for a reason worth writing down: nothing
     updates it on THIS bar. setAdminCtx() writes to #ab-ctx, which is the
     /admin console's chip; the front bar renders a .ab-ctx that says "Nothing
     selected" and never says anything else. On a 46px desktop bar that is a
     quiet dead spot. As the widest element of a 34px strip it would be the
     main thing an operator reads, and it would always be wrong. */
  #adminbar .ab-ctx{display:none}
  /* So the build number leads and is the strip's whole status: which build am I
     looking at. order:-1 because this rule makes the zone a flex ITEM again (it
     beats the display:contents above on source order, same specificity), and
     margin-right:auto pushes the one control to the far end. */
  #adminbar .ab-meta-zone{display:flex;order:-1;align-items:center;flex:none;
    margin-right:auto;padding:0;border:0}
  #adminbar .ab-meta-zone:empty{display:none}
  #adminbar .ab-meta{font-size:9.5px;letter-spacing:.04em}
  /* One control, and it is the whole right-hand end of the strip. 34px is the
     tallest target this bar can offer, so it takes every pixel of it. */
  #adminbar .ab-btn.ab-more{display:flex;flex:none;align-items:center;gap:6px;
    height:var(--ab-strip);margin-right:-12px;padding:0 12px;border-radius:0;
    color:var(--aink2);font-size:11.5px;font-weight:600}
  #adminbar .ab-more[aria-expanded="true"]{background:var(--grl);color:var(--aink)}
  #adminbar .ab-more .ab-t{display:block;line-height:1}
  #adminbar .ab-more .ab-i{width:17px;height:17px}
  #adminbar .ab-more .ab-count{font-size:9px;line-height:14px;padding:0 5px;min-width:16px;text-align:center}
  #adminbar .ab-sub,#adminbar .ab-ticks,#adminbar .ab-quiet,#adminbar kbd{display:none}
}
/* LANDSCAPE: the thumb zone folds away (css/21-tabbar.php) and this bar is the
   only navigation left, so it goes back to being one — the four-tile bottom nav
   it was before the tab bar existed. Every rule the strip above sets is undone
   here rather than guarded up there, because the strip is the common case. */
@media(max-width:640px) and (max-height:520px){
  #adminbar{height:auto;min-height:72px;overflow-x:hidden;flex-wrap:wrap;
    align-items:stretch;gap:0;padding:0 0 env(safe-area-inset-bottom)}
  #adminbar .ab-zone{display:contents}
  #adminbar .ab-btn,#adminbar .ab-ctx,#adminbar .ab-cmd,#adminbar .ab-hide,#adminbar .ab-bell{display:none}
  #adminbar .ab-meta-zone{display:flex;order:-1;flex:1 0 100%;justify-content:center;align-items:center;
    min-height:16px;padding:0 14px;border-right:0;border-bottom:1px solid var(--grr)}
  #adminbar .ab-meta-zone:empty{display:none}
  #adminbar .ab-meta{font-size:9.5px}
  #adminbar .ab-btn.ab-primary,#adminbar .ab-btn.ab-more{
    display:flex;flex:1 1 0;min-width:0;flex-direction:column;align-items:center;justify-content:center;
    gap:3px;min-height:56px;padding:7px 2px;border-radius:0;position:relative;color:var(--aink2);
    align-self:auto;margin-right:0;font-size:12.5px;font-weight:500}
  #adminbar .ab-primary[aria-expanded="true"],#adminbar .ab-more[aria-expanded="true"]{background:var(--sigwash);color:var(--sig);font-weight:500}
  #adminbar .ab-primary .ab-t,#adminbar .ab-more .ab-t{display:block;font-size:10px;font-weight:600;line-height:1;letter-spacing:.01em}
  #adminbar .ab-primary .ab-i,#adminbar .ab-more .ab-i{width:21px;height:21px}
  #adminbar .ab-primary .ab-count,#adminbar .ab-more .ab-count{position:absolute;top:6px;right:calc(50% - 20px);left:auto;font-size:9.5px;line-height:15px;padding:0 5px;min-width:15px;text-align:center}
  #adminbar .ab-primary .ab-quiet{display:none}
  #adminbar .ab-sub,#adminbar .ab-ticks,#adminbar .ab-cmd kbd{display:none}
}
/* the "More" sheet: a labelled grid of every secondary admin action */
#ams-adrawer .ab-mgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;padding:14px 16px}
#ams-adrawer .ab-mtile{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:9px;min-height:80px;padding:12px 6px;border-radius:12px;background:var(--grl);border:1px solid var(--grr);color:var(--aink);font:600 11.5px/1.15 var(--abody);text-align:center;text-decoration:none;cursor:pointer}
#ams-adrawer .ab-mtile:hover,#ams-adrawer .ab-mtile:active{background:var(--grr)}
#ams-adrawer .ab-mtile .ab-i{width:22px;height:22px;color:var(--aink2)}
#ams-adrawer .ab-mt{color:var(--aink)}
#ams-adrawer .ab-mcount{position:absolute;top:8px;right:12px;font-family:var(--amono);font-size:10px;background:#E0553F;color:#fff;border-radius:100px;padding:1px 6px}
@media(max-width:360px){ #ams-adrawer .ab-mgrid{grid-template-columns:repeat(3,1fr)} }
/* The New panel's create tiles: same tile, but each carries a line of context
   under the label, so a 3-wide grid with room to read beats a 4-wide icon wall. */
/* "Viewing as" banner — pinned to the top of the viewport, above everything,
   because an operator must never be able to forget they are wearing someone
   else's account. Server-rendered (adminbar.php) so it survives a broken
   bundle, and its own colour so it can't be mistaken for site chrome. */
.ams-vabanner{position:fixed;left:0;right:0;top:0;z-index:2147482000;display:flex;align-items:center;gap:10px;
  padding:7px 14px;background:#7C2D12;color:#FFEDD5;font:500 12.5px/1.3 var(--ui);letter-spacing:-.005em;
  box-shadow:0 1px 0 rgba(0,0,0,.25)}
.ams-vabanner .va-dot{width:7px;height:7px;border-radius:99px;background:#FB923C;flex:none;
  box-shadow:0 0 0 3px rgba(251,146,60,.25)}
.ams-vabanner .va-txt{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ams-vabanner .va-txt b{color:#fff;font-weight:600}
.ams-vabanner .va-h{opacity:.7;margin-left:6px}
.ams-vabanner .va-ro{flex:none;font-size:10.5px;text-transform:uppercase;letter-spacing:.07em;
  border:1px solid rgba(255,237,213,.35);border-radius:999px;padding:2px 8px;opacity:.85}
.ams-vabanner .va-stop{flex:none;margin-left:auto;border:1px solid rgba(255,237,213,.45);background:rgba(0,0,0,.18);
  color:#FFEDD5;border-radius:8px;padding:4px 11px;font:600 12px/1 var(--ui);cursor:pointer}
.ams-vabanner .va-stop:hover{background:rgba(0,0,0,.32);color:#fff}
body:has(#ams-vabanner){padding-top:34px}
@media(max-width:560px){ .ams-vabanner .va-h,.ams-vabanner .va-ro{display:none} }
/* The active "viewing as" row inside the View as panel. */
#ams-adrawer .ab-vaon{display:flex;align-items:center;gap:11px;margin:0 0 12px;padding:11px 13px;
  border:1px solid var(--accent-line,#FAD4BC);background:var(--accent-soft,#FFF3EB);border-radius:10px}
#ams-adrawer .ab-vadot{width:7px;height:7px;border-radius:99px;background:#EA580C;flex:none;
  box-shadow:0 0 0 3px rgba(234,88,12,.18)}
#ams-adrawer .ab-vatxt{min-width:0;font-size:13px;line-height:1.4}
#ams-adrawer .ab-vatxt b{font-weight:600}
#ams-adrawer .ab-vatxt span{display:block;font-size:11.5px;color:var(--aink2);margin-top:1px}
#ams-adrawer .ab-vaon .abtn{margin-left:auto;flex:none}
#ams-adrawer .ab-newgrid{grid-template-columns:repeat(3,1fr)}
#ams-adrawer .ab-newgrid .ab-mtile{min-height:92px;gap:6px;justify-content:flex-start;padding:14px 10px}
#ams-adrawer .ab-msub{display:block;font:400 10.5px/1.35 var(--abody);color:var(--aink2);text-align:center}
@media(max-width:560px){ #ams-adrawer .ab-newgrid{grid-template-columns:repeat(2,1fr)} }
/* (padding-bottom + --abh defined once above, near the #adminbar rule) */
/* ---------- the Lab sheet ----------
   The real /lab page, framed at 80% of the viewport above the bar, rather than
   a summary of it in the drawer. Two reasons it is not the drawer: the lab is a
   whole page (a grid, a notes rail, an upload target), and the way you leave it
   should be clicking the site you can still see behind it. The scrim is what
   makes that true — it darkens the page, takes the click, and hands you back.

   It stops at the admin bar (inset-bottom keys off --abh) so the bar itself
   stays live underneath: closing the sheet and opening another panel is one
   click, not two. */
#ab-labwrap{position:fixed;left:0;right:0;top:0;bottom:var(--abh,0px);z-index:1898;display:flex;align-items:flex-end;justify-content:center}
#ab-labwrap[hidden]{display:none}
/* ---------- what is new in the lab ----------
   A card above the bar's Lab button. It appears on its own when something
   lands, so it sits at the bar rather than in the middle of the screen: a
   modal for "somebody uploaded a prototype" would interrupt work to announce
   work. Narrow, above the bar, dismissible, and it never covers the page. */
#ab-labfly{position:fixed;left:var(--flyx,14px);bottom:calc(var(--abh,0px) + 10px);z-index:1901;width:min(340px,calc(100vw - 28px));
  background:var(--asurf);color:var(--aink);border:1px solid var(--arule);border-radius:12px;
  box-shadow:0 14px 44px rgba(0,0,0,.5);font-family:var(--abody);overflow:hidden}
#ab-labfly[hidden]{display:none}
#ab-labfly .fly-h{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid var(--arulesoft);font-size:13px}
#ab-labfly .fly-h b{font-family:var(--adisp);font-weight:600}
#ab-labfly .fly-n{font-family:var(--amono);font-size:10px;background:var(--sig);color:#fff;border-radius:100px;padding:1px 6px}
#ab-labfly .fly-h .abtn{margin-left:auto;padding:2px 7px}
#ab-labfly .fly-l{list-style:none;margin:0;padding:0;max-height:270px;overflow-y:auto}
#ab-labfly .fly-l li{display:flex;flex-direction:column;gap:1px;padding:9px 12px;border-bottom:1px solid var(--arulesoft)}
#ab-labfly .fly-l li:last-child{border-bottom:0}
#ab-labfly .fly-l li.fresh{border-left:2px solid var(--sig);padding-left:10px}
#ab-labfly .fly-l .k{font-family:var(--amono);font-size:9.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--sigink)}
#ab-labfly .fly-l .k i{font-style:normal;color:var(--aink3);letter-spacing:.04em}
#ab-labfly .fly-l .t{font-size:13px;font-weight:500;overflow-wrap:anywhere}
#ab-labfly .fly-l .d{font-size:12px;color:var(--aink2);overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
#ab-labfly .fly-l .m{font-family:var(--amono);font-size:10px;color:var(--aink3);margin-top:2px}
#ab-labfly .fly-f{display:flex;align-items:center;gap:8px;padding:10px 12px;border-top:1px solid var(--arule);flex-wrap:wrap}
#ab-labfly .fly-note{font-size:11.5px;color:var(--aink3)}
@media(max-width:640px){ #ab-labfly{left:8px;right:8px;width:auto} }

/* The strip above the sheet is the site itself, live and untinted — that is
   what you are coming back to, and seeing it is the whole affordance. The
   SHEET is what has to be opaque: a half-lit page showing through the board
   is something to read by mistake. So the backdrop paints nothing and only
   takes the click. */
#ab-labwrap .ab-lab-scrim{position:absolute;inset:0;background:transparent;cursor:pointer}
#ab-labwrap .ab-lab-sheet{position:relative;width:100%;height:80vh;max-height:calc(100% - 10px);
  background:var(--asurf);color:var(--aink);border-top:1px solid var(--arule);border-radius:14px 14px 0 0;
  box-shadow:0 -22px 60px rgba(0,0,0,.45);display:flex;flex-direction:column;overflow:hidden;font-family:var(--abody)}
#ab-labwrap .ab-lab-head{display:flex;align-items:center;gap:10px;padding:9px 14px;border-bottom:1px solid var(--arulesoft);flex:none}
#ab-labwrap .ab-lab-head h2{font-family:var(--adisp);font-size:14px;font-weight:600;margin:0;letter-spacing:-.01em}
#ab-labwrap .ab-lab-head .eyebrow{font-family:var(--amono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--aink3)}
#ab-labwrap .ab-lab-head .sp{margin-left:auto}
#ab-labwrap .ab-lab-head [data-lab-back][hidden]{display:none}
#ab-labwrap .ab-lab-head .where{font-family:var(--amono);font-size:10.5px;color:var(--aink3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:38ch}
#ab-labwrap .ab-lab-grip{position:absolute;left:50%;transform:translateX(-50%);top:3px;width:38px;height:3px;border-radius:99px;background:var(--grr)}
#ab-labwrap iframe{flex:1;width:100%;border:0;background:#0E0E11;display:block}
@media(max-width:640px){ #ab-labwrap .ab-lab-sheet{height:86vh;border-radius:12px 12px 0 0} }
#ams-adrawer{position:fixed;left:0;right:0;bottom:var(--abh);z-index:1899;background:var(--asurf);color:var(--aink);border-top:1px solid var(--arule);box-shadow:0 -12px 32px rgba(20,22,26,.10);max-height:min(58vh,440px);display:flex;flex-direction:column;font-family:var(--abody)}
#ams-adrawer .drawer-head{display:flex;align-items:center;gap:10px;padding:12px 24px;border-bottom:1px solid var(--arulesoft);flex:none}
#ams-adrawer .drawer-body{overflow-y:auto;padding:0}
#ams-adrawer .drawer-foot{display:flex;align-items:center;gap:8px;padding:11px 24px;border-top:1px solid var(--arule);flex:none}
#ams-adrawer .panel-title{font-family:var(--adisp);font-size:14px;font-weight:600;margin:0;letter-spacing:-.01em}
#ams-adrawer .eyebrow{font-family:var(--amono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--aink3)}
#ams-adrawer .t-sub{display:block;font-family:var(--amono);font-size:10.5px;color:var(--aink3);margin-top:2px}
#ams-adrawer .abtn,#ab-labwrap .abtn,#ab-labfly .abtn{border:1px solid var(--arule);background:var(--asurf);border-radius:3px;padding:4px 9px;font-size:12px;font-weight:500;color:var(--aink);cursor:pointer;font-family:inherit;white-space:nowrap;text-decoration:none;display:inline-flex;align-items:center;gap:6px}
#ams-adrawer .abtn:hover,#ab-labwrap .abtn:hover,#ab-labfly .abtn:hover{border-color:var(--grr);background:var(--grl)}
#ams-adrawer .abtn.solid,#ab-labwrap .abtn.solid,#ab-labfly .abtn.solid{background:var(--sig);color:#fff;border-color:transparent}
#ams-adrawer .abtn.solid:hover,#ab-labwrap .abtn.solid:hover,#ab-labfly .abtn.solid:hover{filter:brightness(1.08)}
#ams-adrawer .abtn.ghost,#ab-labwrap .abtn.ghost,#ab-labfly .abtn.ghost{border-color:transparent;background:transparent}
#ams-adrawer .abtn.ghost:hover,#ab-labwrap .abtn.ghost:hover,#ab-labfly .abtn.ghost:hover{background:var(--grl)}
#ams-adrawer .pill{display:inline-block;font-family:var(--amono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;border-radius:2px;padding:2px 6px;white-space:nowrap;background:var(--grl);color:var(--aink2)}
/* the drawer palette is always dark (color-scheme:dark above), so this pill's
   ink has to be the light jade, not the dark one — a "done" pill in #0A6E55 on
   a jade wash was legible on paper and invisible here, which nobody saw until
   done bugs started rendering in the Bugs panel's Archived group. */
#ams-adrawer .pill.ok{background:var(--jadewash);color:var(--jade)}
#ams-adrawer .pill.warn{background:var(--sigwash);color:var(--sigink)}
#ams-adrawer .pill.info{background:rgba(91,147,214,.16);color:#8FB4E4}
#ams-adrawer .review{list-style:none;margin:0;padding:0}
#ams-adrawer .review li{display:flex;align-items:center;gap:12px;padding:12px 24px;border-bottom:1px solid var(--arulesoft)}
#ams-adrawer .review li:last-child{border-bottom:0}
#ams-adrawer .review-text{min-width:0;flex:1}
#ams-adrawer .review-text b{font-weight:600;font-size:13.5px}
#ams-adrawer .bug-group-head{display:flex;align-items:center;gap:10px;padding:9px 24px;background:var(--grl);border-bottom:1px solid var(--arulesoft)}
#ams-adrawer .bug-group-head .eyebrow:last-child{margin-left:auto}
#ams-adrawer .bug-list{list-style:none;margin:0;padding:0}
/* Archived bugs (done · won't fix) — present but folded away, so the count on
   the button is always explainable without leaving the page, and a row closed
   by mistake can be reopened from here. */
#ams-adrawer .bug-arch>summary{display:flex;align-items:center;gap:10px;padding:9px 24px;cursor:pointer;
  background:var(--grl);border-top:1px solid var(--arulesoft);border-bottom:1px solid var(--arulesoft);list-style:none}
#ams-adrawer .bug-arch>summary::-webkit-details-marker{display:none}
#ams-adrawer .bug-arch>summary::after{content:'▸';color:var(--aink3);font-size:11px}
#ams-adrawer .bug-arch[open]>summary::after{content:'▾'}
#ams-adrawer .bug-arch>summary .eyebrow:last-of-type{margin-left:auto}
#ams-adrawer .bug-arch .bug-item{opacity:.8}
#ams-adrawer .bug-item{display:flex;align-items:center;gap:12px;padding:11px 24px;border-bottom:1px solid var(--arulesoft)}
#ams-adrawer .bug-item:last-child{border-bottom:0}
#ams-adrawer .bug-text{min-width:0;flex:1}
#ams-adrawer .bug-text b{font-weight:600;font-size:13.5px;display:block}
#ams-adrawer .bug-acts,#ams-adrawer .review-acts{display:flex;gap:6px;flex:none}
#ams-adrawer .aempty{padding:30px 20px;text-align:center}
#ams-adrawer .aempty h3{font-family:var(--adisp);font-size:18px;font-weight:700;margin:0;letter-spacing:-.02em}
#ams-adrawer .aempty p{margin:6px auto 0;max-width:44ch;color:var(--aink2);font-size:13px}
#ams-adrawer .aempty .mk{width:32px;height:32px;margin:0 auto 12px;border:1.5px dashed var(--grr);border-radius:50%;display:grid;place-items:center;font-family:var(--amono);font-size:13px;color:var(--aink3)}
#ams-adrawer .qform{padding:16px 24px 18px;max-width:600px}
#ams-adrawer .qfield{margin-bottom:12px}
#ams-adrawer .qfield label{display:block;font-size:12.5px;font-weight:600;margin-bottom:5px}
#ams-adrawer .qfield .opt{font-weight:400;color:var(--aink3);font-family:var(--amono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;margin-left:5px}
#ams-adrawer .qinp{width:100%;border:1px solid var(--arule);border-radius:3px;padding:8px 10px;font-size:13.5px;background:var(--asurf);color:var(--aink);font-family:inherit}
#ams-adrawer .qinp:focus{outline:none;border-color:var(--sig)}
#ams-adrawer .qseg{display:inline-flex;border:1px solid var(--arule);border-radius:3px;overflow:hidden}
#ams-adrawer .qseg button{background:var(--asurf);border:0;border-right:1px solid var(--arule);padding:5px 12px;font-size:12.5px;color:var(--aink2);cursor:pointer;font-family:inherit}
#ams-adrawer .qseg button:last-child{border-right:0}
#ams-adrawer .qseg button.on{background:var(--sig);color:#fff}
#ams-adrawer .capture{margin:0 0 14px;font-family:var(--amono);font-size:10.5px;color:var(--aink3)}
/* The sentence under a group head in the Hidden panel. It describes the rows
   below it, so it carries THEIR inset: .capture on its own is a form note that
   lives inside a padded .qform body, and reused here it sat flush against the
   edge while every row it was describing started 24px in. */
#ams-adrawer .ab-hnote{margin:9px 24px 2px;font-family:var(--amono);font-size:10.5px;color:var(--aink3)}
#ams-adrawer .capture b{color:var(--aink2);font-weight:400}
#ams-adrawer .qform-foot{display:flex;align-items:center;gap:8px}
/* full bug detail inside a drawer row */
#ams-adrawer .bug-body{display:block;font-size:12.5px;color:var(--aink2);margin-top:6px;white-space:pre-wrap;line-height:1.45;overflow-wrap:anywhere}
#ams-adrawer .bug-note{display:block;font-family:var(--amono);font-size:11px;color:var(--sigink);margin-top:5px}
#ams-adrawer .bug-photos{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
#ams-adrawer .bug-thumb{width:64px;height:48px;object-fit:cover;border-radius:3px;border:1px solid var(--arule);cursor:zoom-in;background:var(--grl);display:block}
#ams-adrawer .bug-thumb:hover{border-color:var(--grr)}
/* every bug in the bar carries its own console address */
#ams-adrawer .bug-link{color:inherit;text-decoration:none;border-bottom:1px solid transparent}
#ams-adrawer .bug-link:hover{color:var(--sigink);border-bottom-color:currentColor}
/* generic admin-side image lightbox (real attachment URLs) — open/download live
   in the pop-up, so no admin image is ever a bare link to the file */
#ab-lightbox{position:fixed;inset:0;z-index:4000;display:none;background:rgba(10,12,13,.9)}
#ab-lightbox.on{display:flex;flex-direction:column}
#ab-lightbox .ablb-top{display:flex;align-items:center;gap:10px;padding:12px 14px;color:#fff}
#ab-lightbox .ablb-name{font-size:12.5px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#ab-lightbox .ablb-ct{font-family:"JetBrains Mono",ui-monospace,monospace;font-size:11.5px;opacity:.7;flex:none}
#ab-lightbox .ablb-acts{margin-left:auto;display:flex;gap:8px;flex:none}
#ab-lightbox .ablb-btn{display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 12px;border-radius:6px;cursor:pointer;
  border:1px solid rgba(255,255,255,.22);background:rgba(255,255,255,.1);color:#fff;font:inherit;font-size:12.5px;font-weight:600;text-decoration:none}
#ab-lightbox .ablb-btn:hover{background:rgba(255,255,255,.2)}
#ab-lightbox .ablb-stage{flex:1;min-height:0;position:relative;display:flex;align-items:center;justify-content:center;padding:0 14px 18px}
#ab-lightbox .ablb-img{max-width:100%;max-height:100%;object-fit:contain;border-radius:4px;box-shadow:0 12px 48px rgba(0,0,0,.5)}
#ab-lightbox .ablb-nav{position:absolute;top:50%;transform:translateY(-50%);width:44px;height:44px;border-radius:50%;border:0;background:rgba(255,255,255,.14);color:#fff;font-size:26px;line-height:1;cursor:pointer}
#ab-lightbox .ablb-nav:hover{background:rgba(255,255,255,.24)}
#ab-lightbox .ablb-prev{left:14px}
#ab-lightbox .ablb-next{right:14px}
@media (max-width:700px){#ab-lightbox .ablb-name{display:none}}
/* mod-page photo lightbox */
/* THE photo lightbox (#ams-lb, amsLightbox) — every gallery on the site opens
   here: mod photos, vehicle photos. Always a gallery, never one lone image, so
   the stage carries prev/next and the foot carries the counter + a thumbnail
   strip you can jump around in. */
body.lb-open{overflow:hidden}
#ams-lb{position:fixed;inset:0;z-index:4000;display:none;flex-direction:column;
  background:rgba(8,9,11,.94);backdrop-filter:blur(4px)}
#ams-lb.on{display:flex}
#ams-lb .alb-stage{position:relative;flex:1;min-height:0;display:flex;align-items:center;
  justify-content:center;padding:56px 68px 12px}
#ams-lb .alb-img{max-width:100%;max-height:100%;object-fit:contain;border-radius:5px;
  box-shadow:0 12px 48px rgba(0,0,0,.5)}
#ams-lb .alb-x{position:absolute;top:14px;right:16px;z-index:2;width:40px;height:40px;border-radius:50%;
  border:0;background:rgba(255,255,255,.14);color:#fff;font-size:17px;cursor:pointer}
#ams-lb .alb-x:hover{background:rgba(255,255,255,.26)}
#ams-lb .alb-nav{position:absolute;top:50%;transform:translateY(-50%);width:46px;height:46px;
  border-radius:50%;border:0;background:rgba(255,255,255,.14);color:#fff;font-size:27px;line-height:1;
  cursor:pointer;transition:background .16s,transform .16s var(--ease)}
#ams-lb .alb-nav:hover{background:rgba(255,255,255,.26)}
#ams-lb .alb-nav:active{transform:translateY(-50%) scale(.94)}
#ams-lb .alb-prev{left:14px}
#ams-lb .alb-next{right:14px}
#ams-lb .alb-foot{flex:none;display:flex;flex-direction:column;align-items:center;gap:9px;
  padding:4px 14px 16px}
#ams-lb .alb-ct{color:rgba(255,255,255,.72);font-family:"JetBrains Mono",ui-monospace,monospace;
  font-size:12px;background:rgba(0,0,0,.4);padding:4px 10px;border-radius:100px}
/* The owner's note on the photograph. NOT mono: .num and the mono face mean a
   measured figure on this site, and this is a sentence somebody wrote. It wraps
   — the tile above clips its note to one line and this is where a long one is
   read — and it is centred on the picture it belongs to rather than filling the
   window, so a three-word note does not sit alone across 1400px. */
#ams-lb .alb-note{max-width:min(72ch,92%);text-align:center;color:#F4F1EC;font-size:14px;
  line-height:1.5;background:rgba(0,0,0,.44);padding:8px 14px;border-radius:9px}
#ams-lb .alb-note[hidden]{display:none}
/* The markers (380). The layer is placed onto the picture by albPlace() — see
   the note in js/07-live-data/08-post-detail-and-lightbox/02-lightbox.php for
   why it is measured rather than laid out. Pins are the accent, the tool's
   own drawing of them; a label opens on hover and on press, and flips above
   the pin near the bottom edge so it is never cut by the frame. */
#ams-lb .alb-pins{position:absolute;pointer-events:none;z-index:1}
#ams-lb .alb-pins[hidden]{display:none}
#ams-lb .alb-pin{position:absolute;transform:translate(-50%,-50%);width:22px;height:22px;border-radius:4px;
  padding:0;pointer-events:auto;background:var(--accent);color:#fff;border:1.5px solid rgba(255,255,255,.92);
  font:500 10px/1 var(--mono);display:grid;place-items:center;cursor:pointer;overflow:visible;
  box-shadow:0 2px 9px rgba(0,0,0,.5)}
#ams-lb .alb-pin:hover,#ams-lb .alb-pin.on{z-index:2}
#ams-lb .alb-pin.on{background:#111}
#ams-lb .alb-pinl{position:absolute;left:50%;top:calc(100% + 7px);transform:translateX(-50%);
  max-width:230px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  background:rgba(8,11,13,.96);border:1px solid rgba(255,255,255,.15);color:#F4F1EC;
  font:400 11.5px/1.3 var(--ui);padding:5px 7px;border-radius:4px;pointer-events:none;
  opacity:0;transition:opacity .13s var(--ease)}
#ams-lb .alb-pin.flip .alb-pinl{top:auto;bottom:calc(100% + 7px)}
#ams-lb .alb-pin:hover .alb-pinl,#ams-lb .alb-pin.on .alb-pinl{opacity:1}
#ams-lb .alb-strip{display:flex;gap:7px;max-width:100%;overflow-x:auto;padding:3px;
  scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.3) transparent}
#ams-lb .alb-strip::-webkit-scrollbar{height:6px}
#ams-lb .alb-strip::-webkit-scrollbar-thumb{background:rgba(255,255,255,.28);border-radius:99px}
#ams-lb .alb-th{flex:none;width:62px;height:44px;border-radius:6px;border:0;padding:0;cursor:pointer;
  background:#1b1c20 center/cover no-repeat;opacity:.5;
  outline:2px solid transparent;outline-offset:2px;transition:opacity .16s,outline-color .16s}
#ams-lb .alb-th:hover{opacity:.85}
#ams-lb .alb-th.on{opacity:1;outline-color:var(--accent)}
@media(max-width:760px){
  #ams-lb .alb-stage{padding:52px 12px 8px}
  #ams-lb .alb-nav{width:40px;height:40px;font-size:24px;background:rgba(255,255,255,.18)}
  #ams-lb .alb-prev{left:8px}
  #ams-lb .alb-next{right:8px}
  #ams-lb .alb-th{width:52px;height:38px}
  #ams-lb .alb-foot{padding-bottom:calc(14px + env(safe-area-inset-bottom))}
}
@media(max-width:640px){
  /* Sit above the taller mobile bar (+ safe area), give the sheet more height,
     wrap each row's action buttons onto their own line so titles aren't crushed,
     enlarge tap targets, and use 16px inputs so iOS doesn't zoom on focus. */
  /* --abh already carries the strip AND the home-indicator pad at this width,
     so the drawer's `bottom` above needs no second copy of either — it used to
     say 56px + inset here against a 34px + inset bar and floated 22px clear. */
  #ams-adrawer{max-height:min(72vh,600px)}
  #ams-adrawer .drawer-head,#ams-adrawer .review li,#ams-adrawer .bug-item,#ams-adrawer .bug-group-head,#ams-adrawer .drawer-foot{padding-left:16px;padding-right:16px}
  #ams-adrawer .ab-hnote{margin-left:16px;margin-right:16px}
  #ams-adrawer .qform{padding:16px}
  #ams-adrawer .bug-item,#ams-adrawer .review li{flex-wrap:wrap}
  #ams-adrawer .bug-text,#ams-adrawer .review-text{flex-basis:calc(100% - 70px)}
  #ams-adrawer .bug-acts,#ams-adrawer .review-acts{width:100%;justify-content:flex-end;margin-top:2px}
  #ams-adrawer .abtn,#ab-labwrap .abtn{min-height:38px;padding:0 14px}
  #ams-adrawer .qinp{font-size:16px;padding:10px 12px}
  #ams-adrawer .qseg button{padding:9px 14px;font-size:13.5px}
}

/* Default image placeholder — a clean, consistent slot with a subtle car glyph,
   used wherever there is no real photo yet (profiles, garages, vehicles, feed,
   cards). Any real image (upload or stock) still loads on top of it. */
/* AMS placeholder render for anything without a photo yet. Also resets the size
   the marketplace `.noimg` dashed slot (62x47) would otherwise leak in and
   collapse the tile with — the empty-garage layout bug. */
.photo.noimg{background:#e9e9ee center/cover url(/assets/vehicle-placeholder.svg) no-repeat!important;
  width:auto!important;height:auto!important;flex:initial!important;display:block!important;border:0!important}
.photo.noimg::before{content:none!important;background:none!important}
.photo.noimg::after{background:none!important}

/* ============================================================
   Split out of 08-announcement-and-admin-bar.php, which was over the §10 cap.
   It KEEPS ITS PLACE IN THE CASCADE — styles.php includes it between 08 and
   08b, exactly where these rules used to sit — because order is the cascade and
   a split that reorders is not a split.
   ============================================================ */
/* ============================================================
   Unified profile + garage view (.gx) — cover-identity header, aggregate
   stat row, 2-up vehicle tiles, about. Scoped under .gx so the design's
   generic class names never touch the rest of the app.
   ============================================================ */
/* The cover-identity HEADER that used to live here is gone. The profile is
   drawn by 23-profile.php now — a full-bleed cover with the identity
   under it rather than white type over a gradient — and views/app/
   page-profile.php stopped putting `.phead` on the host, so every rule in
   that block matched nothing. What is still live below is what the
   Vehicles tab uses: the section headings and the garage tiles. */

.gx .gsec{padding:26px 0 0}
.gx .gsec-h{display:flex;align-items:baseline;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-bottom:14px}
.gx .gsec-h h2{font-size:13px;font-weight:600;color:var(--t3);letter-spacing:.07em;font-family:var(--ui)}
.gx .gsec-h .note{font-size:12.5px;color:var(--t3)}
.gx .gsum{display:flex;flex-wrap:wrap;border:1px solid var(--border);border-radius:var(--r-lg);
  background:linear-gradient(180deg,var(--surface3),var(--surface2) 62%);overflow:hidden}
.gx .gsum>div{flex:1;min-width:118px;padding:14px 18px;border-left:1px solid var(--border)}
.gx .gsum>div:first-child{border-left:0}
.gx .gsum b{display:block;font-family:var(--dis);font-size:23px;font-weight:600;letter-spacing:-.036em;
  line-height:1;font-variant-numeric:tabular-nums}
.gx .gsum b u{text-decoration:none;font-size:11.5px;font-weight:500;color:var(--t3);margin-left:3px}
.gx .gsum span{display:block;font-size:10px;color:var(--t3);letter-spacing:.05em;margin-top:6px}
.gx .gtiles{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-top:14px}
.gx .gtile{border:1px solid var(--border);border-radius:var(--r-xl);overflow:hidden;background:var(--surface);
  box-shadow:var(--sh-sm);transition:transform .2s var(--ease),box-shadow .2s var(--ease),border-color .2s;display:block;color:inherit}
.gx .gtile:hover{transform:translateY(-2px);box-shadow:var(--sh);border-color:var(--border2)}
.gx .gtile>.photo{border-radius:0;aspect-ratio:16/10;min-height:0}
.gx .gtile .bd{padding:16px 18px 17px}
.gx .gtile .top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.gx .gtile h3{font-size:20px;letter-spacing:-.032em;line-height:1.1}
/* `gymm`, NOT `ymm`. The finder widget owns .ymm site-wide — a bordered,
   shadowed, rounded bar of three dropdowns — and this line is a caption that
   happened to share its name. It inherited the whole box: border, 14px
   radius, surface fill, shadow and display:flex, which drew the year and
   model inside a chip nobody designed. Two different things, one class name. */
.gx .gtile .gymm{font-size:13px;color:var(--t2);margin-top:5px}
/* The generation, opposite the title. `.top` aligns to flex-start, so the 3px
   drops it onto the 20px title's cap height rather than its box top. */
.gx .gtile .gen{flex:none;margin-top:3px;font-size:12px;font-weight:500;
  letter-spacing:.02em;color:var(--t3);white-space:nowrap}
.gx .gtile .qs{display:flex;flex-wrap:wrap;gap:11px 22px;margin-top:15px;padding-top:14px;border-top:1px solid var(--border)}
.gx .gtile .qs b{display:block;font-family:var(--dis);font-size:17px;font-weight:600;letter-spacing:-.03em;
  line-height:1;font-variant-numeric:tabular-nums}
.gx .gtile .qs b u{text-decoration:none;font-size:10.5px;font-weight:500;color:var(--t3);margin-left:2px}
.gx .gtile .qs span{display:block;font-size:9.5px;color:var(--t3);letter-spacing:.05em;margin-top:5px}
@media(max-width:820px){.gx .gtiles{grid-template-columns:1fr}}
.gx .bio{font-size:15px;color:var(--t2);line-height:1.72;max-width:62ch}
.gx .bio b{color:var(--text);font-weight:500}
.gx .gpstat{display:flex;flex-wrap:wrap;gap:26px;margin-top:18px;padding-top:17px;border-top:1px solid var(--border)}
.gx .gpstat b{display:block;font-family:var(--dis);font-size:18px;font-weight:600;letter-spacing:-.03em;
  line-height:1;font-variant-numeric:tabular-nums}
.gx .gpstat span{display:block;font-size:10px;color:var(--t3);letter-spacing:.05em;margin-top:5px}
.gx .about{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:38px;align-items:start;padding-top:8px}
.gx .about .pstat{display:flex;flex-wrap:wrap;gap:26px;margin-top:18px;padding-top:17px;border-top:1px solid var(--border)}
.gx .about .pstat b{display:block;font-family:var(--dis);font-size:18px;font-weight:600;letter-spacing:-.03em;line-height:1;font-variant-numeric:tabular-nums}
.gx .about .pstat span{display:block;font-size:10px;color:var(--t3);letter-spacing:.05em;margin-top:5px}
.gx .gside .card{padding:15px 16px 16px;border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface)}
.gx .gside .card+.card{margin-top:14px}
.gx .tagrow{display:flex;flex-wrap:wrap;gap:6px}
.gx .rep{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--border)}
.gx .rep:last-child{border-bottom:0}
.gx .rep .ri{width:26px;height:26px;border-radius:8px;flex:none;display:grid;place-items:center;font-size:12px;font-weight:600}
.gx .rep b{display:block;font-size:12.5px;font-weight:500;letter-spacing:-.012em}
.gx .rep span{display:block;font-size:11px;color:var(--t3);margin-top:2px}
@media(max-width:900px){.gx .about{grid-template-columns:1fr;gap:26px}}


/* ---- Facebook-style photo editor (cover / avatar) ---- */
.pe-host{position:relative}
/* `.photo` sets isolation:isolate, which seals everything inside it into its own
   stacking context — so the camera, its menu and the reposition bar painted
   BELOW whatever identity overlay is stacked on the same cover (.pov on the
   profile header, .ov3 on the vehicle hero), no matter what z-index they asked
   for. On a phone that overlay reaches far enough up a short cover to bury the
   menu completely, which is how "add a header image" stopped working there.
   The host's own gradient layers are already dropped by .hasimg, so releasing
   the isolation costs nothing and lets the z-indexes below mean what they say. */
.photo.pe-host{isolation:auto}
/* Banner camera lives top-right: the bottom of a cover is occupied by the
   profile head's action buttons and by the vehicle hero's title/actions, so a
   bottom-right button would sit under them and be unclickable. */
.pedit{position:absolute;right:12px;top:12px;z-index:12;display:inline-flex;align-items:center;gap:6px;
  height:32px;padding:0 12px;border-radius:9px;border:1px solid rgba(255,255,255,.28);
  background:rgba(12,12,16,.62);color:#fff;font:600 12.5px var(--ui);cursor:pointer;backdrop-filter:blur(6px)}
.pedit:hover{background:rgba(12,12,16,.8)}
.pedit.pedit-av{right:-2px;bottom:-2px;top:auto;width:30px;height:30px;padding:0;justify-content:center;border-radius:50%}
.pedit-menu{position:absolute;right:12px;top:52px;z-index:13;min-width:170px;padding:6px;
  background:var(--surface);border:1px solid var(--border2);border-radius:12px;box-shadow:var(--sh-lg)}
/* The avatar menu opens up-and-RIGHT from the bubble. Anchoring it right (to a
   32–52px bubble that sits at the left edge of its header) pushed its 170px of
   width off the left of the page, so most of it was unreachable. */
.pedit-av + .pedit-menu{left:-2px;right:auto;top:auto;bottom:34px}
/* The vehicle hero is a full-bleed image that runs under the sticky nav
   (#pg-myvehicle has padding-top:0), so its camera + menu sit below the nav's
   height instead of at the very top where the nav would cover them. */
#ov-head .ovhero .pedit{top:73px}
#ov-head .ovhero .pedit-menu{top:113px}
.pedit-menu button{display:block;width:100%;text-align:left;background:none;border:0;cursor:pointer;
  padding:8px 10px;border-radius:8px;font:500 13px var(--ui);color:var(--text)}
.pedit-menu button:hover{background:var(--surface2)}
.pedit-menu button.danger{color:#E5484D}
/* While repositioning, lift the banner above any overlay that sits on top of
   it (the vehicle hero's title/gradient, the profile head) so the whole image
   is grabbable — otherwise the overlay eats the drag and nothing moves. Stays
   below the nav (z-index 60). */
.pe-reposition{cursor:grab;user-select:none;z-index:30}
.pe-reposition:active{cursor:grabbing}
.pe-reposition .pe-img,.pe-reposition img{pointer-events:none}
.pe-bar{position:absolute;left:0;right:0;bottom:0;z-index:8;display:flex;align-items:center;gap:10px;
  padding:10px 14px;background:linear-gradient(0deg,rgba(8,8,12,.82),rgba(8,8,12,.4));color:#fff;font:500 13px var(--ui)}
.pe-bar .pe-bar-a{margin-left:auto;display:flex;gap:8px}
.pe-bar button{height:30px;padding:0 14px;border-radius:8px;border:1px solid rgba(255,255,255,.28);
  background:rgba(255,255,255,.12);color:#fff;font:600 12.5px var(--ui);cursor:pointer}
.pe-bar button[data-pe-save]{background:var(--accent);border-color:var(--accent)}

/* THE BAR ON AN AVATAR HANGS BELOW IT.
   `.pe-bar` is left:0;right:0;bottom:0 — right for a cover, and inside a
   112px avatar that is a 112px box holding 236px of content, clipped by the
   host's own overflow. So on an avatar it sits under the photo at its
   natural width instead of across it.

   Letting the overflow out is safe HERE and only here: paint() puts the
   photo on as a background-image, and a background is already clipped by
   border-radius with no help from overflow:hidden. The extra `.pe-host` is
   specificity — the page that mounts the avatar sets overflow on it too. */
/* An avatar host NEVER clips. paint() puts the photo on as a
   background-image, and a background is already clipped by border-radius —
   overflow:hidden buys nothing there and costs both controls: the editor
   menu opens ABOVE the 112px box and lost its top half, and the bar below it
   came out 112px wide holding 236px of content. */
.pe-host.pe-avatar{overflow:visible}
.pe-avatar .pe-bar{top:calc(100% + 10px);bottom:auto;left:0;right:auto;
  width:max-content;max-width:min(320px,calc(100vw - 32px));
  border-radius:var(--r);padding:9px 10px;gap:8px;font-size:12.5px;
  background:rgba(8,8,12,.92);box-shadow:var(--sh-lg)}
.pe-avatar .pe-bar button{height:28px;padding:0 11px}
.pe-busy{pointer-events:none}
/* live upload spinner + overlay (a real child, so .hasimg's ::before/::after
   suppression can't hide it) */
@keyframes ams-spin{to{transform:rotate(360deg)}}
.ams-spin{width:26px;height:26px;border-radius:50%;border:3px solid rgba(255,255,255,.25);
  border-top-color:#fff;animation:ams-spin .7s linear infinite;box-sizing:border-box}
.pe-loading{position:absolute;inset:0;z-index:40;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:10px;border-radius:inherit;
  background:rgba(8,8,11,.62);backdrop-filter:blur(2px);color:#fff}
.pe-loading-t{font:500 12.5px var(--ui);letter-spacing:.01em}
/* skeleton photo tiles while a gallery upload lands */
.vphoto.loading{display:flex;align-items:center;justify-content:center;cursor:default;
  background:#26262c!important}
.vphoto.loading .ams-spin{width:22px;height:22px;border-width:2.5px}
.vphoto.failed{display:flex;align-items:center;justify-content:center;background:#3a1d1d!important}
.vphoto .vph-x{color:#ff8f8f;font:700 16px var(--ui)}

/* ================= MY GARAGE (/garage) =================
   The member's own cars, and what has been logged on each.

   EVERY COLOUR HERE IS A TOKEN :root ALREADY PUBLISHES. Not one hex value, and
   not one dark-mode block: the accent is operator-configurable from the
   Appearance screen, so a rule carrying #EA580C would have been the one orange
   thing on the site that did not move when somebody repainted it — and a second
   dark palette here would be the copy that drifts. The tokens flip one element
   up and everything below follows. That is the hover card's rule, and
   24-image-picker.php is the lesson in reverse: it was written against the
   catalogue page's PRIVATE names and had no background at all outside it.

   The prefix is gg-. The old page's ggr- rules are still in
   00-tokens-and-buttons.php and still style #pg-garage — they belong to the
   card grid this replaces, and are removed there rather than shadowed here,
   because two stylesheets over one id is how a rule nobody can find wins.

   ROOM FOR THE ADMIN BAR IS --floor's JOB (§6). Nothing in this file measures
   the bottom of the window; body{padding-bottom:var(--floor)} already did it,
   and a sticky element here that wanted its own number would be the second
   opinion that goes wrong the moment an operator collapses the bar. */

#pg-garage .gg-head{display:flex;align-items:flex-start;gap:16px;flex-wrap:wrap;padding:4px 0 0}
#pg-garage .gg-head h1{font-size:29px;font-weight:700;letter-spacing:-.032em;margin:0;line-height:1.05}
#pg-garage .gg-who{margin:5px 0 0;font-size:13px;color:var(--t2)}
#pg-garage .gg-who b{color:var(--text);font-weight:500}
#pg-garage .gg-acts{margin-left:auto;display:flex;align-items:center;gap:8px;flex-wrap:wrap}

/* The two-state privacy segment lived here. It is gone from the header —
   a setting rather than a property of this screen, and one press from the
   per-vehicle visibility tags below, which mean something else. Settings →
   Privacy draws it now, with the site's own switch. */

/* ---------- needs you ---------- */
#pg-garage .gg-needs{margin-top:24px;border:1px solid var(--border);border-radius:var(--r);background:var(--surface);overflow:hidden}
#pg-garage .gg-needs-h{display:flex;align-items:center;gap:9px;padding:10px 14px;border-bottom:1px solid var(--border);background:var(--surface2)}
#pg-garage .gg-needs-h h2{font-size:12px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;margin:0;white-space:nowrap}
#pg-garage .gg-n{font-size:11px;color:var(--t2);border:1px solid var(--border2);padding:0 5px;border-radius:3px;background:var(--surface)}
#pg-garage .gg-hint{margin-left:auto;font-size:11.5px;color:var(--t3)}
/* THE ROW ITSELF IS IN 08e-garage-rail.php, with the column it stands in.
   The band is not a full-width strip any more and .gg-need appears nowhere
   else, so the rules travelled with it rather than being written here and
   overridden there — two stylesheets over one id is how a rule nobody can find
   wins, which is the note at the top of this file. */

/* the fold — a native <details>, so the browser owns the state */
#pg-garage .gg-fold>summary{list-style:none;cursor:pointer}
#pg-garage .gg-fold>summary::-webkit-details-marker{display:none}
#pg-garage .gg-needs-act{margin-left:auto;display:flex;align-items:center;gap:2px;margin-right:-6px}
#pg-garage .gg-link{display:inline-flex;align-items:center;gap:4px;border:0;background:transparent;color:var(--t3);font-size:11.5px;padding:3px 6px;border-radius:4px}
#pg-garage .gg-link:hover{background:var(--surface3);color:var(--text)}
#pg-garage .gg-fold-c{width:27px;height:27px;display:grid;place-items:center;color:var(--t3);transition:transform .18s}
#pg-garage .gg-fold[open]>summary .gg-fold-c{transform:rotate(180deg)}

/* the dismissed drawer — closed, counted, every row recoverable */
#pg-garage .gg-drawer{border-top:1px solid var(--border);background:var(--surface2)}
#pg-garage .gg-drawer>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:7px;
  padding:8px 14px;color:var(--t2);font-size:12px;font-weight:500}
#pg-garage .gg-drawer>summary::-webkit-details-marker{display:none}
#pg-garage .gg-drawer>summary:hover{color:var(--text)}
#pg-garage .gg-drawer-c{display:grid;place-items:center;color:var(--t3);transition:transform .18s}
#pg-garage .gg-drawer[open]>summary .gg-drawer-c{transform:rotate(180deg)}
#pg-garage .gg-drawer-l{padding:0 14px 10px}
#pg-garage .gg-drow{display:flex;align-items:center;gap:10px;padding:7px 0;border-top:1px solid var(--border)}
#pg-garage .gg-drow-n{font-size:12.5px;font-weight:500;color:var(--t2);min-width:0;flex:1;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#pg-garage .gg-drow-n span{color:var(--t3);font-weight:400}

/* ALL CLEAR — the band shrinks rather than vanishing, because the drawer under
   it is the only route back to anything dismissed. Green, because it is the one
   state on this page that is good news. */
#pg-garage .gg-needs-clear{background:transparent;border-style:dashed}
#pg-garage .gg-clear{display:flex;align-items:center;gap:11px;padding:11px 14px}
#pg-garage .gg-clear-t{width:26px;height:26px;flex:none;display:grid;place-items:center;
  border:1px solid var(--green-line);border-radius:5px;background:var(--green-soft);color:var(--green)}
#pg-garage .gg-clear b{display:block;font-size:13.5px;font-weight:600;letter-spacing:-.01em}
#pg-garage .gg-clear span{display:block;font-size:12px;color:var(--t3);margin-top:1px}

/* ---------- the control bar ---------- */
#pg-garage .gg-bar{display:flex;align-items:center;gap:12px;margin:32px 0 12px;flex-wrap:wrap}
#pg-garage .gg-bar h2{font-size:17px;font-weight:700;letter-spacing:-.02em;margin:0}
#pg-garage .gg-rule{flex:1;height:1px;background:var(--border);min-width:20px}
#pg-garage .gg-ctl{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
#pg-garage .gg-chips{display:inline-flex;border:1px solid var(--border2);border-radius:var(--btn-r);background:var(--surface);overflow:hidden;flex-wrap:wrap}
#pg-garage .gg-chip{height:27px;padding:0 9px;display:inline-flex;align-items:center;gap:5px;
  color:var(--t2);font-size:12px;font-weight:500;text-decoration:none;
  border-right:1px solid var(--border);transition:background .13s,color .13s}
#pg-garage .gg-chip:last-child{border-right:0}
#pg-garage .gg-chip:hover{background:var(--surface2);color:var(--text)}
#pg-garage .gg-chip.on{background:var(--surface3);color:var(--text);font-weight:600}
#pg-garage .gg-chip .num{opacity:.55}
/* A chip with nothing behind it is DIMMED, never hidden: "Parked 0" is an
   answer, and a bar that changes shape as you work reads as losing a control. */
#pg-garage .gg-chip.gg-zero{color:var(--t3)}
#pg-garage .gg-chip.gg-zero.on{color:var(--text)}

#pg-garage .gg-sort{position:relative}
#pg-garage .gg-sort>summary{list-style:none;cursor:pointer;height:27px;padding:0 9px;display:inline-flex;align-items:center;gap:6px;
  border:1px solid var(--border2);border-radius:var(--btn-r);background:var(--surface);color:var(--text);font-size:12px;font-weight:500}
#pg-garage .gg-sort>summary::-webkit-details-marker{display:none}
#pg-garage .gg-sort>summary:hover{background:var(--surface2)}
#pg-garage .gg-sortm{position:absolute;right:0;top:calc(100% + 5px);z-index:20;min-width:190px;padding:5px;
  background:var(--surface);border:1px solid var(--border2);border-radius:8px;box-shadow:var(--sh-lg)}
#pg-garage .gg-sopt{display:block;padding:7px 9px;border-radius:5px;font-size:12.5px;color:var(--text);text-decoration:none}
#pg-garage .gg-sopt:hover{background:var(--surface2)}
#pg-garage .gg-sopt.on{background:var(--accent-soft);color:var(--accent-fg);font-weight:600}

#pg-garage .gg-views{display:inline-flex;border:1px solid var(--border2);border-radius:var(--btn-r);background:var(--surface);overflow:hidden}
#pg-garage .gg-vbtn{width:31px;height:27px;display:grid;place-items:center;color:var(--t2);border-right:1px solid var(--border)}
#pg-garage .gg-vbtn:last-child{border-right:0}
#pg-garage .gg-vbtn:hover{background:var(--surface2);color:var(--text)}
#pg-garage .gg-vbtn.on{background:var(--surface3);color:var(--text)}

/* ---------- the cars ---------- */
#pg-garage .gg-list{display:flex;flex-direction:column;gap:10px}
#pg-garage .gg-shelf{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
#pg-garage .gg-row{display:grid;grid-template-columns:200px 1fr;gap:16px;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r);padding:12px;transition:border-color .15s,box-shadow .15s}
#pg-garage .gg-row:hover{border-color:var(--border2);box-shadow:var(--sh-sm)}
/* A car with nothing logged wears a hairline in the accent — it is the one
   thing on the row that says "this is where the work is", and it is a border
   rather than a badge because a badge on nine rows is nine badges. */
#pg-garage .gg-row.is-bare{border-left:2px solid var(--accent-line);padding-left:11px}
#pg-garage .gg-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);overflow:hidden;
  transition:border-color .15s,box-shadow .15s;display:flex;flex-direction:column}
#pg-garage .gg-card:hover{border-color:var(--border2);box-shadow:var(--sh-sm)}
#pg-garage .gg-cbody{padding:11px 12px 12px;display:flex;flex-direction:column;flex:1}
#pg-garage .gg-main{min-width:0;display:flex;flex-direction:column}

/* An old project is drawn quieter, and comes back on hover. It is finished
   work, not deleted work — the build history is the whole reason it is kept. */
#pg-garage .gg-row.is-old,#pg-garage .gg-card.is-old{background:transparent}
#pg-garage .is-old .gg-shot img{filter:grayscale(.45);opacity:.9;transition:filter .2s,opacity .2s}
#pg-garage .is-old:hover .gg-shot img{filter:none;opacity:1}
#pg-garage .is-old .gg-name{color:var(--t2)}
#pg-garage .is-old:hover .gg-name{color:var(--text)}

#pg-garage .gg-shot{position:relative;aspect-ratio:3/2;border-radius:7px;overflow:hidden;background:var(--surface3);
  border:1px solid var(--border);width:100%;padding:0;display:block}
#pg-garage .gg-card .gg-shot{border-radius:0;border:0;border-bottom:1px solid var(--border)}
#pg-garage .gg-shot img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .35s ease}
#pg-garage .gg-shot:hover img{transform:scale(1.03)}
#pg-garage .gg-count{position:absolute;left:7px;bottom:7px;font-size:10.5px;display:inline-flex;align-items:center;gap:4px;
  background:rgba(8,8,10,.72);color:#fff;padding:1px 5px;border-radius:3px}
#pg-garage .gg-shot-empty{display:grid;place-items:center;border-style:dashed;border-color:var(--border2);cursor:pointer}
#pg-garage .gg-shot-empty:hover{border-color:var(--accent);background:var(--accent-soft)}
#pg-garage .gg-ph{text-align:center;color:var(--t3);font-size:11.5px;line-height:1.5;display:block}
#pg-garage .gg-shot-empty:hover .gg-ph{color:var(--accent-fg)}
#pg-garage .gg-ph svg{margin:0 auto 4px;display:block;opacity:.7}

#pg-garage .gg-top{display:flex;align-items:flex-start;gap:8px}
#pg-garage .gg-idty{min-width:0}
#pg-garage .gg-name{font-size:17px;font-weight:600;letter-spacing:-.022em;line-height:1.2;color:var(--text)}
#pg-garage .gg-card .gg-name{font-size:15px}
#pg-garage .gg-name:hover{color:var(--accent-fg)}
#pg-garage .gg-unnamed{color:var(--t2);font-weight:500}
#pg-garage .gg-nameit{height:23px;font-size:11px;vertical-align:2px}
#pg-garage .gg-ymm{font-size:12.5px;color:var(--t2);margin-top:2px}
#pg-garage .gg-eng{color:var(--t3)}
#pg-garage .gg-tags{margin-left:auto;display:flex;align-items:center;gap:6px;flex:none}
#pg-garage .gg-tag{font-size:10px;font-weight:500;letter-spacing:.06em;text-transform:uppercase;
  border:1px solid var(--border2);color:var(--t2);padding:2px 6px;border-radius:3px;background:var(--surface);white-space:nowrap}
#pg-garage .gg-tag-st{cursor:pointer;transition:border-color .13s,color .13s}
#pg-garage .gg-tag-st:hover{border-color:var(--t2);color:var(--text)}
#pg-garage .gg-tag-priv,#pg-garage .gg-tag-pin{color:var(--t3)}
#pg-garage .gg-kebab{width:26px;height:26px;display:grid;place-items:center;border:1px solid transparent;
  border-radius:var(--btn-r);color:var(--t3)}
#pg-garage .gg-kebab:hover{background:var(--surface2);color:var(--text);border-color:var(--border)}

/* ---------- the mod chips ---------- */
#pg-garage .gg-mods{margin-top:12px;display:flex;align-items:center;gap:7px;flex-wrap:wrap}
#pg-garage .gg-mod{display:inline-flex;align-items:center;gap:7px;max-width:100%;height:29px;
  border:1px solid var(--border2);background:var(--surface2);border-radius:5px;
  padding:0 10px 0 7px;text-align:left;color:var(--text);transition:border-color .13s,background .13s,color .13s}
#pg-garage .gg-mod:hover{border-color:var(--accent-line);background:var(--accent-soft)}
#pg-garage .gg-mw{color:var(--accent-fg);flex:none;display:flex}
#pg-garage .gg-mn{font-size:12.5px;font-weight:500;letter-spacing:-.005em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* A hidden mod is the owner's own and is shown to them, marked. On their page
   a mod they cannot see reads as a mod they have lost. */
#pg-garage .gg-mod.is-hidden{border-style:dashed}
#pg-garage .gg-mod.is-hidden .gg-mw{color:var(--t3)}
/* A DRAFT SAYS SO. The dashed border above meant "not public" to whoever wrote
   it and nothing at all to the member reading it — two chips side by side, one
   solid and one dashed, with no word anywhere to say which is which. The tag is
   the amber the rest of the site uses for "you still have to do something with
   this", and it is a WORD rather than a colour on its own, because a colour is
   only a legend if there is a legend. */
#pg-garage .gg-mod.is-draft{border-style:dashed;border-color:var(--warn-line,#EED6AB);
  background:var(--warn-soft,#FDF1E0);color:var(--text);cursor:pointer;font:inherit}
#pg-garage .gg-mod.is-draft:hover{border-style:solid;border-color:var(--warn,#A8630C);
  background:var(--warn-soft,#FDF1E0)}
#pg-garage .gg-mod.is-draft .gg-mw{color:var(--warn,#A8630C)}
#pg-garage .gg-draftn{color:var(--warn,#A8630C)}
#pg-garage .gg-draftn .num{color:inherit}
#pg-garage .gg-mtag{flex:none;font-family:var(--mono);font-size:8.5px;font-weight:600;
  letter-spacing:.11em;text-transform:uppercase;padding:2px 5px;border-radius:4px;
  background:var(--warn,#A8630C);color:#fff;line-height:1}
body.dark #pg-garage .gg-mod.is-draft{border-color:var(--warn-line,rgba(217,154,74,.32));
  background:var(--warn-soft,rgba(217,154,74,.13))}
body.dark #pg-garage .gg-mtag{background:var(--warn,#D99A4A);color:#1A1A1E}
#pg-garage .gg-mod-add{border-style:dashed;border-color:var(--border2);background:transparent;color:var(--t2)}
#pg-garage .gg-mod-add .gg-mw{color:var(--t3)}
#pg-garage .gg-mod-add:hover{border-style:solid;border-color:var(--accent);background:var(--accent);color:var(--accent-on)}
#pg-garage .gg-mod-add:hover .gg-mw{color:var(--accent-on)}
#pg-garage .gg-nomods,#pg-garage .gg-more{font-size:12.5px;color:var(--t3)}
#pg-garage .gg-more:hover{color:var(--accent-fg)}

/* ---------- the footer ---------- */
#pg-garage .gg-foot{margin-top:auto;padding-top:12px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
#pg-garage .gg-card .gg-foot{flex-direction:column;align-items:flex-start;gap:9px;padding-top:11px}
#pg-garage .gg-meta{font-size:12px;color:var(--t3);display:flex;align-items:center;gap:7px;flex-wrap:wrap}
#pg-garage .gg-mi{font-size:12.5px;font-weight:500;color:var(--t2);letter-spacing:-.01em}
#pg-garage .gg-meta b{font-weight:500;color:var(--t2)}
#pg-garage .gg-sep{color:var(--border2)}
#pg-garage .gg-stale{color:var(--accent-fg)}
#pg-garage .gg-vacts{margin-left:auto;display:flex;align-items:center;gap:6px}
#pg-garage .gg-card .gg-vacts{margin-left:0}
#pg-garage .gg-icononly{padding:0;width:27px;justify-content:center}

/* ---------- old projects, the empty states, the add tile ---------- */
#pg-garage .gg-oldhead{display:flex;align-items:center;gap:12px;margin:26px 0 12px;flex-wrap:wrap}
#pg-garage .gg-oldhead h3{font-size:13px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--t2);margin:0;white-space:nowrap}
#pg-garage .gg-c{font-size:11px;color:var(--t3);border:1px solid var(--border2);padding:0 5px;border-radius:3px}
#pg-garage .gg-why{font-size:12px;color:var(--t3)}
#pg-garage .gg-none{border:1px dashed var(--border2);border-radius:var(--r);padding:26px 18px;text-align:center;color:var(--t2)}
#pg-garage .gg-none b{display:block;font-size:15px;font-weight:600;color:var(--text)}
#pg-garage .gg-none p{margin:5px 0 0;font-size:13px;color:var(--t3)}
#pg-garage .gg-add{border:1px dashed var(--border2);border-radius:var(--r);background:transparent;display:flex;align-items:center;
  gap:12px;padding:14px 16px;width:100%;text-align:left;color:var(--t2);margin-top:12px;
  transition:border-color .15s,background .15s,color .15s}
#pg-garage .gg-add:hover{border-color:var(--accent);background:var(--accent-soft);color:var(--accent-fg)}
#pg-garage .gg-add-p{width:30px;height:30px;flex:none;background:var(--surface2);border:1px solid var(--border2);
  border-radius:6px;display:grid;place-items:center;color:var(--t2);transition:background .15s,color .15s,border-color .15s}
#pg-garage .gg-add:hover .gg-add-p{background:var(--accent);border-color:var(--accent);color:var(--accent-on)}
#pg-garage .gg-add-t{display:block;font-weight:600;font-size:14px;color:var(--text);letter-spacing:-.01em}
#pg-garage .gg-add:hover .gg-add-t{color:var(--accent-fg)}
#pg-garage .gg-add-s{display:block;font-size:12px;color:var(--t3);margin-top:1px}

@media (max-width:1000px){#pg-garage .gg-shelf{grid-template-columns:repeat(2,1fr)}}
@media (max-width:720px){
  #pg-garage .gg-row{grid-template-columns:1fr;gap:12px}
  #pg-garage .gg-shelf{grid-template-columns:1fr}
  #pg-garage .gg-head h1{font-size:24px}
  #pg-garage .gg-acts{margin-left:0;width:100%}
  #pg-garage .gg-vacts{width:100%;margin-left:0}
  #pg-garage .gg-foot{align-items:flex-start}
}

/* ---------- the status menu and the lightbox ----------
   Both are children of <body>, never of the row that opened them: .gg-row and
   .gg-card clip their own overflow so a photograph stays inside the rounded
   corners, and .page.on carries an enter transform — a transformed ancestor
   becomes the containing block for anything fixed inside it, which is the pair
   that put the feed's panels ~5,800px down the page. So these are NOT scoped to
   #pg-garage: by the time they are drawn they are not inside it. */
.gg-pop{position:fixed;z-index:80;background:var(--surface);border:1px solid var(--border2);
  border-radius:8px;box-shadow:var(--sh-lg);padding:5px;min-width:224px;max-width:280px;display:none}
.gg-pop.on{display:block}
.gg-pop-h{font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--t3);padding:5px 8px 6px}
.gg-pop button{display:flex;width:100%;align-items:flex-start;gap:8px;padding:7px 8px;border:0;
  background:transparent;border-radius:5px;text-align:left;color:var(--text)}
.gg-pop button:hover{background:var(--surface2)}
.gg-pop button b{font-weight:500;font-size:12.5px;display:block}
.gg-pop button i{font-style:normal;display:block;font-size:11.5px;color:var(--t3);margin-top:1px;line-height:1.35}
.gg-pop .gg-chk{width:13px;flex:none;color:var(--accent);opacity:0;margin-top:2px}
.gg-pop button.on .gg-chk{opacity:1}

body.gg-locked{overflow:hidden}
/* A DIALOG, not a screen: .gg-lb is the dimmed backdrop and .gg-lb-box the
   bounded panel inside it. Pinned to all four edges it would REPLACE the page,
   which is what made the bench's first lightbox take away the item you had
   opened the picture to compare against. */
.gg-lb{position:fixed;inset:0;z-index:95;display:none;align-items:center;justify-content:center;
  padding:24px;background:rgba(6,6,8,.72);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
.gg-lb.on{display:flex}
.gg-lb-box{display:flex;flex-direction:column;gap:0;max-width:min(1100px,100%);max-height:100%;
  background:var(--surface);border:1px solid var(--border2);border-radius:12px;box-shadow:var(--sh-lg);overflow:hidden}
.gg-lb-h{display:flex;align-items:center;gap:12px;padding:11px 13px;border-bottom:1px solid var(--border);flex:none}
.gg-lb-t{font-weight:600;font-size:15px;letter-spacing:-.02em;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gg-lb-n{margin-left:auto;font-size:12px;color:var(--t3);flex:none}
.gg-lb-b{width:32px;height:32px;flex:none;display:grid;place-items:center;border:1px solid var(--border2);
  background:var(--surface);color:var(--text);border-radius:var(--btn-r);transition:background .13s}
.gg-lb-b:hover{background:var(--surface2)}
.gg-lb-b[disabled]{opacity:.3;cursor:default}
.gg-lb-stage{flex:1;display:flex;align-items:center;justify-content:center;gap:12px;padding:12px;min-height:0;background:var(--surface2)}
/* A min-height on the picture, because a media row that has gone missing
   collapses the panel to a strip — and a broken image inside a broken-looking
   dialog are indistinguishable. */
.gg-lb-stage img{max-width:100%;max-height:70vh;min-height:120px;object-fit:contain;border-radius:8px;display:block}
.gg-lb-strip{display:flex;gap:7px;justify-content:center;padding:11px 13px;flex:none;overflow-x:auto;border-top:1px solid var(--border)}
.gg-lb-th{width:74px;height:50px;flex:none;border-radius:4px;overflow:hidden;border:1.5px solid transparent;
  opacity:.55;padding:0;background:none;transition:opacity .13s,border-color .13s}
.gg-lb-th img{width:100%;height:100%;object-fit:cover;display:block}
.gg-lb-th:hover{opacity:.85}
.gg-lb-th.on{opacity:1;border-color:var(--accent)}
@media (max-width:720px){
  .gg-lb{padding:0}
  .gg-lb-box{max-width:100%;height:100%;border-radius:0;border:0}
  .gg-lb-stage img{max-height:none}
}

/* The toast's one action. Not scoped to #pg-garage: the toast is the site's,
   and the button is on it rather than on this page — the garage is only the
   first caller to pass one. */
#toast .t-undo{border:1px solid currentColor;background:transparent;color:inherit;opacity:.75;
  border-radius:5px;padding:2px 8px;font-size:11.5px;font-weight:600;margin-left:8px;cursor:pointer}
#toast .t-undo:hover{opacity:1}

/* ---------- the two sheets ----------
   Children of <body>, so not scoped to #pg-garage: .page.on carries a transform
   and a transformed ancestor becomes the containing block for anything fixed
   inside it. */
.gg-scrim{position:fixed;inset:0;z-index:88;background:rgba(8,8,10,.42);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
.gg-sheet{position:fixed;z-index:90;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(560px,calc(100vw - 32px));max-height:min(86vh,760px);display:flex;flex-direction:column;
  background:var(--surface);border:1px solid var(--border2);border-radius:12px;box-shadow:var(--sh-lg)}
.gg-sheet[hidden],.gg-scrim[hidden]{display:none}
.gg-sheet-h{display:flex;align-items:flex-start;gap:10px;padding:15px 16px 13px;border-bottom:1px solid var(--border);flex:none}
.gg-sheet-h h3{font-size:16px;font-weight:700;letter-spacing:-.02em;margin:0}
.gg-sheet-s{display:block;font-size:12.5px;font-weight:400;color:var(--t3);margin-top:2px}
.gg-sheet-x{margin-left:auto;width:28px;height:28px;flex:none;display:grid;place-items:center;
  border:1px solid transparent;background:transparent;border-radius:var(--btn-r);color:var(--t3)}
.gg-sheet-x:hover{background:var(--surface2);color:var(--text);border-color:var(--border)}
.gg-sheet-b{padding:16px;overflow:auto;flex:1}
.gg-sheet-f{display:flex;align-items:center;gap:10px;padding:12px 16px;border-top:1px solid var(--border);
  background:var(--surface2);border-radius:0 0 12px 12px;flex-wrap:wrap;flex:none}
.gg-sheet-n{font-size:11.5px;color:var(--t3);max-width:44ch}
/* The same line carries the sheet's own note and, while something is
   happening, what is happening — a refusal or a percentage. It changes colour
   rather than position, so the footer does not jump under the button being
   pressed. */
.gg-sheet-n[data-gg-warn]{color:var(--accent-fg);font-weight:500}
.gg-sheet-r{margin-left:auto;display:flex;gap:8px}

.gg-drop{border:1px dashed var(--border2);border-radius:var(--btn-r);padding:22px 16px;text-align:center;
  color:var(--t2);background:var(--surface2);width:100%;transition:border-color .15s,background .15s,color .15s}
.gg-drop:hover,.gg-drop.over{border-color:var(--accent);background:var(--accent-soft);color:var(--accent-fg)}
.gg-drop svg{margin:0 auto 7px;display:block;opacity:.75}
.gg-drop b{display:block;font-size:13px;font-weight:600}
/* ONE OF THE TWO, NEVER BOTH. The line names a gesture, and a phone has the
   other one — "Drop photos here" was the one thing a touch screen cannot do.
   Both are drawn and this picks, the shape the vehicle profile's
   strip-or-dots already uses, so crossing the breakpoint rebinds nothing.
   Two classes deep on purpose: `.gg-drop b` above is (0,1,1) and would
   otherwise win, which is exactly how both lines came to show at once. */
.gg-drop .gg-drop-touch{display:none}
@media (hover:none),(pointer:coarse){
  .gg-drop .gg-drop-fine{display:none}
  .gg-drop .gg-drop-touch{display:block}
}
.gg-drop span{display:block;font-size:11.5px;color:var(--t3);margin-top:2px}
.gg-pgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-bottom:14px}
.gg-pgrid[hidden]{display:none}
.gg-pcell{position:relative;aspect-ratio:3/2;border-radius:6px;overflow:hidden;border:1px solid var(--border)}
.gg-pcell img{width:100%;height:100%;object-fit:cover;display:block}
.gg-pnew{position:absolute;left:5px;top:5px;font-size:9px;letter-spacing:.06em;text-transform:uppercase;
  background:var(--green);color:#fff;padding:2px 5px;border-radius:3px}
.gg-prm{position:absolute;right:5px;top:5px;width:21px;height:21px;display:grid;place-items:center;
  border:0;border-radius:4px;background:rgba(8,8,10,.66);color:#fff;opacity:0;transition:opacity .13s}
.gg-pcell:hover .gg-prm,.gg-pcell:focus-within .gg-prm{opacity:1}

.gg-field{margin-bottom:14px}
.gg-field:last-child{margin-bottom:0}
.gg-lbl{display:block;font-size:12px;font-weight:500;color:var(--t2);margin-bottom:5px}
.gg-lbl span{color:var(--t3);font-weight:400}
.gg-inp{width:100%;height:34px;padding:0 10px;border:1px solid var(--border2);background:var(--surface);
  color:var(--text);border-radius:var(--btn-r);font:inherit;font-size:13px}
.gg-inp:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.gg-help{display:block;font-size:11.5px;color:var(--t3);margin-top:4px}

/* NOTHING JUMPS WHEN A SHEET OPENS. Locking the body takes the scrollbar away
   and everything under it slides sideways by its width; the JS measures that
   width and pays it back as padding. This rule is only the lock — the
   compensation cannot be written here because the number is the browser's. */
body.gg-locked{overflow:hidden}

@media (max-width:560px){
  /* A FULL-SCREEN SHEET ENDS AT THE FLOOR, NOT AT THE WINDOW. This was
     `height:100vh; top:0`, so its footer — the Save button, which is the only
     way to finish adding photographs — sat behind the phone's tab bar and,
     for an operator, behind the admin bar under it: ninety-odd pixels of a
     sheet that could not be reached or scrolled to. 100vh was the second half
     of it, since on iOS that measures past the address bar as well.
     Anchoring top and bottom instead means the height is the browser's
     arithmetic and --floor is the only number here (§6). */
  .gg-sheet{width:auto;max-width:none;height:auto;max-height:none;
    top:0;left:0;right:0;bottom:var(--floor-modal,0px);transform:none;border-radius:0;border:0}
  .gg-sheet-f{border-radius:0}
  .gg-pgrid{grid-template-columns:repeat(2,1fr)}
}
/* ================= MY GARAGE — the two columns =================
   The cars on the left, "Needs you" as a rail on the right.

   WHY THIS IS A SIBLING PARTIAL AND NOT MORE LINES IN 08d-garage.php: that file
   is already over the 400-line target (§10), which is the same reason
   08b-admin-bar-analytics.php exists beside 08-announcement-and-admin-bar.php.
   It is included AFTER 08d in views/app/styles.php and the order is
   load-bearing: the rail's own .gg-needs rules answer the band ones there at
   equal specificity, so written first they would lose.

   EVERY COLOUR IS A TOKEN :root ALREADY PUBLISHES, exactly as 08d says — not
   one hex value and not one dark block. The tokens flip one element up.

   THE ROW RULES LIVE HERE, NOT THERE. "Needs you" is not a full-width strip any
   more and .gg-need appears nowhere else, so the rules moved with the thing
   rather than being written in one file and overridden in another. */

/* ---------- the grid ----------
   The rail is a fixed 340px and the cars take the rest: a fraction would make
   the rail wider on a 5K display, and it holds one column of short rows whose
   width buys nothing past the point the longest car name fits. */
#pg-garage .gg-cols{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:26px;
  align-items:start;margin-top:22px}
#pg-garage .gg-col{min-width:0}
#pg-garage .gg-col>.gg-bar:first-child{margin-top:0}

/* THE RAIL STICKS, AND ITS BOTTOM IS --floor's (§6). Nothing here measures the
   window's bottom edge by hand: the admin bar, the phone's tab bar and the home
   indicator are one number the site already publishes, and a height written as
   100dvh would run the last row of the queue behind whichever of them is up. */
#pg-garage .gg-rail{position:sticky;top:calc(var(--navh) + 14px);
  max-height:calc(100dvh - var(--navh) - var(--floor,0px) - 28px);
  overflow:auto;overscroll-behavior:contain;scrollbar-width:thin}
#pg-garage .gg-rail .gg-needs{margin-top:0}

/* ---------- the rail's head ----------
   The hint takes its own line rather than being cut off. It is the sentence
   that says the list empties itself, so a 340px column that truncates it to
   "They drop off as you fi…" has spent the room and said nothing. */
#pg-garage .gg-rail .gg-needs-h{padding:9px 8px 8px 12px;row-gap:1px;flex-wrap:wrap;
  position:sticky;top:0;z-index:2}
#pg-garage .gg-rail .gg-hint{order:3;flex:1 1 100%;margin-left:0;font-size:11px;line-height:1.35}
#pg-garage .gg-rail .gg-needs-act{order:2}

/* ---------- the groups ----------
   The verb and the reason are said once at the head of a group; the rows under
   it carry only what differs. Five cars with no picture used to be five copies
   of "Add photos" over five copies of one sentence. */
#pg-garage .gg-grp+.gg-grp{border-top:1px solid var(--border)}
#pg-garage .gg-grp-h{display:flex;align-items:center;gap:8px;padding:11px 12px 0}
#pg-garage .gg-grp-l{font-size:10.5px;font-weight:700;letter-spacing:.085em;text-transform:uppercase;
  color:var(--t2);white-space:nowrap}
#pg-garage .gg-grp-r{flex:1 1 0;height:1px;background:var(--border);min-width:10px}
#pg-garage .gg-grp-n{font-size:11px;color:var(--t3)}
#pg-garage .gg-grp-w{padding:2px 12px 8px;font-size:11.5px;line-height:1.4;color:var(--t3)}

/* ---------- the rows: the whole row is the action ----------
   The old row had a 44px "Add photos" button off to the right with the icon,
   the title and the sentence beside it all inert. In 340px there is no room for
   that button and no reason for it — the group heading says what pressing does,
   so the link takes the row and the × is the only other target on it. */
#pg-garage .gg-need{display:flex;align-items:center;gap:0;padding:0 6px 0 0}
#pg-garage .gg-need+.gg-need{border-top:1px solid var(--border)}
#pg-garage .gg-need:hover{background:var(--surface2)}
#pg-garage .gg-need-go{display:flex;align-items:center;gap:10px;flex:1 1 0;min-width:0;
  padding:9px 4px 9px 12px;color:inherit;text-align:left}
#pg-garage .gg-need-t{width:26px;height:26px;flex:none;display:grid;place-items:center;
  border:1px solid var(--border2);border-radius:5px;background:var(--surface2);color:var(--t2)}
#pg-garage .gg-need-t.is-mod{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent-fg)}
#pg-garage .gg-need-b{min-width:0;flex:1 1 0}
/* BOTH LINES TRUNCATE. A nickname somebody wrote and a year/make/model are both
   open-ended strings in a fixed column, and wrapping one of them is what turns
   a row of 40px into a row of 76px and the queue into a page of its own. */
#pg-garage .gg-need-c{display:block;font-size:13px;font-weight:600;letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#pg-garage .gg-need-m{display:block;font-size:11.5px;color:var(--t3);margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The chevron is drawn on the link rather than shipped as a glyph: it is
   decoration on a control that already has a name, and an <svg> per row would
   be one more thing in the icon registry that is inlined on every page. */
#pg-garage .gg-need-go::after{content:"";flex:none;width:6px;height:6px;margin-left:2px;
  border-right:1.5px solid var(--t3);border-top:1.5px solid var(--t3);transform:rotate(45deg);
  opacity:0;transition:opacity .13s,transform .13s}
#pg-garage .gg-need:hover .gg-need-go::after{opacity:1;transform:rotate(45deg) translate(1px,-1px)}

/* THE × IS QUIET UNTIL YOU ARE NEAR IT. It is the destructive-looking control
   on a row whose point is the other one — so it fades in on hover and on
   focus-within, which is what keeps it reachable by keyboard rather than
   hover-only. */
#pg-garage .gg-need-x{width:27px;height:27px;flex:none;margin:0;display:grid;place-items:center;
  border:1px solid transparent;background:transparent;border-radius:var(--btn-r);color:var(--t3);
  opacity:.45;transition:opacity .13s,background .13s,color .13s,border-color .13s}
#pg-garage .gg-need:hover .gg-need-x,#pg-garage .gg-need:focus-within .gg-need-x{opacity:1}
#pg-garage .gg-need-x:hover{background:var(--surface2);color:var(--text);border-color:var(--border)}
#pg-garage .gg-need-x:focus-visible{opacity:1}

/* the dismissed drawer, at the rail's padding */
#pg-garage .gg-rail .gg-drawer>summary{padding:8px 12px}
#pg-garage .gg-rail .gg-drawer-l{padding:0 12px 9px}
#pg-garage .gg-rail .gg-drow{gap:8px}

/* ---------- the vehicle column ----------
   The whole control row cannot sit beside the heading in what is left of the
   width, so it is split deliberately rather than left to wrap: sort and view
   stay level with "Vehicles", and the chips take the line underneath, flush
   left over the list they filter. */
#pg-garage .gg-col .gg-bar{margin:0 0 12px;row-gap:10px;align-items:center}
#pg-garage .gg-col .gg-ctl{flex:0 0 auto;margin-left:auto}
/* `order` rather than a second markup order: the chips are drawn before the
   sort in the document because that is the order they read in on a full-width
   bar, and here they are moved past it onto a line of their own. */
#pg-garage .gg-col .gg-chips{order:1;flex:1 1 100%}
#pg-garage .gg-col .gg-shelf{grid-template-columns:repeat(2,1fr)}

/* ---------- below the split, the two columns stack ----------
   The rail goes ABOVE the cars here (`order`), because a to-do list under nine
   cars is a list nobody scrolls to. It is still last in the document, so the
   first thing read out on a page about vehicles is the vehicles. */
@media (max-width:1080px){
  #pg-garage .gg-cols{grid-template-columns:minmax(0,1fr);gap:0}
  #pg-garage .gg-rail{position:static;max-height:none;overflow:visible;order:-1;margin-bottom:26px}
  #pg-garage .gg-rail .gg-needs-h{position:static}
  #pg-garage .gg-rail .gg-hint{order:0;flex:1 1 auto;margin-left:auto;text-align:right}
  /* the count sits next to the label it counts rather than a screen away */
  #pg-garage .gg-grp-n{order:1}
  #pg-garage .gg-grp-r{order:2}
  /* rows go multi-up, so six gaps cost two lines rather than six */
  #pg-garage .gg-grp-rows{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}
  #pg-garage .gg-grp-rows .gg-need{border-top:1px solid var(--border)}
  #pg-garage .gg-grp-rows .gg-need:not(:nth-child(3n)){border-right:1px solid var(--border)}
  /* no dangling divider where the last line is only part-filled */
  #pg-garage .gg-grp-rows .gg-need:last-child:nth-child(3n+1){border-right:0}
  #pg-garage .gg-col .gg-shelf{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:1000px){
  #pg-garage .gg-grp-rows{grid-template-columns:repeat(2,minmax(0,1fr))}
  #pg-garage .gg-grp-rows .gg-need:not(:nth-child(3n)){border-right:0}
  #pg-garage .gg-grp-rows .gg-need:nth-child(odd){border-right:1px solid var(--border)}
  #pg-garage .gg-grp-rows .gg-need:last-child:nth-child(odd){border-right:0}
  #pg-garage .gg-col .gg-shelf{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:720px){
  /* The hint is scene-setting, and scene-setting does not get to push "Dismiss
     all" onto a second line of the head — 08d hid it here before the rail
     existed and it is hidden here still. */
  #pg-garage .gg-hint{display:none}
  #pg-garage .gg-grp-rows{grid-template-columns:minmax(0,1fr)}
  #pg-garage .gg-grp-rows .gg-need:nth-child(odd){border-right:0}
  #pg-garage .gg-col .gg-shelf{grid-template-columns:1fr}

  /* ---- the filter bar wraps, and STOPS BEING A SEGMENTED CONTROL to do it ----
     It was one sideways-scrolling strip under a 28px fade, so a filter past
     the third was off the right edge — on the bar whose whole job is to say
     what the page can be narrowed to. Wrapping it as it stands is not enough:
     the segment is ONE pill (a border and a radius on the box, hairline
     separators between the chips, none on the last), and that drawing only
     describes a single row — wrapped, the separators fall at the line breaks
     instead of between the chips, the last chip on every line but the last
     keeps a rule that now ends nothing, and two rows of chips touch with the
     radius still on the box. A segment that has wrapped is not a segment.
     So at this width each filter is its OWN pill and the box is just the
     container: the same chips, drawn as what they have become. */
  #pg-garage .gg-col .gg-chips{display:flex;gap:6px;border:0;border-radius:0;
    background:transparent;overflow:visible}
  #pg-garage .gg-col .gg-chip,
  #pg-garage .gg-col .gg-chip:last-child{border:1px solid var(--border2);
    border-radius:var(--btn-r);background:var(--surface)}

  /* ---- the rows stay horizontal ----
     A full-bleed 3:2 photograph is 240px of a 390px screen per car, so nine
     cars are nine screens and the list stops being one. The photo is square and
     84px wide, and it spans both content rows so the mods fill the space beside
     it instead of leaving a blank column. */
  #pg-garage .gg-row{grid-template-columns:84px minmax(0,1fr);column-gap:12px;row-gap:10px;padding:10px}
  #pg-garage .gg-main{display:contents}
  #pg-garage .gg-row .gg-shot{grid-column:1;grid-row:1/3;aspect-ratio:1/1;align-self:start}
  #pg-garage .gg-row .gg-shot-empty{aspect-ratio:1/1}
  /* the status tag and the kebab drop under the identity rather than taking
     150px of a 250px column — that squeeze wrapped "2008 Volkswagen Touareg ·
     5.0L V10 TDI" onto four lines */
  #pg-garage .gg-top{grid-column:2;grid-row:1;flex-wrap:wrap;align-items:flex-start;gap:6px}
  #pg-garage .gg-idty{flex:1 1 100%}
  #pg-garage .gg-tags{flex:1 1 100%;margin-left:0;justify-content:flex-start}
  #pg-garage .gg-kebab{margin-left:auto}
  /* THE MODS WRAP. They used to be one sideways-scrolling strip, which kept
     every row the same height whether a car had one mod or six — and cost the
     member the only thing the strip is for: the mods past the second one were
     off the right edge with nothing but a 26px fade to say so, and a sideways
     scroll inside a vertically scrolling list is a gesture people do not find.
     A garage is read to see what is ON the cars, so the row grows instead. The
     mask goes with the overflow: a fade over a wrapped block dims the last chip
     on every line for no reason. */
  #pg-garage .gg-mods{grid-column:2;grid-row:2;margin-top:0}
  #pg-garage .gg-mod{height:27px}
  #pg-garage .gg-mn{max-width:190px}
  /* the meta gets the full width so it fits on one line; the actions sit under it */
  #pg-garage .gg-foot{grid-column:1/-1;grid-row:3;padding-top:0;margin-top:0;
    flex-direction:column;align-items:stretch;gap:8px}
  #pg-garage .gg-meta{font-size:11px;gap:5px;flex-wrap:wrap}
  #pg-garage .gg-vacts{width:auto;margin-left:auto}
  /* the nickname truncates rather than shoving the status tag off the row */
  #pg-garage .gg-name{display:block;font-size:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #pg-garage .gg-ymm{font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #pg-garage .gg-add{padding:12px}
}
/* ===================== the admin bar's Analytics drawer =====================
   A sibling partial rather than more lines in 08-announcement-and-admin-bar,
   which is already over the 600-line cap §10 sets. Adding to it would make a
   file somebody has to split harder to split; a new partial listed in
   styles.php is what §10 asks for and costs nothing — the stylesheet is
   concatenated either way.

   Everything here is drawn from a measured figure or is not drawn at all
   (CONVENTIONS §14). There is no skeleton bar, no placeholder row and no tile
   that has a shape before the payload lands: the panel renders "not counted",
   "nothing recorded yet" or the real numbers, and never a fourth thing that
   merely looks like data. */

/* `.drawer-body` is `padding:0` on purpose — every panel in this drawer pads
   its own rows so a list can run edge to edge and still have its text line up
   (see .ab-kv and .ab-seo-h, both 24px). So these blocks carry the gutter
   themselves; without it the tiles, the chart and the window buttons all ran
   off both edges of the drawer, which the markup and the class list could not
   show and one screenshot could. One token, so the phone override below is a
   single rule rather than six. */
#ams-adrawer{--abst-pad:24px}
@media(max-width:640px){ #ams-adrawer{--abst-pad:16px} }
.abst-top,.abst-tiles,.abst-warn,.abst-chart,.abst-rows{
  padding-left:var(--abst-pad); padding-right:var(--abst-pad)}

.abst-top{display:flex; align-items:center; gap:10px; margin-bottom:12px; flex-wrap:wrap; padding-top:12px}
/* The address is the subject of the whole panel, so it gets the mono treatment
   a measured thing gets and is allowed to shrink before the buttons do. */
.abst-path{flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  font-size:12.5px; opacity:.85}
.abst-seg{display:flex; gap:4px; flex:none}
.abst-seg .abtn.sm{padding:3px 9px; font-size:12px}
.abst-seg .abtn.on{background:var(--ab-accent,#EA580C); border-color:var(--ab-accent,#EA580C); color:#fff}

.abst-tiles{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:8px; margin-bottom:12px}
@media(max-width:520px){ .abst-tiles{grid-template-columns:1fr} }
.abst-tile{background:rgba(255,255,255,.04); border:1px solid rgba(255,255,255,.10);
  border-radius:10px; padding:9px 11px; min-width:0}
.abst-tile .k{display:block; font-size:10.5px; font-weight:650; text-transform:uppercase;
  letter-spacing:.05em; opacity:.6}
.abst-tile .v{display:block; font-size:22px; font-weight:680; line-height:1.15; margin-top:2px;
  font-variant-numeric:tabular-nums}
.abst-tile .d{display:block; font-size:11px; opacity:.6; margin-top:2px}
.abst-tile .d.up{color:#4FA96A; opacity:1} .abst-tile .d.down{color:#E0A82E; opacity:1}

/* A 404 on the address you are standing on is the most useful thing this panel
   can say, so it is a band rather than a row in a list. */
.abst-warn{border:1px solid rgba(224,168,46,.5); background:rgba(224,168,46,.12);
  border-radius:9px; padding:8px 11px; font-size:12.5px; margin-bottom:12px}

.abst-chart{margin-bottom:14px}
/* Capped, and left-aligned. Seven days stretched across a full-width drawer
   draws seven 200px slabs — a bar chart of blocks, where the shape is the point
   and the shape is unreadable at that width. */
.abst-bars{display:flex; align-items:flex-end; gap:3px; height:64px; max-width:520px}
.abst-axis{max-width:520px}
.abst-bar{flex:1 1 0; min-width:2px; display:flex; flex-direction:column; justify-content:flex-end;
  height:100%}
/* display:block, and it matters: these are spans, and width/height do not apply
   to an inline box. The console's funnel shipped once as three empty troughs
   for exactly this reason — the markup was right and nothing was drawn. */
.abst-bar i{display:block; background:var(--ab-accent,#EA580C); border-radius:2px 2px 0 0; min-height:2px}
.abst-bar.zero i{background:rgba(255,255,255,.16)}
.abst-axis{display:flex; justify-content:space-between; font-size:10.5px; opacity:.55; margin-top:5px;
  padding-left:var(--abst-pad); padding-right:var(--abst-pad)}

/* The gutter is on the CONTAINER and not on each row, and that is the whole
   reason the share bar lines up: .abst-fill is absolutely positioned, so
   `left:0` and a percentage width resolve against its row's padding box. Pad
   the row and the bar starts under the gutter and overflows the right edge by
   the same amount — which is what it did, invisibly, until a screenshot showed
   an orange line running to both edges of the drawer.
   Note the row's own padding stays LONGHAND: `padding:5px 0` here would be a
   shorthand reset that silently wipes the container's gutter back to zero. */
.abst-rows{display:flex; flex-direction:column; margin-bottom:12px}
.abst-row{position:relative; display:grid; grid-template-columns:1fr auto; gap:10px;
  align-items:center; padding-top:5px; padding-bottom:5px;
  border-top:1px solid rgba(255,255,255,.08); font-size:12.5px}
.abst-row:first-child{border-top:none}
.abst-l{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.abst-n{font-variant-numeric:tabular-nums; font-weight:640}
/* The share bar sits under the text rather than beside it, so a long referring
   host is never squeezed to three characters to make room for a bar. */
.abst-fill{position:absolute; left:0; bottom:0; height:2px; background:var(--ab-accent,#EA580C);
  opacity:.55; border-radius:2px}

/* ---- who read it -----------------------------------------------------
   The member bubble is AMSR.avatar()'s, not a second one drawn here: one
   member, one bubble, everywhere (§1). All this adds is the row around it. */
.abst-readers{display:flex; flex-direction:column;
  padding-left:var(--abst-pad); padding-right:var(--abst-pad); margin-bottom:8px}
.abst-reader{display:grid; grid-template-columns:auto 1fr auto auto; gap:10px; align-items:center;
  padding-top:6px; padding-bottom:6px; border-top:1px solid rgba(255,255,255,.08); font-size:12.5px}
.abst-reader:first-child{border-top:none}
.abst-rname{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.abst-rh{opacity:.55; margin-left:6px}
.abst-rn{font-variant-numeric:tabular-nums; font-weight:640}
.abst-rwhen{opacity:.55; font-variant-numeric:tabular-nums; white-space:nowrap; font-size:11.5px}
@media(max-width:520px){ .abst-rwhen{display:none} }
/* The count nobody can put a name to. Quiet, but never omitted — a list of
   three beside a total of forty is a lie by framing if the rest is unstated. */
.abst-anon{padding:6px var(--abst-pad) 10px; font-size:11.5px; opacity:.6; line-height:1.45}
/* ---------- drag-and-drop photo uploader ---------- */
.amsup{display:block}
.amsup-zone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;
  min-height:120px;padding:20px;border:1.5px dashed var(--border2);border-radius:12px;
  background:var(--surface2);color:var(--t2);cursor:pointer;text-align:center;
  transition:border-color .15s var(--ease),background .15s var(--ease),color .15s var(--ease)}
.amsup-zone:hover,.amsup-zone:focus-visible{border-color:var(--accent);color:var(--text);outline:none}
.amsup-zone.drag{border-color:var(--accent);border-style:solid;background:color-mix(in srgb,var(--accent) 12%,var(--surface2));color:var(--text)}
.amsup-ic{color:var(--t3);flex:none}
.amsup-zone:hover .amsup-ic,.amsup-zone.drag .amsup-ic{color:var(--accent)}
.amsup-cta b{display:block;font-size:14px;font-weight:600;color:var(--text)}
.amsup-cta span{font-size:12px;color:var(--t3)}
.amsup.has-items .amsup-zone{min-height:74px;padding:12px}
/* WHY A FILE WAS NOT TAKEN, in the uploader's own words. A refusal used to be
   a bare `return` — you picked a photo and the screen did not move, which is
   indistinguishable from a broken button and is what "I tried to upload photos
   and nothing" was. It is a warning, not an error: what was taken IS being
   uploaded above it. */
.amsup-note{margin-top:9px;padding:8px 10px;border-radius:9px;font-size:12.5px;line-height:1.45;
  color:var(--accent-fg);background:var(--accent-soft);border:1px solid var(--accent-line)}
.amsup-note[hidden]{display:none}
.amsup-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));gap:8px;margin-top:10px}
.amsup-grid:empty{margin-top:0}
.amsup-tile{position:relative;aspect-ratio:1;border-radius:10px;overflow:hidden;background:#26262c;
  border:1px solid var(--border)}
.amsup-tile img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.amsup-ov{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:rgba(8,8,11,.5);transition:opacity .2s var(--ease)}
.amsup-tile.is-done .amsup-ov{opacity:0;pointer-events:none}
.amsup-tile.is-error .amsup-ov{background:rgba(120,20,20,.6)}
.amsup-tile.is-error img{filter:grayscale(.5) brightness(.7)}
.amsup-retry{width:30px;height:30px;border-radius:50%;border:1px solid rgba(255,255,255,.5);
  background:rgba(0,0,0,.4);color:#fff;font-size:15px;cursor:pointer;line-height:1}
.amsup-bar{position:absolute;left:0;right:0;bottom:0;height:3px;background:rgba(255,255,255,.18)}
.amsup-bar > i{display:block;height:100%;width:0;background:var(--accent);transition:width .15s linear}
.amsup-tile.is-done .amsup-bar,.amsup-tile.is-error .amsup-bar{opacity:0}
.amsup-badge{position:absolute;left:6px;top:6px;width:18px;height:18px;border-radius:50%;
  display:grid;place-items:center;background:#16a34a;color:#fff;opacity:0;transition:opacity .2s var(--ease)}
.amsup-tile.is-done .amsup-badge{opacity:1}
.amsup-x{position:absolute;right:5px;top:5px;width:22px;height:22px;padding:0;display:grid;place-items:center;
  border-radius:50%;border:0;background:rgba(8,8,11,.66);color:#fff;font-size:12px;line-height:1;cursor:pointer;
  backdrop-filter:blur(4px);opacity:0;transition:opacity .15s var(--ease)}
.amsup-tile:hover .amsup-x,.amsup-tile:focus-within .amsup-x{opacity:1}
.amsup-x:hover{background:#B91C1C}

/* ---------- post / project detail ---------- */
.pd-shots{display:flex;gap:8px;overflow-x:auto;margin:-2px 0 12px;padding-bottom:4px}
.pd-shot{height:150px;border-radius:10px;cursor:zoom-in;flex:none;object-fit:cover;background:#26262c}
.pd-tags{display:flex;align-items:center;gap:8px;margin-bottom:10px}
.pd-body{font-size:14.5px;line-height:1.6;color:var(--text)}
.pd-by{margin:12px 0 0}
.pd-by a{color:var(--accent-fg,var(--accent));text-decoration:none}
.pd-by a:hover{text-decoration:underline}
.pd-acts{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:14px 0 4px;padding:12px 0;
  border-top:1px solid var(--border);border-bottom:1px solid var(--border)}
.pd-comments{margin-top:14px}
.pd-comments h4{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--t3);margin:0 0 10px}
.pd-clist{display:flex;flex-direction:column;gap:12px;margin-bottom:12px}
.pd-cmt{display:flex;gap:9px}
.pd-cmt .av-sm{flex:none}
.pd-cmt-b{min-width:0}
.pd-cmt-h{font-size:12.5px;color:var(--t2)}
.pd-cmt-h b{color:var(--text);font-weight:600}
.pd-cmt-h em{color:var(--t3);font-style:normal;margin-left:6px;font-size:11.5px}
.pd-cmt p{font-size:13.5px;line-height:1.5;margin-top:2px;color:var(--text);word-wrap:break-word}
.pd-cadd{display:flex;gap:8px;align-items:flex-end}
.pd-cadd textarea{flex:1;resize:vertical}
.pd-cadd .btn{flex:none}

/* The modal inbox and the modal thread had their rules here. Both are
   deleted (js/07-live-data/07-messaging-and-following.php says why), so
   these classes are drawn by nothing — and a rule for markup nobody emits
   is how a stylesheet stops describing the site. The chat dock's own
   rules are css/26-chat-dock.php; /messages carries its own inside the
   shadow root it mounts into. */

/* ---------- build detail ---------- */
.bd-phases{display:flex;flex-wrap:wrap;gap:6px;margin:12px 0 4px}
.bd-log{display:flex;flex-direction:column;gap:8px}
.bd-log-row{display:block;width:100%;text-align:left;padding:11px 13px;border:1px solid var(--border);
  border-radius:10px;background:var(--surface);cursor:pointer;color:var(--text);font:inherit}
.bd-log-row:hover{border-color:var(--border2);background:var(--surface2)}
.bd-log-row b{font-size:14px}
.bd-log-row em{color:var(--t3);font-style:normal;font-size:11.5px;margin-left:6px}
.bd-log-row p{font-size:13px;color:var(--t2);margin-top:4px;line-height:1.45}

/* ---------- permissions admin ---------- */
.permsec{margin:14px 0 4px;padding-top:14px;border-top:1px solid var(--border)}
.permsec-h{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
.permsec-h b{font-size:13.5px}
.permlist{display:flex;flex-direction:column;gap:2px}
.permrow{display:flex;gap:10px;align-items:flex-start;padding:7px 8px;border-radius:8px;cursor:pointer}
.permrow:hover{background:var(--surface2)}
.permrow input{margin-top:2px;flex:none}
.permrow span{display:flex;flex-direction:column;gap:1px;min-width:0}
.permrow b{font-size:13px;font-weight:500;color:var(--text)}
.permrow em{font-size:11.5px;color:var(--t3);font-style:normal;line-height:1.4}
.permrow input:disabled + span{opacity:.55}
.permcols{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.permcol h4{font-size:12px;letter-spacing:.05em;text-transform:uppercase;color:var(--t3);margin:0 0 8px}
@media(max-width:560px){.permcols{grid-template-columns:1fr}}

/* ---------- /post on-page hub ---------- */
.hub-drafts{margin-top:26px;padding-top:18px;border-top:1px solid var(--border)}
.hub-drafts .sect-t{margin-bottom:10px}
.hub-draft{display:flex;align-items:center;gap:12px;padding:11px 13px;border:1px solid var(--border);
  border-radius:11px;margin-bottom:8px;background:var(--surface)}
.hub-draft-b{min-width:0;display:flex;flex-direction:column;gap:2px;flex:1}
.hub-draft-b b{font-size:13.5px}
.hub-draft-b span{font-size:12.5px;color:var(--t3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hub-prev{border:1px solid var(--border);border-radius:12px;padding:16px;background:var(--surface)}
.hub-prev h4{color:var(--text)}

/* ============================================================
   PROJECT PAGE (build detail) — one stream, several authors.
   All classes scoped under #pg-project / prefixed .pj- so they
   never collide with the rest of the app.
   ============================================================ */
#pg-project,#pg-mod{--pj-gut:66px}
.pj-col{max-width:var(--col);margin:0 auto;padding:0 var(--pad)}
.pj-hero{position:relative}
.pj-hero .pj-shot{height:min(56vh,460px);border-radius:0}
.pj-hero .pj-over{position:absolute;left:0;right:0;bottom:0;z-index:4;padding:0 0 30px;
  background:linear-gradient(180deg,transparent,rgba(4,5,8,.82) 62%)}
.pj-hero .pj-over .pj-col{color:#fff}
.pj-hero h1{font-family:var(--dis);font-weight:600;font-size:clamp(30px,5.4vw,48px);color:#fff;letter-spacing:-.035em;line-height:1.05}
.pj-hero .pj-one{color:rgba(255,255,255,.84);font-size:16px;margin-top:10px;max-width:54ch;line-height:1.5}
.pj-hero .pj-who{display:flex;align-items:center;gap:9px;margin-top:16px;font-size:13.5px;color:rgba(255,255,255,.74);flex-wrap:wrap}
.pj-hero .pj-who b{color:#fff;font-weight:500}
.pj-hero .pj-who .av{box-shadow:0 0 0 2px rgba(20,20,24,.85)}

.pj-factline{border-bottom:1px solid var(--border);background:var(--surface)}
.pj-factline .pj-col{display:flex;align-items:center;gap:28px;height:60px;overflow-x:auto;scrollbar-width:none}
.pj-factline .pj-col::-webkit-scrollbar{display:none}
.pj-factline .f{flex:none}
.pj-factline .f span{display:block;font-size:11px;color:var(--t3);text-transform:uppercase;letter-spacing:.06em}
.pj-factline .f b{font-family:var(--dis);font-size:15.5px;font-weight:600;letter-spacing:-.02em}

.pj-fit{border-bottom:1px solid var(--border);background:var(--surface2)}
.pj-fit .pj-col{display:flex;align-items:center;gap:10px;padding:12px var(--pad);font-size:13.5px;color:var(--t2)}
.pj-fit b{font-weight:500;color:var(--text)}

/* maker-space action bar: fork / star / lineage */
.pj-actions{border-bottom:1px solid var(--border);background:var(--surface)}
.pj-actions .pj-col{padding:16px var(--pad)}
.pj-lineage{display:inline-flex;align-items:center;gap:7px;font-size:13px;color:var(--t2);
  text-decoration:none;margin-bottom:12px}
.pj-lineage b{color:var(--text);font-weight:600}
.pj-lineage:hover{color:var(--accent-fg)}
.pj-lineage svg{color:var(--t3);flex:none}
.pj-actrow{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.pj-star.on{border-color:var(--accent-line);background:var(--accent-soft);color:var(--accent-fg)}
.pj-star.on svg{fill:var(--accent-fg)}
.pj-ct{font-weight:600;font-variant-numeric:tabular-nums;margin-left:2px}
.pj-forks{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:var(--t3);margin-left:4px}
.pj-forks b{color:var(--text);font-weight:600}
.pj-forks svg{color:var(--t3)}
.pd-comments .pj-col{padding-top:8px;padding-bottom:40px}
.pd-comments h4{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--t3);margin:0 0 14px}
.pd-comments h4 .pj-ct{color:var(--t2)}

.pj-main{padding:var(--pad-top) var(--pad) 0}
.pj-phases{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:6px}

.pj-streamhead{display:flex;align-items:center;gap:10px;margin:26px 0 4px;flex-wrap:wrap}
.pj-filters{display:flex;gap:4px;margin-left:auto;flex-wrap:wrap}
.pj-filters button{font-size:12.5px;color:var(--t3);padding:5px 10px;border-radius:999px;border:1px solid transparent;transition:all .16s}
.pj-filters button:hover{color:var(--text);background:var(--surface2)}
.pj-filters button.on{color:var(--text);background:var(--surface2);border-color:var(--border);font-weight:500}

.pj-stream{position:relative;margin-top:16px}
.pj-stream::before{content:"";position:absolute;left:15px;top:6px;bottom:40px;width:1px;
  background:linear-gradient(180deg,var(--border2),var(--border) 82%,transparent)}
.pj-ev{position:relative;padding-left:var(--pj-gut)}
.pj-ev-h{width:100%;display:flex;align-items:flex-start;gap:12px;padding:15px 0;background:none;border:0;cursor:pointer;text-align:left;transition:opacity .16s}
.pj-ev-h:hover{opacity:.66}
.pj-ev .pj-mark{position:absolute;left:0;top:15px;width:32px;display:flex;justify-content:center}
.pj-ev .pj-knob{width:31px;height:31px;border-radius:999px;background:var(--canvas);border:1px solid var(--border2);display:grid;place-items:center;color:var(--t3)}
.pj-ev .pj-when{font:500 11px var(--mono);color:var(--t3);position:absolute;left:44px;top:22px;width:26px}
.pj-ev .pj-ttl{font-family:var(--dis);font-size:16.5px;font-weight:600;line-height:1.35;letter-spacing:-.02em;flex:1;min-width:0}
.pj-ev .pj-by{font-size:12.5px;color:var(--t3);margin-top:4px;display:block;font-family:var(--ui);font-weight:400;letter-spacing:0}
.pj-ev .pj-by b{color:var(--t2);font-weight:500}
.pj-ev .pj-tag{flex:none;align-self:center}
.pj-ev-own .pj-knob{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.pj-ev-b{display:none;padding:0 0 24px}
.pj-ev.open .pj-ev-b{display:block;animation:pjreveal .3s var(--ease)}
.pj-ev.open .pj-ev-h{padding-bottom:9px}
@keyframes pjreveal{from{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:none}}
.pj-ev-b p{font-size:15px;line-height:1.72;color:var(--t2);max-width:60ch;margin:0 0 14px;white-space:pre-line}
.pj-ev-b p:last-of-type{margin-bottom:0}
.pj-ev-b strong{color:var(--text);font-weight:500}
.pj-warn{border-left:2px solid var(--accent);padding:2px 0 2px 15px;margin:0 0 15px}
.pj-warn b{display:block;font-size:12px;font-weight:600;color:var(--accent-fg);text-transform:uppercase;letter-spacing:.05em;margin-bottom:5px}
.pj-warn p{font-size:14px;color:var(--t2);margin:0;max-width:60ch}
.pj-shots{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px;margin:16px 0}
.pj-shots .photo{aspect-ratio:16/10;border-radius:12px}
.pj-emeta{display:flex;gap:16px;flex-wrap:wrap;margin-top:14px;font-size:12.5px;color:var(--t3)}
.pj-emeta b{color:var(--t2);font-weight:500}
.pj-ev-f{display:flex;gap:8px;margin-top:16px;flex-wrap:wrap;align-items:center}

.pj-joinrow{position:relative;padding-left:var(--pj-gut);margin-top:8px}
.pj-joinrow .pj-mark{position:absolute;left:0;top:14px;width:32px;display:flex;justify-content:center}
.pj-joinrow .pj-knob{width:31px;height:31px;border-radius:999px;border:1px dashed var(--border2);display:grid;place-items:center;color:var(--t3);background:var(--canvas)}
.pj-join{border:1px dashed var(--border2);border-radius:var(--r-lg);padding:16px 18px;background:var(--surface2)}
.pj-join h4{font-size:15px;margin-bottom:5px}
.pj-join p{font-size:13.5px;color:var(--t2);max-width:54ch;line-height:1.55}
.pj-join .row{margin-top:13px;flex-wrap:wrap}

.pj-ref{margin-top:44px}
.pj-disc{border-top:1px solid var(--border)}
.pj-disc:last-of-type{border-bottom:1px solid var(--border)}
.pj-disc-h{width:100%;display:flex;align-items:center;gap:13px;padding:18px 0;background:none;border:0;cursor:pointer;text-align:left;transition:opacity .16s}
.pj-disc-h:hover{opacity:.64}
.pj-disc-h .t{font-family:var(--dis);font-size:16px;font-weight:600;letter-spacing:-.02em;flex:none}
.pj-disc-h .n{font:500 12px var(--mono);color:var(--t3);flex:none}
.pj-disc-h .peek{margin-left:auto;font-size:12.5px;color:var(--t3)}
.pj-disc-h .chev{flex:none;color:var(--t3);transition:transform .26s var(--ease)}
.pj-disc.open .chev{transform:rotate(90deg)}
.pj-disc-b{display:none;padding-bottom:26px}
.pj-disc.open .pj-disc-b{display:block;animation:pjreveal .3s var(--ease)}
.pj-gal{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px}
.pj-gal .photo{aspect-ratio:4/3;border-radius:10px}
.pj-spec{display:grid;grid-template-columns:1fr 1fr;gap:0 32px}
.pj-spec div{display:flex;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px solid var(--border);font-size:13.5px}
.pj-spec span{color:var(--t3)}
.pj-spec b{font:500 13px var(--mono)}
.pj-empty{padding:34px 4px;color:var(--t3);font-size:14px}

@media(max-width:680px){
  #pg-project,#pg-mod{--pj-gut:50px}
  .pj-hero .pj-shot{height:44vh}
  .pj-stream::before{left:11px}
  .pj-ev .pj-mark{width:24px}.pj-ev .pj-knob{width:24px;height:24px}
  .pj-ev .pj-when{display:none}
  .pj-spec{grid-template-columns:1fr}
}

/* ===== 404 / not found (SPA) ===== */
#pg-notfound .nf{max-width:560px;margin:0 auto;text-align:center}
#pg-notfound .nf-art{max-width:400px;margin:0 auto 26px;border-radius:16px;overflow:hidden;
  border:1px solid var(--ln);box-shadow:0 30px 80px -30px rgba(0,0,0,.55)}
#pg-notfound .nf-art img{display:block;width:100%;height:auto}
#pg-notfound .nf-kick{display:inline-block;font:600 11px/1 var(--f);letter-spacing:.2em;
  text-transform:uppercase;color:var(--ac);margin:0 0 14px;padding:6px 11px;
  border:1px solid rgba(238,112,22,.4);border-radius:999px}
#pg-notfound h1{font-size:clamp(28px,5vw,42px);letter-spacing:-.03em;margin:0 0 14px}
#pg-notfound .nf .muted{max-width:44ch;margin:0 auto 26px;font-size:16.5px}
#pg-notfound .nf-acts{display:flex;gap:11px;flex-wrap:wrap;justify-content:center}

/* ═══════════════════════ GENERATION PAGE (#pg-vehicle) ═══════════════════════
   Ported from the generation design. All classes namespaced `gp-` and every
   rule scoped under #pg-vehicle so nothing bleeds into the rest of the app.
   Tokens are local to the page; dark mode via body.dark. */
#pg-vehicle{
  --gp-bg:#f4f4f2; --gp-panel:#fff; --gp-sunken:#f7f7f5; --gp-line:#e5e4e0; --gp-line-strong:#d2d1cc;
  --gp-ink:#171614; --gp-ink-2:#5c5a55; --gp-ink-3:#8d8b85;
  --gp-accent:#f05a24; --gp-accent-ink:#b23c11; --gp-accent-wash:#fdeee7; --gp-accent-line:#f7c0a8;
  --gp-ok:#2f7d4f; --gp-ok-wash:#e8f4ec; --gp-warn:#a8630c; --gp-warn-wash:#fdf1e0;
  --gp-danger:#b4342c; --gp-danger-wash:#fbebe9;
  --gp-shadow:0 1px 2px rgba(20,18,15,.05); --gp-pop:0 10px 32px rgba(20,18,15,.13);
  --gp-r:10px; --gp-mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  /* An id beats `.page`, so this rule has to restate the top — but it restates
     the TOKEN, not the number. Written as a literal 36px it silently held that
     value while every other page stepped down to 30 and 26, which is exactly
     the drift §11 exists to stop. */
  padding:var(--pad-top) 0 40px;
}
body.dark #pg-vehicle{
  --gp-bg:#121211; --gp-panel:#1c1c1a; --gp-sunken:#232320; --gp-line:#2e2e2b; --gp-line-strong:#3d3d39;
  --gp-ink:#f2f1ee; --gp-ink-2:#a3a19b; --gp-ink-3:#76746e;
  --gp-accent:#ff6b33; --gp-accent-ink:#ffa47a; --gp-accent-wash:#33190f; --gp-accent-line:#4d2716;
  --gp-ok:#6cc08c; --gp-ok-wash:#16281d; --gp-warn:#d99a4a; --gp-warn-wash:#2b2113;
  --gp-danger:#e2766c; --gp-danger-wash:#2d1917;
  --gp-shadow:0 1px 2px rgba(0,0,0,.4); --gp-pop:0 10px 32px rgba(0,0,0,.55);
}
#pg-vehicle{color:var(--gp-ink);font-size:15px}
#pg-vehicle h1,#pg-vehicle h2,#pg-vehicle h3,#pg-vehicle h4{margin:0;font-weight:600;letter-spacing:-.015em;line-height:1.25}
#pg-vehicle p{margin:0}
#pg-vehicle a{color:inherit;text-decoration:none}
/* the feed avatar is an <a> when the profile is linkable; #pg-vehicle a's
   color:inherit would tint the initials with page ink on the dark avatar —
   keep them white, matching the shared feed template on the home page */
#pg-vehicle .feed-item .av{color:#fff}
/* :not(.btn) — this reset is (0,1,1) and .btn (0,1,0), so it OUTRANKED the
   site's button component and stripped its border, padding and fill. */
#pg-vehicle button:not(.btn){font:inherit;color:inherit;cursor:pointer;background:none;border:none;padding:0}
#pg-vehicle .gp-wrap{max-width:var(--col);margin:0 auto;padding:0 var(--pad)}
#pg-vehicle .gp-mono{font-family:var(--gp-mono)}
#pg-vehicle .gp-muted{color:var(--gp-ink-2)}
#pg-vehicle .gp-row{display:flex;align-items:center;gap:8px}
#pg-vehicle .gp-eyebrow{font-family:var(--gp-mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--gp-ink-3)}
/* buttons: the ported design's PALETTE on the site's one ladder — this shell
   restated the whole SHAPE too, press included. Colour only; the shape is
   css/00b-buttons.php (§1). */
#pg-vehicle .btn{border-color:var(--gp-line-strong);background:var(--gp-panel);color:var(--gp-ink-2)}
#pg-vehicle .btn:hover{background:var(--gp-panel);border-color:var(--gp-ink-3);color:var(--gp-ink)}
#pg-vehicle .btn-primary{background:var(--gp-accent);border-color:var(--gp-accent);color:#fff}
#pg-vehicle .btn-primary:hover{background:var(--gp-accent-ink);border-color:var(--gp-accent-ink);color:#fff}
#pg-vehicle .btn-ghost,#pg-vehicle .gp-ghost{border-color:transparent;background:transparent}
#pg-vehicle .btn-ghost:hover,#pg-vehicle .gp-ghost:hover{background:var(--gp-sunken);border-color:transparent;color:var(--gp-ink)}
#pg-vehicle .btn.on{background:var(--gp-accent-wash);border-color:var(--gp-accent-line);color:var(--gp-accent-ink)}
#pg-vehicle .gp-ghost{border-color:transparent;background:transparent}
/* avatars */
#pg-vehicle .gp-av{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;background:var(--gp-accent);color:#fff;font-weight:600;flex-shrink:0;width:20px;height:20px;font-size:9px}
#pg-vehicle .gp-av-md{width:34px;height:34px;font-size:12px}
/* pills */
#pg-vehicle .gp-pill{display:inline-flex;align-items:center;gap:5px;height:23px;padding:0 9px;border-radius:999px;border:1px solid var(--gp-line);background:var(--gp-panel);font-size:11.5px;font-weight:500;color:var(--gp-ink-2);white-space:nowrap}
#pg-vehicle .gp-pill-g{color:var(--gp-ok);border-color:color-mix(in srgb,var(--gp-ok) 30%,transparent);background:var(--gp-ok-wash)}
#pg-vehicle .gp-pill-g i{width:5px;height:5px;border-radius:50%;background:var(--gp-ok);display:block}
#pg-vehicle .gp-pill-a{color:var(--gp-accent-ink);border-color:var(--gp-accent-line);background:var(--gp-accent-wash)}
#pg-vehicle .gp-pill-w{color:var(--gp-warn);border-color:color-mix(in srgb,var(--gp-warn) 30%,transparent);background:var(--gp-warn-wash)}
#pg-vehicle .gp-pill-d{color:var(--gp-danger);border-color:color-mix(in srgb,var(--gp-danger) 30%,transparent);background:var(--gp-danger-wash)}
/* photos: reuse app loader (.photo); this only sizes them and styles overlays */
#pg-vehicle .photo{border-radius:var(--gp-r);overflow:hidden;background:var(--gp-sunken) center/cover no-repeat;border:1px solid var(--gp-line);display:block;position:relative}
#pg-vehicle .photo.noimg{background:#e9e9ee center/cover url(/assets/vehicle-placeholder.svg) no-repeat}
body.dark #pg-vehicle .photo.noimg{background-color:#232320}
/* the app's global .photo paints a moodFor gradient (::before) and a dark
   vignette (::after) over the slot; on this page we always render a real
   <img> (cover or the default placeholder), so drop both — image only, no
   gradient laid over it. */
#pg-vehicle .photo::before,#pg-vehicle .photo::after{content:none!important;background:none!important}
#pg-vehicle .photo .ph-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:1;opacity:1}
#pg-vehicle .gp-tl{position:absolute;top:9px;left:9px;z-index:2;display:flex;gap:5px}
#pg-vehicle .photo .gp-pill{background:rgba(18,17,15,.62);border-color:rgba(255,255,255,.18);color:#fff;backdrop-filter:blur(6px)}
/* mosaic */
#pg-vehicle .gp-mosaic{display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(2,124px);gap:8px;margin-top:16px}
#pg-vehicle .gp-mosaic .photo:first-child{grid-column:span 2;grid-row:span 2}
#pg-vehicle .gp-allbtn{position:absolute;right:11px;bottom:11px;z-index:3;height:29px;padding:0 12px;border-radius:7px;background:rgba(18,17,15,.7);color:#fff;font-size:12px;font-weight:500;border:1px solid rgba(255,255,255,.2);backdrop-filter:blur(6px)}
#pg-vehicle .gp-mos-cred{position:absolute;left:11px;bottom:11px;padding:6px 9px;border-radius:7px;background:rgba(12,11,10,.55);backdrop-filter:blur(4px);z-index:3;font-size:11.5px;color:rgba(255,255,255,.9);display:flex;align-items:center;gap:6px}
/* crumbs */
#pg-vehicle .gp-crumbs{display:flex;align-items:center;gap:7px;padding:0;font-size:12.5px;color:var(--gp-ink-3);flex-wrap:wrap}
#pg-vehicle .gp-crumbs a:hover{color:var(--gp-ink)}
#pg-vehicle .gp-crumbs em{font-style:normal;color:var(--gp-line-strong)}
/* identity */
#pg-vehicle .gp-ident{display:flex;gap:32px;align-items:flex-end;padding:22px 0 20px;border-bottom:1px solid var(--gp-line)}
#pg-vehicle .gp-ident-l{min-width:0}
#pg-vehicle .gp-ident h1{font-size:31px;margin:9px 0 6px}
#pg-vehicle .gp-sub{font-size:13.5px;color:var(--gp-ink-2)}
#pg-vehicle .gp-acts{margin-left:auto;display:flex;gap:8px;flex-shrink:0}
#pg-vehicle .gp-gencode{font-size:.62em;font-weight:500;color:var(--gp-ink-3);letter-spacing:.04em;margin-left:10px;vertical-align:.18em;font-family:var(--gp-mono)}
#pg-vehicle .gp-ymm{display:block;font-size:.44em;font-weight:500;color:var(--gp-ink-2,var(--t2));letter-spacing:.01em;margin-top:6px}
/* signals */
#pg-vehicle .gp-signals{display:grid;grid-template-columns:repeat(6,1fr);border:1px solid var(--gp-line);border-radius:var(--gp-r);background:var(--gp-panel);margin:20px 0 0;overflow:hidden;box-shadow:var(--gp-shadow)}
#pg-vehicle .gp-sig{padding:14px 16px;border-right:1px solid var(--gp-line);display:block;transition:background .14s}
#pg-vehicle .gp-sig:last-child{border-right:none}
#pg-vehicle .gp-sig:hover{background:var(--gp-sunken)}
#pg-vehicle .gp-sig b{display:block;font-size:22px;font-weight:600;letter-spacing:-.02em;line-height:1.15}
#pg-vehicle .gp-sig b.gp-txt{font-size:15px;line-height:1.5;padding:3px 0 4px}
#pg-vehicle .gp-sig span{display:block;font-family:var(--gp-mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--gp-ink-3);margin-top:5px}
#pg-vehicle .gp-sig .gp-delta{font-size:11px;color:var(--gp-ok);font-family:inherit;letter-spacing:0;text-transform:none;margin-top:3px}
/* your context */
#pg-vehicle .gp-yours{display:flex;align-items:center;gap:14px;margin-top:12px;padding:11px 16px;border:1px solid var(--gp-accent-line);background:var(--gp-accent-wash);border-radius:var(--gp-r)}
#pg-vehicle .gp-yours .gp-thumb{width:44px;height:33px;border-radius:6px;flex-shrink:0}
#pg-vehicle .gp-yt{font-size:13.5px;font-weight:600}
#pg-vehicle .gp-yd{font-size:12.5px;color:var(--gp-ink-2)}
#pg-vehicle .gp-yacts{margin-left:auto;display:flex;gap:7px;flex-shrink:0}
/* tab rail */
#pg-vehicle .gp-tabrail{position:sticky;top:var(--navh);z-index:30;background:color-mix(in srgb,var(--gp-bg) 92%,transparent);backdrop-filter:blur(10px);border-bottom:1px solid var(--gp-line);margin-top:20px}
#pg-vehicle .gp-tabrail-in{max-width:var(--col);margin:0 auto;padding:0 var(--pad);display:flex;align-items:center;gap:2px;overflow-x:auto;scrollbar-width:none}
#pg-vehicle .gp-tabrail-in::-webkit-scrollbar{display:none}
#pg-vehicle .gp-tab{padding:12px 13px;font-size:13.5px;font-weight:500;color:var(--gp-ink-2);border-bottom:2px solid transparent;white-space:nowrap;margin-bottom:-1px}
#pg-vehicle .gp-tab:hover{color:var(--gp-ink)}
#pg-vehicle .gp-tab.on{color:var(--gp-ink);border-bottom-color:var(--gp-accent);font-weight:600}
#pg-vehicle .gp-tab u{text-decoration:none;color:var(--gp-ink-3);font-family:var(--gp-mono);font-size:11px;margin-left:5px}
#pg-vehicle .gp-tab.on u{color:var(--gp-accent-ink)}
#pg-vehicle .gp-yearsel{margin-left:auto;display:flex;align-items:center;gap:7px;padding-left:14px;flex-shrink:0}
#pg-vehicle .gp-yearsel select{height:29px;border-radius:7px;border:1px solid var(--gp-line);background:var(--gp-panel);color:var(--gp-ink);font-size:12.5px;padding:0 8px;font-family:inherit}
/* layout */
#pg-vehicle .gp-cols{display:grid;grid-template-columns:minmax(0,1fr) 336px;gap:30px;padding:26px 0 40px;align-items:start}
#pg-vehicle .gp-cols>*,#pg-vehicle .gp-cols>*>*{min-width:0}
#pg-vehicle .gp-panel{background:var(--gp-panel);border:1px solid var(--gp-line);border-radius:var(--gp-r);box-shadow:var(--gp-shadow)}
#pg-vehicle .gp-mod-head{display:flex;align-items:center;gap:10px;padding:13px 16px;border-bottom:1px solid var(--gp-line)}
#pg-vehicle .gp-mod-head h3{font-size:13.5px}
#pg-vehicle .gp-more{margin-left:auto;font-size:12px;color:var(--gp-ink-3)}
#pg-vehicle .gp-more:hover{color:var(--gp-accent-ink)}
#pg-vehicle .gp-rail{display:flex;flex-direction:column;gap:16px;position:sticky;top:calc(var(--navh) + 54px)}
/* composer */
#pg-vehicle .gp-composer{display:flex;align-items:center;gap:10px;padding:11px 13px;margin-bottom:14px}
#pg-vehicle .gp-fake{flex:1;height:36px;border-radius:8px;border:1px solid var(--gp-line);background:var(--gp-sunken);display:flex;align-items:center;padding:0 13px;font-size:13.5px;color:var(--gp-ink-3);cursor:text}
#pg-vehicle .gp-quick{display:flex;gap:6px}
/* chips */
#pg-vehicle .gp-chips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:14px}
#pg-vehicle .gp-chip{height:29px;padding:0 12px;border-radius:999px;border:1px solid var(--gp-line);background:var(--gp-panel);font-size:12.5px;font-weight:500;color:var(--gp-ink-2)}
#pg-vehicle .gp-chip:hover{border-color:var(--gp-line-strong);color:var(--gp-ink)}
#pg-vehicle .gp-chip.on{background:var(--gp-ink);border-color:var(--gp-ink);color:var(--gp-bg)}
/* feed */
#pg-vehicle .gp-feed{display:flex;flex-direction:column;gap:12px}
#pg-vehicle .gp-fc{padding:15px 17px;transition:border-color .14s}
#pg-vehicle .gp-fc:hover{border-color:var(--gp-line-strong)}
#pg-vehicle .gp-fc .gp-hdr{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--gp-ink-2);margin-bottom:10px;flex-wrap:wrap}
#pg-vehicle .gp-fc .gp-hdr b{color:var(--gp-ink);font-weight:600}
#pg-vehicle .gp-fc .gp-kind{font-family:var(--gp-mono);font-size:10px;letter-spacing:.11em;text-transform:uppercase;color:var(--gp-ink-3);margin-left:auto;flex-shrink:0}
#pg-vehicle .gp-fc h4{font-size:16px;margin-bottom:5px;overflow-wrap:anywhere}
#pg-vehicle .gp-fc .gp-body{font-size:14px;color:var(--gp-ink-2);overflow-wrap:anywhere}
#pg-vehicle .gp-fc .gp-media{margin-top:12px;height:210px}
#pg-vehicle .gp-fc .gp-foot{display:flex;align-items:center;gap:14px;margin-top:12px;padding-top:11px;border-top:1px solid var(--gp-line);font-size:12.5px;color:var(--gp-ink-3);flex-wrap:wrap}
#pg-vehicle .gp-fc .gp-foot button:hover{color:var(--gp-accent-ink)}
#pg-vehicle .gp-specrow{display:flex;gap:22px;margin-top:11px;padding:10px 0;border-top:1px solid var(--gp-line);border-bottom:1px solid var(--gp-line);flex-wrap:wrap}
#pg-vehicle .gp-specrow b{display:block;font-size:13.5px;font-weight:600}
#pg-vehicle .gp-specrow span{font-family:var(--gp-mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--gp-ink-3)}
/* rail modules */
#pg-vehicle .gp-ranklist{display:flex;flex-direction:column}
#pg-vehicle .gp-rank{display:flex;align-items:center;gap:11px;padding:10px 16px;border-bottom:1px solid var(--gp-line)}
#pg-vehicle .gp-rank:last-child{border-bottom:none}
#pg-vehicle .gp-rank:hover{background:var(--gp-sunken)}
#pg-vehicle .gp-rank .gp-n{font-family:var(--gp-mono);font-size:11px;color:var(--gp-ink-3);width:14px;flex-shrink:0}
#pg-vehicle .gp-rank .gp-th{width:38px;height:29px;border-radius:6px;flex-shrink:0}
#pg-vehicle .gp-rank .gp-t{min-width:0;flex:1}
#pg-vehicle .gp-rank .gp-t b{display:block;font-size:13px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#pg-vehicle .gp-rank .gp-t span{font-size:11.5px;color:var(--gp-ink-3)}
#pg-vehicle .gp-dots{display:flex;gap:2px;flex-shrink:0}
#pg-vehicle .gp-dots i{width:4px;height:4px;border-radius:50%;background:var(--gp-line-strong);display:block}
#pg-vehicle .gp-dots i.f{background:var(--gp-accent)}
#pg-vehicle .gp-issue{padding:12px 16px;border-bottom:1px solid var(--gp-line)}
#pg-vehicle .gp-issue:last-child{border-bottom:none}
#pg-vehicle .gp-issue .gp-t{display:flex;align-items:flex-start;gap:8px}
#pg-vehicle .gp-issue .gp-t b{font-size:13px;font-weight:600;flex:1}
#pg-vehicle .gp-issue .gp-sym{font-size:12.5px;color:var(--gp-ink-2);margin-top:3px}
#pg-vehicle .gp-issue .gp-m{display:flex;align-items:center;gap:12px;margin-top:8px;font-size:11.5px;color:var(--gp-ink-3)}
#pg-vehicle .gp-metoo{margin-left:auto;height:24px;padding:0 9px;border-radius:6px;border:1px solid var(--gp-line);font-size:11.5px;font-weight:500;color:var(--gp-ink-2)}
#pg-vehicle .gp-metoo:hover{border-color:var(--gp-accent-line);background:var(--gp-accent-wash);color:var(--gp-accent-ink)}
#pg-vehicle .gp-garagelist{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--gp-line)}
#pg-vehicle .gp-gcard{background:var(--gp-panel);padding:10px}
#pg-vehicle .gp-gcard:hover{background:var(--gp-sunken)}
#pg-vehicle .gp-gcard .photo{height:66px;margin-bottom:8px}
#pg-vehicle .gp-gcard b{display:block;font-size:12.5px;font-weight:600}
#pg-vehicle .gp-gcard .gp-sp{font-family:var(--gp-mono);font-size:10.5px;color:var(--gp-ink-3)}
#pg-vehicle .gp-own{display:flex;align-items:center;gap:5px;margin-top:6px;font-size:11.5px;color:var(--gp-ink-2)}
#pg-vehicle .gp-livedot{width:5px;height:5px;border-radius:50%;background:var(--gp-ok);display:inline-block;flex-shrink:0}
#pg-vehicle .gp-relgroup{padding:12px 16px;border-bottom:1px solid var(--gp-line)}
#pg-vehicle .gp-relgroup:last-child{border-bottom:none}
#pg-vehicle .gp-relgroup .gp-lbl{display:flex;align-items:center;gap:6px;margin-bottom:9px}
#pg-vehicle .gp-rel{display:flex;align-items:center;gap:9px;padding:6px 0}
#pg-vehicle .gp-rel .photo{width:42px;height:30px;flex-shrink:0}
#pg-vehicle .gp-rel b{font-size:12.5px;font-weight:500;display:block}
#pg-vehicle .gp-rel span{font-size:11.5px;color:var(--gp-ink-3)}
#pg-vehicle .gp-cnt{margin-left:auto;font-family:var(--gp-mono);font-size:11px;color:var(--gp-accent-ink);flex-shrink:0}
#pg-vehicle .gp-partrow{display:flex;align-items:center;gap:10px;padding:9px 16px;border-bottom:1px solid var(--gp-line)}
#pg-vehicle .gp-partrow:last-child{border-bottom:none}
#pg-vehicle .gp-partrow .gp-t{flex:1;min-width:0}
#pg-vehicle .gp-partrow b{display:block;font-size:12.5px;font-weight:500}
#pg-vehicle .gp-pn{font-family:var(--gp-mono);font-size:10.5px;color:var(--gp-ink-3);overflow-wrap:anywhere}
#pg-vehicle .gp-partrow .gp-u{font-size:11.5px;color:var(--gp-ink-3);text-align:right;flex-shrink:0}
#pg-vehicle .gp-partrow .gp-u b{font-size:12.5px;color:var(--gp-ink);font-weight:600}
/* panes */
#pg-vehicle .gp-pane{display:none}
#pg-vehicle .gp-pane.on{display:block}
#pg-vehicle .gp-pane-full{padding:26px 0 40px}
#pg-vehicle .gp-sectionhead{display:flex;align-items:flex-end;gap:14px;margin-bottom:16px}
#pg-vehicle .gp-sectionhead>div:first-child{min-width:0}
#pg-vehicle .gp-sectionhead h2{font-size:19px}
#pg-vehicle .gp-sectionhead p{font-size:13px;color:var(--gp-ink-2);margin-top:3px}
#pg-vehicle .gp-ctl{margin-left:auto;display:flex;gap:6px;flex-shrink:0}
#pg-vehicle .gp-modgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
#pg-vehicle .gp-mcard{display:block;overflow:hidden;transition:transform .14s,box-shadow .14s}
#pg-vehicle .gp-mcard:hover{transform:translateY(-2px);box-shadow:var(--gp-pop)}
#pg-vehicle .gp-mcard .photo{border-radius:0;border:none;border-bottom:1px solid var(--gp-line);height:132px}
#pg-vehicle .gp-mcard .gp-body{padding:13px 14px}
#pg-vehicle .gp-mcard h4{font-size:14.5px;margin-bottom:8px;overflow-wrap:anywhere}
#pg-vehicle .gp-spec{display:flex;gap:16px;padding:9px 0;border-top:1px solid var(--gp-line);border-bottom:1px solid var(--gp-line)}
#pg-vehicle .gp-spec b{display:block;font-size:12.5px;font-weight:600}
#pg-vehicle .gp-spec span{font-family:var(--gp-mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--gp-ink-3)}
#pg-vehicle .gp-mcard .gp-foot{display:flex;align-items:center;gap:6px;margin-top:10px;font-size:12px;color:var(--gp-ink-3);padding:0 14px 13px}
#pg-vehicle .gp-catbar{display:flex;align-items:center;gap:10px;margin:26px 0 13px}
#pg-vehicle .gp-catbar h3{font-size:14px}
#pg-vehicle .gp-ln{flex:1;height:1px;background:var(--gp-line)}
#pg-vehicle .gp-ct{font-family:var(--gp-mono);font-size:11px;color:var(--gp-ink-3)}
#pg-vehicle .gp-itable{width:100%;border-collapse:collapse;background:var(--gp-panel);border:1px solid var(--gp-line);border-radius:var(--gp-r);overflow:hidden;box-shadow:var(--gp-shadow)}
#pg-vehicle .gp-itable th{text-align:left;font-family:var(--gp-mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--gp-ink-3);font-weight:400;padding:11px 14px;border-bottom:1px solid var(--gp-line);background:var(--gp-sunken)}
#pg-vehicle .gp-itable td{padding:13px 14px;border-bottom:1px solid var(--gp-line);font-size:13.5px;vertical-align:top}
#pg-vehicle .gp-itable tr:last-child td{border-bottom:none}
#pg-vehicle .gp-itable tr:hover td{background:var(--gp-sunken)}
#pg-vehicle .gp-ttl{font-weight:600;display:block;margin-bottom:2px}
#pg-vehicle .gp-itable .gp-sym{font-size:12.5px;color:var(--gp-ink-2)}
#pg-vehicle .gp-num{font-family:var(--gp-mono);font-size:13px;white-space:nowrap}
#pg-vehicle .gp-bar{height:4px;border-radius:2px;background:var(--gp-line);margin-top:6px;overflow:hidden;width:100px}
#pg-vehicle .gp-bar i{display:block;height:100%;background:var(--gp-accent)}
#pg-vehicle .gp-gargrid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
#pg-vehicle .gp-vcard{display:block;overflow:hidden;transition:transform .14s,box-shadow .14s}
#pg-vehicle .gp-vcard:hover{transform:translateY(-2px);box-shadow:var(--gp-pop)}
#pg-vehicle .gp-vcard .photo{border-radius:0;border:none;border-bottom:1px solid var(--gp-line);height:118px}
#pg-vehicle .gp-vcard .gp-body{padding:11px 13px}
#pg-vehicle .gp-vcard h4{font-size:13.5px;overflow-wrap:anywhere}
#pg-vehicle .gp-vcard .gp-sp{font-family:var(--gp-mono);font-size:11px;color:var(--gp-ink-3);margin-top:3px}
#pg-vehicle .gp-vcard .gp-own{margin-top:9px;padding-top:9px;border-top:1px solid var(--gp-line);font-size:12px}
#pg-vehicle .gp-specgrid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
#pg-vehicle .gp-spectable{width:100%;border-collapse:collapse}
#pg-vehicle .gp-spectable td{padding:9px 16px;border-bottom:1px solid var(--gp-line);font-size:13.5px}
#pg-vehicle .gp-spectable tr:last-child td{border-bottom:none}
#pg-vehicle .gp-spectable td:first-child{color:var(--gp-ink-2);width:42%}
#pg-vehicle .gp-spectable td:last-child{font-family:var(--gp-mono);font-size:12.5px}
/* full-width spec blocks (engines, trims, colours) inside the specs grid */
#pg-vehicle .gp-specwide{grid-column:1 / -1;overflow:hidden}
#pg-vehicle .gp-specwide .gp-itable{box-shadow:none;border:none;border-radius:0;background:transparent}
#pg-vehicle .gp-specwide .gp-itable td{vertical-align:middle}
#pg-vehicle .gp-eng-sub{display:block;font-family:var(--gp-mono);font-size:10.5px;color:var(--gp-ink-3);margin-top:2px;letter-spacing:.02em}
#pg-vehicle .gp-eng-std{display:block;font-size:11.5px;color:var(--gp-ink-3);margin-top:4px;line-height:1.4}
#pg-vehicle .gp-colorgrid{display:flex;flex-wrap:wrap;gap:8px;padding:14px 16px}
#pg-vehicle .gp-swatch{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--gp-line);border-radius:20px;padding:3px 12px 3px 4px;font-size:12px;color:var(--gp-ink-2)}
#pg-vehicle .gp-swatch i{width:15px;height:15px;border-radius:50%;border:1px solid rgba(0,0,0,.15);flex-shrink:0;display:inline-block}
#pg-vehicle .gp-swatch .gp-sw-code{font-family:var(--gp-mono);font-size:10px;color:var(--gp-ink-3)}
/* subtle specs footer — suggest an edit / confirm the data (understated on purpose) */
#pg-vehicle .gp-specfoot{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-top:20px;padding-top:15px;border-top:1px solid var(--gp-line);font-size:12.5px;color:var(--gp-ink-3)}
#pg-vehicle .gp-sf-note{margin-right:auto}
#pg-vehicle .gp-sf-link{background:none;border:none;color:var(--gp-ink-2);font:inherit;cursor:pointer;padding:4px 3px;display:inline-flex;align-items:center;gap:6px;transition:color .12s}
#pg-vehicle .gp-sf-link:hover{color:var(--gp-accent-ink)}
#pg-vehicle .gp-sf-confirm.on{color:var(--gp-ok);font-weight:500}
#pg-vehicle .gp-sf-count{font-family:var(--gp-mono);font-size:11px;color:var(--gp-ink-3)}
@media(max-width:600px){#pg-vehicle .gp-sf-note{margin-right:0;flex:0 0 100%}}
#pg-vehicle .gp-empty{padding:26px;text-align:center;color:var(--gp-ink-3);font-size:13.5px;border:1px dashed var(--gp-line-strong);border-radius:var(--gp-r);background:var(--gp-sunken)}
/* mosaic empty-state band (no owner photos yet) */
#pg-vehicle .gp-mosaic-empty{grid-column:1/-1;grid-row:1/-1;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:7px;padding:26px 30px;min-height:200px;border:1px solid var(--gp-line);border-radius:var(--gp-r);background:var(--gp-sunken)}
#pg-vehicle .gp-mosaic-empty .gp-me-code{font-family:var(--gp-mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--gp-accent-ink);background:var(--gp-accent-wash);border:1px solid var(--gp-accent-line);padding:3px 10px;border-radius:999px}
#pg-vehicle .gp-mosaic-empty h2{font-size:23px;margin:5px 0 0;letter-spacing:-.02em}
#pg-vehicle .gp-mosaic-empty p{font-size:13.5px;color:var(--gp-ink-2)}
#pg-vehicle .gp-mosaic-empty .btn{margin-top:9px}
/* link polish on cards/rows */
#pg-vehicle .gp-fc h4 a{color:inherit}
#pg-vehicle .gp-fc h4 a:hover{color:var(--gp-accent-ink)}
#pg-vehicle a.gp-partrow{transition:background .12s}
#pg-vehicle a.gp-partrow:hover{background:var(--gp-sunken)}
#pg-vehicle a.gp-ttl{color:var(--gp-ink)}
#pg-vehicle a.gp-ttl:hover{color:var(--gp-accent-ink)}
#pg-vehicle .gp-sig[data-goto]{cursor:pointer}
#pg-vehicle .gp-fc-media{display:block;margin-top:12px;border-radius:9px;overflow:hidden;border:1px solid var(--gp-line)}
#pg-vehicle .gp-fc-media .photo{border:none;border-radius:0}
#pg-vehicle .gp-foot a{color:var(--gp-ink-3)}
#pg-vehicle .gp-foot a:hover{color:var(--gp-accent-ink)}
#pg-vehicle .photo.is-ph{background:#e9e9ee}
body.dark #pg-vehicle .photo.is-ph{background:#232320}
/* ═══ flyout system (overlay, always with scrim) ═══ */
#pg-vehicle .gp-fly{position:fixed;right:0;top:0;bottom:var(--floor,0px);z-index:1001;width:min(460px,94vw);display:flex;flex-direction:column;background:var(--gp-panel);border-left:1px solid var(--gp-line);box-shadow:-14px 0 40px rgba(20,18,15,.16);transform:translateX(100%);transition:transform .24s ease;visibility:hidden}
#pg-vehicle .gp-fly.on{transform:none;visibility:visible}
#pg-vehicle .gp-fly.gp-wide{width:min(640px,96vw)}
#pg-vehicle .gp-mh{display:flex;align-items:flex-start;gap:12px;padding:16px 20px;border-bottom:1px solid var(--gp-line);flex-shrink:0}
#pg-vehicle .gp-mh h3{font-size:16px}
#pg-vehicle .gp-sub2{font-size:12.5px;color:var(--gp-ink-3);display:block;margin-top:2px;font-weight:400}
#pg-vehicle .gp-x{margin-left:auto;width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;color:var(--gp-ink-3);flex-shrink:0}
#pg-vehicle .gp-x:hover{background:var(--gp-sunken);color:var(--gp-ink)}
#pg-vehicle .gp-back{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;color:var(--gp-ink-3);flex-shrink:0;margin:-4px 0 0 -6px}
#pg-vehicle .gp-back:hover{background:var(--gp-sunken);color:var(--gp-ink)}
#pg-vehicle .gp-mb{overflow:auto;padding:20px;flex:1}
#pg-vehicle .gp-mf{display:flex;align-items:center;gap:8px;padding:14px 20px;border-top:1px solid var(--gp-line);background:var(--gp-sunken);flex-shrink:0;flex-wrap:wrap}
#pg-vehicle .gp-right{margin-left:auto;display:flex;gap:8px}
#pg-vehicle .gp-scrim{position:fixed;inset:0;background:rgba(12,11,10,.4);z-index:1000;display:none}
#pg-vehicle .gp-scrim.on{display:block}
/* form controls */
#pg-vehicle .gp-field{margin-bottom:16px}
#pg-vehicle .gp-field:last-child{margin-bottom:0}
#pg-vehicle .gp-lbl{display:block;font-size:12.5px;font-weight:600;margin-bottom:5px}
#pg-vehicle .gp-opt-note{font-weight:400;color:var(--gp-ink-3)}
#pg-vehicle .gp-hint{font-size:12px;color:var(--gp-ink-3);margin-top:5px;line-height:1.5}
#pg-vehicle .gp-inp{width:100%;height:38px;padding:0 12px;border-radius:8px;border:1px solid var(--gp-line);background:var(--gp-panel);color:var(--gp-ink);font-family:inherit;font-size:13.5px}
#pg-vehicle textarea.gp-inp{height:auto;min-height:84px;padding:10px 12px;line-height:1.6;resize:vertical}
#pg-vehicle select.gp-inp{cursor:pointer;height:38px}
#pg-vehicle .gp-inp:focus{outline:none;border-color:var(--gp-accent-line);box-shadow:0 0 0 3px var(--gp-accent-wash)}
#pg-vehicle .gp-grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
#pg-vehicle .gp-opt{display:flex;gap:11px;padding:12px 13px;border:1px solid var(--gp-line);border-radius:9px;margin-bottom:8px;cursor:pointer;align-items:flex-start;background:var(--gp-panel)}
#pg-vehicle .gp-opt:hover{border-color:var(--gp-line-strong)}
#pg-vehicle .gp-opt.on{border-color:var(--gp-accent);background:var(--gp-accent-wash)}
#pg-vehicle .gp-opt .gp-mark{width:16px;height:16px;border-radius:50%;border:1.5px solid var(--gp-line-strong);flex-shrink:0;margin-top:2px}
#pg-vehicle .gp-opt.on .gp-mark{border-color:var(--gp-accent);border-width:5px}
#pg-vehicle .gp-opt b{font-size:13.5px;display:block}
#pg-vehicle .gp-opt span{font-size:12.5px;color:var(--gp-ink-2);display:block;margin-top:2px}
#pg-vehicle .gp-switch{width:38px;height:22px;border-radius:999px;background:var(--gp-line-strong);position:relative;flex-shrink:0;transition:background .15s;cursor:pointer}
#pg-vehicle .gp-switch::after{content:"";position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:50%;background:#fff;transition:left .15s}
#pg-vehicle .gp-switch.on{background:var(--gp-ok)}
#pg-vehicle .gp-switch.on::after{left:19px}
#pg-vehicle .gp-togrow{display:flex;align-items:center;gap:14px;padding:13px 0;border-bottom:1px solid var(--gp-line)}
#pg-vehicle .gp-togrow:last-child{border-bottom:none}
#pg-vehicle .gp-togrow .gp-c{flex:1;min-width:0}
#pg-vehicle .gp-togrow b{font-size:13.5px;display:block}
#pg-vehicle .gp-togrow span{font-size:12.5px;color:var(--gp-ink-3)}
#pg-vehicle .gp-callout{padding:12px 14px;border-radius:9px;background:var(--gp-sunken);border:1px solid var(--gp-line);font-size:13px;color:var(--gp-ink-2);margin-bottom:16px}
#pg-vehicle .gp-okbox{background:var(--gp-ok-wash);border-color:color-mix(in srgb,var(--gp-ok) 30%,transparent);color:var(--gp-ok)}
#pg-vehicle .gp-permtable{width:100%;border-collapse:collapse;font-size:12.5px;margin-top:10px}
#pg-vehicle .gp-permtable th{text-align:left;font-family:var(--gp-mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--gp-ink-3);font-weight:400;padding:7px 10px;border-bottom:1px solid var(--gp-line)}
#pg-vehicle .gp-permtable td{padding:7px 10px;border-bottom:1px solid var(--gp-line)}
#pg-vehicle .gp-permtable td:not(:first-child){text-align:center}
#pg-vehicle .gp-yes{color:var(--gp-ok);font-weight:600}
#pg-vehicle .gp-no{color:var(--gp-ink-3)}
#pg-vehicle .gp-hgroup .gp-eyebrow{display:block;margin:18px 0 8px}
#pg-vehicle .gp-hgroup:first-child .gp-eyebrow{margin-top:0}
#pg-vehicle .gp-rev{display:flex;gap:12px;padding:12px 0;border-bottom:1px solid var(--gp-line);font-size:13px}
#pg-vehicle .gp-rev:last-child{border-bottom:none}
#pg-vehicle .gp-rev .gp-when{font-family:var(--gp-mono);font-size:11.5px;color:var(--gp-ink-3);width:88px;flex-shrink:0}
#pg-vehicle .gp-rev .gp-c{flex:1}
#pg-vehicle .gp-toast{position:fixed;left:50%;bottom:calc(28px + var(--floor,0px));transform:translateX(-50%) translateY(20px);z-index:1002;background:var(--gp-ink);color:var(--gp-bg);padding:11px 18px;border-radius:10px;font-size:13.5px;box-shadow:var(--gp-pop);opacity:0;transition:opacity .2s,transform .2s;pointer-events:none;display:flex;align-items:center;gap:9px}
#pg-vehicle .gp-toast.on{opacity:1;transform:translateX(-50%) translateY(0)}
/* responsive */
@media(max-width:1100px){
  #pg-vehicle .gp-cols{grid-template-columns:1fr;gap:22px}
  #pg-vehicle .gp-rail{position:static;display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:start}
  #pg-vehicle .gp-gargrid{grid-template-columns:repeat(3,1fr)}
}
@media(max-width:860px){
  #pg-vehicle .gp-sectionhead{flex-direction:column;align-items:stretch;gap:12px}
  #pg-vehicle .gp-ctl{margin-left:0;overflow-x:auto;padding-bottom:2px;scrollbar-width:none}
  #pg-vehicle .gp-ctl::-webkit-scrollbar{display:none}
  #pg-vehicle .gp-signals{grid-template-columns:1fr 1fr 1fr}
  #pg-vehicle .gp-sig{border-bottom:1px solid var(--gp-line)}
  #pg-vehicle .gp-sig:nth-child(3n){border-right:none}
  #pg-vehicle .gp-mosaic{grid-template-rows:repeat(2,92px)}
  #pg-vehicle .gp-modgrid,#pg-vehicle .gp-gargrid{grid-template-columns:1fr 1fr}
  #pg-vehicle .gp-rail{grid-template-columns:1fr}
  #pg-vehicle .gp-ident{flex-direction:column;align-items:flex-start;gap:16px}
  #pg-vehicle .gp-acts{margin-left:0;width:100%;flex-wrap:wrap}
  #pg-vehicle .gp-ident h1{font-size:25px}
  #pg-vehicle .gp-specgrid{grid-template-columns:1fr}
}
@media(max-width:600px){
  #pg-vehicle .gp-mosaic{grid-template-columns:repeat(2,1fr);grid-template-rows:186px 92px}
  #pg-vehicle .gp-mosaic .photo:first-child{grid-column:1 / -1}
  #pg-vehicle .gp-mosaic .photo:nth-child(n+4){display:none}
  #pg-vehicle .gp-signals{grid-template-columns:1fr 1fr}
  #pg-vehicle .gp-sig:nth-child(2n){border-right:none}
  #pg-vehicle .gp-modgrid,#pg-vehicle .gp-gargrid{grid-template-columns:1fr}
  #pg-vehicle .gp-garagelist{grid-template-columns:1fr 1fr}
  /* tables become stacked cards */
  #pg-vehicle .gp-tbl thead{display:none}
  #pg-vehicle .gp-tbl,#pg-vehicle .gp-tbl tbody,#pg-vehicle .gp-tbl tr,#pg-vehicle .gp-tbl td{display:block;width:100%}
  #pg-vehicle .gp-tbl tr{border-bottom:1px solid var(--gp-line);padding:11px 15px}
  #pg-vehicle .gp-tbl td{border:none;padding:3px 0;display:flex;gap:12px;align-items:baseline}
  #pg-vehicle .gp-tbl td::before{content:attr(data-l);flex:0 0 40%;font-family:var(--gp-mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--gp-ink-3);padding-top:3px}
  #pg-vehicle .gp-tbl td:empty{display:none}
  #pg-vehicle .gp-tbl .gp-bar{width:100%}
}

/* ═══════════════════════ VEHICLES INDEX — search + catalogue ═══════════════════════ */
/* Catalogue browse (makes + generation cards) */
#pg-vehicles .cat-head{display:flex;align-items:baseline;gap:12px;margin:30px 0 14px}
#pg-vehicles .cat-head h2{font-size:19px;margin:0}
#pg-vehicles .cat-count{font-size:13px;color:var(--t2)}
#pg-vehicles .cat-makes{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:18px}
#pg-vehicles .cat-chip{height:32px;padding:0 13px;border-radius:999px;border:1px solid var(--border2);background:var(--surface);font-size:13px;font-weight:500;color:var(--t2);display:inline-flex;align-items:center;gap:7px}
#pg-vehicles .cat-chip:hover{border-color:var(--t3);color:var(--text)}
#pg-vehicles .cat-chip[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
#pg-vehicles .cat-chip .n{font-size:11px;opacity:.7;font-variant-numeric:tabular-nums}
#pg-vehicles .cat-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:14px}
#pg-vehicles .cat-card{display:block;border:1px solid var(--border);border-radius:var(--r-lg,14px);background:var(--surface);overflow:hidden;box-shadow:var(--sh-sm);transition:transform .14s,box-shadow .14s}
#pg-vehicles .cat-card:hover{transform:translateY(-2px);box-shadow:var(--sh-md,0 8px 24px rgba(0,0,0,.1))}
#pg-vehicles .cat-card .cc-photo{display:block;height:118px;background:#e9e9ee center/cover url(/assets/vehicle-placeholder.svg) no-repeat;position:relative;border-bottom:1px solid var(--border)}
body.dark #pg-vehicles .cat-card .cc-photo{background-color:#232320}
#pg-vehicles .cat-card .cc-photo.hasimg{background-size:cover;background-position:center;background-repeat:no-repeat}
#pg-vehicles .cat-card .cc-code{position:absolute;top:9px;left:9px;height:22px;padding:0 9px;border-radius:999px;background:rgba(18,17,15,.62);color:#fff;font-size:11px;font-weight:500;display:inline-flex;align-items:center;backdrop-filter:blur(6px)}
#pg-vehicles .cat-card .cc-body{display:block;padding:12px 14px}
#pg-vehicles .cat-card h3{font-size:14.5px;margin:0 0 3px}
#pg-vehicles .cat-card .cc-yrs{display:block;font-size:12px;color:var(--t3);font-variant-numeric:tabular-nums}
#pg-vehicles .cat-card .cc-meta{display:flex;gap:14px;margin-top:10px;font-size:11.5px;color:var(--t2)}
#pg-vehicles .cat-empty{grid-column:1/-1;padding:30px;text-align:center;color:var(--t3);border:1px dashed var(--border2);border-radius:14px;background:var(--surface2)}

/* ── the ported search component, scoped so its generic class names cannot
   leak into the rest of the app; local tokens preserve its exact look.

   ONE EXCEPTION, HERE AND IN .mdp BELOW: `--accent` is NOT local. It is
   operator-configurable from the Appearance screen, and a block holding its own
   hex was a block that did not move when somebody repainted the site — these
   two carried #f05a24 against :root's #EA580C, so one button was two oranges
   depending which screen it was on. The accent inherits; only the private
   shades these blocks use under their own names are mixed from it, the way
   views/app.php mixes :root's. The scoping's real job — stopping the ported
   design leaking OUT — is untouched. ── */
#vehicle-search{
  --page:#f5f5f4; --card:#fff; --sunken:#f6f6f5; --line:#e8e7e4; --line-strong:#dcdbd7;
  --ink:#1a1a19; --ink-2:#5f5e59; --ink-3:#8f8e88;
  --accent-ink:color-mix(in srgb,var(--accent) 76%,#000); --accent-wash:color-mix(in srgb,var(--accent) 8%,#fff); --accent-line:color-mix(in srgb,var(--accent) 30%,#fff);
  --warn:#8a6d1f; --warn-wash:#fdf6e3; --warn-line:#e8d9a8;
  --vsmono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  position:relative;max-width:none;width:100%;color:var(--ink);font-size:15px;display:block;margin-bottom:6px;
}
body.dark #vehicle-search{
  --page:#121211; --card:#1c1c1a; --sunken:#232320; --line:#2e2e2b; --line-strong:#3f3f3a;
  --ink:#f2f1ee; --ink-2:#a5a39d; --ink-3:#76746e;
  --accent-ink:color-mix(in srgb,var(--accent) 62%,#fff); --accent-wash:color-mix(in srgb,var(--accent) 14%,#000); --accent-line:color-mix(in srgb,var(--accent) 26%,#000);
  --warn:#d9bd6a; --warn-wash:#2a2410; --warn-line:#4a4020;
}
#vehicle-search button:not(.btn){font:inherit;color:inherit;cursor:pointer;background:none;border:none}
#vehicle-search input{font:inherit}
#vehicle-search .vs-row{display:flex;align-items:stretch;gap:8px}
#vehicle-search .vs-box{flex:1;min-width:0;display:flex;align-items:center;gap:8px;min-height:54px;padding:7px 10px;border:1px solid var(--line-strong);border-radius:13px;background:var(--card);transition:.14s;flex-wrap:wrap}
#vehicle-search .vs-box:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-wash)}
#vehicle-search .vs-lead{flex:none;color:var(--ink-3);display:grid;place-items:center;width:26px;height:26px}
#vehicle-search .vs-box input{flex:1;min-width:110px;border:none;background:none;outline:none;font-size:15px;color:var(--ink);height:28px}
#vehicle-search .vs-box input::placeholder{color:var(--ink-3)}
#vehicle-search .spin{width:15px;height:15px;border:2px solid var(--line-strong);border-top-color:var(--accent);border-radius:50%;animation:vsspin .6s linear infinite}
@keyframes vsspin{to{transform:rotate(360deg)}}
#vehicle-search .slot{flex:none;display:flex;align-items:center;gap:7px;height:30px;padding:0 5px 0 11px;border-radius:999px;border:1px solid var(--accent-line);background:var(--accent-wash);color:var(--accent-ink);font-size:13px;font-weight:500}
#vehicle-search .slot .k{font-family:var(--vsmono);font-size:9px;letter-spacing:.1em;text-transform:uppercase;opacity:.7;font-weight:400}
#vehicle-search .slot .x{width:18px;height:18px;border-radius:50%;display:grid;place-items:center;font-size:9px;flex:none}
#vehicle-search .slot .x:hover{background:rgba(0,0,0,.09)}
#vehicle-search .vs-pop{position:absolute;top:calc(100% + 7px);left:0;right:0;z-index:60;background:var(--card);border:1px solid var(--line-strong);border-radius:13px;box-shadow:0 14px 38px -8px rgba(20,18,15,.2);overflow:hidden}
body.dark #vehicle-search .vs-pop{box-shadow:0 14px 38px -8px rgba(0,0,0,.6)}
#vehicle-search .vs-pop[hidden],#vehicle-search .g-pop[hidden]{display:none}
#vehicle-search .rail{display:flex;align-items:stretch;gap:7px;padding:9px;border-bottom:1px solid var(--line);background:var(--sunken)}
#vehicle-search .dd{flex:1;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:1px;padding:6px 24px 6px 11px;border:1px solid var(--line-strong);border-radius:10px;background:var(--card);text-align:left;position:relative;transition:.13s}
#vehicle-search .dd:hover:not(:disabled){border-color:var(--ink-3)}
#vehicle-search .dd:disabled{background:var(--sunken);border-style:dashed;cursor:not-allowed;opacity:.75}
#vehicle-search .dd .dd-l{font-family:var(--vsmono);font-size:9px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}
#vehicle-search .dd .dd-v{font-size:13px;font-weight:450;color:var(--ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
#vehicle-search .dd .cv{position:absolute;right:9px;top:50%;transform:translateY(-50%);font-size:9px;color:var(--ink-3);transition:transform .15s}
#vehicle-search .dd.open{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-wash)}
#vehicle-search .dd.open .cv{transform:translateY(-50%) rotate(180deg);color:var(--accent-ink)}
#vehicle-search .dd.filled{border-color:var(--accent-line);background:var(--accent-wash)}
#vehicle-search .dd.filled .dd-l{color:var(--accent-ink);opacity:.8}
#vehicle-search .dd.filled .dd-v{color:var(--accent-ink);font-weight:500}
#vehicle-search .gate{display:flex;align-items:center;gap:8px;padding:7px 11px;font-size:12px;color:var(--ink-3);border-bottom:1px solid var(--line);background:var(--sunken)}
#vehicle-search .gate b{color:var(--ink-2);font-weight:500}
#vehicle-search .clearall{margin-left:auto;font-size:11.5px;color:inherit;opacity:.75;text-decoration:underline;text-underline-offset:3px}
#vehicle-search .clearall:hover{opacity:1}
#vehicle-search .gate.ready{color:var(--accent-ink);background:var(--accent-wash);border-color:var(--accent-line)}
#vehicle-search .gate.ready b{color:inherit}
#vehicle-search .body{max-height:330px;overflow:auto;padding:6px}
#vehicle-search .grp{font-family:var(--vsmono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);padding:9px 10px 5px;display:flex;gap:8px;align-items:baseline}
#vehicle-search .grp span{letter-spacing:0;text-transform:none;font-family:inherit;font-size:11px;opacity:.85}
#vehicle-search .row{display:flex;align-items:center;gap:11px;width:100%;padding:7px 9px;border-radius:9px;text-align:left}
#vehicle-search .row:hover,#vehicle-search .row.cursor{background:var(--sunken)}
#vehicle-search .row .th{width:44px;height:29px;border-radius:6px;overflow:hidden;background:var(--sunken);border:1px solid var(--line);flex:none;position:relative}
#vehicle-search .row .th svg{position:absolute;inset:0;width:100%;height:100%}
#vehicle-search .row .icon{width:44px;height:29px;border-radius:6px;border:1px dashed var(--line-strong);display:grid;place-items:center;color:var(--ink-3);flex:none;font-size:11px;font-weight:500}
#vehicle-search .row .tx{min-width:0;flex:1}
#vehicle-search .row .l1{display:block;font-size:13.5px;font-weight:450}
#vehicle-search .row .l1 mark{background:none;color:var(--accent-ink);font-weight:600}
#vehicle-search .row .l2{display:block;font-size:11.5px;color:var(--ink-3)}
#vehicle-search .row .tag{margin-left:auto;font-size:10.5px;color:var(--accent-ink);background:var(--accent-wash);border:1px solid var(--accent-line);padding:2px 9px;border-radius:999px;flex:none}
#vehicle-search .ygrid{display:grid;grid-template-columns:repeat(6,1fr);gap:5px;padding:4px}
#vehicle-search .ygrid button{height:34px;border-radius:8px;border:1px solid var(--line);font-size:13px;color:var(--ink-2)}
#vehicle-search .ygrid button:hover,#vehicle-search .ygrid button.cursor{border-color:var(--accent);color:var(--accent-ink);background:var(--accent-wash)}
#vehicle-search .msg{padding:13px 11px;font-size:13px;color:var(--ink-3);line-height:1.6}
#vehicle-search .msg b{color:var(--ink-2);font-weight:500}
#vehicle-search .ignored{display:flex;align-items:flex-start;gap:9px;margin:6px;padding:8px 11px;border-radius:9px;background:var(--warn-wash);border:1px solid var(--warn-line);color:var(--warn);font-size:12px;line-height:1.55}
#vehicle-search .ignored code{font-family:var(--vsmono);background:rgba(0,0,0,.05);border-radius:4px;padding:1px 5px}
body.dark #vehicle-search .ignored code{background:rgba(255,255,255,.07)}
#vehicle-search .substep{display:flex;align-items:baseline;gap:8px;padding:9px 10px 4px}
#vehicle-search .substep b{font-size:13px;font-weight:500}
#vehicle-search .substep span{font-size:11.5px;color:var(--ink-3)}
#vehicle-search .gbtn{flex:none;display:flex;align-items:center;gap:8px;padding:0 16px;border-radius:13px;border:1px solid var(--line-strong);background:var(--card);color:var(--ink-2);font-size:13.5px;transition:.14s;white-space:nowrap}
#vehicle-search .gbtn:hover{border-color:var(--ink-3);color:var(--ink)}
#vehicle-search .gbtn svg{flex:none;opacity:.75}
#vehicle-search .gbtn .n{font-family:var(--vsmono);font-size:10.5px;color:var(--ink-3);background:var(--sunken);border:1px solid var(--line);border-radius:6px;padding:2px 7px}
#vehicle-search .gbtn[aria-pressed="true"]{border-color:var(--accent);background:var(--accent-wash);color:var(--accent-ink)}
#vehicle-search .gbtn[aria-pressed="true"] svg{opacity:1}
#vehicle-search .g-pop{position:absolute;top:calc(100% + 7px);right:0;z-index:61;width:308px;max-width:100%;background:var(--card);border:1px solid var(--line-strong);border-radius:13px;box-shadow:0 14px 38px -8px rgba(20,18,15,.2);overflow:hidden}
body.dark #vehicle-search .g-pop{box-shadow:0 14px 38px -8px rgba(0,0,0,.6)}
#vehicle-search .g-head{display:flex;align-items:baseline;gap:8px;padding:11px 13px 9px;border-bottom:1px solid var(--line);background:var(--sunken)}
#vehicle-search .g-head b{font-size:11px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--ink-2)}
#vehicle-search .g-head span{font-size:11.5px;color:var(--ink-3);margin-left:auto}
#vehicle-search .g-list{max-height:290px;overflow:auto;padding:6px}
#vehicle-search .g-row{display:flex;align-items:center;gap:11px;width:100%;padding:7px;border-radius:9px;text-align:left;transition:.12s}
#vehicle-search .g-row:hover,#vehicle-search .g-row.cursor{background:var(--sunken)}
#vehicle-search .g-row .th{width:46px;height:31px;border-radius:6px;overflow:hidden;position:relative;flex:none;border:1px solid var(--line)}
#vehicle-search .g-row .th svg{position:absolute;inset:0;width:100%;height:100%}
/* real cover photo, else the standard placeholder — never generated shapes */
#vehicle-search .th.th-img{background-size:cover;background-position:center;background-repeat:no-repeat}
#vehicle-search .th.th-ph{background:var(--sunken) center/cover no-repeat url(/assets/vehicle-placeholder.svg)}
body.dark #vehicle-search .th.th-ph{background-color:#232320}
#vehicle-search .g-row .tx{min-width:0;flex:1}
#vehicle-search .g-row .l1{display:block;font-size:13.5px;font-weight:450;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#vehicle-search .g-row .l2{display:block;font-size:11.5px;color:var(--ink-3)}
#vehicle-search .g-row.active{background:var(--accent-wash);box-shadow:inset 0 0 0 1px var(--accent-line)}
#vehicle-search .g-row.active .l2{color:var(--accent-ink)}
#vehicle-search .g-foot{padding:9px 13px;border-top:1px solid var(--line);background:var(--sunken);display:flex;align-items:center;gap:10px}
#vehicle-search .g-foot .hint{font-size:11.5px;color:var(--ink-3);line-height:1.5}
#vehicle-search .g-foot button{margin-left:auto;font-size:12px;color:var(--ink-3);white-space:nowrap}
#vehicle-search .g-foot button:hover{color:var(--ink)}
#vehicle-search .g-empty{padding:16px 13px;font-size:12.5px;color:var(--ink-3);line-height:1.6}
#vehicle-search .cta{flex:none;height:54px;line-height:52px;min-width:max-content;padding:0 20px;border-radius:13px;font-size:13.5px;font-weight:500;white-space:nowrap;text-align:center;border:1px solid var(--line);background:var(--sunken);color:var(--ink-3);cursor:not-allowed;transition:background .16s,border-color .16s,color .16s,box-shadow .16s}
#vehicle-search .cta.live{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);cursor:pointer;box-shadow:0 1px 2px rgba(240,90,36,.3)}
#vehicle-search .cta.live:hover{filter:brightness(1.06)}
#vehicle-search .foot{display:flex;align-items:center;gap:9px;padding:9px;border-top:1px solid var(--line);background:var(--sunken)}
#vehicle-search .foot .pos{font-family:var(--vsmono);font-size:10px;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-3);margin:0 auto}
#vehicle-search .foot .next{height:34px;padding:0 16px;border-radius:9px;font-size:13px;font-weight:500;border:1px solid var(--line-strong);background:var(--card);color:var(--ink-2);transition:.13s}
#vehicle-search .foot .next.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
#vehicle-search .foot .next.primary:hover:not(:disabled){filter:brightness(1.06)}
#vehicle-search .vs-out{display:flex;align-items:center;gap:10px;margin-top:11px}
#vehicle-search .vs-out[hidden]{display:none}
#vehicle-search .outchip{display:flex;align-items:center;gap:9px;padding:5px 13px 5px 6px;border-radius:999px;border:1px solid var(--accent);background:var(--accent-wash);color:var(--accent-ink);font-size:13px}
#vehicle-search .outchip .th{width:34px;height:23px;border-radius:4px;overflow:hidden;position:relative;flex:none}
#vehicle-search .outchip .th svg{position:absolute;inset:0;width:100%;height:100%}
#vehicle-search .outchip .x{width:18px;height:18px;border-radius:50%;display:grid;place-items:center;font-size:9px}
#vehicle-search .sheet-scrim{display:none}
#vehicle-search .sheet-grip{display:none}
#vehicle-search .row.row-compact{padding:10px 11px;gap:10px}
#vehicle-search .row .count{margin-left:auto;flex:none;font-size:12px;color:var(--ink-3);font-variant-numeric:tabular-nums;background:var(--sunken);border:1px solid var(--line);border-radius:999px;padding:2px 9px;min-width:30px;text-align:center}
#vehicle-search .orline{display:flex;align-items:center;gap:11px;padding:10px 10px 4px}
#vehicle-search .orline::before,#vehicle-search .orline::after{content:"";flex:1;height:1px;background:var(--line)}
#vehicle-search .orline span{font-family:var(--vsmono);font-size:9.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}
@media (max-width:640px){
  #vehicle-search .vs-row{flex-wrap:wrap;gap:8px}
  #vehicle-search .vs-box{flex:1 1 100%;min-height:50px}
  #vehicle-search .gbtn{flex:1 1 auto;justify-content:center;padding:0 14px;height:46px}
  #vehicle-search .cta{flex:2 1 auto;height:46px;line-height:44px;padding:0 14px}
  #vehicle-search .vs-pop,#vehicle-search .g-pop{position:fixed;inset:auto 0 var(--floor-modal,0px) 0;top:auto;width:auto;max-width:none;z-index:120;border-radius:20px 20px 0 0;border-left:none;border-right:none;border-bottom:none;max-height:86vh;display:flex;flex-direction:column;box-shadow:0 -12px 40px rgba(20,18,15,.24)}
  #vehicle-search .sheet-grip{display:block;width:38px;height:4px;border-radius:99px;background:var(--line-strong);margin:9px auto 3px;flex:none}
  #vehicle-search .sheet-scrim{display:block;position:fixed;inset:0;background:rgba(20,18,15,.4);z-index:119;opacity:0;pointer-events:none;transition:opacity .2s}
  #vehicle-search.is-open .sheet-scrim{opacity:1;pointer-events:auto}
  #vehicle-search .body,#vehicle-search .g-list{max-height:none;flex:1;min-height:0}
  #vehicle-search .ygrid{grid-template-columns:repeat(4,1fr);gap:6px}
  #vehicle-search .foot{position:sticky;bottom:0}
  #vehicle-search .foot .pos{display:none}
  #vehicle-search .foot .next{flex:1;height:46px;font-size:14px}
}

/* ══════════ MOD DETAIL PAGE (.mdp) — scoped import of the 1:1 design ══════════
   Generated from the mods design mockup; every selector namespaced under .mdp
   so the mockup design system cannot touch the app chrome. See page-project. */
.mdp{
  --bg:#f4f4f2; --panel:#ffffff; --sunken:#f7f7f5; --line:#e5e4e0; --line-strong:#d2d1cc;
  --ink:#171614; --ink-2:#5c5a55; --ink-3:#8d8b85;
  --accent-ink:color-mix(in srgb,var(--accent) 76%,#000); --accent-wash:color-mix(in srgb,var(--accent) 8%,#fff); --accent-line:color-mix(in srgb,var(--accent) 30%,#fff);
  --ok:#2f7d4f; --ok-wash:#e8f4ec;
  --warn:#a8630c; --warn-wash:#fdf1e0;
  --danger:#b4342c; --danger-wash:#fbebe9;
  --shadow:0 1px 2px rgba(20,18,15,.05);
  --pop-shadow:0 10px 32px rgba(20,18,15,.13);
  --r:10px;
}
body.dark .mdp{
  --bg:#121211; --panel:#1c1c1a; --sunken:#232320; --line:#2e2e2b; --line-strong:#3d3d39;
  --ink:#f2f1ee; --ink-2:#a3a19b; --ink-3:#76746e;
  --accent-ink:color-mix(in srgb,var(--accent) 62%,#fff); --accent-wash:color-mix(in srgb,var(--accent) 14%,#000); --accent-line:color-mix(in srgb,var(--accent) 26%,#000);
  --ok:#6cc08c; --ok-wash:#16281d;
  --warn:#d99a4a; --warn-wash:#2b2113;
  --danger:#e2766c; --danger-wash:#2d1917;
  --shadow:0 1px 2px rgba(0,0,0,.4);
  --pop-shadow:0 10px 32px rgba(0,0,0,.55);
}
.mdp *{box-sizing:border-box}
.mdp{margin:0;background:var(--bg);color:var(--ink);
  font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  font-size:15px;line-height:1.6;-webkit-font-smoothing:antialiased}
.mdp.locked{overflow:hidden}
.mdp h1, .mdp h2, .mdp h3, .mdp h4{margin:0;font-weight:600;letter-spacing:-.015em;line-height:1.25}
.mdp p{margin:0}
.mdp a{color:inherit;text-decoration:none}
/* :not(.btn) — see #pg-vehicle: (0,1,1) beats .btn's (0,1,0), so this reset
   was stripping the site's own button component down to bare text. */
.mdp button:not(.btn){font:inherit;color:inherit;cursor:pointer;background:none;border:none;padding:0}
.mdp :focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.mdp .mono{font-family:"JetBrains Mono",monospace}
.mdp .muted{color:var(--ink-2)}
.mdp .wrap{max-width:var(--col);margin:0 auto;padding:0 var(--pad)}
.mdp .row{display:flex;align-items:center;gap:8px}
.mdp .eyebrow{font-family:"JetBrains Mono",monospace;font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-3)}
.mdp .topbar{position:sticky;top:0;z-index:60;background:color-mix(in srgb,var(--bg) 88%,transparent);
  backdrop-filter:saturate(160%) blur(12px);border-bottom:1px solid var(--line)}
.mdp .topbar .inner{max-width:var(--col);margin:0 auto;padding:0 var(--pad);height:58px;display:flex;align-items:center;gap:22px}
.mdp .brand{display:flex;align-items:center;gap:9px;flex-shrink:0}
.mdp .hx{width:19px;height:19px;color:var(--accent)}
.mdp .hx-in{fill:currentColor}
.mdp .wm{display:flex;flex-direction:column;line-height:1.05}
.mdp .wm i{font-style:normal;font-size:11px;font-weight:600;letter-spacing:.02em}
.mdp .wm i:last-child{color:var(--ink-3)}
.mdp .navlinks{display:flex;gap:2px;margin-left:6px}
.mdp .navlinks a{padding:6px 11px;border-radius:7px;font-size:13.5px;color:var(--ink-2);font-weight:500}
.mdp .navlinks a:hover{background:var(--sunken);color:var(--ink)}
.mdp .navlinks a.on{color:var(--ink);background:var(--sunken)}
.mdp .search{margin-left:auto;position:relative;flex:0 1 260px;display:flex;align-items:center}
.mdp .search .mag{position:absolute;left:11px;color:var(--ink-3)}
.mdp .search input{width:100%;height:34px;padding:0 12px 0 32px;border-radius:8px;border:1px solid var(--line);
  background:var(--panel);color:var(--ink);font-size:13px}
.mdp .search input::placeholder{color:var(--ink-3)}
.mdp .av{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;
  background:var(--accent);color:var(--accent-ink);font-weight:600;flex-shrink:0}
.mdp .av-sm{width:26px;height:26px;font-size:10.5px}
.mdp .av-xs{width:20px;height:20px;font-size:9px}
.mdp .av-md{width:34px;height:34px;font-size:12px}
.mdp .av-lg{width:46px;height:46px;font-size:15px}
/* Palette only — the shape is the site's one ladder (css/00b-buttons.php, §1).
   .mdp's --accent-ink is a DARKER orange, not white, so the primary fill puts
   the site's --accent-ink on it and hovers to this shell's own. */
.mdp .btn{border-color:var(--line-strong);background:var(--panel);color:var(--ink-2)}
.mdp .btn:hover{background:var(--panel);border-color:var(--ink-3);color:var(--ink)}
.mdp .btn-ghost{border-color:transparent;background:transparent}
.mdp .btn-ghost:hover{background:var(--sunken);border-color:transparent;color:var(--ink)}
.mdp .btn-primary{background:var(--accent);border-color:var(--accent);color:#fff}
.mdp .btn-primary:hover{background:var(--accent-ink);border-color:var(--accent-ink);color:#fff}
.mdp .btn-acc{color:var(--accent-ink);border-color:var(--accent-line);background:var(--panel)}
.mdp .btn-acc:hover{color:var(--accent-ink);border-color:var(--accent);background:var(--accent-wash)}
.mdp .btn-danger{background:var(--danger);border-color:var(--danger);color:#fff}
.mdp .btn.on{background:var(--accent-wash);border-color:var(--accent-line);color:var(--accent-ink)}
.mdp .pill{display:inline-flex;align-items:center;gap:5px;height:23px;padding:0 9px;border-radius:999px;
  border:1px solid var(--line);background:var(--panel);font-size:11.5px;font-weight:500;color:var(--ink-2);
  white-space:nowrap}
.mdp .pill-g{color:var(--ok);border-color:color-mix(in srgb,var(--ok) 30%,transparent);background:var(--ok-wash)}
.mdp .pill-g i{width:5px;height:5px;border-radius:50%;background:var(--ok);display:block}
.mdp .pill-a{color:var(--accent-ink);border-color:var(--accent-line);background:var(--accent-wash)}
.mdp .pill-w{color:var(--warn);border-color:color-mix(in srgb,var(--warn) 30%,transparent);background:var(--warn-wash)}
.mdp .pill-d{color:var(--danger);border-color:color-mix(in srgb,var(--danger) 30%,transparent);background:var(--danger-wash)}
.mdp .photo{position:relative;border-radius:var(--r);overflow:hidden;background:var(--sunken) center/cover no-repeat;
  border:1px solid var(--line);display:block}
.mdp .ph-lift{background-image:var(--im-lift),linear-gradient(150deg,#3a3d42,#69707a 50%,#232629)}
.mdp .ph-engine{background-image:var(--im-engine),linear-gradient(150deg,#2d3a44,#546a78 50%,#1e262c)}
.mdp .ph-engine2{background-image:var(--im-engine2),linear-gradient(150deg,#37424a,#5d7181 50%,#212a30)}
.mdp .ph-mech{background-image:var(--im-mech),linear-gradient(150deg,#4a4540,#6b625a 45%,#2f2b28)}
.mdp .ph-oil{background-image:var(--im-oil),linear-gradient(150deg,#3f3a33,#6e6455 48%,#282420)}
.mdp .ph-suv{background-image:var(--im-suv),linear-gradient(150deg,#3d4a52,#7d8b91 52%,#262d31)}
.mdp .ph-garage{background-image:var(--im-garage),linear-gradient(150deg,#57514a,#8a7f72 48%,#33302c)}
.mdp .ph-red{background-image:var(--im-red),linear-gradient(150deg,#7a3f2c,#b06a43 50%,#43241a)}
.mdp .ph-shop{background-image:var(--im-shop),linear-gradient(150deg,#4c4740,#736a5e 46%,#2c2925)}
.mdp .ph-white{background-image:var(--im-white),linear-gradient(150deg,#6f6f6c,#a3a29d 50%,#43423f)}
.mdp .ph-black{background-image:var(--im-black),linear-gradient(150deg,#1f2530,#3d4759 55%,#12151c)}
.mdp .ph-silver{background-image:var(--im-silver),linear-gradient(150deg,#5a5f63,#93999d 50%,#34383a)}
.mdp .ph-speedo{background-image:var(--im-speedo),linear-gradient(150deg,#4b423c,#7c6d61 50%,#2c2724)}
.mdp .ph-tach{background-image:var(--im-tach),linear-gradient(150deg,#33383f,#606a76 50%,#20242a)}
.mdp .ph-honda{background-image:var(--im-honda),linear-gradient(150deg,#6a5540,#9b8058 50%,#3f3327)}
.mdp .photo .tl{position:absolute;top:9px;left:9px;z-index:2;display:flex;gap:5px}
.mdp .photo .pill{background:rgba(18,17,15,.62);border-color:rgba(255,255,255,.18);color:#fff;backdrop-filter:blur(6px)}
.mdp .cap{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:22px 12px 10px;font-size:12px;color:#fff;
  background:linear-gradient(transparent,rgba(12,11,10,.78))}
.mdp .crumbs{display:flex;align-items:center;gap:7px;padding:16px 0 0;font-size:12.5px;color:var(--ink-3);flex-wrap:wrap}
.mdp .crumbs a:hover{color:var(--ink)}
.mdp .crumbs em{font-style:normal;color:var(--line-strong)}
.mdp .seg{display:flex;border:1px solid var(--line);border-radius:7px;overflow:hidden;background:var(--panel)}
.mdp .seg button{padding:3px 9px;font-size:11px;color:var(--ink-3);border-right:1px solid var(--line)}
.mdp .seg button:last-child{border-right:none}
.mdp .seg button.on{background:var(--sunken);color:var(--ink)}
.mdp .cover{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:8px;margin-top:16px;height:340px;position:relative}
.mdp .cover .main{height:100%}
.mdp .cover .side{display:grid;grid-template-rows:1fr 1fr;gap:8px}
.mdp .cover .side .r2{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.mdp .beforeafter{position:absolute;left:11px;bottom:11px;z-index:3;display:flex;gap:5px}
.mdp .allbtn{position:absolute;right:11px;bottom:11px;z-index:3;height:29px;padding:0 12px;border-radius:7px;
  background:rgba(18,17,15,.7);color:#fff;font-size:12px;font-weight:500;border:1px solid rgba(255,255,255,.2);
  backdrop-filter:blur(6px)}
.mdp .title{display:flex;gap:28px;align-items:flex-end;padding:20px 0 16px}
.mdp .title h1{font-size:clamp(22px,2.4vw,31px);margin:9px 0 7px;max-width:30ch;text-wrap:balance}
.mdp .title .by{display:flex;align-items:center;gap:8px;font-size:13.5px;color:var(--ink-2);flex-wrap:wrap}
.mdp .title .by-user{display:inline-flex;align-items:center;gap:8px;text-decoration:none;color:var(--ink);border-radius:999px}
.mdp .title .by-user b{color:var(--ink);font-weight:600}
.mdp .title .by-user .mono{color:var(--accent-ink)}
.mdp .title .by-user:hover b{color:var(--accent-ink)}
.mdp .title .acts{margin-left:auto;display:flex;gap:8px;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end}
.mdp .specbar{display:grid;grid-template-columns:repeat(6,1fr);border:1px solid var(--line);border-radius:var(--r);
  background:var(--panel);overflow:hidden;box-shadow:var(--shadow)}
.mdp .sp{padding:13px 16px;border-right:1px solid var(--line)}
.mdp .sp:last-child{border-right:none}
.mdp .sp b{display:block;font-size:16px;font-weight:600;letter-spacing:-.02em}
.mdp .sp b small{font-weight:400;font-size:12px;color:var(--ink-3);letter-spacing:0}
.mdp .sp span{display:block;font-family:"JetBrains Mono",monospace;font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3);margin-top:4px}
.mdp button.sp{font:inherit;text-align:left;background:none;border:none;border-right:1px solid var(--line);cursor:pointer}
.mdp button.sp.sp-add b{color:var(--accent-ink)}
.mdp button.sp.sp-add:hover{background:var(--sunken)}
.mdp .dots{display:inline-flex;gap:3px;vertical-align:2px;margin-left:6px}
.mdp .dots i{width:5px;height:5px;border-radius:50%;background:var(--line-strong);display:block}
.mdp .dots i.f{background:var(--accent)}
.mdp .social{display:flex;align-items:center;gap:8px;margin-top:12px;flex-wrap:wrap}
.mdp .social .sep{width:1px;height:20px;background:var(--line);margin:0 4px}
.mdp .notice{display:flex;align-items:center;gap:12px;margin-top:12px;padding:11px 15px;border-radius:var(--r);
  border:1px solid var(--accent-line);background:var(--accent-wash);font-size:13.5px}
.mdp .notice .btn{margin-left:auto}
.mdp .notice.warnbox{border-color:color-mix(in srgb,var(--warn) 35%,transparent);background:var(--warn-wash)}
.mdp .notice.dangerbox{border-color:color-mix(in srgb,var(--danger) 35%,transparent);background:var(--danger-wash)}
.mdp .tabrail{position:sticky;top:58px;z-index:50;background:color-mix(in srgb,var(--bg) 92%,transparent);
  backdrop-filter:blur(10px);border-bottom:1px solid var(--line);margin-top:18px}
.mdp .tabrail .inner{max-width:var(--col);margin:0 auto;padding:0 var(--pad);display:flex;align-items:center;gap:2px;
  overflow-x:auto;scrollbar-width:none}
.mdp .tabrail .inner::-webkit-scrollbar{display:none}
.mdp .tab{padding:12px 13px;font-size:13.5px;font-weight:500;color:var(--ink-2);border-bottom:2px solid transparent;
  white-space:nowrap;margin-bottom:-1px}
.mdp .tab:hover{color:var(--ink)}
.mdp .tab.on{color:var(--ink);border-bottom-color:var(--accent);font-weight:600}
.mdp .tab u{text-decoration:none;color:var(--ink-3);font-family:"JetBrains Mono",monospace;font-size:11px;margin-left:5px}
.mdp .tab.on u{color:var(--accent-ink)}
.mdp .cols{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:30px;padding:26px 0 90px;align-items:start}
.mdp .panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow)}
.mdp .phead{display:flex;align-items:center;gap:10px;padding:13px 16px;border-bottom:1px solid var(--line)}
.mdp .phead h3{font-size:13.5px}
.mdp .phead .more{margin-left:auto;font-size:12px;color:var(--ink-3)}
.mdp .phead .more:hover{color:var(--accent-ink)}
.mdp .rail{display:flex;flex-direction:column;gap:16px;position:sticky;top:112px}
.mdp .pane{display:none}
.mdp .pane.on{display:block}
.mdp .pbody{padding:18px 20px}
.mdp .prose{max-width:70ch;font-size:15px}
.mdp .prose h3{font-size:16px;margin:22px 0 8px}
.mdp .prose h3:first-child{margin-top:0}
.mdp .prose p{margin-bottom:12px;color:var(--ink-2)}
.mdp .prose ul{margin:0 0 12px;padding-left:20px;color:var(--ink-2)}
.mdp .prose li{margin-bottom:5px}
.mdp .prose strong{color:var(--ink);font-weight:600}
.mdp .inlinefig{margin:16px 0}
.mdp .inlinefig .photo{height:280px}
.mdp .toolbox{display:flex;flex-wrap:wrap;gap:6px;padding:14px 16px;border-bottom:1px solid var(--line)}
.mdp .step{display:flex;gap:16px;padding:18px 20px;border-bottom:1px solid var(--line);position:relative}
.mdp .step:last-child{border-bottom:none}
.mdp .step .num{width:26px;height:26px;border-radius:8px;background:var(--sunken);border:1px solid var(--line);
  display:flex;align-items:center;justify-content:center;font-family:"JetBrains Mono",monospace;font-size:11px;
  color:var(--ink-2);flex-shrink:0;margin-top:2px}
.mdp .step .c{min-width:0;flex:1}
.mdp .step h4{font-size:15px;margin-bottom:5px}
.mdp .step p{font-size:14px;color:var(--ink-2)}
.mdp .step .meta{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.mdp .torque{font-family:"JetBrains Mono",monospace;font-size:11.5px;color:var(--ink);background:var(--sunken);
  border:1px solid var(--line);border-radius:6px;padding:2px 8px}
.mdp .stepshots{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-top:11px}
.mdp .stepshots .photo{height:96px}
.mdp .anchor{display:flex;align-items:flex-start;gap:9px;margin-top:11px;padding:10px 12px;border-radius:8px;
  background:var(--ok-wash);border:1px solid color-mix(in srgb,var(--ok) 25%,transparent);font-size:13px}
.mdp .anchor .lbl{font-size:10.5px;font-family:"JetBrains Mono",monospace;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ok);display:block;margin-bottom:3px}
.mdp .warnstep{display:flex;align-items:flex-start;gap:9px;margin-top:11px;padding:10px 12px;border-radius:8px;
  background:var(--warn-wash);border:1px solid color-mix(in srgb,var(--warn) 25%,transparent);font-size:13px;color:var(--warn)}
/* It ends at --floor, not at the window. z-200 clears the tab bar but not the
   operator's #adminbar (z-1900), so at inset:0 the .bot — which is where Next
   and Done are, the only way THROUGH a guided step — finished underneath it.
   --floor carries the home indicator too, so .bot pads no more for it. */
.mdp .cook{position:fixed;inset:0 0 var(--floor-modal,0px) 0;z-index:200;background:var(--bg);display:none;flex-direction:column}
.mdp .cook.on{display:flex}
.mdp .cook .top{display:flex;align-items:center;gap:14px;padding:16px 24px;border-bottom:1px solid var(--line)}
.mdp .cook .prog{flex:1;height:4px;border-radius:2px;background:var(--line);overflow:hidden}
.mdp .cook .prog i{display:block;height:100%;background:var(--accent);transition:width .2s}
.mdp .cook .mid{flex:1;overflow:auto;padding:40px 24px;display:flex;justify-content:center}
.mdp .cook .inner{max-width:620px;width:100%}
.mdp .cook .inner h2{font-size:26px;margin:12px 0}
.mdp .cook .inner p{font-size:16px;color:var(--ink-2);margin-bottom:16px}
.mdp .cook .inner .photo{height:260px;margin-bottom:16px}
.mdp .cook .bot{display:flex;align-items:center;gap:10px;padding:16px 24px;border-top:1px solid var(--line)}
.mdp .tbl{width:100%;border-collapse:collapse}
.mdp .tbl th{text-align:left;font-family:"JetBrains Mono",monospace;font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:10px 14px;border-bottom:1px solid var(--line);
  background:var(--sunken)}
.mdp .tbl td{padding:11px 14px;border-bottom:1px solid var(--line);font-size:13.5px;vertical-align:top}
.mdp .tbl tr:last-child td{border-bottom:none}
.mdp .tbl .num{font-family:"JetBrains Mono",monospace;font-size:13px;white-space:nowrap;text-align:right}
.mdp .tbl .grp td{background:var(--sunken);font-family:"JetBrains Mono",monospace;font-size:10.5px;letter-spacing:.11em;
  text-transform:uppercase;color:var(--ink-3);padding:8px 14px}
.mdp .tbl .alt td:first-child{padding-left:34px;position:relative}
.mdp .tbl .alt td:first-child::before{content:"↳";position:absolute;left:18px;color:var(--ink-3)}
.mdp .tbl .sub td{font-weight:600;background:var(--sunken)}
.mdp .tbl .total td{font-size:15px;font-weight:600;background:var(--sunken);border-top:2px solid var(--line-strong)}
.mdp .pn{font-family:"JetBrains Mono",monospace;font-size:11px;color:var(--ink-3);display:block}
.mdp .chk{width:15px;height:15px;border-radius:4px;border:1.5px solid var(--line-strong);display:inline-block;
  vertical-align:-2px;cursor:pointer}
.mdp .chk.on{background:var(--ok);border-color:var(--ok);position:relative}
.mdp .chk.on::after{content:"✓";position:absolute;inset:0;color:#fff;font-size:10px;display:flex;align-items:center;justify-content:center}
.mdp .stale{font-size:10.5px;color:var(--warn)}
.mdp .pgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
.mdp .pgrid .photo{height:320px;border-radius:0}
.mdp .pgrid .photo.lb{cursor:zoom-in;transition:filter .12s var(--ease,ease)}
.mdp .pgrid .photo.lb:hover{filter:brightness(1.04)}
.mdp .stepshots .photo.lb{cursor:zoom-in}
@media(max-width:640px){.mdp .pgrid{grid-template-columns:1fr}.mdp .pgrid .photo{height:260px}}
.mdp .shelf{margin-top:26px;padding-top:20px;border-top:1px solid var(--line)}
.mdp .stages{position:relative;padding-left:26px}
.mdp .stages::before{content:"";position:absolute;left:6px;top:8px;bottom:8px;width:1px;background:var(--line)}
.mdp .stage{position:relative;margin-bottom:16px}
.mdp .stage::before{content:"";position:absolute;left:-23px;top:16px;width:9px;height:9px;border-radius:50%;
  background:var(--accent);border:2px solid var(--bg)}
.mdp .stage .hd{display:flex;align-items:baseline;gap:10px;margin-bottom:4px}
.mdp .stage .odo{font-family:"JetBrains Mono",monospace;font-size:11.5px;color:var(--ink-3);margin-left:auto}
.mdp .progwrap{display:flex;align-items:center;gap:12px;padding:13px 16px;border-bottom:1px solid var(--line)}
.mdp .progwrap .bar{flex:1;height:5px;border-radius:3px;background:var(--line);overflow:hidden}
.mdp .progwrap .bar i{display:block;height:100%;background:var(--accent)}
.mdp .cmt{display:flex;gap:11px;padding:15px 18px;border-bottom:1px solid var(--line)}
.mdp .cmt:last-child{border-bottom:none}
.mdp .cmt .c{flex:1;min-width:0}
.mdp .cmt .hd{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--ink-3);margin-bottom:4px;flex-wrap:wrap}
.mdp .cmt .hd b{color:var(--ink);font-size:13.5px}
.mdp .cmt p{font-size:14px;color:var(--ink-2)}
.mdp .cmt .acts{display:flex;gap:12px;margin-top:8px;font-size:12.5px;color:var(--ink-3)}
.mdp .cmt .acts button:hover{color:var(--accent-ink)}
.mdp .reply{margin-left:31px;border-left:2px solid var(--line);padding-left:14px}
.mdp .anchortag{display:inline-flex;align-items:center;gap:5px;height:21px;padding:0 8px;border-radius:6px;
  background:var(--sunken);border:1px solid var(--line);font-size:11px;color:var(--ink-2);font-family:"JetBrains Mono",monospace}
.mdp .fork{display:flex;gap:13px;padding:14px 18px;border-bottom:1px solid var(--line)}
.mdp .fork:last-child{border-bottom:none}
.mdp .fork .photo{width:88px;height:62px;flex-shrink:0}
.mdp .fork .c{flex:1;min-width:0}
.mdp .fork h4{font-size:14px;margin-bottom:3px}
.mdp .fork .chg{font-size:12.5px;color:var(--ink-2);margin-top:5px}
.mdp .fork .m{display:flex;align-items:center;gap:12px;margin-top:7px;font-size:12px;color:var(--ink-3);flex-wrap:wrap}
.mdp .lineage{display:flex;align-items:center;gap:8px;padding:12px 16px;font-size:13px;background:var(--sunken)}
.mdp .proposal{padding:14px 18px;border-bottom:1px solid var(--line)}
.mdp .diff{margin-top:9px;border:1px solid var(--line);border-radius:8px;overflow:hidden;
  font-family:"JetBrains Mono",monospace;font-size:12px}
.mdp .diff div{padding:6px 11px}
.mdp .diff .del{background:var(--danger-wash);color:var(--danger)}
.mdp .diff .add{background:var(--ok-wash);color:var(--ok)}
.mdp .diff .ctx{color:var(--ink-3)}
.mdp .fit{display:flex;align-items:center;gap:12px;padding:13px 18px;border-bottom:1px solid var(--line)}
.mdp .fit:last-child{border-bottom:none}
.mdp .fit .photo{width:52px;height:38px;flex-shrink:0}
.mdp .fit .c{flex:1;min-width:0}
.mdp .fit b{font-size:13.5px;display:block}
.mdp .fit span{font-size:12px;color:var(--ink-3)}
.mdp .person{display:flex;align-items:center;gap:10px;padding:11px 16px;border-bottom:1px solid var(--line)}
.mdp .person:last-child{border-bottom:none}
.mdp .person .c{flex:1;min-width:0}
.mdp .person b{font-size:13px;display:block}
.mdp .person span{font-size:11.5px;color:var(--ink-3)}
.mdp .person .cnt{font-family:"JetBrains Mono",monospace;font-size:11px;color:var(--ink-3);flex-shrink:0}
.mdp .relmod{display:flex;gap:10px;padding:10px 16px;border-bottom:1px solid var(--line)}
.mdp .relmod:last-child{border-bottom:none}
.mdp .relmod:hover{background:var(--sunken)}
.mdp .relmod .photo{width:52px;height:38px;flex-shrink:0}
.mdp .relmod b{font-size:12.5px;font-weight:500;display:block}
.mdp .relmod span{font-size:11.5px;color:var(--ink-3)}
.mdp .vehcard{padding:12px 16px;display:block}
.mdp .vehcard .photo{height:96px;margin-bottom:10px}
.mdp .vehcard b{font-size:13.5px;display:block}
.mdp .vehcard span{font-size:12px;color:var(--ink-3)}
.mdp .r-owner, .mdp .r-canedit{display:flex}
.mdp .r-editor, .mdp .r-contrib, .mdp .r-visitor, .mdp .r-forker, .mdp .r-noedit, .mdp .forkbanner{display:none !important}
.mdp .editbar{position:fixed;left:0;right:0;bottom:var(--floor,0px);z-index:120;display:none;align-items:center;gap:12px;
  padding:12px 28px;background:var(--ink);color:var(--bg);box-shadow:0 -6px 24px rgba(0,0,0,.18)}
.mdp[data-edit="on"] .editbar{display:flex}
.mdp .editbar .btn{background:transparent;border-color:rgba(255,255,255,.28);color:var(--bg)}
.mdp .editbar .btn:hover{background:rgba(255,255,255,.12)}
.mdp .editbar .btn-primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
.mdp .savedot{width:6px;height:6px;border-radius:50%;background:var(--ok);display:inline-block}
.mdp .editable{position:relative}
.mdp[data-edit="on"] .editable{outline:1px dashed var(--accent-line);outline-offset:6px;border-radius:4px}
.mdp[data-edit="on"] .editable:hover{outline-color:var(--accent);background:var(--accent-wash)}
.mdp .edittag{display:none;position:absolute;top:-11px;right:-6px;z-index:5;height:21px;padding:0 8px;border-radius:6px;
  background:var(--accent);color:var(--accent-ink);font-size:10.5px;font-weight:600;align-items:center;gap:4px}
.mdp[data-edit="on"] .edittag{display:inline-flex}
.mdp .addrow{display:none;align-items:center;justify-content:center;gap:7px;padding:12px;margin-top:10px;
  border:1px dashed var(--line-strong);border-radius:var(--r);color:var(--ink-3);font-size:13px;width:100%}
.mdp .addrow:hover{border-color:var(--accent);color:var(--accent-ink);background:var(--accent-wash)}
.mdp[data-edit="on"] .addrow{display:flex}
.mdp .draghandle{display:none;color:var(--ink-3);cursor:grab;font-size:14px;flex-shrink:0;padding-top:3px}
.mdp[data-edit="on"] .draghandle{display:block}
@media(max-width:1100px){
.mdp .cols{grid-template-columns:1fr}
.mdp .rail{position:static;display:grid;grid-template-columns:1fr 1fr;gap:16px}
}
@media(max-width:860px){
.mdp .navlinks, .mdp .search{display:none}
.mdp .cover{grid-template-columns:1fr;height:auto}
.mdp .cover .main{height:230px}
.mdp .cover .side{height:150px}
.mdp .specbar{grid-template-columns:1fr 1fr 1fr}
.mdp .sp{border-bottom:1px solid var(--line)}
.mdp .sp:nth-child(3n){border-right:none}
.mdp .title{flex-direction:column;align-items:flex-start;gap:14px}
.mdp .title .acts{margin-left:0;width:100%;justify-content:flex-start}
.mdp .title h1{font-size:24px}
.mdp .pgrid, .mdp .stepshots, .mdp .grid2, .mdp .grid3, .mdp .rail{grid-template-columns:1fr}
.mdp .editbar{padding:12px var(--pad);flex-wrap:wrap}
}
@media(max-width:600px){
.mdp .specbar{grid-template-columns:1fr 1fr}
.mdp .sp:nth-child(3n){border-right:1px solid var(--line)}
.mdp .sp:nth-child(2n){border-right:none}
.mdp .pgrid{grid-template-columns:1fr}
}
@media(prefers-reduced-motion:reduce){
.mdp *{animation:none !important;transition:none !important}
}
.mdp #page{transition:margin-right .24s ease}
.mdp.flyopen #page{margin-right:var(--flyw,460px)}
/* IT ENDS AT --floor-modal, NOT --floor. Its scrim covers the phone's tab
   bar, so leaving room for that bar holds a band of unusable navigation
   open under the sheet — 90px of scrimmed page on an operator's phone.
   What a scrim cannot cover is #adminbar (z-1900) and the home
   indicator, and --floor-modal is exactly those two (§6). */
.mdp .fly{position:fixed;right:0;top:0;bottom:var(--floor-modal,0px);z-index:130;width:var(--flyw,460px);
  display:flex;flex-direction:column;background:var(--panel);border-left:1px solid var(--line);
  box-shadow:-12px 0 34px rgba(20,18,15,.10);transform:translateX(100%);
  transition:transform .24s ease;visibility:hidden}
.mdp .fly.on{transform:none;visibility:visible}
body.dark .mdp .fly{box-shadow:-12px 0 34px rgba(0,0,0,.5)}
.mdp.flyopen.flywide #page{margin-right:var(--flyw2,620px)}
.mdp .fly.wide{width:var(--flyw2,620px)}
.mdp .mh{display:flex;align-items:flex-start;gap:12px;padding:16px 20px;border-bottom:1px solid var(--line);flex-shrink:0}
.mdp .mh h3{font-size:16px}
.mdp .mh .sub{font-size:12.5px;color:var(--ink-3);display:block;margin-top:2px;font-weight:400}
.mdp .mh .x{margin-left:auto;width:30px;height:30px;border-radius:8px;display:flex;align-items:center;
  justify-content:center;color:var(--ink-3);flex-shrink:0}
.mdp .mh .x:hover{background:var(--sunken);color:var(--ink)}
.mdp .mh .back{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;
  color:var(--ink-3);flex-shrink:0;margin:-4px 0 0 -6px}
.mdp .mh .back:hover{background:var(--sunken);color:var(--ink)}
.mdp .mb{overflow:auto;padding:20px;flex:1}
.mdp .mf{display:flex;align-items:center;gap:8px;padding:14px 20px;border-top:1px solid var(--line);
  background:var(--sunken);flex-shrink:0;flex-wrap:wrap}
.mdp .mf .right{margin-left:auto;display:flex;gap:8px}
.mdp .flyscrim{position:fixed;inset:0;background:rgba(12,11,10,.4);z-index:125;display:none}
.mdp .field{margin-bottom:16px}
.mdp .field:last-child{margin-bottom:0}
.mdp .lbl{display:block;font-size:12.5px;font-weight:600;margin-bottom:5px}
.mdp .lbl .opt-note{font-weight:400;color:var(--ink-3)}
.mdp .hint{font-size:12px;color:var(--ink-3);margin-top:5px;line-height:1.5}
.mdp .inp, .mdp select.inp, .mdp textarea.inp{width:100%;height:38px;padding:0 12px;border-radius:8px;border:1px solid var(--line);
  background:var(--panel);color:var(--ink);font-family:inherit;font-size:13.5px}
.mdp textarea.inp{height:auto;min-height:84px;padding:10px 12px;line-height:1.6;resize:vertical}
.mdp select.inp{cursor:pointer}
.mdp .inp:focus{outline:none;border-color:var(--accent-line);box-shadow:0 0 0 3px var(--accent-wash)}
.mdp .inp::placeholder{color:var(--ink-3)}
.mdp .grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.mdp .grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}
.mdp .opt{display:flex;gap:11px;padding:12px 13px;border:1px solid var(--line);border-radius:9px;margin-bottom:8px;
  cursor:pointer;align-items:flex-start;background:var(--panel)}
.mdp .opt:hover{border-color:var(--line-strong)}
.mdp .opt.on{border-color:var(--accent);background:var(--accent-wash)}
.mdp .opt .mark{width:16px;height:16px;border-radius:50%;border:1.5px solid var(--line-strong);flex-shrink:0;margin-top:2px}
.mdp .opt.on .mark{border-color:var(--accent);border-width:5px}
.mdp .opt.sq .mark{border-radius:5px}
.mdp .opt.sq.on .mark{border-width:1.5px;background:var(--accent);position:relative}
.mdp .opt.sq.on .mark::after{content:"✓";position:absolute;inset:0;color:#fff;font-size:11px;display:flex;
  align-items:center;justify-content:center}
.mdp .opt b{font-size:13.5px;display:block}
.mdp .opt span{font-size:12.5px;color:var(--ink-2);display:block;margin-top:2px}
.mdp .opt[data-disabled]{opacity:.55;pointer-events:none}
.mdp .switch{width:38px;height:22px;border-radius:999px;background:var(--line-strong);position:relative;flex-shrink:0;
  transition:background .15s;cursor:pointer}
.mdp .switch::after{content:"";position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:50%;
  background:#fff;transition:left .15s}
.mdp .switch.on{background:var(--ok)}
.mdp .switch.on::after{left:19px}
.mdp .togrow{display:flex;align-items:center;gap:14px;padding:13px 0;border-bottom:1px solid var(--line)}
.mdp .togrow:last-child{border-bottom:none}
.mdp .togrow .c{flex:1;min-width:0}
.mdp .togrow b{font-size:13.5px;display:block}
.mdp .togrow span{font-size:12.5px;color:var(--ink-3)}
.mdp .callout{padding:12px 14px;border-radius:9px;background:var(--sunken);border:1px solid var(--line);
  font-size:13px;color:var(--ink-2);margin-bottom:16px}
.mdp .callout.warnbox{background:var(--warn-wash);border-color:color-mix(in srgb,var(--warn) 30%,transparent);color:var(--warn)}
.mdp .callout.dangerbox{background:var(--danger-wash);border-color:color-mix(in srgb,var(--danger) 30%,transparent);color:var(--danger)}
.mdp .callout.okbox{background:var(--ok-wash);border-color:color-mix(in srgb,var(--ok) 30%,transparent);color:var(--ok)}
.mdp .dropzone{border:1px dashed var(--line-strong);border-radius:10px;padding:26px;text-align:center;
  color:var(--ink-3);font-size:13px;background:var(--sunken);cursor:pointer}
.mdp .dropzone:hover{border-color:var(--accent);color:var(--accent-ink)}
.mdp .permtable{width:100%;border-collapse:collapse;font-size:12.5px;margin-top:10px}
.mdp .permtable th{text-align:left;font-family:"JetBrains Mono",monospace;font-size:9.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3);font-weight:400;padding:7px 10px;border-bottom:1px solid var(--line)}
.mdp .permtable td{padding:7px 10px;border-bottom:1px solid var(--line)}
.mdp .permtable td:not(:first-child){text-align:center}
.mdp .yes{color:var(--ok);font-weight:600}
.mdp .no{color:var(--ink-3)}
.mdp .stepper{display:flex;gap:6px;padding:0 20px 14px}
.mdp .stepper i{flex:1;height:3px;border-radius:2px;background:var(--line);display:block}
.mdp .stepper i.on{background:var(--accent)}
.mdp .stepper i.done{background:var(--accent-line)}
.mdp .wstep{display:none}
.mdp .wstep.on{display:block}
.mdp .hgroup .eyebrow{display:block;margin:18px 0 8px}
.mdp .hgroup:first-child .eyebrow{margin-top:0}
.mdp .diff{margin-top:9px;border:1px solid var(--line);border-radius:8px;overflow:hidden;
  font-family:"JetBrains Mono",monospace;font-size:12px}
.mdp .diff div{padding:6px 11px}
.mdp .diff .del{background:var(--danger-wash);color:var(--danger)}
.mdp .diff .add{background:var(--ok-wash);color:var(--ok)}
.mdp .diff .ctx{color:var(--ink-3)}
.mdp .rev{display:flex;gap:12px;padding:12px 0;border-bottom:1px solid var(--line);font-size:13px}
.mdp .rev:last-child{border-bottom:none}
.mdp .rev .when{font-family:"JetBrains Mono",monospace;font-size:11.5px;color:var(--ink-3);width:88px;flex-shrink:0}
.mdp .rev .c{flex:1}
.mdp .toast{position:fixed;left:50%;bottom:calc(28px + var(--floor,0px));transform:translateX(-50%) translateY(20px);z-index:250;
  background:var(--ink);color:var(--bg);padding:11px 18px;border-radius:10px;font-size:13.5px;
  box-shadow:var(--pop-shadow);opacity:0;transition:opacity .2s,transform .2s;pointer-events:none;
  display:flex;align-items:center;gap:9px}
.mdp .toast.on{opacity:1;transform:translateX(-50%) translateY(0)}
@media(max-width:1200px){
.mdp.flyopen #page, .mdp.flyopen.flywide #page{margin-right:0}
.mdp .flyscrim.on{display:block}
.mdp .fly{box-shadow:-16px 0 44px rgba(20,18,15,.22)}
}
@media(max-width:620px){
.mdp .fly, .mdp .fly.wide{width:100vw}
.mdp .grid2, .mdp .grid3{grid-template-columns:1fr}
}
.mdp{-webkit-text-size-adjust:100%}
.mdp{overflow-x:hidden;overscroll-behavior-y:none}
.mdp img, .mdp svg, .mdp video{max-width:100%;height:auto}
.mdp button, .mdp a{-webkit-tap-highlight-color:rgba(240,90,36,.14)}
.mdp .wrap, .mdp .topbar .inner, .mdp .tabrail .inner{width:100%}
.mdp .tabrail .inner{scroll-padding:0 20px}
.mdp .pane, .mdp .panel{scroll-margin-top:120px}
.mdp .pn, .mdp .mono, .mdp .inp{overflow-wrap:anywhere}
@media(min-width:1600px){
.mdp .cols{grid-template-columns:minmax(0,1fr) 372px;gap:36px}
.mdp .cover{height:400px}
.mdp .mosaic{grid-template-rows:repeat(2,150px)}
.mdp .modgrid{grid-template-columns:repeat(3,1fr);gap:16px}
.mdp .gargrid{grid-template-columns:repeat(4,1fr);gap:16px}
.mdp{--flyw:520px;--flyw2:720px}
.mdp .fc .media{height:250px}
}
@media(min-width:1900px){
.mdp .gargrid{grid-template-columns:repeat(5,1fr)}
.mdp .pgrid{grid-template-columns:repeat(4,1fr)}
}
@media(max-width:1200px){
.mdp.flyopen #page, .mdp.flyopen.flywide #page{margin-right:0}
.mdp .flyscrim.on{display:block}
.mdp.flyopen{overflow:hidden}
.mdp .fly{width:min(520px,92vw)}
.mdp .fly.wide{width:min(640px,96vw)}
}
@media(max-width:1100px){
.mdp .cols{grid-template-columns:1fr;gap:22px}
.mdp .rail{position:static;display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:start}
}
@media(max-width:1023px){
.mdp .search{flex:0 1 200px}
.mdp .navlinks a{padding:6px 9px;font-size:13px}
.mdp .modgrid{grid-template-columns:1fr 1fr}
.mdp .gargrid{grid-template-columns:repeat(3,1fr)}
.mdp .signals{grid-template-columns:repeat(3,1fr)}
.mdp .signals .sig:nth-child(-n+3){border-bottom:1px solid var(--line)}
.mdp .signals .sig:nth-child(3n){border-right:none}
.mdp .specbar{grid-template-columns:repeat(3,1fr)}
.mdp .specbar .sp:nth-child(-n+3){border-bottom:1px solid var(--line)}
.mdp .specbar .sp:nth-child(3n){border-right:none}
}
@media(max-width:767px){
.mdp{font-size:15px;padding-bottom:58px}   /* the .mobnav's own height, and
   nothing more: it stands on --floor, body{padding-bottom:var(--floor)}
   already cleared that, and --floor carries the home indicator (§6). */
.mdp .topbar .inner{height:52px;gap:12px}
.mdp .navlinks{display:none}
.mdp .search{display:none}
.mdp.searching .search{display:flex;position:absolute;left:var(--pad);right:var(--pad);top:52px;
    background:var(--panel);padding:8px 0;flex:1 1 auto;z-index:5}
.mdp.searching .search input{height:40px;font-size:16px}
.mdp .searchbtn{display:flex !important;align-items:center;justify-content:center;
    width:34px;height:34px;border-radius:8px;color:var(--ink-2);margin-left:auto}
.mdp .searchbtn:hover{background:var(--sunken)}
.mdp .topbar .btn.btn-sm{height:34px;padding:0 11px}
.mdp .tabrail{top:52px}
.mdp .tab{padding:12px 11px;font-size:13px}
.mdp .tabrail .inner{-webkit-overflow-scrolling:touch}
.mdp .tabrail::after{content:"";position:absolute;right:0;top:0;bottom:0;width:26px;pointer-events:none;
    background:linear-gradient(90deg,transparent,var(--bg))}
.mdp .tabrail{position:sticky;overflow:visible}
.mdp .yearsel{padding-left:10px}
.mdp .mobnav{display:flex !important}
.mdp .ident h1, .mdp .title h1{font-size:22px;letter-spacing:-.02em}
.mdp .ident{flex-direction:column;align-items:stretch;gap:14px;padding:18px 0 16px}
.mdp .ident .acts{margin-left:0;display:grid;grid-template-columns:1fr 1fr;gap:8px}
.mdp .ident .acts .btn{justify-content:center;width:100%}
.mdp .title{flex-direction:column;align-items:stretch;gap:14px;padding:16px 0 14px}
.mdp .title .acts{margin-left:0;display:grid;grid-template-columns:1fr 1fr;gap:8px;justify-content:stretch}
.mdp .title .acts .btn{justify-content:center;width:100%}
.mdp .sectionhead{flex-direction:column;align-items:stretch;gap:12px}
.mdp .sectionhead .ctl{margin-left:0;overflow-x:auto;padding-bottom:2px;scrollbar-width:none}
.mdp .sectionhead .ctl::-webkit-scrollbar{display:none}
.mdp .mosaic{grid-template-columns:repeat(2,1fr);grid-template-rows:150px 84px;gap:6px}
.mdp .mosaic .photo:nth-child(n+4){display:none}
.mdp .cover{grid-template-columns:1fr;height:auto;gap:6px}
.mdp .cover .main{height:210px}
.mdp .cover .side{height:104px;grid-template-rows:1fr;grid-template-columns:1fr 1fr}
.mdp .cover .side .r2{display:contents}
.mdp .cover .side .r2 .photo:last-child{display:none}
.mdp .signals{grid-template-columns:1fr 1fr}
.mdp .signals .sig{border-right:1px solid var(--line);border-bottom:1px solid var(--line);padding:12px 14px}
.mdp .signals .sig:nth-child(2n){border-right:none}
.mdp .signals .sig b{font-size:19px}
.mdp .signals .sig b.txt{font-size:14px}
.mdp .specbar{grid-template-columns:1fr 1fr}
.mdp .specbar .sp{border-right:1px solid var(--line);border-bottom:1px solid var(--line);padding:11px 14px}
.mdp .specbar .sp:nth-child(2n){border-right:none}
.mdp .yours{flex-wrap:wrap;gap:10px}
.mdp .yours .acts{margin-left:0;width:100%;display:grid;grid-template-columns:1fr 1fr 1fr;gap:6px}
.mdp .yours .acts .btn{justify-content:center;padding:0 6px;font-size:11.5px}
.mdp .fc{padding:14px 15px}
.mdp .fc h4{font-size:15px}
.mdp .fc .media{height:190px}
.mdp .fc .media.grid3{height:100px;gap:4px}
.mdp .specrow{gap:14px;overflow-x:auto;scrollbar-width:none}
.mdp .specrow::-webkit-scrollbar{display:none}
.mdp .specrow div{flex-shrink:0}
.mdp .modgrid, .mdp .gargrid, .mdp .pgrid, .mdp .specgrid, .mdp .stepshots, .mdp .grid2, .mdp .grid3{grid-template-columns:1fr}
.mdp .rail{grid-template-columns:1fr}
.mdp .garagelist{grid-template-columns:1fr 1fr}
.mdp .chips{overflow-x:auto;flex-wrap:nowrap;scrollbar-width:none;padding-bottom:2px;
    margin-left:calc(var(--pad) * -1);margin-right:calc(var(--pad) * -1);padding-left:var(--pad);padding-right:var(--pad)}
.mdp .chips::-webkit-scrollbar{display:none}
.mdp .chip{flex-shrink:0;height:32px}
.mdp .composer{flex-wrap:wrap}
.mdp .composer .fake{min-width:0;flex:1 1 100%;order:1;height:40px}
.mdp .composer .quick{order:2;width:100%;display:grid;grid-template-columns:1fr 1fr 1fr;gap:6px}
.mdp .composer .quick .btn{justify-content:center}
.mdp .composer .av{display:none}
.mdp .step{padding:16px 15px;gap:12px}
.mdp .step .num{width:24px;height:24px}
.mdp .toolbox{padding:12px 15px}
.mdp .cook .mid{padding:24px 18px}
.mdp .cook .inner h2{font-size:21px}
.mdp .cook .inner .photo{height:190px}
.mdp .cook .top, .mdp .cook .bot{padding:12px 16px}
.mdp .cook .bot{padding-bottom:12px}
.mdp .cook .bot .muted{display:none}
.mdp .cook .bot .btn{flex:1;justify-content:center}
.mdp .tbl thead{display:none}
.mdp .tbl, .mdp .tbl tbody, .mdp .tbl tr, .mdp .tbl td{display:block;width:100%}
.mdp .tbl tr{border-bottom:1px solid var(--line);padding:11px 15px}
.mdp .tbl tr:last-child{border-bottom:none}
.mdp .tbl td{border:none;padding:3px 0;font-size:13.5px;display:flex;gap:12px;align-items:baseline}
.mdp .tbl td::before{content:attr(data-l);flex:0 0 40%;font-family:"JetBrains Mono",monospace;font-size:9.5px;
    letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3);padding-top:3px}
.mdp .tbl td:empty{display:none}
.mdp .tbl td[data-l=""]::before{display:none}
.mdp .tbl td.num{text-align:left;justify-content:flex-start}
.mdp .tbl td b, .mdp .tbl td .ttl{font-size:14px}
.mdp .tbl .pn{display:block;margin-top:2px}
.mdp .tbl .grp td, .mdp .tbl .sub td, .mdp .tbl .total td{display:block}
.mdp .tbl .grp td::before, .mdp .tbl .sub td::before, .mdp .tbl .total td::before{display:none}
.mdp .tbl .grp{padding:8px 15px;background:var(--sunken)}
.mdp .tbl .sub, .mdp .tbl .total{background:var(--sunken);display:flex;justify-content:space-between;gap:12px}
.mdp .tbl .alt td:first-child{padding-left:16px}
.mdp .tbl .alt td:first-child::before{left:0}
.mdp .tbl .bar{width:100%}
.mdp .itable tr:hover td{background:transparent}
.mdp .permtable td:not(:first-child){text-align:right}
.mdp .spectable td{padding:9px 14px;font-size:13px}
.mdp .spectable td:first-child{width:50%}
.mdp .cmt{padding:13px 15px;gap:9px}
.mdp .reply{margin-left:14px;padding-left:11px}
.mdp .fork{flex-direction:column;gap:10px}
.mdp .fork .photo{width:100%;height:140px}
.mdp .fit{padding:12px 15px}
.mdp .stages{padding-left:20px}
.mdp .stage::before{left:-18px}
.mdp .fly, .mdp .fly.wide{width:100vw;border-left:none}
.mdp .mh{padding:14px 16px;position:sticky;top:0;background:var(--panel);z-index:2}
.mdp .mb{padding:16px;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}
.mdp .mf{padding:12px 16px;flex-wrap:wrap;gap:8px}  /* .fly ends at --floor,
   which carries the indicator — padding for it here counted it twice */
.mdp .mf .right{width:100%;display:grid;grid-template-columns:1fr 1fr;gap:8px}
.mdp .mf .right .btn{justify-content:center;width:100%}
.mdp .mf .muted, .mdp .mf > .btn-sm.btn-ghost{width:100%;text-align:left}
.mdp .mh .x{width:38px;height:38px}
.mdp .inp, .mdp select.inp, .mdp textarea.inp, .mdp .search input{font-size:16px}
.mdp .inp, .mdp select.inp{height:44px}
.mdp .opt{padding:13px}
.mdp .switch{width:44px;height:26px}
.mdp .switch::after{width:20px;height:20px}
.mdp .switch.on::after{left:21px}
.mdp .chk{width:20px;height:20px}
.mdp .btn{height:40px}
.mdp .btn-sm{height:34px;padding:0 12px}
.mdp .pill{height:26px}
.mdp .editbar{padding:10px 16px;gap:8px}   /* NOT `bottom:0`. Save and Cancel
   are the only way out of edit mode, and at the window's own edge they sat
   behind the tab bar and the admin bar under it; the rule that positions
   this bar already says bottom:var(--floor), and this width has no reason
   to disagree with it. The indicator comes with --floor, so no pad for it. */
.mdp .editbar > span:nth-child(3){display:none}
.mdp .editbar > div{width:100%;display:grid;grid-template-columns:1fr 1fr;gap:8px}
.mdp .editbar > div .btn{justify-content:center;width:100%}
.mdp .editbar > div .btn:nth-child(2){display:none}
.mdp[data-edit="on"]{padding-bottom:140px}
.mdp .lightbox{padding:16px}
.mdp .lightbox .photo{height:52vh}
.mdp .lightbox .bar{flex-wrap:wrap;gap:9px}
.mdp .lightbox .bar .btn{flex:1;justify-content:center}
}
@media(max-width:480px){
.mdp .ident h1, .mdp .title h1{font-size:20px}
.mdp .ident .acts, .mdp .title .acts{grid-template-columns:1fr}
.mdp .garagelist{grid-template-columns:1fr}
.mdp .yours .acts{grid-template-columns:1fr 1fr}
.mdp .yours .acts .btn:nth-child(3){grid-column:span 2}
.mdp .signals .sig b{font-size:17px}
.mdp .mosaic{grid-template-rows:130px 72px}
.mdp .cover .main{height:180px}
.mdp .tbl td::before{flex-basis:44%}
.mdp .mf .right{grid-template-columns:1fr}
.mdp .wm{display:none}
}
/* Sits ON the floor rather than on the window's edge — --floor already
   includes the home indicator, so this no longer pads for it a second time. */
.mdp .mobnav{display:none;position:fixed;left:0;right:0;bottom:var(--floor,0px);z-index:90;
  background:color-mix(in srgb,var(--panel) 94%,transparent);backdrop-filter:blur(12px);
  border-top:1px solid var(--line)}
.mdp .mobnav a{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;
  height:58px;font-size:10px;font-weight:500;color:var(--ink-3);letter-spacing:.01em}
.mdp .mobnav a em{font-style:normal;font-size:17px;line-height:1}
.mdp .mobnav a.on{color:var(--accent)}
.mdp.flyopen .mobnav{display:none !important}
.mdp[data-edit="on"] .mobnav{display:none !important}
.mdp .searchbtn{display:none}
@media(max-width:900px) and (orientation:landscape) and (max-height:520px){
.mdp .topbar{position:static}
.mdp .tabrail{top:0}
.mdp .cover .main{height:170px}
.mdp .mosaic{grid-template-rows:110px 70px}
.mdp .cook .inner .photo{height:150px}
}
@media print{
.mdp .topbar, .mdp .tabrail, .mdp .mobnav, .mdp .editbar, .mdp .fly, .mdp .flyscrim, .mdp .rail, .mdp .social, .mdp .allbtn, .mdp .addrow, .mdp .toast{display:none !important}
.mdp #page{margin:0 !important}
.mdp{background:#fff;color:#000;font-size:11pt}
.mdp .panel{border:1px solid #ccc;box-shadow:none;break-inside:avoid}
.mdp .cols{grid-template-columns:1fr;padding:0}
.mdp .pane{display:block !important}
.mdp .step{break-inside:avoid}
.mdp .photo{border:1px solid #ddd}
.mdp a[href]::after{content:""}
}
@media(hover:none){
.mdp .mcard:hover, .mdp .vcard:hover{transform:none;box-shadow:var(--shadow)}
.mdp .rank:hover, .mdp .relmod:hover, .mdp .gcard:hover{background:transparent}
}
.mdp .cols{grid-template-columns:minmax(0,1fr) 320px}
.mdp .cols > *, .mdp .cols > * > *{min-width:0}
.mdp .feed, .mdp .fc, .mdp .fc > *, .mdp .pane, .mdp .panel, .mdp .rail, .mdp .rail > *, .mdp .wrap, .mdp #page{min-width:0}
.mdp .fc .hdr, .mdp .fc .body, .mdp .fc h4, .mdp .step .c, .mdp .cmt .c, .mdp .fork .c, .mdp .fit .c, .mdp .person .c, .mdp .rank .t, .mdp .relmod, .mdp .gcard, .mdp .vcard .body, .mdp .mcard .body{min-width:0}
.mdp .specrow, .mdp .chips, .mdp .tabrail .inner, .mdp .sectionhead .ctl{min-width:0}
.mdp .fc h4, .mdp .fc .body, .mdp .prose, .mdp .step h4, .mdp .step p, .mdp .cmt p, .mdp .fork h4, .mdp .fork .chg, .mdp .mcard h4, .mdp .vcard h4, .mdp .issue b, .mdp .issue .sym, .mdp .ttl, .mdp .sym, .mdp .opt b, .mdp .opt span, .mdp .togrow b, .mdp .togrow span, .mdp .mh h3, .mdp .mh .sub{overflow-wrap:anywhere;word-break:normal}
.mdp, .mdp{max-width:100%}
.mdp{overflow-x:clip}
@media(max-width:1100px){
.mdp .cols{grid-template-columns:minmax(0,1fr)}
}
@media(max-width:767px){
.mdp .wm{display:flex !important}
.mdp .wm i{font-size:10.5px}
.mdp .brand{gap:8px}
.mdp .topbar .inner{gap:8px}
.mdp .searchbtn, .mdp #theme{width:36px;height:36px;padding:0;border:none;background:transparent;
    display:flex !important;align-items:center;justify-content:center;border-radius:9px;
    font-size:15px;color:var(--ink-2)}
.mdp .searchbtn{margin-left:auto}
.mdp #theme{margin-left:0}
.mdp .topbar .av-sm{width:30px;height:30px;font-size:11px}
.mdp .topbar .btn.btn-sm[data-open="m-create"]{display:none}
}
@media(max-width:480px){
.mdp .wm{display:flex !important}
.mdp .wm i:last-child{display:none}
}
@media(max-width:767px){
.mdp .fc .hdr{flex-wrap:wrap;row-gap:4px}
.mdp .fc .hdr .kind{margin-left:auto;order:3}
.mdp .fc .foot{flex-wrap:wrap;row-gap:8px}
.mdp .fc .foot > span:last-child{margin-left:auto}
.mdp .specrow{margin-left:-15px;margin-right:-15px;padding-left:15px;padding-right:15px}
.mdp .specrow div{min-width:76px}
}
@media(max-width:767px){
.mdp .composer{flex-wrap:wrap;gap:8px;padding:12px}
.mdp .composer .fake{flex:1 1 100%;order:1;height:42px;font-size:14px}
.mdp .composer .quick{order:2;width:100%;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}
.mdp .composer .quick .btn{justify-content:center;width:100%;min-width:0;padding:0 4px}
}
@media(max-width:767px){
/* the rail scrolls; the extra room past the last tab is a scroll runway, so it
   sits on the gutter rather than replacing it */
.mdp .tabrail .inner{gap:0;padding-right:calc(var(--pad) + 12px)}
.mdp .tab{padding:11px 10px;font-size:13px}
.mdp .tab u{margin-left:4px;font-size:10.5px}
.mdp .yearsel .eyebrow{display:none}
}
.mdp .mobnav a svg{width:20px;height:20px;display:block}
.mdp .mobnav a{gap:3px;height:56px;font-size:10.5px}
.mdp .mobnav a.on svg{color:var(--accent)}
@media(max-width:767px){
.mdp .fly{top:0;height:100%;height:calc(100dvh - var(--floor-modal,0px))}
.mdp .mb{padding-bottom:24px}
.mdp .mh{border-bottom:1px solid var(--line);align-items:center}
.mdp .mh h3{font-size:15.5px;line-height:1.3}
}
@media(max-width:767px){
.mdp .crumbs{font-size:12px;row-gap:4px}
.mdp .social{gap:6px}
.mdp .social .sep{display:none}
.mdp .notice{flex-wrap:wrap;row-gap:9px;font-size:13px}
.mdp .notice .btn{margin-left:0;width:100%;justify-content:center}
.mdp .phead{flex-wrap:wrap;row-gap:8px}
.mdp .phead .more{margin-left:auto}
.mdp .catbar{margin:20px 0 11px}
.mdp .shelf{margin-top:20px}
.mdp .stepshots{grid-template-columns:1fr 1fr}
.mdp .toolbox{gap:5px}
.mdp .progwrap{flex-wrap:wrap;row-gap:9px}
.mdp .lineage{flex-wrap:wrap;row-gap:9px}
.mdp .lineage .btn{margin-left:0;width:100%;justify-content:center}
}
.mdp .photo{background-color:#3a3733;background-blend-mode:normal}
@media(max-width:767px){
.mdp .mosaic{grid-template-columns:1fr 1fr;grid-template-rows:186px 92px;gap:6px}
.mdp .mosaic .photo:first-child{grid-column:1 / -1;grid-row:1;height:auto}
.mdp .mosaic .photo:nth-child(2){grid-column:1;grid-row:2}
.mdp .mosaic .photo:nth-child(3){grid-column:2;grid-row:2}
.mdp .mosaic .photo:nth-child(n+4){display:none}
.mdp .mos-cred{display:none}
.mdp .allbtn{right:8px;bottom:8px;height:32px;font-size:12px}
.mdp .mosaic .photo:first-child .tl{top:8px;left:8px}
.mdp .ident .sub{font-size:11.5px;line-height:1.55;letter-spacing:-.01em}
.mdp .ident h1{margin:8px 0 5px}
.mdp .wm i:last-child{display:block !important}
.mdp .cover{grid-template-columns:1fr;grid-template-rows:auto auto;height:auto;gap:6px}
.mdp .cover .main{height:200px}
.mdp .cover .side{height:96px;display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr;gap:6px}
.mdp .cover .side .r2{display:contents}
.mdp .cover .side .r2 .photo:last-child{display:none}
.mdp .beforeafter{left:8px;bottom:8px}
}
@media(max-width:480px){
.mdp .wm i:last-child{display:block !important}
.mdp .mosaic{grid-template-rows:164px 82px}
.mdp .cover .main{height:176px}
}
@media(max-width:767px){
.mdp .permtable{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}
.mdp .permtable thead, .mdp .permtable tbody{display:table;width:100%;min-width:430px}
.mdp .permtable th, .mdp .permtable td{white-space:nowrap}
.mdp .permtable td:first-child{white-space:normal}
.mdp .spectable td{padding:8px 14px}
.mdp .spectable td:last-child{text-align:right}
}
.mdp .fly :focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.mdp .mobnav a:focus-visible{outline:2px solid var(--accent);outline-offset:-3px}
@media(prefers-reduced-motion:reduce){
.mdp .fly, .mdp #page{transition:none !important}
}
/* It ends at --floor, not at the window. z-200 clears the tab bar but not the
   operator's #adminbar (z-1900), so at inset:0 the .bot — which is where Next
   and Done are, the only way THROUGH a guided step — finished underneath it.
   --floor carries the home indicator too, so .bot pads no more for it. */
.mdp .cook{position:fixed;inset:0 0 var(--floor-modal,0px) 0;z-index:200;background:var(--bg);display:none;flex-direction:column}
.mdp .cook.on{display:flex}
.mdp .cook .top{display:flex;align-items:center;gap:12px;padding:14px 22px;border-bottom:1px solid var(--line);flex-shrink:0}
.mdp .cook .top .ttl{font-size:13px;font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mdp .cook .count{font-family:"JetBrains Mono",monospace;font-size:12px;color:var(--ink-3);margin-left:auto;flex-shrink:0}
.mdp .stepstrip{display:flex;gap:3px;padding:0 22px 12px;flex-shrink:0}
.mdp .stepstrip button{flex:1;height:20px;padding:0;display:flex;align-items:flex-end;min-width:0}
.mdp .stepstrip button i{display:block;width:100%;height:4px;border-radius:2px;background:var(--line);
  transition:background .15s,height .15s}
.mdp .stepstrip button:hover i{height:8px}
.mdp .stepstrip button.done i{background:var(--ok)}
.mdp .stepstrip button.on i{background:var(--accent);height:8px}
.mdp .cook .mid{flex:1;overflow:auto;padding:14px 22px 30px;display:flex;justify-content:center;
  -webkit-overflow-scrolling:touch}
.mdp .cook .inner{max-width:640px;width:100%}
.mdp .cook .inner .eyebrow{display:block;margin-bottom:10px}
.mdp .cook .inner h2{font-size:25px;margin-bottom:12px;text-wrap:balance}
.mdp .cook .inner p{font-size:16px;color:var(--ink-2);margin-bottom:16px}
.mdp .cook .inner .photo{height:250px;margin-bottom:16px}
.mdp .cook .warnstep{font-size:14px}
.mdp .cook .bot{display:flex;align-items:center;gap:10px;padding:14px 22px;border-top:1px solid var(--line);flex-shrink:0}
.mdp .cook .bot .nav{display:flex;gap:8px;flex:1}
.mdp .cook .bot .nav .btn{height:46px;font-size:14.5px}
.mdp .cook .bot .btn.prev{width:56px;justify-content:center;padding:0}
.mdp .cook .bot .btn.next{flex:1;justify-content:center}
.mdp .donebtn{display:inline-flex;align-items:center;gap:8px;height:38px;padding:0 14px;border-radius:9px;
  border:1px solid var(--line-strong);background:var(--panel);font-size:13.5px;font-weight:500;margin-bottom:16px}
.mdp .donebtn.on{background:var(--ok-wash);border-color:color-mix(in srgb,var(--ok) 35%,transparent);color:var(--ok)}
.mdp .jumplist{position:absolute;left:0;right:0;top:0;bottom:0;background:var(--bg);z-index:5;display:none;
  flex-direction:column}
.mdp .jumplist.on{display:flex}
.mdp .jumplist .items{flex:1;overflow:auto;padding:8px 0}
.mdp .jumprow{display:flex;align-items:center;gap:13px;padding:13px 22px;width:100%;text-align:left;
  border-bottom:1px solid var(--line)}
.mdp .jumprow:hover{background:var(--sunken)}
.mdp .jumprow .n{font-family:"JetBrains Mono",monospace;font-size:11.5px;color:var(--ink-3);width:20px;flex-shrink:0}
.mdp .jumprow .t{flex:1;min-width:0;font-size:14px}
.mdp .jumprow .t span{display:block;font-size:11.5px;color:var(--ink-3)}
.mdp .jumprow.on{background:var(--accent-wash)}
.mdp .jumprow.on .t{font-weight:600}
.mdp .jumprow .tick{color:var(--ok);flex-shrink:0}
@media(max-width:767px){
.mdp .cook .top, .mdp .cook .bot{padding:12px 16px}
.mdp .stepstrip{padding:0 16px 10px}
.mdp .cook .mid{padding:12px 16px 24px}
.mdp .cook .inner h2{font-size:20px}
.mdp .cook .inner p{font-size:15px}
.mdp .cook .inner .photo{height:190px}
.mdp .cook .bot{padding-bottom:12px}
.mdp .cook .bot .nav .btn{height:48px}
.mdp .jumprow{padding:14px 16px}
}
.mdp .editable{position:relative}
.mdp[data-edit="on"] [contenteditable="true"]{outline:none;background:var(--panel);
  box-shadow:0 0 0 1px var(--accent-line);border-radius:6px;padding:2px 6px;margin:-2px -6px}
.mdp[data-edit="on"] [contenteditable="true"]:focus{box-shadow:0 0 0 2px var(--accent);background:var(--panel)}
.mdp[data-edit="on"] .editable{outline:1px dashed var(--accent-line);outline-offset:8px;border-radius:4px;
  cursor:text}
.mdp[data-edit="on"] .editable:hover{outline-color:var(--accent)}
.mdp .edittag{cursor:pointer}
.mdp[data-edit="on"] .edittag:hover{background:var(--accent-ink)}
.mdp .editbar .savedot{transition:background .2s}
.mdp .editbar .savedot.saving{background:var(--warn)}
.mdp .pthumb{width:44px;height:34px;border-radius:6px;flex-shrink:0}
.mdp .pcell{display:flex;gap:11px;align-items:flex-start;min-width:0}
.mdp .pcell .t{min-width:0;flex:1}
.mdp .pcell .t a{color:var(--ink)}
.mdp .pcell .t a:hover b{color:var(--accent-ink)}
.mdp .pmeta{display:flex;gap:5px;flex-wrap:wrap;margin-top:5px;align-items:center}
.mdp .pdate{font-family:"JetBrains Mono",monospace;font-size:10.5px;color:var(--ink-3)}
.mdp .pdate.stale{color:var(--warn)}
.mdp .contrib{display:inline-flex;align-items:center;gap:4px;font-size:11px;color:var(--ink-3)}
.mdp .tbl th.thin, .mdp .tbl td.thin{width:30px}
.mdp .attachbar{display:flex;gap:6px;padding:0 16px 13px;flex-wrap:wrap}
.mdp .attachbar button{display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 11px;border-radius:8px;
  border:1px solid var(--line);background:var(--panel);font-size:12.5px;color:var(--ink-2)}
.mdp .attachbar button:hover{border-color:var(--accent-line);background:var(--accent-wash);color:var(--accent-ink)}
.mdp .attached{display:flex;flex-direction:column;gap:7px;margin-top:10px}
.mdp .att{display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--line);
  border-radius:9px;background:var(--sunken)}
.mdp .att .photo{width:44px;height:33px;flex-shrink:0}
.mdp .att .attic{width:34px;height:33px;border-radius:7px;background:var(--panel);border:1px solid var(--line);
  display:flex;align-items:center;justify-content:center;color:var(--ink-3);flex-shrink:0;font-size:14px}
.mdp .att b{display:block;font-size:12.5px}
.mdp .att > span > span{display:block;font-size:11.5px;color:var(--ink-3)}
.mdp .attachpick{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.mdp .attachpick button{text-align:left;padding:11px 12px;border:1px solid var(--line);border-radius:10px;background:var(--panel)}
.mdp .attachpick button.on{border-color:var(--accent);background:var(--accent-wash)}
.mdp .attachpick b{display:block;font-size:13px;margin-top:5px}
.mdp .attachpick span{display:block;font-size:11.5px;color:var(--ink-3);margin-top:1px}
.mdp .presult{display:flex;align-items:center;gap:12px;width:100%;text-align:left;padding:11px 12px;
  border:1px solid var(--line);border-radius:10px;margin-bottom:8px;background:var(--panel)}
.mdp .presult:hover{border-color:var(--line-strong)}
.mdp .presult.on{border-color:var(--accent);background:var(--accent-wash)}
.mdp .presult .photo{width:56px;height:42px;flex-shrink:0}
.mdp .presult .t{flex:1;min-width:0}
.mdp .presult .t b{display:block;font-size:13.5px}
.mdp .presult .t .mono{display:block;font-size:11.5px;color:var(--ink-3);margin-top:1px}
.mdp .presult .meta{display:flex;gap:5px;margin-top:6px;flex-wrap:wrap}
.mdp .presult .p{font-family:"JetBrains Mono",monospace;font-size:13px;font-weight:500;flex-shrink:0}
@media(max-width:767px){
.mdp .attachpick{grid-template-columns:1fr}
.mdp .pcell{gap:9px}
.mdp .tbl td .pcell{width:100%}
}
.mdp .title, .mdp .ident{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:16px 30px;
  align-items:end;padding:20px 0 16px}
.mdp .title > .editable, .mdp .title > div:first-child, .mdp .ident .left{min-width:0}
.mdp .title h1{font-size:clamp(21px,2.3vw,30px);margin:9px 0 7px;max-width:26ch;text-wrap:balance}
.mdp .ident h1{font-size:clamp(22px,2.5vw,31px);max-width:22ch;text-wrap:balance}
.mdp .title .acts, .mdp .ident .acts{margin-left:0;justify-self:end;align-self:end;
  display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end;
  max-width:min(460px,42vw);flex-shrink:1}
.mdp .title .acts .btn, .mdp .ident .acts .btn{white-space:nowrap;flex-shrink:0}
@media(max-width:1023px){
.mdp .title, .mdp .ident{grid-template-columns:minmax(0,1fr);gap:14px}
.mdp .title .acts, .mdp .ident .acts{justify-self:stretch;justify-content:flex-start;max-width:none}
.mdp .title h1{max-width:34ch}
.mdp .ident h1{max-width:30ch}
}
@media(max-width:767px){
.mdp .title, .mdp .ident{padding:16px 0 14px;gap:13px}
.mdp .title h1, .mdp .ident h1{font-size:clamp(19px,5.2vw,23px);max-width:none}
.mdp .title .acts, .mdp .ident .acts{display:grid;grid-template-columns:1fr 1fr;gap:8px;justify-self:stretch}
.mdp .title .acts .btn, .mdp .ident .acts .btn{justify-content:center;width:100%}
}
@media(max-width:480px){
.mdp .title .acts, .mdp .ident .acts{grid-template-columns:1fr}
}
.mdp .origin{padding:13px 16px}
.mdp .origin .photo{height:96px;margin-bottom:11px}
.mdp .origin .veh{font-size:14px;font-weight:600;display:block}
.mdp .origin .veh a{color:inherit}
.mdp .origin .veh a:hover{color:var(--accent-ink)}
.mdp .origin .snap{display:flex;flex-direction:column;gap:5px;margin-top:9px;padding-top:9px;
  border-top:1px solid var(--line)}
.mdp .origin .snap div{display:flex;gap:10px;font-size:12.5px}
.mdp .origin .snap span:first-child{color:var(--ink-3);width:96px;flex-shrink:0}
.mdp .origin .snap span:last-child{font-family:"JetBrains Mono",monospace;font-size:12px;min-width:0}
.mdp .origin .frozen{display:flex;gap:8px;margin-top:11px;padding:9px 11px;border-radius:8px;
  background:var(--sunken);border:1px solid var(--line);font-size:11.5px;color:var(--ink-3);line-height:1.5}
.mdp .originline{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--ink-2)}
.mdp .originline b{color:var(--ink)}
.mdp .pill-origin{color:var(--accent-ink);border-color:var(--accent-line);background:var(--accent-wash);
  font-family:"JetBrains Mono",monospace;font-size:10px;letter-spacing:.08em;text-transform:uppercase}
.mdp .title{display:block;padding:24px 0 20px}
.mdp .title > .editable{min-width:0;width:100%}
.mdp .title > .editable > .row{gap:6px;margin-bottom:14px}
.mdp .title > .editable > .row .pill{height:22px;font-size:11px}
.mdp .title h1{
  font-size:clamp(27px,4.1vw,45px);
  line-height:1.06;
  letter-spacing:-.03em;
  font-weight:600;
  max-width:none;          
  text-wrap:balance;
  margin:0 0 14px;
}
.mdp .title .by{font-size:14px;color:var(--ink-2);display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.mdp .title .by b{font-weight:600}
.mdp .title .acts{
  display:flex;flex-wrap:wrap;gap:8px;
  margin:20px 0 0;padding-top:18px;
  border-top:1px solid var(--line);
  max-width:none;justify-self:stretch;justify-content:flex-start;
}
.mdp .title .acts .actgap{flex:1 1 auto;min-width:0}
.mdp .title .acts .btn{white-space:nowrap;flex-shrink:0}
@media(max-width:1023px){
.mdp .title h1{font-size:clamp(25px,4.6vw,36px)}
}
@media(max-width:767px){
.mdp .title{padding:18px 0 16px}
.mdp .title h1{font-size:clamp(23px,6.4vw,30px);line-height:1.1;letter-spacing:-.024em;margin-bottom:12px}
.mdp .title > .editable > .row{margin-bottom:11px}
.mdp .title .by{font-size:13px}
.mdp .title .acts{margin-top:16px;padding-top:14px;display:grid;grid-template-columns:1fr 1fr;gap:8px}
.mdp .title .acts .actgap{display:none}
.mdp .title .acts .btn{justify-content:center;width:100%}
.mdp .title .acts .btn-primary{grid-column:1 / -1}
}
@media(max-width:480px){
.mdp .title .acts{grid-template-columns:1fr 1fr}
}

/* ══════════════════════════════════════════════════════════════════════
   THE MOD PAGE — .mdx-*   (app/render-mod*.php), ported from v14.

   THREE DELIBERATE DEPARTURES FROM THE UPLOADED FILE, each for a reason
   this codebase has already paid for once:

   · IT DEFINES ALMOST NO COLOUR OF ITS OWN. v14 ships a full palette and
     a second one under html[data-theme=dark]. The accent here is
     OPERATOR-CONFIGURABLE from the Appearance screen, so a literal would
     be the one orange thing on the site that did not move when somebody
     repainted it — the hover card's rule, and the lesson
     24-image-picker.php taught in reverse by being written against a
     page's private names and having no background anywhere else. Every
     value below resolves to a token :root already publishes, which is
     also why there is no `.dark .mdx-*` block: the tokens flip one
     element up and a second dark palette here would be the copy that
     drifts. The exceptions are named and tokenised at the top.

   · EVERY CLASS IS NAMESPACED. v14 styles `.plate`, `.sheet`, `.tools`,
     `.fit`, `.tbl`, `.steps`, `.cols`, `.card` — all of which either
     exist globally on this site or would collide with something that
     does. `.fit` in particular is a bare global green PILL
     (03-ymm-finder-and-combo.php), which is exactly how the share sheet
     came to render a chip inside a row that already had one.

   · THE COLUMN IS THE SITE'S. .mdx-wrap caps at var(--col) and pads by
     var(--pad) like every other content container (§11); only the cover
     bleeds, which is why views/app/page-mods.php drops its .wrap for
     this view and the section carries `bleeds`.
   ══════════════════════════════════════════════════════════════════════ */

.mdx{
  /* The three values with no token behind them. --mdx-blue is the
     blueprint blue the cover's gradient is made of: the site publishes no
     dark blue, and this is the page's own material rather than something
     another screen can repaint. Stated once, so it is findable. */
  --mdx-blue:#115390;
  --mdx-lift:0 16px 46px rgba(20,18,15,.18);
  --mdx-overlap:30px;
  --mdx-ease:cubic-bezier(.22,.68,0,1);
  /* the sticky chain, in one place, so a section scrolled to never lands
     under the header (§6's --floor, at the other end of the window) */
  --mdx-top:calc(var(--navh,58px) + 8px);
}
:root:not([data-theme="light"]) .mdx,.dark .mdx{--mdx-lift:0 16px 46px rgba(0,0,0,.55)}
.mdx-wrap{max-width:var(--col);margin:0 auto;padding:0 var(--pad)}
.mdx-eyebrow{font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.16em;
  text-transform:uppercase;color:var(--t3)}
.mdx .num{font-family:var(--mono);font-variant-numeric:tabular-nums}
.mdx .is-none,.mdx-none{color:var(--t3)}
.mdx-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ════ COVER — tall, the title set low on it, the plate lifted into it ════ */
.mdx-cover{position:relative;overflow:hidden;
  background:var(--mdx-blue) center 42%/cover no-repeat;
  height:clamp(400px,44vw,620px);border-bottom:1px solid var(--border)}
.mdx-cover.is-bare{background:linear-gradient(160deg,var(--mdx-blue),#0b3a66)}
.mdx-cover::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(9,44,78,0) 46%,rgba(9,44,78,.42) 72%,rgba(9,44,78,.86) 100%)}
.mdx-cover__in{position:relative;z-index:2;height:100%;display:flex;flex-direction:column;
  justify-content:flex-end;padding-bottom:64px}
.mdx-kick{display:flex;align-items:center;gap:11px;flex-wrap:wrap;margin-bottom:14px}
.mdx-nick{display:inline-flex;align-items:center;height:26px;padding:0 12px;border-radius:999px;
  background:var(--accent);color:var(--accent-on);font-size:12.5px;font-weight:600;letter-spacing:-.01em}
.mdx-ymm{display:flex;align-items:center;gap:7px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.14em;text-transform:uppercase;color:rgba(219,236,250,.8);flex-wrap:wrap}
.mdx-ymm a{color:inherit}
.mdx-ymm a:hover{color:#fff}
.mdx-ymm i{font-style:normal;color:rgba(219,236,250,.36)}
.mdx-title{color:#fff;font-size:clamp(34px,4.4vw,56px);font-weight:700;line-height:.99;
  letter-spacing:-.038em;max-width:13ch;margin:0;text-wrap:balance;
  text-shadow:0 2px 26px rgba(6,30,56,.55)}

/* ════ PLATE ════ */
.mdx-plate{position:relative;z-index:5;margin-top:calc(var(--mdx-overlap) * -1);
  background:var(--surface);border:1px solid var(--border);border-radius:12px;
  box-shadow:var(--mdx-lift);overflow:hidden;
  display:grid;grid-template-columns:minmax(0,1.6fr) repeat(4,minmax(0,1fr))}
.mdx-plate::before{content:"";position:absolute;left:0;right:0;top:0;height:3px;
  background:var(--accent);z-index:2}
.mdx-cell{padding:20px 18px 18px;border-right:1px solid var(--border);min-width:0}
.mdx-cell:last-child{border-right:none}
.mdx-fig{display:block;margin-top:8px;font-size:13.5px;font-weight:500;letter-spacing:-.01em;
  color:var(--text);overflow-wrap:anywhere}
.mdx-cell.is-empty .mdx-fig{color:var(--t3)}
/* an unset figure asks to be filled, in the owner's words — a dashed
   underline says "this is a value you can set", which a plain button does not */
.mdx-set{display:inline-flex;align-items:center;gap:5px;margin-top:8px;font-family:var(--mono);font-size:13px;
  color:var(--accent-fg);background:none;border:none;padding:0 0 3px;cursor:pointer;
  border-bottom:1px dashed var(--border2);transition:border-color .14s}
.mdx-set:hover{border-color:var(--accent)}
.mdx-id{display:flex;align-items:center;gap:12px;margin-top:9px;color:inherit;min-width:0}
.mdx-id__t{min-width:0}
.mdx-id__t b{display:block;font-size:17px;font-weight:600;letter-spacing:-.024em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mdx-id__t span{display:block;font-size:12px;color:var(--t3);margin-top:2px}
a.mdx-id:hover .mdx-id__t b{color:var(--accent-fg)}
.mdx-thumb{width:58px;height:44px;border-radius:7px;flex-shrink:0;
  background:var(--surface2) center/cover no-repeat;border:1px solid var(--border);
  box-shadow:var(--sh-sm)}

/* the difficulty meter: bars that step up, so the shape says how far
   along before anything is read, and the topmost filled bar IS the level */
.mdx-diffwrap{display:flex;align-items:flex-end;gap:11px;margin-top:9px}
.mdx-diff{display:flex;gap:3px;flex:1;align-items:flex-end}
.mdx-diff i{flex:1;border-radius:2px 2px 0 0;background:var(--border);font-style:normal;
  transition:background .2s var(--mdx-ease)}
.mdx-diff i:nth-child(1){height:7px}
.mdx-diff i:nth-child(2){height:10px}
.mdx-diff i:nth-child(3){height:13px}
.mdx-diff i:nth-child(4){height:16px}
.mdx-diff i:nth-child(5){height:19px}
.mdx-diff i.f{background:var(--t2)}
.mdx-diff i.f.top{background:var(--accent)}
.mdx-dnum{font-size:17px;font-weight:600;line-height:1;color:var(--text);flex-shrink:0}
.mdx-dnum i{font-style:normal;font-size:11px;font-weight:500;color:var(--t3)}

/* ════ UTILITY ROW — in the page, never on the cover ════ */
.mdx-util{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:15px 2px 0}
.mdx-who{display:inline-flex;align-items:center;gap:7px;color:var(--t2);font-size:13px}
.mdx-who b{font-weight:600;color:var(--text)}
.mdx-who:hover b{color:var(--accent-fg)}
.mdx-upd{font-size:13px;color:var(--t3)}
.mdx-cnt{font-size:11.5px;font-weight:500;color:var(--t3)}
.mdx-util__a{margin-left:auto;display:flex;gap:7px;align-items:center;flex-wrap:wrap}

/* ════ BODY GRID ════ */
.mdx-cols{display:grid;grid-template-columns:210px minmax(0,1fr);gap:40px;
  padding:28px 0 calc(72px + var(--floor,0px));align-items:start}
.mdx-entry{min-width:0;display:flex;flex-direction:column;gap:20px}
.mdx-card{background:var(--surface);border:1px solid var(--border);border-radius:12px;
  box-shadow:var(--sh-sm);overflow:hidden}

/* ════ LEFT RAIL + COMPLETENESS ════ */
.mdx-side{position:sticky;top:calc(var(--mdx-top) + 16px);min-width:0;
  display:flex;flex-direction:column;gap:16px}
.mdx-meter{padding:14px 14px 15px;border:1px solid var(--border);border-radius:10px;
  background:var(--surface)}
.mdx-meter__t{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:9px}
.mdx-meter__t b{font-size:15px;font-weight:600}
.mdx-bar{height:5px;border-radius:3px;background:var(--surface2);overflow:hidden;
  border:1px solid var(--border)}
.mdx-bar i{display:block;height:100%;background:var(--accent);transition:width .5s var(--mdx-ease)}
.mdx-bar.is-full i{background:var(--green)}
.mdx-meter p{font-size:12px;color:var(--t3);margin:9px 0 0;line-height:1.45}
.mdx-nav{display:flex;flex-direction:column;gap:1px}
.mdx-navtop{display:flex;align-items:center;gap:8px;padding:0 11px 8px}
.mdx-navr{display:flex;align-items:center;gap:9px;width:100%;padding:8px 11px;border-radius:7px;
  font-size:13.5px;font-weight:500;color:var(--t2);transition:background .14s,color .14s}
.mdx-navr:hover{background:var(--surface2);color:var(--text)}
.mdx-navr.on{color:var(--text);font-weight:600;box-shadow:inset 2px 0 0 var(--accent)}
.mdx-navr__l{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mdx-navr__n{margin-left:auto;font-size:11px;color:var(--t3)}
.mdx-navr.on .mdx-navr__n{color:var(--accent-fg)}
/* the dot is the to-do list the meter summarises: hollow is work left */
.mdx-mk{width:6px;height:6px;border-radius:50%;border:1.5px solid var(--border2);
  flex-shrink:0;box-sizing:border-box}
.mdx-mk.f{border-color:transparent;background:var(--accent)}
.mdx-mk.is-off{opacity:0}
.mdx-navgap{display:block;height:12px;pointer-events:none}
.mdx-nav > .mdx-navgap:first-child{display:none}

/* ════ SECTIONS ════ */
.mdx-sec{scroll-margin-top:calc(var(--mdx-top) + 20px)}
/* group dividers give eleven flat sections a shape */
.mdx-gsep{display:flex;align-items:center;gap:12px;padding:14px 2px 2px}
.mdx-entry > .mdx-gsep:first-child{padding-top:0}
.mdx-gsep b{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--t3);flex-shrink:0}
.mdx-gsep hr{flex:1;border:none;border-top:1px solid var(--border);margin:0}
.mdx-shead{display:flex;align-items:center;gap:12px;padding:18px 24px 14px;
  border-bottom:1px solid var(--border);cursor:pointer;user-select:none}
.mdx-shead__t{min-width:0}
.mdx-shead h2{margin:0;font-size:16.5px;font-weight:600;letter-spacing:-.02em}
.mdx-shead .mdx-eyebrow{display:block;margin-bottom:3px}
.mdx-shead__a{margin-left:auto;display:flex;gap:6px;align-items:center;flex-shrink:0}
.mdx-stog{width:26px;height:26px;border-radius:7px;display:flex;align-items:center;
  justify-content:center;color:var(--t3);flex-shrink:0;margin-left:-4px;background:none;
  border:none;cursor:pointer;transition:transform .2s var(--mdx-ease),background .14s,color .14s}
.mdx-shead:hover .mdx-stog{background:var(--surface2);color:var(--text)}
/* folded: the chevron points at the closed thing and the body goes */
.mdx-sec.is-closed .mdx-stog{transform:rotate(-90deg)}
.mdx-sec.is-closed .mdx-card > :not(.mdx-shead){display:none}
.mdx-sec.is-closed .mdx-shead{border-bottom:none;padding-bottom:18px}
.mdx-sec.is-closed .mdx-shead .mdx-eyebrow{color:var(--t2)}
.mdx-sbody{padding:22px 24px 24px}
.mdx-sbody--notes{padding-top:4px}
.mdx-sbody--tip{padding:8px 24px 0}
.mdx-subhead{display:flex;align-items:center;gap:12px;padding:16px 24px 8px}
.mdx-subhead hr{flex:1;border:none;border-top:1px solid var(--border);margin:0}

/* ════ SHADOW BOARD SLOT — an empty section, drawn as its own outline ════ */
.mdx-slot{position:relative;display:flex;align-items:center;gap:14px;width:100%;text-align:left;
  padding:20px 22px;border:1.5px dashed var(--border2);border-radius:12px;background:transparent;
  cursor:pointer;transition:border-color .16s,background .16s}
.mdx-slot:hover{border-color:var(--accent);background:var(--accent-soft)}
.mdx-slot__i{display:flex;align-items:center;justify-content:center;width:38px;height:38px;
  border-radius:9px;background:var(--surface2);color:var(--t3);flex-shrink:0}
.mdx-slot:hover .mdx-slot__i{background:var(--surface);color:var(--accent-fg)}
.mdx-slot__t{min-width:0}
.mdx-slot__t b{display:block;font-size:14.5px;font-weight:600;letter-spacing:-.012em;color:var(--text)}
.mdx-slot__t span{display:block;margin-top:3px;font-size:13px;line-height:1.5;color:var(--t3)}

/* ════ PROSE ════ */
.mdx-prose{max-width:68ch}
.mdx-prose p{margin:0 0 12px;color:var(--t2);font-size:15px;line-height:1.62}
.mdx-prose p:first-child{font-size:17.5px;line-height:1.55;color:var(--text);letter-spacing:-.011em}
.mdx-prose p:last-child{margin-bottom:0}
/* the verdict: the sentence people screenshot, and its own column (363) */
.mdx-final{margin-top:18px !important;padding:14px 17px;border-left:3px solid var(--accent);
  background:var(--accent-soft);border-radius:0 8px 8px 0;color:var(--text) !important;
  font-weight:500;font-size:15px !important}
.mdx-lineage{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 24px 22px;
  padding:12px 16px;border-radius:var(--r);background:var(--surface2);
  border:1px solid var(--border);font-size:13.5px;color:var(--t2)}
.mdx-lineage a{color:var(--accent-fg)}

/* ════ SPEC SHEET (the install record) ════ */
.mdx-sheet{display:grid;grid-template-columns:1fr 1fr;gap:0 44px;margin:0;padding:22px 24px 24px}
.mdx-sheet > div{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:10px 0;border-bottom:1px solid var(--border)}
.mdx-sheet dt{font-size:13.5px;color:var(--t3)}
.mdx-sheet dd{margin:0;font-size:13px;color:var(--text);text-align:right;overflow-wrap:anywhere}
.mdx-sheet dd.un{color:var(--t3)}
.mdx-sheet .mdx-tot{border-bottom:none;padding-top:14px}
.mdx-sheet .mdx-tot dt{color:var(--text);font-weight:600}
.mdx-sheet .mdx-tot dd{font-family:var(--mono);font-size:15px;font-weight:600}
/* a set value is quietly editable; an unset one asks. Both open the same
   one-value popover, so the two states are one control in two moods. */
.mdx-qv{display:inline-flex;align-items:baseline;gap:5px;background:none;border:none;padding:0;
  cursor:pointer;color:inherit;font:inherit;
  border-bottom:1px dashed transparent;transition:border-color .14s,color .14s}
/* the pencil is quiet until the value is pointed at: it is there to be found,
   not to be read — the row is a fact first and a control second */
.mdx-qv .ic{opacity:.35;transition:opacity .14s}
.mdx-qv:hover .ic,.mdx-qv:focus-visible .ic{opacity:1}
.mdx-qv:hover{color:var(--accent-fg);border-color:var(--accent)}
.mdx-qv.is-set{color:var(--accent-fg);border-color:var(--border2)}
.mdx-over{color:var(--accent-fg)}
.mdx-note{margin:0 0 8px;font-size:13.5px;line-height:1.55;color:var(--t2)}
.mdx-note b{color:var(--text)}
.mdx-note--tip{display:flex;gap:8px;padding:10px 13px;border-radius:8px;
  background:var(--accent-soft);border:1px solid var(--accent-line);color:var(--accent-fg)}

/* ════ WALKTHROUGH ════ */
.mdx-tools{display:flex;flex-direction:column}
.mdx-toolpills{display:flex;gap:6px;flex-wrap:wrap}
.mdx-step{display:flex;gap:14px;padding:16px 24px;border-bottom:1px solid var(--border)}
.mdx-step:last-child{border-bottom:none}
.mdx-step__n{flex-shrink:0;font-family:var(--mono);font-size:13px;font-weight:500;
  color:var(--t3);padding-top:1px}
.mdx-step__c{flex:1;min-width:0}
.mdx-step__c h4{margin:0 0 5px;font-size:14.5px;font-weight:600;letter-spacing:-.012em}
.mdx-step__c p{margin:0;font-size:14px;line-height:1.6;color:var(--t2)}
.mdx-step__m{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:9px}
.mdx-step__ctl{margin-left:auto;display:inline-flex;gap:4px}
.mdx-mv{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;
  border-radius:6px;border:1px solid var(--border);background:var(--surface);color:var(--t3);cursor:pointer}
.mdx-mv:hover{color:var(--text);border-color:var(--border2)}
.mdx-torque{font-family:var(--mono);font-size:11.5px;color:var(--t2)}
.mdx-warn{display:flex;gap:8px;margin-top:9px;padding:9px 12px;border-radius:8px;
  background:var(--accent-soft);border:1px solid var(--accent-line);color:var(--accent-fg);font-size:13px}

/* ════ TABLES (parts, files) ════ */
.mdx-scroll{overflow-x:auto}
.mdx-tbl{width:100%;border-collapse:collapse;font-size:13px}
.mdx-tbl th{text-align:left;font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--t3);font-weight:400;padding:9px 12px;
  border-bottom:1px solid var(--border);white-space:nowrap}
.mdx-tbl td{padding:11px 12px;border-bottom:1px solid var(--border);vertical-align:top}
.mdx-tbl tr:last-child td{border-bottom:none}
.mdx-tbl th.num,.mdx-tbl td.num{text-align:right}
.mdx-thin{width:1%;white-space:nowrap}
.mdx-tbl td b{font-weight:600}
.mdx-pn,.mdx-pmeta{display:block;margin-top:3px;font-size:12px;color:var(--t3)}
.mdx-pmeta{display:flex;gap:5px;flex-wrap:wrap;align-items:center}
.mdx-contrib{font-size:11.5px;color:var(--t3)}
.mdx-alt td{background:var(--surface2);color:var(--t2)}
.mdx-grp td{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--t3);background:var(--surface2);padding:7px 12px}
.mdx-sub td,.mdx-opt td{color:var(--t3);font-size:12.5px}
.mdx-total td{font-weight:600;background:var(--surface2)}
.mdx-chk{display:inline-block;width:15px;height:15px;border-radius:4px;
  border:1.5px solid var(--border2);background:var(--surface);cursor:pointer}
.mdx-chk.on{background:var(--green);border-color:var(--green)}

/* ════ TOOLS ════ */
.mdx-tool{display:flex;align-items:center;gap:12px;padding:12px 24px;
  border-bottom:1px solid var(--border)}
.mdx-tool:last-child{border-bottom:none}
.mdx-tool__i{display:flex;align-items:center;justify-content:center;width:30px;height:30px;
  border-radius:7px;background:var(--surface2);color:var(--t3);flex-shrink:0}
.mdx-tool__c{flex:1;min-width:0}
.mdx-tool__c b{display:block;font-size:14px;font-weight:600;letter-spacing:-.012em}
.mdx-tool__c span{display:block;margin-top:2px;font-size:12.5px;color:var(--t3)}
.mdx-tool__r{font-family:var(--mono);font-size:11.5px;color:var(--t2);flex-shrink:0}

/* ════ FITMENT ════ */
.mdx-fcheck{padding:20px 24px;border-bottom:1px solid var(--border);background:var(--surface2)}
.mdx-fveh{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.mdx-fv{display:flex;align-items:center;gap:9px;color:var(--t2);padding:9px 13px;border-radius:9px;
  border:1px solid var(--border);background:var(--surface);cursor:pointer;text-align:left;
  transition:border-color .14s,background .14s}
.mdx-fv:hover{border-color:var(--border2)}
.mdx-fv.on{border-color:var(--accent);background:var(--accent-soft)}
.mdx-fv__t b{display:block;font-size:13.5px;font-weight:600;letter-spacing:-.012em}
.mdx-fv__t span{display:block;margin-top:1px;font-size:11.5px;color:var(--t3)}
.mdx-fverdict{margin-top:12px;padding:12px 15px;border-radius:9px;font-size:13.5px;
  border:1px solid var(--border);background:var(--surface);color:var(--t2)}
.mdx-fverdict.is-yes{background:var(--green-soft);border-color:var(--green-line);color:var(--green)}
.mdx-fverdict.is-no{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent-fg)}
.mdx-fverdict b{display:block;font-size:14.5px;margin-bottom:2px}
.mdx-fitlist{display:flex;flex-direction:column}
.mdx-fitrow{display:flex;align-items:flex-start;gap:11px;padding:12px 24px;
  border-bottom:1px solid var(--border)}
.mdx-fitrow:last-child{border-bottom:none}
.mdx-fitrow__v{display:flex;align-items:center;justify-content:center;width:22px;height:22px;
  border-radius:50%;background:var(--green-soft);color:var(--green);flex-shrink:0}
.mdx-fitrow.is-bad .mdx-fitrow__v{background:var(--accent-soft);color:var(--accent-fg)}
.mdx-fitrow__c{min-width:0}
.mdx-fitrow__c b{display:block;font-size:14px;font-weight:600;letter-spacing:-.012em}
.mdx-fitrow__c span{display:block;margin-top:2px;font-size:12.5px;color:var(--t3);line-height:1.5}

/* ════ MEDIA ════ */
.mdx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;padding:14px}
.mdx-shot{display:block;aspect-ratio:4/3;border-radius:8px;
  background:var(--surface2) center/cover no-repeat;border:1px solid var(--border);cursor:zoom-in}
.mdx-strip{display:flex;gap:7px;margin-top:10px}
.mdx-strip .mdx-shot{width:88px;aspect-ratio:4/3}

/* ════ LOG ════ */
.mdx-prog{display:flex;align-items:center;gap:10px;padding:12px 24px;
  border-bottom:1px solid var(--border)}
.mdx-entryrow{padding:15px 24px;border-bottom:1px solid var(--border)}
.mdx-entryrow:last-child{border-bottom:none}
.mdx-entryrow__h{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.mdx-entryrow__h h4{margin:0;font-size:14.5px;font-weight:600;letter-spacing:-.012em}
.mdx-entryrow__h span{margin-left:auto;font-family:var(--mono);font-size:11.5px;color:var(--t3)}
.mdx-entryrow p{margin:6px 0 0;font-size:14px;line-height:1.6;color:var(--t2)}

/* ════ OWNER / VEHICLE ════ */
.mdx-ohead{display:flex;align-items:center;gap:14px;padding:22px 24px 16px}
.mdx-ohead h2{margin:0;font-size:19px;font-weight:600;letter-spacing:-.02em}
.mdx-ohead > .btn{margin-left:auto}
.mdx-handle{font-family:var(--mono);font-size:12px;color:var(--t3);margin-top:2px}
.mdx-handle i{font-style:normal}
.mdx-bio{margin:0;padding:0 24px 20px;color:var(--t2);max-width:60ch;font-size:14.5px;line-height:1.6}
.mdx-ostats{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid var(--border);margin:0}
.mdx-ostats > div{padding:15px 18px;border-right:1px solid var(--border)}
.mdx-ostats > div:last-child{border-right:none}
.mdx-ostats dt{font-size:10.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--t3)}
.mdx-ostats dd{margin:6px 0 0;font-size:15px;color:var(--text)}
.mdx-more{display:inline-flex;align-items:center;gap:6px;padding:13px 24px;font-size:13px;
  font-weight:600;color:var(--accent-fg);border-top:1px solid var(--border)}

/* ════ SHARED SMALL PARTS ════ */
.mdx-pill{display:inline-flex;align-items:center;gap:5px;height:21px;padding:0 8px;border-radius:5px;
  background:var(--surface2);border:1px solid var(--border);font-size:11.5px;color:var(--t2)}
.mdx-pill--a{background:var(--accent-soft);border-color:var(--accent-line);color:var(--accent-fg)}
.mdx-blank{padding:36px 24px;text-align:center;color:var(--t3);font-size:13.5px}
.mdx-blank b{display:block;color:var(--text);font-size:15px;margin-bottom:4px}
.mdx-blank span{display:block}

/* ════ NARROW ════ */
@media(max-width:1040px){
  .mdx-plate{grid-template-columns:1fr 1fr}
  .mdx-cell{border-bottom:1px solid var(--border)}
  .mdx-cell--id{grid-column:1/-1}
  .mdx-cell:nth-child(2n+1){border-right:none}
  .mdx-cell:nth-last-child(-n+2){border-bottom:none}
}
@media(max-width:860px){
  .mdx-cover{height:clamp(330px,60vw,430px);background-position:center center}
  .mdx-cover::after{background:linear-gradient(180deg,rgba(9,44,78,0) 34%,rgba(9,44,78,.5) 62%,rgba(9,44,78,.9) 100%)}
  .mdx-cover__in{padding-bottom:58px}
  .mdx-title{font-size:clamp(28px,7.4vw,38px);max-width:none}
  .mdx{--mdx-overlap:24px}
  .mdx-cell{padding:16px}
  .mdx-util__a{margin-left:0;width:100%}
  .mdx-cols{grid-template-columns:1fr;gap:20px;padding:24px 0 calc(64px + var(--floor,0px))}
  /* the rail becomes a strip across the top rather than hiding: it IS the
     navigation, and a phone is where the sections matter most */
  .mdx-side{position:static}
  .mdx-nav{flex-direction:row;flex-wrap:nowrap;overflow-x:auto;gap:6px;padding-bottom:4px;
    -webkit-overflow-scrolling:touch}
  .mdx-navtop{display:none}
  .mdx-navgap{display:none}
  .mdx-navr{flex:0 0 auto;width:auto;background:var(--surface);border:1px solid var(--border);
    white-space:nowrap}
  .mdx-navr.on{box-shadow:none;border-color:var(--accent-line)}
  .mdx-sheet,.mdx-ostats{grid-template-columns:1fr}
  .mdx-ostats > div{border-right:none;border-bottom:1px solid var(--border)}
  .mdx-ostats > div:last-child{border-bottom:none}
  .mdx-sbody,.mdx-sheet{padding-left:20px;padding-right:20px}
  .mdx-ohead,.mdx-bio,.mdx-step,.mdx-tool,.mdx-fitrow,.mdx-entryrow,.mdx-fcheck,.mdx-subhead{
    padding-left:20px;padding-right:20px}
  .mdx-lineage{margin-left:20px;margin-right:20px}
}
@media(prefers-reduced-motion:reduce){.mdx-bar i,.mdx-stog,.mdx-diff i{transition:none}}
/* ── AMS integration overrides (Phase 1) ───────────────────────────── */
.mdp{background:var(--bg);min-height:60vh}
/* the app supplies the page chrome; neutralise the mockup's own topbar offset */
.mdp .tabrail{top:0}
.mdp .rail{top:16px}
@media(max-width:860px){.mdp .tabrail{top:0}}
/* real photos fill via inline background; keep a neutral ground under them */
.mdp .photo{background-color:var(--sunken)}
.mdp .photo.hasimg{background-size:cover;background-position:center}
/* no photos yet → show the car full-width instead of an empty mosaic */
.mdp .cover.solo{grid-template-columns:1fr}
.mdp .cover.solo .side{display:none}

/* ============================================================================
   NEW VENDORS PAGE (ported 1:1 from the mockup, embedded under the app nav).
   Everything is prefixed .vp-* / #vp-* and tokens are scoped to #pg-vendors so
   nothing here touches the rest of the app. Theme follows the app (body.dark).
   ========================================================================== */
#pg-vendors.vpage{
  --vp-ams:#F26A21; --vp-wash:#FFF1E8;
  --vp-ink:#111112; --vp-ink2:#5C5F66; --vp-ink3:#8B8F96;
  --vp-line:#E6E7E9; --vp-line2:#D2D4D8;
  --vp-surface:#FFFFFF; --vp-canvas:#FAFAFA; --vp-sunken:#F4F4F5;
  --vp-ok:#10794F; --vp-okwash:#E7F4EE; --vp-shadow:0 4px 20px rgba(0,0,0,.10);
  padding:0;overflow:hidden;color:var(--vp-ink);
  font-family:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif}
body.dark #pg-vendors.vpage{
  --vp-ams:#FF7C36; --vp-wash:#3A1F10;
  --vp-ink:#F2F2F3; --vp-ink2:#A2A6AD; --vp-ink3:#7C8088;
  --vp-line:#2A2B2E; --vp-line2:#3A3C40;
  --vp-surface:#171819; --vp-canvas:#0F1011; --vp-sunken:#1F2022;
  --vp-ok:#4FBF8B; --vp-okwash:#14301F; --vp-shadow:0 4px 20px rgba(0,0,0,.5)}
#pg-vendors .mono,#pg-vendors .vp-mono{font-family:"JetBrains Mono",ui-monospace,monospace;font-variant-numeric:tabular-nums}

/* slim vendors sub-header (sits under the app nav) */
.vp-bar{display:flex;align-items:center;gap:14px;padding:0 18px;height:56px;flex:none;
  background:var(--vp-surface);border-bottom:1px solid var(--vp-line)}
.vp-brand{font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--vp-ink3);white-space:nowrap}
.vp-search{position:relative;flex:1;max-width:460px}
.vp-sbox{display:flex;align-items:center;gap:9px;background:var(--vp-sunken);border:1px solid transparent;border-radius:8px;padding:0 12px;height:38px;transition:border-color .14s,background .14s}
.vp-search.open .vp-sbox,.vp-sbox:focus-within{background:var(--vp-surface);border-color:var(--vp-ams)}
/* the magnifier in the search box. It used to carry its colour and flex in an
   inline style; the icon helper takes a class, not a style, so the geometry
   lives here with the rest of this bar. */
.vp-sbox-ic{color:var(--vp-ink3);flex:none}
.vp-sbox input{flex:1;border:none;background:none;font-size:14px;color:var(--vp-ink);height:100%}
.vp-sbox input:focus{outline:none}
.vp-sbox input::placeholder{color:var(--vp-ink3)}
.vp-ac{position:absolute;top:calc(100% + 6px);left:0;right:0;background:var(--vp-surface);border:1px solid var(--vp-line);border-radius:10px;padding:6px;box-shadow:var(--vp-shadow);display:none;max-height:340px;overflow:auto;z-index:1200}
.vp-search.open .vp-ac{display:block}
.vp-acg{font-size:10px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--vp-ink3);padding:9px 11px 4px;margin:0}
.vp-aci{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:none;border:none;border-radius:6px;padding:8px 11px;font-size:14px;color:var(--vp-ink);cursor:pointer}
.vp-aci:hover,.vp-aci.sel{background:var(--vp-sunken)}
.vp-aci .sub{margin-left:auto;font-size:12px;color:var(--vp-ink3)}
.vp-origin{display:flex;align-items:center;gap:7px;font-size:13px;color:var(--vp-ink2);white-space:nowrap}
.vp-origin b{color:var(--vp-ink);font-weight:500}
.vp-origin-edit{cursor:pointer;border-bottom:1px dashed var(--vp-line2);transition:color .12s,border-color .12s}
.vp-origin-edit:hover,.vp-origin-edit:focus{color:var(--vp-ams);border-bottom-color:var(--vp-ams);outline:none}
.vp-spacer{flex:1}
.vp-tbbtn{background:transparent;border:1px solid var(--vp-line2);color:var(--vp-ink2);border-radius:8px;height:36px;padding:0 13px;font-size:13px;cursor:pointer;white-space:nowrap}
.vp-tbbtn:hover{border-color:var(--vp-ink3);color:var(--vp-ink)}
.vp-tbbtn-pri{background:var(--vp-ams);border-color:var(--vp-ams);color:#fff}
.vp-add-sm{display:none}  /* desktop shows the full "Add a vendor"; mobile swaps to compact "+ Add" */
.vp-tbbtn-pri:hover{opacity:.9;color:#fff}

/* body: rail + map, fixed to the viewport below the nav + sub-header */
.vp-body{flex:1;display:flex;min-height:0;position:relative;background:var(--vp-canvas);
  height:calc(100vh - var(--navh) - 57px - var(--floor,0px))}
.vp-rail{width:432px;flex:none;background:var(--vp-surface);border-right:1px solid var(--vp-line);display:flex;flex-direction:column;min-height:0}

.vp-garage{padding:12px 18px 13px;border-bottom:1px solid var(--vp-line);flex:none;background:var(--vp-canvas)}
.vp-glabel{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:9px}
.vp-glabel span{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--vp-ink3)}
.vp-glabel button{background:none;border:none;font-size:12px;color:var(--vp-ink2);cursor:pointer;padding:0}
.vp-glabel button:hover{color:var(--vp-ams)}
.vp-vsel{position:relative}
.vp-vbtn{width:100%;display:flex;align-items:center;gap:11px;background:var(--vp-surface);border:1px solid var(--vp-line);border-radius:10px;padding:8px 12px 8px 8px;cursor:pointer;text-align:left;color:inherit}
.vp-vbtn:hover{border-color:var(--vp-line2)}
.vp-vsel.open .vp-vbtn{border-color:var(--vp-ams)}
.vp-thumb{position:relative;width:58px;height:38px;border-radius:7px;flex:none;display:grid;place-items:center;background:var(--vp-sunken);overflow:hidden}
.vp-thumb img{width:100%;height:100%;object-fit:cover}
/* scope-icon image sits on top of the fallback glyph; removed via onerror if missing */
.vp-thumbover{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* one-time hint nudging the user to add vehicles to their garage */
.vp-ghint{display:flex;align-items:flex-start;gap:10px;margin:10px 0 0;padding:10px 12px;
  background:var(--vp-wash,rgba(234,88,12,.08));border:1px solid var(--vp-line2,rgba(127,127,127,.3));
  border-radius:10px;font-size:12.5px;line-height:1.45;color:var(--vp-ink,inherit)}
.vp-ghint[hidden]{display:none}
.vp-ghint-t{flex:1}
.vp-ghint-act{display:flex;align-items:center;gap:6px;flex:none}
.vp-ghint-add{background:var(--vp-ams,#EA580C);color:#fff;border:none;border-radius:7px;
  padding:5px 10px;font:600 12px var(--ui);cursor:pointer;white-space:nowrap}
.vp-ghint-add:hover{filter:brightness(1.05)}
.vp-ghint-x{background:none;border:none;color:var(--vp-ink3,#888);font-size:17px;line-height:1;
  cursor:pointer;padding:0 2px}
.vp-ghint-x:hover{color:var(--vp-ink,#333)}
.vp-vtext{flex:1;min-width:0;line-height:1.3}
.vp-vtext b{display:block;font-size:14px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vp-vtext i{display:block;font-style:normal;font-size:12px;color:var(--vp-ink3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vp-chev{color:var(--vp-ink3);font-size:11px;flex:none;transition:transform .16s}
.vp-vsel.open .vp-chev{transform:rotate(180deg)}
.vp-vmenu{position:absolute;z-index:1100;top:calc(100% + 6px);left:0;right:0;background:var(--vp-surface);border:1px solid var(--vp-line);border-radius:10px;padding:6px;box-shadow:var(--vp-shadow);display:none;max-height:340px;overflow:auto}
.vp-vsel.open .vp-vmenu{display:block}
.vp-vopt{width:100%;display:flex;align-items:center;gap:11px;background:none;border:none;border-radius:8px;padding:7px 8px;cursor:pointer;text-align:left;color:inherit}
.vp-vopt:hover,.vp-vopt.cur{background:var(--vp-sunken)}
.vp-vopt[aria-selected="true"]{background:var(--vp-wash)}
.vp-vopt[aria-selected="true"] .vp-vtext b{color:var(--vp-ams)}
.vp-vdiv{height:1px;background:var(--vp-line);margin:6px 4px}
.vp-vadd{width:100%;display:flex;align-items:center;gap:11px;background:none;border:none;border-radius:8px;padding:9px 8px;font-size:13px;color:var(--vp-ink2);cursor:pointer;text-align:left}
.vp-vadd:hover{background:var(--vp-sunken);color:var(--vp-ams)}
.vp-plus{width:58px;height:34px;border-radius:7px;flex:none;display:grid;place-items:center;border:1px dashed var(--vp-line2);font-size:15px}
.vp-job{background:var(--vp-surface);border:1px solid var(--vp-line);border-radius:999px;padding:5px 11px;font-size:12px;color:var(--vp-ink2);cursor:pointer;white-space:nowrap}
.vp-job:hover{border-color:var(--vp-line2)}
.vp-job[aria-pressed="true"]{background:var(--vp-ams);border-color:var(--vp-ams);color:#fff}

.vp-railhead{padding:13px 18px 12px;border-bottom:1px solid var(--vp-line);flex:none}
.vp-rhtop{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:11px}
.vp-count{font-size:14px;color:var(--vp-ink2);margin:0}
.vp-count b{color:var(--vp-ink);font-weight:500}
.vp-sort{border:none;background:none;font-size:13px;color:var(--vp-ink2);cursor:pointer;padding:0}
.vp-sort:focus{outline:none}
.vp-svc{display:flex;gap:7px;overflow-x:auto;padding-bottom:2px;scrollbar-width:none}
.vp-svc::-webkit-scrollbar{display:none}
.vp-svcbtn{flex:none;background:var(--vp-sunken);border:1px solid transparent;border-radius:999px;padding:6px 13px;font-size:13px;color:var(--vp-ink2);cursor:pointer;white-space:nowrap}
.vp-svcbtn:hover{border-color:var(--vp-line2)}
.vp-svcbtn[aria-pressed="true"]{background:var(--vp-wash);border-color:var(--vp-ams);color:var(--vp-ams)}
.vp-svcbtn .n{font-size:11px;color:var(--vp-ink3);margin-left:5px}
.vp-svcbtn[aria-pressed="true"] .n{color:var(--vp-ams)}

.vp-rows{flex:1;overflow-y:auto;min-height:0}
.vp-row{display:block;width:100%;text-align:left;background:none;border:none;border-bottom:1px solid var(--vp-line);padding:0;cursor:pointer;font:inherit;color:inherit}
.vp-rowin{display:flex;gap:13px;padding:14px 18px;align-items:flex-start;transition:background .12s}
.vp-row:hover .vp-rowin,.vp-row.active .vp-rowin{background:var(--vp-sunken)}
.vp-row.active .vp-rowin{background:var(--vp-wash)}
body.dark #pg-vendors .vp-row.active .vp-rowin{background:var(--vp-sunken)}
.vp-idx{font-family:"JetBrains Mono",ui-monospace,monospace;font-size:12px;font-weight:600;color:var(--vp-ink3);width:22px;flex:none;padding-top:2px}
.vp-row.active .vp-idx{color:var(--vp-ams)}
.vp-rmain{flex:1;min-width:0}
.vp-rname{font-size:15px;font-weight:500;display:flex;align-items:center;gap:6px;flex-wrap:wrap;line-height:1.35}
.vp-check{color:var(--vp-ok);font-size:13px}
.vp-fits{font-size:10px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;background:var(--vp-okwash);color:var(--vp-ok);border-radius:4px;padding:2px 6px}
.vp-rmeta{display:block;font-size:13px;color:var(--vp-ink2);margin-top:2px;line-height:1.45}
.vp-rsvc{display:block;font-size:12px;color:var(--vp-ink3);margin-top:5px;line-height:1.45}
.vp-rsvc em{font-style:normal;color:var(--vp-ams)}
.vp-rdist{font-family:"JetBrains Mono",ui-monospace,monospace;font-size:12px;color:var(--vp-ink2);text-align:right;flex:none;padding-top:2px;line-height:1.5;white-space:nowrap}
.vp-rdist span{display:block;font-size:11px;color:var(--vp-ink3);font-family:"Inter",sans-serif}
.vp-thumbimg{width:52px;height:40px;border-radius:7px;flex:none;background:var(--vp-sunken) center/cover no-repeat;overflow:hidden}
.vp-rthumb{width:46px;height:46px;border-radius:8px;flex:none;background:var(--vp-sunken) center/cover no-repeat;
  display:grid;place-items:center;font-weight:600;font-size:16px;color:var(--vp-ink3);overflow:hidden}

.vp-detail{padding:0 18px 18px 53px;border-bottom:1px solid var(--vp-line);background:var(--vp-sunken);display:none}
.vp-detail.open{display:block}
.vp-dgrid{display:grid;grid-template-columns:auto 1fr;gap:7px 16px;font-size:13px;padding:14px 0 0}
.vp-dgrid dt{color:var(--vp-ink3)}
.vp-dgrid dd{margin:0;color:var(--vp-ink)}
.vp-dgrid dd.hit{color:var(--vp-ok);font-weight:500}
.vp-dact{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}
.vp-dbtn{background:var(--vp-surface);border:1px solid var(--vp-line2);color:var(--vp-ink);border-radius:8px;padding:7px 13px;font-size:13px;cursor:pointer;text-decoration:none;display:inline-block}
.vp-dbtn:hover{border-color:var(--vp-ink3)}
.vp-dbtn.pri{background:var(--vp-ink);border-color:var(--vp-ink);color:var(--vp-surface)}
.vp-dbtn.pri:hover{opacity:.86}

.vp-empty{padding:34px 22px;text-align:center}
.vp-empty h3{font-size:15px;font-weight:500;margin:0 0 5px}
.vp-empty p{font-size:13px;color:var(--vp-ink2);margin:0 auto 15px;max-width:34ch;line-height:1.55}
.vp-eact{display:flex;gap:8px;justify-content:center;flex-wrap:wrap}
.vp-railfoot{flex:none;border-top:1px solid var(--vp-line);padding:12px 18px;background:var(--vp-surface)}
.vp-railfoot button{width:100%;background:transparent;border:1px dashed var(--vp-line2);color:var(--vp-ink2);border-radius:8px;padding:10px;font-size:13px;cursor:pointer}
.vp-railfoot button:hover{border-color:var(--vp-ams);color:var(--vp-ams)}

.vp-mapwrap{flex:1;position:relative;min-width:0}
/* own stacking context (isolation + z-index:0) so Leaflet's marker/tooltip/
   popup panes — which its own CSS pins at z-index 600-700 — stay trapped below
   the floating filter bar (z-index:600) instead of covering it and eating clicks */
#vp-map{position:absolute;inset:0;background:var(--vp-sunken);z-index:0;isolation:isolate}
.vp-floatbar{position:absolute;top:14px;left:50%;transform:translateX(-50%);z-index:600;display:flex;gap:7px;background:var(--vp-surface);border:1px solid var(--vp-line);border-radius:999px;padding:5px;box-shadow:var(--vp-shadow);max-width:calc(100% - 28px);overflow-x:auto;scrollbar-width:none}
.vp-floatbar::-webkit-scrollbar{display:none}
.vp-fb{background:none;border:none;border-radius:999px;padding:6px 13px;font-size:13px;color:var(--vp-ink2);cursor:pointer;white-space:nowrap;display:inline-flex;align-items:center;gap:6px}
.vp-fb:hover{background:var(--vp-sunken)}
.vp-fb[aria-pressed="true"]{background:var(--vp-wash);color:var(--vp-ams)}
.vp-fb select{border:none;background:none;font-size:13px;color:inherit;cursor:pointer;padding:0}
.vp-fb select:focus{outline:none}

.vp-pin{width:28px;height:28px;border-radius:999px;background:var(--vp-surface);border:1.5px solid var(--vp-line2);display:grid;place-items:center;font-family:"JetBrains Mono",ui-monospace,monospace;font-size:12px;font-weight:600;color:var(--vp-ink2);box-shadow:0 2px 6px rgba(0,0,0,.18);transition:transform .14s,background .14s,border-color .14s,color .14s}
.vp-pin.fit{border-color:var(--vp-ok);color:var(--vp-ok)}
.vp-pin.hot{background:var(--vp-ams);border-color:var(--vp-ams);color:#fff;transform:scale(1.25);z-index:800}
#pg-vendors .leaflet-container{font-family:"Inter",sans-serif;background:var(--vp-sunken)}
#pg-vendors .leaflet-popup-content-wrapper{border-radius:9px}
.vp-pop-n{font-weight:600;font-size:14px}
.vp-pop-m{color:#5C5F66}

/* ==========================================================================
   Vendors v2 content area (vd-*). New rail + clustered map + hover cards.
   Lives inside #pg-vendors; reuses the --vp-* theme tokens above so it tracks
   light/dark with the rest of the page. The bar (.vp-bar) is untouched.
   ========================================================================== */
/* fill the viewport below the app nav (60px) + vendors bar (57px) so the map
   and list get the full height and the parent-company (MPL) footer stays below
   the fold instead of eating content area */
.vd-body{flex:1;display:flex;min-height:0;position:relative;background:var(--vp-canvas);
  height:calc(100vh - var(--navh) - 57px - var(--floor,0px))}
.vd-rail{width:404px;flex:none;background:var(--vp-surface);border-right:1px solid var(--vp-line);display:flex;flex-direction:column;min-height:0;z-index:700}
.vd-garage{padding:14px 16px;border-bottom:1px solid var(--vp-line);flex:none}
.vd-glabel{font-size:10px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--vp-ink3);margin:0 0 9px}
.vd-vsel{position:relative}
.vd-vbtn{width:100%;display:flex;align-items:center;gap:12px;background:var(--vp-sunken);border:1px solid transparent;border-radius:11px;padding:8px 13px 8px 8px;cursor:pointer;text-align:left;color:inherit;min-height:60px}
.vd-vbtn:hover{border-color:var(--vp-line2)}
.vd-vsel.open .vd-vbtn{background:var(--vp-surface);border-color:var(--vp-ams)}
.vd-vthumb{width:64px;height:44px;border-radius:8px;flex:none;overflow:hidden;background:var(--vp-line);position:relative}
.vd-vthumb img{width:100%;height:100%;object-fit:cover}
.vd-vthumb.none{display:grid;place-items:center;background:var(--vp-sunken);border:1px dashed var(--vp-line2);color:var(--vp-ink3);font-size:16px}
.vd-vtext{flex:1;min-width:0;line-height:1.3}
.vd-vtext b{display:block;font-size:14px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vd-vtext i{display:block;font-style:normal;font-size:12px;color:var(--vp-ink3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vd-vcount{font-family:"JetBrains Mono",monospace;font-size:11px;color:var(--vp-ink3);background:var(--vp-surface);border:1px solid var(--vp-line);border-radius:5px;padding:1px 6px;flex:none}
.vd-vchev{color:var(--vp-ink3);font-size:9px;flex:none;transition:transform .16s}
.vd-vsel.open .vd-vchev{transform:rotate(180deg)}
.vd-vmenu{position:absolute;z-index:1100;top:calc(100% + 7px);left:0;right:0;background:var(--vp-surface);border:1px solid var(--vp-line);border-radius:12px;padding:7px;box-shadow:var(--vp-shadow);display:none;max-height:360px;overflow:auto}
.vd-vsel.open .vd-vmenu{display:block}
.vd-vhead{font-size:10px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--vp-ink3);margin:3px 0 6px;padding:0 7px}
.vd-vopt{width:100%;display:flex;align-items:center;gap:12px;background:none;border:none;border-radius:9px;padding:7px;cursor:pointer;text-align:left;color:inherit}
.vd-vopt:hover{background:var(--vp-sunken)}
.vd-vopt[aria-selected="true"]{background:var(--vp-wash)}
.vd-vopt[aria-selected="true"] .vd-vtext b{color:var(--vp-ams)}
.vd-vjobs{font-size:11px;color:var(--vp-ink3);flex:none;font-family:"JetBrains Mono",monospace}
.vd-vdiv{height:1px;background:var(--vp-line);margin:7px 5px}
.vd-vadd{width:100%;display:flex;align-items:center;gap:12px;background:none;border:none;border-radius:9px;padding:8px 7px;font-size:13px;color:var(--vp-ink2);cursor:pointer;text-align:left}
.vd-vadd:hover{background:var(--vp-sunken);color:var(--vp-ams)}
.vd-vplus{width:64px;height:44px;border-radius:7px;flex:none;display:grid;place-items:center;border:1px dashed var(--vp-line2);font-size:16px}

.vd-jobrow{display:flex;gap:6px;flex-wrap:wrap;padding:11px 16px 0}
.vd-jobrow:empty{display:none;padding:0}
.vd-job{background:var(--vp-surface);border:1px solid var(--vp-line2);border-radius:999px;padding:5px 12px;font-size:12px;color:var(--vp-ink2);cursor:pointer;white-space:nowrap}
.vd-job:hover{border-color:var(--vp-ink3)}
.vd-job[aria-pressed="true"]{background:var(--vp-ams);border-color:var(--vp-ams);color:#fff}

/* The scope panel: one card holding the vehicle picker and, under a hairline,
   the controls that narrow what it returns. They were two stacked full-bleed
   strips with their own borders, which read as two unrelated toolbars — the
   card says "these belong to the vehicle above" without a word of copy. */
.vd-panel{background:var(--vp-surface);border:1px solid var(--vp-line);border-radius:12px;padding:7px 8px 8px}
.vd-panel .vp-vbtn{border:none;background:none;padding:7px 8px;border-radius:8px}
.vd-panel .vp-vbtn:hover{background:var(--vp-sunken)}
.vd-panel .vp-vsel.open .vp-vbtn{background:var(--vp-sunken);border:none}
.vd-prule{height:1px;background:var(--vp-line);margin:7px 2px}
.vd-controls{display:flex;align-items:center;gap:7px;padding:0 2px}
.vd-cspacer{flex:1}

.vd-modeseg{display:inline-flex;background:var(--vp-sunken);border:1px solid var(--vp-line);border-radius:999px;padding:2px;flex:none;min-width:0}
.vd-modeseg button{border:none;background:none;font-size:12px;color:var(--vp-ink2);padding:4px 10px;border-radius:999px;cursor:pointer;white-space:nowrap;line-height:1.4}
.vd-modeseg button.on{background:var(--vp-surface);color:var(--vp-ink);font-weight:500;box-shadow:0 1px 3px rgba(0,0,0,.14)}
.vd-modeseg button:hover:not(.on){color:var(--vp-ink)}
/* the per-tab count is the whole point of the segment: it says what each tab
   would give you before you spend a click finding out */
.vd-segn{color:var(--vp-ink3);margin-left:1px}
.vd-modeseg button.on .vd-segn{color:var(--vp-ink2)}
.vd-segn:empty{display:none}

.vd-savedbtn{display:inline-flex;align-items:center;gap:4px;background:none;border:none;border-radius:999px;
  padding:4px 6px;font-size:12px;color:var(--vp-ink2);cursor:pointer;white-space:nowrap;line-height:1.4}
.vd-savedbtn:hover{background:var(--vp-sunken);color:var(--vp-ink)}
.vd-heart{font-size:14px;line-height:1}
.vd-savedbtn.has{color:var(--vp-ams)}
.vd-savedbtn[aria-pressed="true"]{background:var(--vp-ams);color:#fff}
.vd-savedbtn[aria-pressed="true"]:hover{background:var(--vp-ams);color:#fff;opacity:.9}
/* a zero says nothing — the number appears once there is one to show */
#vd-savedn:empty{display:none}

/* Sort is a plain <select> in the markup, but the app upgrades every select to
   its themed dropdown (.sel/.selbtn/.pop, enhanceSelect). So this re-skins that
   widget rather than styling the native control — which is hidden at 1x1 and
   would never have shown these rules — exactly as .vd-floatbar does above for
   the radius picker. The caret is the widget's own .cv; do not add a second. */
.vd-sortwrap{display:inline-flex;align-items:center;gap:2px;padding-left:6px;border-radius:999px;
  color:var(--vp-ink2);min-width:0}
.vd-sortwrap:hover,.vd-sortwrap:focus-within{background:var(--vp-sunken);color:var(--vp-ink)}
.vd-sortwrap svg{flex:none}
#pg-vendors .vd-sortwrap .sel{display:flex;min-width:0}
#pg-vendors .vd-sortwrap .sel--box .selbtn{height:26px;padding:0 6px;border:none;background:none;
  box-shadow:none;border-radius:999px;font:400 12px "Inter",sans-serif;color:inherit;gap:6px}
#pg-vendors .vd-sortwrap .sel--box .selbtn:hover,
#pg-vendors .vd-sortwrap .sel.open.sel--box .selbtn{background:none;box-shadow:none}
#pg-vendors .vd-sortwrap .selbtn .cv{border-color:var(--vp-ink3)}
#pg-vendors .vd-sortwrap .sel.open .selbtn .cv{border-color:var(--vp-ams)}
#pg-vendors .vd-sortwrap .sel .pop{background:var(--vp-surface);border:1px solid var(--vp-line);
  border-radius:12px;box-shadow:var(--vp-shadow);padding:6px;min-width:168px}
#pg-vendors .vd-sortwrap .popopt{padding:8px 10px;border-radius:8px;font-size:13px;color:var(--vp-ink2);gap:10px}
#pg-vendors .vd-sortwrap .popopt:hover,
#pg-vendors .vd-sortwrap .popopt.cur{background:var(--vp-sunken);color:var(--vp-ink)}

.vd-rows{flex:1;overflow-y:auto;min-height:0}
.vd-row{display:flex;gap:13px;width:100%;text-align:left;background:none;border:none;border-bottom:1px solid var(--vp-line);padding:13px 16px;cursor:pointer;font:inherit;color:inherit;align-items:flex-start}
.vd-row:hover,.vd-row.active{background:var(--vp-sunken)}
.vd-row.active{background:var(--vp-wash)}
body.dark .vd-row.active{background:var(--vp-sunken)}
.vd-rthumb{width:78px;height:60px;border-radius:9px;flex:none;overflow:hidden;background:var(--vp-line);position:relative;display:grid;place-items:center;color:var(--vp-ink3);font-weight:600;font-size:20px}
.vd-rthumb img{width:100%;height:100%;object-fit:cover}
.vd-rnum{position:absolute;left:5px;top:5px;background:rgba(0,0,0,.62);color:#fff;font-family:"JetBrains Mono",monospace;font-size:10px;font-weight:600;border-radius:4px;padding:1px 5px}
.vd-rmain{flex:1;min-width:0}
.vd-rname{font-size:15px;font-weight:500;line-height:1.3;display:flex;align-items:center;gap:6px}
.vd-rname .t{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vd-check{color:var(--vp-ok);font-size:13px;flex:none}
/* Provenance marker: a listing compiled by an import rather than a member.
   Deliberately quiet — it is a footnote on the name, not a badge competing
   with the owner-verified tick. */
.vd-ai{font-size:9px;line-height:1.5;letter-spacing:.08em;text-transform:uppercase;
  flex:none;cursor:help;color:var(--vp-ink3);opacity:.62;font-weight:500;
  align-self:center;position:relative;top:.5px}
.vd-row:hover .vd-ai{opacity:.85}
/* Disclosure for the automated listings in the CURRENT results — it names how
   many, so it stays a fact about what you are looking at rather than a standing
   disclaimer the eye learns to skip. */
.vd-ainote{display:flex;align-items:baseline;gap:6px;font-size:11.5px;line-height:1.5;color:var(--vp-ink3);
  margin:0;padding:9px 18px 11px;border-bottom:1px solid var(--vp-line)}
.vd-ainote .vd-ai{flex:none;cursor:inherit;display:inline-block;opacity:1;top:0;
  background:var(--vp-sunken);color:var(--vp-ink2);border-radius:4px;padding:1px 5px}
.vd-ainote b{color:var(--vp-ink2);font-weight:500}
.vd-ainote-s{display:none}
.vd-dai{font-size:12px;line-height:1.5;color:var(--vp-ink3);margin:10px 0 0;max-width:66ch}
.vd-dai button{font:inherit;color:var(--vp-ams);background:none;border:none;padding:0;
  cursor:pointer;text-decoration:underline;text-underline-offset:2px}
.vd-dai button:hover{opacity:.8}
.vd-rcars{display:flex;gap:5px;margin-top:5px;flex-wrap:nowrap;overflow:hidden}
.vd-rcar{font-size:11px;line-height:1.5;padding:1px 7px;border-radius:5px;background:var(--vp-sunken);color:var(--vp-ink2);white-space:nowrap;flex:none}
.vd-rcar.hit{background:var(--vp-okwash);color:var(--vp-ok);font-weight:500}
.vd-rmore{font-size:11px;color:var(--vp-ink3);line-height:1.5;flex:none}
.vd-rfoot{font-size:12px;color:var(--vp-ink3);margin-top:5px;display:flex;align-items:center;gap:6px;white-space:nowrap}
.vd-stars{color:var(--vp-ams);letter-spacing:.5px;font-size:11.5px}
.vd-rsave{flex:none;font-size:16px;line-height:1;color:var(--vp-ink3);padding:2px 0 2px 4px;cursor:pointer;transition:color .12s,transform .12s;background:none;border:none}
.vd-rsave:hover{color:var(--vp-ams);transform:scale(1.15)}
.vd-rsave.on{color:var(--vp-ams)}

.vd-empty{padding:34px 22px;text-align:center}
.vd-empty h3{font-size:15px;font-weight:500;margin:0 0 6px}
.vd-empty p{font-size:13px;color:var(--vp-ink2);margin:0 auto 16px;max-width:34ch;line-height:1.55}
.vd-dbtn{background:var(--vp-ams);border:1px solid var(--vp-ams);color:#fff;border-radius:8px;padding:8px 14px;font-size:13px;cursor:pointer}
.vd-seed{margin:12px 16px 16px;border:1px dashed var(--vp-line2);border-radius:11px;padding:14px 15px;background:var(--vp-surface)}
.vd-seed h4{margin:0 0 4px;font-size:13.5px;font-weight:500}
.vd-seed p{margin:0 0 11px;font-size:12.5px;color:var(--vp-ink2);line-height:1.55}
.vd-seedbtn{background:var(--vp-ink);border:1px solid var(--vp-ink);color:var(--vp-surface);border-radius:8px;padding:7px 13px;font-size:12.5px;cursor:pointer}

.vd-stage{flex:1;position:relative;min-width:0}
#vd-map{position:absolute;inset:0;background:var(--vp-sunken);z-index:0;isolation:isolate}
/* Centre the pill WITHOUT a transform: the enhanced <select>'s dropdown is
   position:fixed, and a transform on any ancestor makes that ancestor the
   containing block for fixed children — which threw the menu off-screen so the
   distance dropdown looked dead. margin-inline centering keeps it transform-free
   so the popup positions against the viewport as intended. */
.vd-floatbar{position:absolute;top:16px;left:0;right:0;margin-inline:auto;width:max-content;max-width:calc(100% - 24px);z-index:1000;pointer-events:auto;display:flex;gap:6px;background:var(--vp-surface);border:1px solid var(--vp-line);border-radius:999px;padding:5px;box-shadow:var(--vp-shadow)}
.vd-fb{background:none;border:none;border-radius:999px;padding:7px 14px;font-size:13px;color:var(--vp-ink2);cursor:pointer;white-space:nowrap;display:inline-flex;align-items:center;gap:6px}
.vd-fb:hover{background:var(--vp-sunken)}
.vd-fb[aria-pressed="true"]{background:var(--vp-wash);color:var(--vp-ams)}
.vd-fb select{border:none;background:none;font-size:13px;color:inherit;cursor:pointer;padding:0}
.vd-fb select:focus{outline:none}
/* "Within" is a single <select> filling the whole pill, with the word overlaid
   as pointer-events:none — so a click ANYWHERE on the pill (label included) opens
   the dropdown, and there's no label/select double-fire that closes it. */
.vd-fb-within{position:relative;padding:0}
.vd-fb-within .vd-fb-lbl{position:absolute;left:14px;top:50%;transform:translateY(-50%);pointer-events:none;font-size:13px;color:var(--vp-ink2);z-index:2;font-weight:500}
.vd-fb-within select{padding:7px 14px 7px 54px}

/* The distance <select> is upgraded to the app's themed dropdown (.sel/.pop).
   Re-skin that widget for the map bar: dissolve the boxed button into the pill
   (leaving room on the left for the overlaid "Within" label) and repaint the
   menu in the vendors palette so it tracks light/dark with the rest of #pg-vendors. */
#pg-vendors .vd-floatbar .sel{display:flex;min-width:0}
#pg-vendors .vd-floatbar .sel--box .selbtn{height:32px;padding:0 13px 0 60px;border:none;background:none;box-shadow:none;border-radius:999px;font:600 13px "Inter",sans-serif;color:var(--vp-ink);gap:8px}
#pg-vendors .vd-floatbar .sel--box .selbtn:hover,
#pg-vendors .vd-floatbar .sel.open.sel--box .selbtn{background:var(--vp-sunken);box-shadow:none}
#pg-vendors .vd-floatbar .selbtn .cv{border-color:var(--vp-ink3)}
#pg-vendors .vd-floatbar .sel.open .selbtn .cv{border-color:var(--vp-ams)}
#pg-vendors .vd-floatbar .sel .pop{background:var(--vp-surface);border:1px solid var(--vp-line);border-radius:13px;box-shadow:var(--vp-shadow);padding:6px;min-width:188px}
#pg-vendors .vd-floatbar .popopt{padding:9px 11px;border-radius:9px;font-size:13px;color:var(--vp-ink2);gap:10px;font-weight:500}
#pg-vendors .vd-floatbar .popopt:hover,
#pg-vendors .vd-floatbar .popopt.cur{background:var(--vp-sunken);color:var(--vp-ink)}
#pg-vendors .vd-floatbar .popopt.on{color:var(--vp-ams);font-weight:600}
#pg-vendors .vd-floatbar .popopt .ck{color:var(--vp-ams)}

.vd-pin{width:30px;height:30px;border-radius:999px;background:var(--vp-surface);border:1.5px solid var(--vp-line2);display:grid;place-items:center;font-family:"JetBrains Mono",monospace;font-size:12px;font-weight:600;color:var(--vp-ink2);box-shadow:0 2px 7px rgba(0,0,0,.2);transition:transform .15s,background .15s,border-color .15s,color .15s}
.vd-pin.fit{border-color:var(--vp-ok);color:var(--vp-ok)}
.vd-pin.hot{background:var(--vp-ams);border-color:var(--vp-ams);color:#fff;transform:scale(1.3);z-index:800}
.vd-clus{width:42px;height:42px;border-radius:999px;background:var(--vp-surface);border:2px solid var(--vp-ams);color:var(--vp-ams);display:grid;place-items:center;font-family:"JetBrains Mono",monospace;font-size:14px;font-weight:600;box-shadow:0 3px 10px rgba(0,0,0,.22);cursor:pointer}
.vd-clus small{display:block;font-size:8px;font-family:"Inter",sans-serif;color:var(--vp-ink3);font-weight:400;letter-spacing:.03em}

.vd-bub{position:absolute;z-index:650;width:288px;background:var(--vp-surface);border:1px solid var(--vp-line);border-radius:13px;box-shadow:var(--vp-shadow);display:none;cursor:pointer;font-size:13px;overflow:hidden}
.vd-bub.on{display:block}
.vd-bubimg{position:relative;height:96px;background:var(--vp-line);overflow:hidden;display:grid;place-items:center;color:var(--vp-ink3);font-size:26px;font-weight:600}
.vd-bubimg img{width:100%;height:100%;object-fit:cover}
.vd-bubv{position:absolute;left:9px;top:9px;background:var(--vp-ok);color:#fff;font-size:10px;font-weight:600;border-radius:5px;padding:2px 7px}
.vd-bubbody{padding:10px 13px 11px}
.vd-bubname{margin:0;font-size:15px;font-weight:500;color:var(--vp-ink);line-height:1.3}
.vd-bubrate{margin:5px 0 0;display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--vp-ink3)}
.vd-bubrate b{color:var(--vp-ink);font-size:13px}
.vd-bubcars{margin:8px 0 0;display:flex;gap:5px;flex-wrap:wrap}
.vd-bubcars span{font-size:11px;background:var(--vp-sunken);color:var(--vp-ink2);border-radius:5px;padding:2px 7px}
.vd-bubcars span.hit{background:var(--vp-okwash);color:var(--vp-ok);font-weight:500}
.vd-bubfoot{margin:8px 0 0;font-size:12px;color:var(--vp-ink2)}

.vd-toggle{display:none}

/* location picker dialog (replaces the browser prompt) */
.vd-locpop{position:fixed;inset:0;z-index:3000;display:none;align-items:center;justify-content:center;padding:20px;background:rgba(0,0,0,.42)}
.vd-locpop.on{display:flex}
.vd-locpop-card{background:var(--vp-surface,#fff);border:1px solid var(--vp-line,#e6e7e9);border-radius:14px;box-shadow:0 10px 40px rgba(0,0,0,.28);width:100%;max-width:340px;padding:18px}
.vd-locpop-card h4{margin:0 0 13px;font-size:16px;font-weight:600;color:var(--vp-ink,#111)}
.vd-loc-geo{width:100%;display:inline-flex;align-items:center;justify-content:center;gap:8px;background:var(--vp-ams);border:1px solid var(--vp-ams);color:#fff;border-radius:10px;padding:11px;font-size:14px;font-weight:500;cursor:pointer}
.vd-loc-geo:hover{opacity:.92}
.vd-loc-geo:disabled{opacity:.65;cursor:default}
.vd-loc-or{display:flex;align-items:center;gap:10px;margin:14px 0;color:var(--vp-ink3);font-size:12px}
.vd-loc-or::before,.vd-loc-or::after{content:"";flex:1;height:1px;background:var(--vp-line)}
.vd-loc-form{display:flex;gap:8px}
.vd-loc-form input{flex:1;min-width:0;border:1px solid var(--vp-line2);border-radius:9px;padding:10px 12px;font-size:16px;background:var(--vp-canvas);color:var(--vp-ink)}
.vd-loc-form input:focus{outline:none;border-color:var(--vp-ams)}
.vd-loc-form button{border:none;background:var(--vp-ink);color:var(--vp-surface);border-radius:9px;padding:0 18px;font-size:14px;font-weight:500;cursor:pointer}
.vd-loc-err{color:#d9534f;font-size:12.5px;margin:9px 0 0;min-height:1em;line-height:1.4}
.vd-loc-close{width:100%;background:none;border:none;color:var(--vp-ink3);font-size:13px;padding:11px 0 1px;cursor:pointer;margin-top:6px}
.vd-loc-close:hover{color:var(--vp-ink)}

@media (max-width:1000px) and (min-width:761px){ .vd-rail{width:340px} }
/* The panel is the first thing to run out of room: at a 340px rail the controls
   want ~316px on one line. Squeezing them truncated the sort label to "C." — a
   control you cannot read is worse than a second row — so the segment takes the
   full width (its counts are the reason it exists) and the two secondary
   controls drop beneath it, right-aligned. */
@media (max-width:1000px) and (min-width:761px), (max-width:430px){
  .vd-controls{flex-wrap:wrap;gap:4px;row-gap:5px}
  .vd-modeseg{width:100%}
  .vd-modeseg button{flex:1;padding:4px 8px;text-align:center}
  .vd-cspacer{display:none}
  .vd-savedbtn{margin-left:auto;gap:2px}
  .vd-ainote-l{display:none}
  .vd-ainote-s{display:inline}
}
@media (max-width:760px){
  .vd-body{flex-direction:column;position:relative;flex:1;min-height:0;height:calc(100dvh - var(--navh) - 57px - var(--floor,0px))}
  .vd-rail{width:100%;border-right:none;height:100%}
  .vd-stage{position:absolute;inset:0;z-index:800;transform:translateY(100%);transition:transform .28s ease;visibility:hidden}
  .vd-body[data-view="map"] .vd-stage{transform:translateY(0);visibility:visible}
  .vd-body[data-view="map"] .vd-rail{visibility:hidden}
  #vd-map{position:absolute;inset:0;height:auto;z-index:0;isolation:isolate}
  .vd-jobrow{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .vd-jobrow::-webkit-scrollbar{display:none}
  .vd-job{flex:none;padding:9px 15px;font-size:13px}
  .vd-row{padding:12px;gap:12px;align-items:center}
  .vd-rthumb{width:84px;height:66px}
  .vd-rname{font-size:16px}
  .vd-rsave{font-size:22px;padding:10px 4px 10px 8px;align-self:center}
  .vd-floatbar{top:10px;left:12px;right:12px;width:auto;max-width:none;margin-inline:0;transform:none;border-radius:12px;overflow-x:auto;scrollbar-width:none;justify-content:flex-start}
  .vd-floatbar::-webkit-scrollbar{display:none}
  .vd-fb{flex:none}
  .vd-toggle{display:inline-flex;position:fixed;left:50%;transform:translateX(-50%);z-index:1500;bottom:calc(18px + var(--floor,0px));background:var(--vp-ink);color:var(--vp-canvas);border:none;border-radius:999px;height:46px;padding:0 22px;font-size:14px;font-weight:500;cursor:pointer;box-shadow:0 6px 22px rgba(0,0,0,.3);align-items:center;gap:8px}
  .vd-bub{position:fixed;left:12px;right:12px;width:auto;top:auto!important;bottom:calc(80px + var(--floor,0px));z-index:1400}
}
@media (max-width:760px) and (hover:none){ .vd-row:hover{background:none} }

@media(max-width:900px){
  #pg-vendors.vpage{overflow:visible}
  .vp-bar{flex-wrap:wrap;height:auto;padding:10px 14px;gap:9px}
  .vp-origin,.vp-brand{display:none}
  .vp-body{flex-direction:column;height:auto}
  .vp-mapwrap{height:280px;flex:none}
  #vp-map{position:relative;height:280px;z-index:0;isolation:isolate}
  .vp-rail{width:100%;border-right:none}
  .vp-rows{overflow:visible}
}

/* ═══════════════ mobile hardening (audit pass) ═══════════════ */
/* Safety net so a single stray wide child can't scroll the whole document
   sideways. overflow-x:clip (not hidden) keeps position:sticky working. */
html,body{overflow-x:clip}

@media(max-width:760px){
  /* 16px form fields stop iOS Safari from zooming the page in on focus */
  .input,textarea.input,select.input,.inp,.search .input,.search input{font-size:16px}
  /* The header's own controls are sized in 18-header-controls.php, with the
     rest of that bar. This block sized two of them and 18 sized the other four,
     so the burger came out 42px next to five 36px neighbours — the one control
     in the bar that was a different size, at the end where the eye starts. A
     stylesheet for the vendors pages has no business measuring the chrome. */
  /* raise the smallest interactive controls to a usable tap size */
  .btn-sm{min-height:40px}
  #pg-garage .ggr-seg button,.vp-svcbtn,.vp-sort,.gp-metoo,.gp-chip,.gp-tab,
  .cat-chip,.chip,.seg button,.filter a{min-height:40px}
  /* Vendors sub-bar polish: one tidy row — the search fills the width and
     "Add a vendor" collapses to a compact + button instead of wrapping to its
     own line and eating vertical space. (id+class beats the older 900px rule.) */
  #pg-vendors .vp-bar{flex-wrap:nowrap;gap:8px;padding:8px 12px;align-items:center}
  #pg-vendors .vp-search{flex:1;max-width:none;min-width:0}
  #pg-vendors .vp-sbox{height:40px}
  #pg-vendors .vp-sbox input{font-size:16px}
  #pg-vendors .vp-tbbtn-pri{flex:none;height:40px;padding:0 14px;font-size:13px;font-weight:500;
    display:inline-flex;align-items:center;gap:4px;border-radius:9px;white-space:nowrap}
  #pg-vendors .vp-tbbtn-pri::before{content:"+";font-size:18px;line-height:1;font-weight:400}
  #pg-vendors .vp-add-lg{display:none}
  #pg-vendors .vp-add-sm{display:inline}
}

/* The header's dropdowns are pinned to the viewport on phones in
   18-header-controls.php, with everything else about that bar. The rule lived
   here and named `.notif` and `.usermenu` — the classes the bell popover and
   the account menu had before either was rebuilt. `.notif` no longer exists,
   and the half of it that still matched the account menu was overridden from
   the later sheet while its `position:fixed` survived, which put the menu four
   pixels past the right edge of every phone. Same lesson as the tap sizes above
   it: one surface, one stylesheet. */

/* modal paired fields stack on the narrowest screens */
@media(max-width:480px){.amsrow{grid-template-columns:1fr}}

/* the signed-in "your context" bar on a generation page must wrap, or its
   fixed-size action buttons overflow the viewport for a logged-in owner */
@media(max-width:600px){
  #pg-vehicle .gp-yours{flex-wrap:wrap}
  #pg-vehicle .gp-yours>span{min-width:0}
  #pg-vehicle .gp-yacts{margin-left:0;width:100%;flex-wrap:wrap}
}

/* the seller "Selling" table scrolls instead of clipping price + row actions */
@media(max-width:560px){
  .sell-table{overflow-x:auto}
  .strow{min-width:360px}
}

/* THESE THREE WERE THE PHANTOM BARS. The toast, the Buy bar and the report
   button each measure from --floor in their own stylesheet — the one number
   that is the admin bar plus the phone's tab bar plus the home indicator
   (css/08-announcement-and-admin-bar.php §6) — and this block sat here
   overriding all three with heights typed by hand before --floor existed.
   Every one of them was wrong on a phone, and wrong in the same direction:
   an operator's floor there is a 34px strip PLUS a 56px tab bar PLUS the home
   indicator, and these put the toast at 80px and the Buy bar at 54px, i.e.
   UNDER the tab bar. The toast is the site's one answer to "did that work" —
   so on a phone, an operator who uploaded a photograph got the confirmation
   painted behind the navigation, which is indistinguishable from nothing
   happening at all.
   The one thing this block was right about is the last rule, and it is kept
   as what it always should have been: --fab-lift is how a SCREEN says what it
   has put in this corner, and a part page has put the Buy bar there. The
   number is that bar's own height (10 + 10 padding, ~40 of content) plus a
   gap; the home indicator is not added, because --floor already carries it. */
body.onpart{--fab-lift:70px}

/* sticky offsets that track the real nav height instead of phantom bars */
.setnav{top:calc(var(--navh) + 12px)}
.mdp .tabrail{top:var(--navh)}

/* the bottom tab bar (phones) reserves its own room via body padding-bottom;
   on wider screens there is no bar, so keep the footer's own breathing room */
body.member .foot{padding-bottom:34px}

/* ============================================================
   /vehicles — community garage (design v9). Scoped under #pg-vehicles;
   the mockup's generic class names are namespaced here so they cannot
   collide with the rest of the app. Ported from the approved v9 mockup;
   photos are real vehicle images, marks are real brand logos.
   ============================================================ */
#pg-vehicles{--text:#111827;--text-2:#4B5563;--text-3:#6B7280;
  --line:#E5E7EB;--line-2:#D1D5DB;
  --bg:#F9FAFB;--card:#FFFFFF;
  /* the accent is :root's (operator-set); only the two shades this block
     uses under its own names are mixed here */
  --accent-hover:color-mix(in srgb,var(--accent) 82%,#000);
  --accent-soft:color-mix(in srgb,var(--accent) 7%,#fff);
  --shadow:0 1px 2px rgba(16,24,40,.05);
  --shadow-lg:0 10px 24px -12px rgba(16,24,40,.28);
  --shadow-tile:0 16px 34px -20px rgba(16,24,40,.45);
  --grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='190' height='190'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");}
#pg-vehicles *{box-sizing:border-box}
#pg-vehicles{margin:0;background:var(--bg);color:var(--text);
  font-family:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased}
#pg-vehicles h1,#pg-vehicles h2,#pg-vehicles h3{margin:0}
#pg-vehicles a{text-decoration:none;color:inherit}
#pg-vehicles .wrap{max-width:var(--col);margin:0 auto;padding:0 var(--pad) 64px}
#pg-vehicles .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* Palette only — the shape is the site's one ladder (css/00b-buttons.php, §1).
   The hover used to be a hard-coded #F3F4F6, which is a grey this shell does
   not own and dark mode could not move: every button on /vehicles came up with
   a light grey wash behind it on a dark page. */
#pg-vehicles .btn{border-color:var(--line-2);background:var(--card);color:var(--text-2);font-family:inherit}
#pg-vehicles .btn:hover{background:var(--card);border-color:var(--text-3);color:var(--text)}
#pg-vehicles .btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink)}
#pg-vehicles .btn.primary:hover{background:var(--accent-hover);border-color:var(--accent-hover);color:var(--accent-ink)}
#pg-vehicles .btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
#pg-vehicles .photo{position:absolute;inset:0;
  background-image:
    radial-gradient(120% 90% at 50% 45%,transparent 42%,rgba(6,8,12,.42) 100%),
    radial-gradient(110% 75% at 20% 8%,hsla(var(--h),60%,76%,.82),transparent 60%),
    radial-gradient(95% 85% at 86% 92%,hsla(var(--h2),72%,30%,.95),transparent 68%),
    linear-gradient(158deg,hsl(var(--h),34%,46%) 0%,hsl(var(--h),42%,16%) 100%);
  background-size:cover;background-position:center;transform:scale(1.02);
  transition:transform .6s cubic-bezier(.2,.7,.3,1)}
#pg-vehicles .scrim{position:absolute;inset:0;
  background:linear-gradient(to top,rgba(8,11,16,.86) 0%,rgba(8,11,16,.30) 44%,rgba(8,11,16,0) 74%)}
#pg-vehicles .scrim::after{content:"";position:absolute;inset:0;pointer-events:none;
  opacity:.14;mix-blend-mode:overlay;background-size:190px 190px;background-image:var(--grain)}
#pg-vehicles .mark{position:relative;overflow:hidden;border-radius:5px;background:#1F2937;flex:none;
  display:flex;align-items:center;justify-content:center;width:22px;height:22px}
#pg-vehicles .mark .grain{position:absolute;inset:0;opacity:.18;mix-blend-mode:overlay;
  background-size:190px 190px;background-image:var(--grain)}
#pg-vehicles .mark b{position:relative;color:#fff;font-weight:700;letter-spacing:.02em;
  text-shadow:0 1px 2px rgba(0,0,0,.35);font-size:9px}
#pg-vehicles .mark.len1 b{font-size:11px}
#pg-vehicles .mark.len3 b{font-size:7px;letter-spacing:0}
#pg-vehicles .mark img{position:relative;width:76%;height:76%;object-fit:contain}
#pg-vehicles .mark.has-logo{background:#fff;border:1px solid var(--line)}
#pg-vehicles .mark.sm{width:16px;height:16px;border-radius:4px}
#pg-vehicles .mark.sm b{font-size:7.5px}
#pg-vehicles .mark.sm.len1 b{font-size:9px}
#pg-vehicles .mark.sm.len3 b{font-size:5.5px}
#pg-vehicles .badge-glass{position:absolute;top:10px;left:10px;display:flex;align-items:center;gap:6px;
  background:rgba(255,255,255,.16);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,.28);color:#fff;border-radius:7px;padding:3px 9px 3px 3px;
  font-size:11.5px;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:.01em}
#pg-vehicles .badge-flag{position:absolute;top:10px;right:10px;background:var(--accent);color:var(--accent-ink);
  border-radius:6px;padding:3px 9px;font-size:11px;font-weight:600;box-shadow:0 2px 8px rgba(0,0,0,.2)}
#pg-vehicles .hero{margin-bottom:26px}
#pg-vehicles .mosaic{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:178px;gap:10px}
#pg-vehicles .tile{position:relative;overflow:hidden;border-radius:12px;background:#1F2937;
  box-shadow:var(--shadow);isolation:isolate;
  animation:tileIn .5s cubic-bezier(.2,.7,.3,1) backwards;animation-delay:var(--d,0ms);
  transition:transform .22s cubic-bezier(.2,.7,.3,1),box-shadow .22s}
@keyframes tileIn{from{opacity:0;transform:translateY(10px) scale(.99)}to{opacity:1;transform:none}}
#pg-vehicles .tile:hover{transform:translateY(-3px);box-shadow:var(--shadow-tile)}
#pg-vehicles .tile:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
#pg-vehicles .tile.lead{grid-column:span 2;grid-row:span 2}
#pg-vehicles .tile:hover .photo{transform:scale(1.07)}
#pg-vehicles .tile.lead .scrim{background:linear-gradient(to top,rgba(8,11,16,.90) 0%,rgba(8,11,16,.34) 50%,rgba(8,11,16,0) 82%)}
#pg-vehicles .tile .cap{position:absolute;left:14px;right:14px;bottom:12px;color:#fff}
#pg-vehicles .tile .cap h3{font-size:15.5px;font-weight:600;letter-spacing:-.012em;text-shadow:0 1px 3px rgba(0,0,0,.45)}
#pg-vehicles .tile .cap p{margin:2px 0 0;font-size:12.5px;color:rgba(255,255,255,.80)}
#pg-vehicles .tile.lead .cap{left:20px;right:20px;bottom:18px}
#pg-vehicles .tile.lead .cap h3{font-size:26px;letter-spacing:-.028em;line-height:1.14}
#pg-vehicles .tile.lead .cap p{font-size:14px;margin-top:4px;color:rgba(255,255,255,.84)}
#pg-vehicles .tile .meta{display:none}
#pg-vehicles .tile.lead .meta{display:flex;align-items:center;gap:8px;margin-top:11px;padding-top:10px;
  border-top:1px solid rgba(255,255,255,.18);color:rgba(255,255,255,.86);font-size:12.5px}
#pg-vehicles .tile.lead .meta .sep{color:rgba(255,255,255,.4)}
#pg-vehicles .tile .avatar{width:22px;height:22px;border-radius:50%;background:rgba(255,255,255,.20);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,.32);color:#fff;display:flex;align-items:center;
  justify-content:center;font-size:9.5px;font-weight:600;flex:none}
#pg-vehicles .mosaic-foot{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:12px}
#pg-vehicles .mosaic-foot .count{font-size:13px;color:var(--text-3)}
#pg-vehicles .mosaic-foot .count b{color:var(--text);font-weight:600}
#pg-vehicles .mosaic-foot .spacer{flex:1}
#pg-vehicles .link-a{font-size:13px;font-weight:500;color:var(--accent);border-radius:6px;padding:4px 2px}
#pg-vehicles .link-a:hover{text-decoration:underline}
#pg-vehicles .link-a:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
#pg-vehicles .select-panel{background:var(--card);border:1px solid var(--line);border-radius:12px;
  box-shadow:var(--shadow);margin-bottom:26px;overflow:hidden}
#pg-vehicles .sp-head{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--line)}
#pg-vehicles .sp-head h2{font-size:14px;font-weight:600}
#pg-vehicles .sp-head .hint{font-size:12.5px;color:var(--text-3)}
#pg-vehicles .sp-head .spacer{flex:1}
#pg-vehicles .seg{display:inline-flex;background:#F3F4F6;border-radius:8px;padding:3px}
#pg-vehicles .seg button{border:0;background:none;cursor:pointer;color:var(--text-2);font-family:inherit;font-size:12.5px;
  font-weight:500;padding:5px 12px;border-radius:6px;transition:background .15s,color .15s,box-shadow .15s}
#pg-vehicles .seg button[aria-pressed="true"]{background:#fff;color:var(--text);box-shadow:var(--shadow)}
#pg-vehicles .sp-body{padding:14px}
#pg-vehicles .filters{display:grid;grid-template-columns:1fr 1fr 1fr auto;gap:10px;align-items:end;transition:opacity .18s}
#pg-vehicles .field label{display:block;font-size:12px;font-weight:500;color:var(--text-2);margin-bottom:5px}
#pg-vehicles .select{position:relative}
#pg-vehicles .select select{appearance:none;-webkit-appearance:none;width:100%;height:38px;padding:0 32px 0 11px;
  border:1px solid var(--line-2);border-radius:8px;background:#fff;font-family:inherit;font-size:13.5px;
  color:var(--text);cursor:pointer;transition:border-color .15s,box-shadow .15s}
#pg-vehicles .select select:hover:not(:disabled){border-color:#9CA3AF}
#pg-vehicles .select select:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(234,88,12,.14)}
#pg-vehicles .select select:disabled{background:#F9FAFB;color:#9CA3AF;cursor:not-allowed}
#pg-vehicles .select .chev{position:absolute;right:11px;top:50%;width:7px;height:7px;pointer-events:none;
  border-right:1.6px solid #6B7280;border-bottom:1.6px solid #6B7280;transform:translateY(-70%) rotate(45deg)}
#pg-vehicles .filters .btn{height:38px}
#pg-vehicles .filters .btn[disabled]{background:#E5E7EB;border-color:#E5E7EB;color:#9CA3AF;cursor:not-allowed}
#pg-vehicles .sp-foot{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-top:11px;padding-top:11px;
  border-top:1px solid var(--line);font-size:12.5px;color:var(--text-3)}
#pg-vehicles .sp-foot b{color:var(--text);font-weight:600}
#pg-vehicles .recents{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-left:auto}
#pg-vehicles .chip-btn{font-family:inherit;font-size:12px;color:var(--text-2);cursor:pointer;background:#F3F4F6;
  border:1px solid var(--line);border-radius:999px;padding:3px 10px;
  transition:background .15s,border-color .15s,color .15s}
#pg-vehicles .chip-btn:hover{background:#fff;border-color:var(--accent);color:var(--accent)}
#pg-vehicles .select-panel.set .sp-body{display:none}
#pg-vehicles .sp-set{display:none;align-items:center;gap:10px;flex-wrap:wrap;padding:12px 14px}
#pg-vehicles .select-panel.set .sp-set{display:flex}
#pg-vehicles .ymm-chip{display:inline-flex;align-items:center;gap:7px;background:var(--accent-soft);border:1px solid #FED7AA;
  color:#7C2D12;border-radius:999px;padding:6px 13px;font-size:13.5px;font-weight:600}
#pg-vehicles .ymm-chip .tick{width:16px;height:16px;border-radius:50%;background:var(--accent);color:var(--accent-ink);
  display:flex;align-items:center;justify-content:center;font-size:9.5px}
#pg-vehicles .link-btn{background:none;border:0;font-family:inherit;font-size:12.5px;font-weight:500;color:var(--accent);
  cursor:pointer;padding:3px 5px;border-radius:6px}
#pg-vehicles .link-btn:hover{text-decoration:underline}
#pg-vehicles .link-btn.muted{color:var(--text-3)}
#pg-vehicles .sec-head{display:flex;align-items:center;gap:10px;margin-bottom:12px}
#pg-vehicles .sec-head h2{font-size:15.5px;font-weight:600;letter-spacing:-.014em}
#pg-vehicles .sec-head .count{color:var(--text-3);font-size:12.5px;font-variant-numeric:tabular-nums}
#pg-vehicles .sec-head .spacer{flex:1}
#pg-vehicles .browse{display:grid;grid-template-columns:232px 1fr;gap:18px;align-items:start}
#pg-vehicles .rail{background:var(--card);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow);
  position:sticky;top:16px;display:flex;flex-direction:column;
  max-height:calc(100vh - 32px - var(--floor,0px));overflow:hidden}
#pg-vehicles .rail-head{display:flex;align-items:center;gap:8px;padding:9px 12px;border-bottom:1px solid var(--line);flex:none}
#pg-vehicles .rail-head h3{font-size:13px;font-weight:600}
#pg-vehicles .rail-head .spacer{flex:1}
#pg-vehicles #clearAll{display:none}
#pg-vehicles #clearAll.on{display:inline-block}
#pg-vehicles .rail-top{padding:10px 12px 8px;flex:none;border-bottom:1px solid var(--line)}
#pg-vehicles .rail-scroll{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:2px 12px 10px;
  scrollbar-width:thin;scrollbar-color:var(--line-2) transparent}
#pg-vehicles .rail-scroll::-webkit-scrollbar{width:9px}
#pg-vehicles .rail-scroll::-webkit-scrollbar-track{background:transparent}
#pg-vehicles .rail-scroll::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:5px;
  border:2.5px solid #fff;background-clip:padding-box}
#pg-vehicles .rail-scroll::-webkit-scrollbar-thumb:hover{background:#9CA3AF;background-clip:padding-box;
  border:2.5px solid #fff}
#pg-vehicles .search{position:relative}
#pg-vehicles .search input{width:100%;height:33px;padding:0 28px 0 30px;border:1px solid var(--line-2);border-radius:8px;
  background:#fff;font-family:inherit;font-size:13px;color:var(--text);
  transition:border-color .15s,box-shadow .15s}
#pg-vehicles .search input::placeholder{color:#9CA3AF}
#pg-vehicles .search input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(234,88,12,.14)}
#pg-vehicles .search .mag{position:absolute;left:10px;top:50%;transform:translateY(-50%);width:11px;height:11px;
  border:1.6px solid #9CA3AF;border-radius:50%;pointer-events:none}
#pg-vehicles .search .mag::after{content:"";position:absolute;right:-4px;bottom:-3px;width:5px;height:1.6px;
  background:#9CA3AF;transform:rotate(45deg)}
#pg-vehicles .search .clear-q{position:absolute;right:5px;top:50%;transform:translateY(-50%);border:0;background:none;
  cursor:pointer;color:var(--text-3);font-size:15px;line-height:1;padding:3px 5px;border-radius:6px;display:none}
#pg-vehicles .search .clear-q.on{display:block}
#pg-vehicles .search .clear-q:hover{color:var(--text)}
#pg-vehicles .facet{border-top:1px solid var(--line);padding:8px 0 2px;margin-top:5px}
#pg-vehicles .facet:first-of-type{border-top:0;margin-top:2px}
#pg-vehicles .facet>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:8px;padding:4px 5px;
  border-radius:7px;font-size:12.5px;font-weight:600;color:var(--text);transition:background .12s}
#pg-vehicles .facet>summary::-webkit-details-marker{display:none}
#pg-vehicles .facet>summary:hover{background:#F3F4F6}
#pg-vehicles .facet>summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
#pg-vehicles .facet>summary .spacer{flex:1}
#pg-vehicles .facet>summary .tag{font-size:10.5px;font-weight:600;color:var(--accent-ink);background:var(--accent);border-radius:999px;
  min-width:16px;height:16px;display:none;align-items:center;justify-content:center;padding:0 5px;
  font-variant-numeric:tabular-nums}
#pg-vehicles .facet.has-active>summary .tag{display:flex}
#pg-vehicles .facet>summary .chev{width:6.5px;height:6.5px;border-right:1.6px solid #9CA3AF;border-bottom:1.6px solid #9CA3AF;
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .18s}
#pg-vehicles .facet[open]>summary .chev{transform:rotate(-135deg)}
#pg-vehicles .fsearch{padding:5px 5px 3px}
#pg-vehicles .fsearch input{width:100%;height:28px;padding:0 9px;border:1px solid var(--line);border-radius:7px;
  background:#F9FAFB;font-family:inherit;font-size:12.5px;color:var(--text);
  transition:border-color .15s,background .15s,box-shadow .15s}
#pg-vehicles .fsearch input::placeholder{color:#9CA3AF}
#pg-vehicles .fsearch input:focus{outline:none;background:#fff;border-color:var(--accent);
  box-shadow:0 0 0 3px rgba(234,88,12,.12)}
#pg-vehicles .opts{padding:1px 0 2px}
#pg-vehicles .nomatch{font-size:12px;color:var(--text-3);padding:6px 5px}
#pg-vehicles .more{background:none;border:0;font-family:inherit;font-size:12px;font-weight:500;color:var(--accent);
  cursor:pointer;padding:5px;border-radius:6px;display:none}
#pg-vehicles .more.on{display:inline-block}
#pg-vehicles .more:hover{text-decoration:underline}
#pg-vehicles .more:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
#pg-vehicles .opt{display:flex;align-items:center;gap:8px;padding:4px 5px;border-radius:7px;cursor:pointer;
  transition:background .12s}
#pg-vehicles .opt:hover{background:#F3F4F6}
#pg-vehicles .opt input{position:absolute;opacity:0;width:0;height:0}
#pg-vehicles .opt .box{width:15px;height:15px;border-radius:4.5px;border:1.5px solid var(--line-2);background:#fff;flex:none;
  display:flex;align-items:center;justify-content:center;transition:background .13s,border-color .13s}
#pg-vehicles .opt .box::after{content:"";width:7.5px;height:3.5px;border-left:1.8px solid #fff;border-bottom:1.8px solid #fff;
  transform:rotate(-45deg) translate(1px,-1px);opacity:0;transition:opacity .13s}
#pg-vehicles .opt input:checked+.box{background:var(--accent);border-color:var(--accent)}
#pg-vehicles .opt input:checked+.box::after{opacity:1}
#pg-vehicles .opt input:focus-visible+.box{outline:2px solid var(--accent);outline-offset:2px}
#pg-vehicles .opt .lbl{font-size:13px;color:var(--text-2);flex:1;line-height:1.35;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#pg-vehicles .opt input:checked~.lbl{color:var(--text);font-weight:500}
#pg-vehicles .opt .n{font-size:11.5px;color:var(--text-3);font-variant-numeric:tabular-nums;flex:none}
#pg-vehicles .opt.zero{opacity:.4}
#pg-vehicles .opt.zero:hover{background:none}
#pg-vehicles .applied{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:11px}
#pg-vehicles .applied:empty{display:none}
#pg-vehicles .afchip{display:inline-flex;align-items:center;gap:6px;background:var(--accent-soft);border:1px solid #FED7AA;
  color:#7C2D12;border-radius:999px;padding:4px 7px 4px 11px;font-family:inherit;font-size:12px;
  font-weight:500;cursor:pointer;transition:background .15s,border-color .15s}
#pg-vehicles .afchip:hover{background:#FFEDD5;border-color:#FDBA74}
#pg-vehicles .afchip:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
#pg-vehicles .afchip .x{font-size:13px;line-height:1;color:#C2410C}
#pg-vehicles .rail-toggle{display:none}
#pg-vehicles .grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
#pg-vehicles .vehicle{position:relative;background:var(--card);border:1px solid var(--line);border-radius:11px;
  overflow:hidden;box-shadow:var(--shadow);display:flex;flex-direction:column;
  transition:border-color .18s,box-shadow .18s,transform .18s}
#pg-vehicles .vehicle:hover{border-color:var(--line-2);box-shadow:var(--shadow-lg);transform:translateY(-3px)}
#pg-vehicles .vehicle:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
#pg-vehicles .thumb{position:relative;aspect-ratio:3/2;overflow:hidden;background:#1F2937;display:block}
#pg-vehicles .vehicle:hover .thumb .photo{transform:scale(1.08)}
#pg-vehicles .thumb .cap{position:absolute;left:11px;right:11px;bottom:9px;color:#fff}
#pg-vehicles .thumb .cap h3{font-size:14.5px;font-weight:600;letter-spacing:-.012em;text-shadow:0 1px 3px rgba(0,0,0,.45)}
#pg-vehicles .thumb .cap p{margin:1px 0 0;font-size:12px;color:rgba(255,255,255,.80)}
#pg-vehicles .thumb .badge-glass{top:9px;left:9px;padding:2px 8px 2px 2px;gap:5px;font-size:11px}
#pg-vehicles .thumb .badge-flag{top:9px;right:9px}
#pg-vehicles .v-body{padding:9px 11px 11px;display:flex;flex-direction:column;gap:8px;flex:1}
#pg-vehicles .owner{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text-2);
  overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
#pg-vehicles .owner .avatar{width:19px;height:19px;border-radius:50%;background:#374151;color:#fff;flex:none;
  display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:600}
#pg-vehicles .owner .dot{color:var(--line-2)}
#pg-vehicles .chips{display:flex;flex-wrap:wrap;gap:5px;margin-top:auto}
#pg-vehicles .chips span{font-size:11px;color:var(--text-2);background:#F3F4F6;border-radius:5px;padding:2px 7px}
#pg-vehicles .loadmore{display:flex;justify-content:center;margin-top:16px}
#pg-vehicles .loadmore[hidden]{display:none}
#pg-vehicles .empty{background:#fff;border:1px dashed var(--line-2);border-radius:12px;padding:34px 24px;text-align:center}
#pg-vehicles .empty h3{font-size:14.5px;font-weight:600;margin-bottom:4px}
#pg-vehicles .empty p{margin:0 0 13px;color:var(--text-3);font-size:13px}
@media (max-width:1080px){#pg-vehicles .mosaic{grid-auto-rows:158px}#pg-vehicles .tile.lead .cap h3{font-size:23px}#pg-vehicles .browse{grid-template-columns:210px 1fr;gap:14px}#pg-vehicles .grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:900px){#pg-vehicles .browse{grid-template-columns:1fr}#pg-vehicles .rail{position:static;display:none;margin-bottom:14px;max-height:none}#pg-vehicles .rail.open{display:flex}#pg-vehicles .rail-scroll{max-height:58vh}#pg-vehicles .rail-toggle{display:inline-flex}#pg-vehicles .rail-toggle .tag{background:var(--accent);color:var(--accent-ink);border-radius:999px;min-width:17px;height:17px;
    display:none;align-items:center;justify-content:center;font-size:10.5px;font-weight:600;padding:0 5px}#pg-vehicles .rail-toggle.has-active .tag{display:flex}#pg-vehicles .grid{grid-template-columns:repeat(3,1fr)}}
@media (max-width:820px){#pg-vehicles .mosaic{grid-template-columns:repeat(2,1fr);grid-auto-rows:150px}#pg-vehicles .tile.lead{grid-column:span 2;grid-row:span 2}#pg-vehicles .tile.lead .cap h3{font-size:23px}#pg-vehicles .grid{grid-template-columns:repeat(2,1fr)}#pg-vehicles .filters{grid-template-columns:1fr 1fr}#pg-vehicles .filters .btn{grid-column:1/-1}}
@media (max-width:520px){#pg-vehicles .wrap{padding:0 var(--pad) 52px}#pg-vehicles .mosaic{grid-template-columns:1fr;grid-auto-rows:136px;gap:9px}#pg-vehicles .tile.lead{grid-column:span 1;grid-row:span 2}#pg-vehicles .tile:nth-child(n+4){display:none}#pg-vehicles .tile.lead .cap{left:16px;right:16px;bottom:16px}#pg-vehicles .tile.lead .cap h3{font-size:22px}#pg-vehicles .mosaic-foot{gap:9px}#pg-vehicles .mosaic-foot .btn{width:100%}#pg-vehicles .grid{grid-template-columns:1fr}#pg-vehicles .filters{grid-template-columns:1fr}#pg-vehicles .sec-head{flex-wrap:wrap}}
@media (prefers-reduced-motion:reduce){#pg-vehicles *{transition:none!important}#pg-vehicles .tile{animation:none}}

/* ---- dark theme: remap the page palette + the handful of hardcoded light
   surfaces, keeping layout/structure identical ---- */
body.dark #pg-vehicles{
  --text:#E6E8EC;--text-2:#AEB4BE;--text-3:#828A96;
  --line:#2A2F38;--line-2:#3A404B;
  --bg:#16181D;--card:#1C1F26;
  --accent-hover:color-mix(in srgb,var(--accent) 78%,#fff);
  --accent-soft:color-mix(in srgb,var(--accent) 12%,#000);
  --shadow:0 1px 2px rgba(0,0,0,.4);
  --shadow-lg:0 10px 24px -12px rgba(0,0,0,.6);
  --shadow-tile:0 16px 34px -20px rgba(0,0,0,.7);
}
body.dark #pg-vehicles .btn:hover{background:#23272F}
body.dark #pg-vehicles .seg{background:#23272F}
body.dark #pg-vehicles .seg button[aria-pressed="true"]{background:#31363F;color:var(--text)}
body.dark #pg-vehicles .select select{background:#20242B;border-color:var(--line-2);color:var(--text)}
body.dark #pg-vehicles .select select:disabled{background:#1A1D23;color:#6B7280}
body.dark #pg-vehicles .filters .btn[disabled]{background:#23272F;border-color:#23272F;color:#6B7280}
body.dark #pg-vehicles .chip-btn{background:#23272F;color:var(--text-2)}
body.dark #pg-vehicles .chip-btn:hover{background:#2C313A}
body.dark #pg-vehicles .search input{background:#20242B;color:var(--text)}
body.dark #pg-vehicles .fsearch input{background:#1A1D23;color:var(--text)}
body.dark #pg-vehicles .fsearch input:focus{background:#20242B}
body.dark #pg-vehicles .opt:hover{background:#23272F}
body.dark #pg-vehicles .facet>summary:hover{background:#23272F}
body.dark #pg-vehicles .opt .box{background:#20242B;border-color:var(--line-2)}
body.dark #pg-vehicles .chips span{background:#23272F;color:var(--text-2)}
body.dark #pg-vehicles .empty{background:var(--card)}
body.dark #pg-vehicles .rail-scroll::-webkit-scrollbar-thumb{border-color:var(--card)}
body.dark #pg-vehicles .mark.has-logo{background:#fff}
body.dark #pg-vehicles .afchip,body.dark #pg-vehicles .ymm-chip{color:#FDBA74;border-color:#5A3A22}
body.dark #pg-vehicles .afchip .x{color:#FDBA74}
body.dark #pg-vehicles .afchip:hover{background:#3A2818;border-color:#7A4A28}


/* --- v9 polish overrides: neutralize app-global class collisions (.hero/.photo/
   .mosaic) and apply the requested logo/spacing tweaks --- */
#pg-vehicles .hero{padding:0;margin-bottom:26px}
#pg-vehicles .hero::before{content:none}
#pg-vehicles .vg-finder{margin-bottom:26px}
/* the app's global .photo shows a placeholder via ::before/::after until a
   .hasimg flag, and .mosaic .photo starts at opacity:0 — both would blank our
   real inline background-images. We use our own .scrim, so drop them here. */
#pg-vehicles .photo{opacity:1;animation:none}
#pg-vehicles .photo::before,#pg-vehicles .photo::after{content:none!important}
/* brand logos: bigger and unboxed (no white tile / border) */
#pg-vehicles .mark{width:24px;height:24px}
#pg-vehicles .mark.sm{width:20px;height:20px;border-radius:5px}
/* logos: unboxed, capped to a consistent height with natural width */
#pg-vehicles .mark.has-logo{width:auto;min-width:20px;background:none;border:none;border-radius:0;overflow:visible;justify-content:flex-start}
#pg-vehicles .mark.has-logo img{height:20px;width:auto;max-width:52px;object-fit:contain;display:block}
#pg-vehicles .mark.sm.has-logo img{height:16px;max-width:40px}
/* FACET rows: a fixed logo gutter so every brand label lines up — kills the
   ragged clear space. Logos vary in aspect (square emblems vs wide wordmarks),
   so they fit the gutter, left-aligned and vertically centered. */
#pg-vehicles .opt .mark.has-logo{width:30px;min-width:30px;height:22px;overflow:hidden}
#pg-vehicles .opt .mark.has-logo img{max-width:30px;max-height:22px;width:auto;height:auto}
/* the glassy top-left bubble sits over a photo, so a bare logo washes out —
   give it a light chip THERE (only there) so every mark reads clearly */
#pg-vehicles .badge-glass .mark.has-logo{background:rgba(255,255,255,.94);border-radius:5px;padding:2px 3px;overflow:hidden}
#pg-vehicles .badge-glass .mark.sm.has-logo img{height:14px;max-width:34px}
body.dark #pg-vehicles .mark.has-logo{background:none;border:none}
body.dark #pg-vehicles .badge-glass .mark.has-logo{background:rgba(255,255,255,.94)}


/* ================= MODS (server-rendered) =================
   The Mods section is drawn by PHP (app/render-mods.php + views/app/mods/*),
   so nothing in here is hydrated or repainted by the bundle. The geometry is
   the Mods design 1:1 — tile sizes, radii, the 880px breakpoint — while every
   colour is a theme token, so the section is at home in light and dark and
   follows the operator's accent like the rest of the site. */
/* Mods ran to 1600px here — it started 190px further out than /garage on a wide
   screen. It caps at var(--col) with everything else now; the tiles get their
   room from the grid's column count, not a page-specific cap (§11). */
/* NB: no `#pg-mods a{...}` reset here. An id selector outranks every class in
   this block, so one would silently beat .btn-primary / .md-sort[aria-current]
   and paint their labels the inherited colour — a black button with an
   invisible label. The global `a{color:inherit}` already does this job. */

/* --- page head + "my mods" (no top pad: `.page` gives the gap under the nav) --- */
.md-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:0 0 10px}
.md-head-t{min-width:0}
.md-head h1{font-size:20px;font-weight:700;letter-spacing:-.022em;margin:0}
.md-strap{margin:3px 0 0;font-size:13.5px;color:var(--t3)}
.md-minewrap{position:relative;flex:none}
.md-tip{position:absolute;top:calc(100% + 8px);right:0;z-index:5;width:260px;max-width:calc(100vw - 32px);
  background:var(--surface);border:1px solid var(--border2);border-radius:10px;box-shadow:var(--sh-lg);padding:12px 13px 8px}
.md-tip::before{content:"";position:absolute;top:-5px;right:24px;width:8px;height:8px;background:var(--surface);
  border-left:1px solid var(--border2);border-top:1px solid var(--border2);transform:rotate(45deg)}
.md-tip p{margin:0 0 6px;font-size:13px;line-height:1.5;color:var(--t2)}
.md-tip-x{display:inline-block;padding:5px 0;font-size:13px;font-weight:600;color:var(--accent-fg)}
.md-mine{display:inline-flex;align-items:center;gap:8px;min-height:36px;border:1px solid var(--border2);
  border-radius:var(--r);padding:7px 14px;color:var(--t2);font-size:13.5px;font-weight:500;background:var(--surface)}
.md-mine:hover{color:var(--text);border-color:var(--t3)}
.md-num{font-size:11.5px;font-weight:600;padding:1px 6px;border-radius:4px;background:var(--accent-soft);color:var(--accent-fg)}
.md-chev{width:14px;height:14px;color:var(--t3)}

/* --- vehicle strip --- */
/* Wraps onto as many rows as it needs: every car you own is on screen at once,
   nothing hides off the right-hand edge behind a scroll nobody notices.
   A tile is sized for a year/make/model — the name it carries is the car's
   catalogue identity, which is longer than a nickname and is the whole point
   of the strip, so it should not ellipsis on the common ones. */
.md-strip{display:flex;flex-wrap:wrap;gap:9px;padding:2px 0 14px}
.md-veh{position:relative;flex:none;width:170px;height:96px;border-radius:10px;
  overflow:hidden;background:var(--surface2);display:block;
  transition:transform .16s var(--ease),box-shadow .16s var(--ease)}
.md-veh:hover{transform:translateY(-2px);box-shadow:var(--sh)}
.md-veh-img{position:absolute;inset:0;background:#26262c center/cover no-repeat}
.md-veh-img::after{content:"";position:absolute;inset:0;
  background:linear-gradient(to top,rgba(8,8,11,.94),rgba(8,8,11,.45) 55%,rgba(8,8,11,.1))}
.md-veh-in{position:relative;z-index:2;height:100%;display:flex;flex-direction:column;justify-content:flex-end;padding:0 11px 10px}
.md-veh-in strong{display:block;font-size:13.5px;line-height:1.25;font-weight:600;letter-spacing:-.012em;color:#fff;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-shadow:0 1px 3px rgba(0,0,0,.55)}
.md-veh-in span{display:block;font-size:11.5px;line-height:1.3;color:rgba(255,255,255,.88);text-shadow:0 1px 2px rgba(0,0,0,.5)}
.md-veh-in .md-none{color:var(--accent)}
.md-veh[aria-current]{box-shadow:0 0 0 2px var(--canvas),0 0 0 4px var(--accent)}
.md-veh-flat{background:var(--surface2);border:1px solid var(--border2)}
.md-veh-flat .md-veh-in{justify-content:space-between;padding:11px}
.md-veh-flat .md-veh-in strong{color:var(--text)}
.md-veh-flat .md-veh-in span{color:var(--t3)}
.md-veh-flat:hover{border-color:var(--t3)}
.md-veh-flat[aria-current]{border-color:var(--accent)}
.md-ic{color:var(--t3);display:block}
.md-ic svg{width:19px;height:19px}
.md-veh-dice{background:var(--accent);border-color:var(--accent)}
.md-veh-dice .md-veh-in strong,.md-veh-dice .md-ic{color:#fff}
.md-veh-dice .md-veh-in span{color:rgba(255,255,255,.82)}
.md-veh-add{border-style:dashed;background:transparent}
.md-veh-add:hover{border-color:var(--accent)}
.md-veh-add:hover .md-ic,.md-veh-add:hover .md-veh-in strong{color:var(--accent)}

/* Three sizes of car tile, chosen from the strip's heading. The number is the
   tile width; the name under it has to survive the small one, which is why S
   loses the count line rather than the name. */
.md-strip-s .md-veh{width:132px;height:78px}
.md-strip-s .md-veh-in{padding:0 9px 8px}
.md-strip-s .md-veh-in strong{font-size:12.5px}
.md-strip-l .md-veh{width:224px;height:132px}
.md-strip-l .md-veh-in strong{font-size:15px}
.md-sizes{margin-left:auto;display:flex;gap:2px;flex:none}
.md-size{display:inline-flex;align-items:center;justify-content:center;
  min-width:28px;min-height:28px;padding:0 7px;border-radius:6px;
  font-size:12px;font-weight:600;letter-spacing:.02em;color:var(--t3)}
.md-size:hover{background:var(--surface2);color:var(--text)}
.md-size[aria-current]{background:var(--surface3);color:var(--text)}

/* --- section heads --- */
.md-sec{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;padding-top:8px;margin-bottom:3px}
.md-sec h2{font-size:19px;font-weight:700;letter-spacing:-.02em;margin:0}
.md-n{font-size:13px;color:var(--t3)}
.md-sorts{margin-left:auto;display:flex;gap:2px;overflow-x:auto;scrollbar-width:none}
.md-sorts::-webkit-scrollbar{display:none}
.md-sort{white-space:nowrap;min-height:38px;display:inline-flex;align-items:center;padding:6px 12px;
  border-radius:6px;font-size:13px;font-weight:500;color:var(--t3)}
.md-sort:hover{color:var(--text);background:var(--surface2)}
.md-sort[aria-current]{color:var(--canvas);background:var(--text);font-weight:600}
.md-sub{margin:0 0 16px;font-size:14px;color:var(--t2);max-width:62ch}

/* --- build tiles --- */
.md-grid{display:grid;grid-template-columns:1fr;gap:12px}
.md-tile{position:relative;display:block;width:100%;border-radius:12px;overflow:hidden;
  background:var(--surface2);aspect-ratio:16/10;transition:transform .16s var(--ease),box-shadow .16s var(--ease)}
.md-tile:hover{transform:translateY(-3px);box-shadow:var(--sh-lg)}
.md-tile-img{position:absolute;inset:0;background:#26262c center/cover no-repeat;transition:transform .5s var(--ease)}
.md-tile:hover .md-tile-img{transform:scale(1.04)}
/* The scrim carries the text, so it is heavier at the bottom than the mockup's
   and the type sits on a shadow — a title over a bright bonnet stays readable. */
.md-tile::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top,rgba(6,6,9,.96) 0%,rgba(6,6,9,.88) 26%,rgba(6,6,9,.6) 48%,
             rgba(6,6,9,.16) 76%,rgba(6,6,9,.34) 100%)}
.md-tile-ph{position:absolute;inset:0;background:var(--surface3);display:flex;align-items:center;justify-content:center;color:var(--t3)}
.md-tile-ph svg{width:28px;height:28px}
.md-tile-top{position:absolute;z-index:2;top:11px;left:12px;right:12px;display:flex;align-items:flex-start;gap:8px}
.md-tagline{font-size:11px;font-weight:600;color:#fff;background:rgba(255,255,255,.18);
  backdrop-filter:blur(6px);padding:4px 9px;border-radius:4px}
.md-tagline-draft{background:rgba(8,8,10,.55)}
.md-heat{margin-left:auto;display:inline-flex;align-items:center;gap:5px;font-size:11px;font-weight:600;
  padding:4px 9px;border-radius:4px;color:#fff;background:rgba(8,8,10,.48);backdrop-filter:blur(6px)}
.md-heat svg{width:11px;height:11px}
.md-heat-hot{background:var(--accent)}
.md-heat-open{color:#ffcaa8}
.md-tile-in{position:absolute;z-index:2;left:12px;right:12px;bottom:12px;display:block}
.md-tile-h{display:block;font-family:var(--dis);font-size:18px;font-weight:700;letter-spacing:-.02em;color:#fff;
  margin:0 0 4px;text-shadow:0 1px 3px rgba(0,0,0,.55)}
.md-tile-p{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  margin:0 0 11px;font-size:13px;line-height:1.5;color:rgba(255,255,255,.9);text-shadow:0 1px 2px rgba(0,0,0,.5)}
.md-tile-foot{display:flex;align-items:center;gap:9px}
.md-faces{display:flex;align-items:center}
.md-faces .av{box-shadow:0 0 0 2px rgba(255,255,255,.9)}
.md-who{font-size:12px;color:rgba(255,255,255,.9);text-shadow:0 1px 2px rgba(0,0,0,.5)}
.md-count{margin-left:auto;font-size:12px;color:rgba(255,255,255,.88);text-shadow:0 1px 2px rgba(0,0,0,.5)}
.md-bar{position:absolute;z-index:3;left:0;right:0;bottom:0;height:3px;background:rgba(255,255,255,.16)}
.md-bar>i{display:block;height:100%;background:var(--accent)}
.md-add{aspect-ratio:16/10;border:1px dashed var(--border2);border-radius:12px;display:flex;
  flex-direction:column;align-items:center;justify-content:center;gap:6px;color:var(--t2);text-align:center;padding:12px}
.md-add:hover{border-color:var(--accent);background:var(--accent-soft)}
.md-add svg{width:21px;height:21px;color:var(--t3)}
.md-add:hover svg{color:var(--accent)}
.md-add strong{font-size:14px;font-weight:600;color:var(--text)}
.md-add span{font-size:12.5px;color:var(--t3)}

/* --- questions --- */
.md-asks-sec{margin-top:38px}
.md-asks{display:grid;gap:10px}
.md-ask{position:relative;display:flex;align-items:flex-start;gap:12px;flex-wrap:wrap;background:var(--surface);
  border:1px solid var(--border);border-radius:10px;padding:14px 15px}
.md-ask-open{border-left:3px solid var(--accent)}
.md-ask-done{background:var(--surface2)}
.md-ask .btn{width:100%}
.md-ask-main{flex:1;min-width:0}
.md-kick{font-size:12px;color:var(--t3);margin-bottom:3px;display:flex;align-items:center;gap:7px}
.md-ask h3{font-size:15px;font-weight:600;margin:0 0 2px;letter-spacing:-.01em}
.md-ask p{margin:0;font-size:13.5px;color:var(--t2)}
.md-by{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--t3);flex:none}
.md-blank{border:1px dashed var(--border2);border-radius:10px;padding:26px 20px;text-align:center;color:var(--t2);font-size:14px}
.md-blank b{color:var(--text)}
.md-none-line{font-size:14px;color:var(--t3);margin:0}
.md-err{margin:0 0 16px;padding:10px 13px;border-radius:var(--r);font-size:13.5px;
  background:var(--accent-soft);border:1px solid var(--accent-line);color:var(--accent-fg)}

/* --- add what you know --- */
.md-know{margin-top:40px;padding:22px;background:var(--surface2);border-radius:12px}
.md-know h3{font-size:16px;font-weight:700;letter-spacing:-.015em;margin:0 0 5px}
.md-know p{margin:0 0 14px;font-size:13.5px;color:var(--t2);max-width:58ch}
.md-chips{display:flex;gap:7px;flex-wrap:wrap}
.md-chip{display:inline-flex;align-items:center;min-height:36px;background:var(--surface);border:1px solid var(--border2);
  border-radius:6px;padding:8px 15px;font-size:13px;color:var(--t2)}
.md-chip:hover{border-color:var(--accent);color:var(--accent-fg)}

/* --- sub-page head (no top pad, same reason as .md-head) --- */
.md-pagehead{display:flex;align-items:center;gap:12px;padding:0 0 4px}
.md-back{display:inline-flex;align-items:center;gap:6px;padding:6px 0;color:var(--t3);font-size:13.5px;font-weight:500}
.md-back:hover{color:var(--accent-fg)}
.md-back svg{width:17px;height:17px}

/* --- a build --- */
.md-cover{position:relative;border-radius:10px;overflow:hidden;background:var(--surface2);aspect-ratio:16/9;margin-bottom:18px}
.md-cover-img{position:absolute;inset:0;background:#26262c center/cover no-repeat}
.md-cover-ph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:var(--t3);background:var(--surface3)}
.md-cover-ph svg{width:34px;height:34px}
.md-detail{max-width:820px}
.md-detail h1{font-size:23px;font-weight:700;letter-spacing:-.026em;margin:0 0 8px}
.md-byline{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--t3);margin-bottom:16px;flex-wrap:wrap}
.md-flag{font-size:11.5px;font-weight:600;padding:3px 9px;border-radius:4px;background:var(--accent-soft);color:var(--accent-fg)}
.md-lead{font-size:15px;color:var(--t2);margin:0 0 14px}
.md-fit{display:flex;align-items:center;gap:7px;font-size:13.5px;color:var(--t3);margin-bottom:8px}
.md-fit svg{width:16px;height:16px;flex:none}
.md-fit b{color:var(--t2);font-weight:500}
.md-fit a{text-decoration:underline;text-underline-offset:2px}
.md-credit{font-size:13px;color:var(--t3);margin:0 0 8px}
.md-credit a{text-decoration:underline;text-underline-offset:2px}
.md-tally{display:flex;gap:16px;flex-wrap:wrap;font-size:13.5px;color:var(--t3);margin:12px 0 0}
.md-tally b{color:var(--text);font-weight:600}
.md-actions{display:grid;grid-template-columns:1fr;gap:8px;padding:18px 0 4px;margin-top:18px;border-top:1px solid var(--border)}
.md-actions .btn,.md-actions form{width:100%}
.md-actions .btn{height:42px}
.md-sh{font-size:12px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--t3);
  margin:30px 0 12px;display:flex;align-items:center;gap:10px}
.md-sh::after{content:"";flex:1;height:1px;background:var(--border)}
.md-entries{list-style:none;margin:0;padding:0}
.md-entry{display:flex;gap:12px;border-bottom:1px solid var(--border);padding:14px 0}
.md-entry-n{flex:none;width:24px;font-size:13px;font-weight:600;color:var(--t3);padding-top:2px}
.md-entry-b{flex:1;min-width:0}
.md-entry-b strong{display:block;font-size:15px;font-weight:600;margin-bottom:3px}
.md-entry-b p{margin:0 0 4px;font-size:14px;color:var(--t2)}
.md-entry-b small{font-size:12.5px;color:var(--t3)}
.md-entry-ph{display:flex;gap:6px;margin:8px 0}
.md-entry-ph>span{width:74px;height:54px;border-radius:6px;background:var(--surface2) center/cover no-repeat}
.md-todo{list-style:none;margin:0;padding:0;display:grid;gap:9px}
.md-todo li{display:flex;align-items:center;gap:10px;font-size:14.5px;color:var(--t2)}
.md-todo svg{width:18px;height:18px;flex:none;color:var(--t3)}
.md-todo li.md-ok{color:var(--t3)}
.md-todo li.md-ok svg{color:var(--accent)}
.md-qbox{border:1px solid var(--border);border-radius:10px;padding:15px 16px;margin-bottom:9px}
.md-qbox strong{display:block;font-size:15.5px;margin-bottom:5px}
.md-qbox p{margin:0 0 11px;font-size:14px;color:var(--t2)}
.md-reply{border-left:2px solid var(--accent);padding:9px 0 9px 13px;margin-top:11px}
.md-reply .md-kick{margin-bottom:4px}
.md-reply p{margin:0}
.md-tools{font-size:13.5px;color:var(--t2);margin:0 0 12px}
.md-steps{margin:0;padding:0 0 0 20px;display:grid;gap:14px}
.md-steps li{font-size:14px}
.md-steps strong{display:block;font-size:15px;font-weight:600;margin-bottom:3px}
.md-steps p{margin:0 0 4px;color:var(--t2)}
.md-steps small{font-size:12.5px;color:var(--t3)}
.md-stepwarn{color:var(--accent-fg)!important}
.md-parts{width:100%;border-collapse:collapse;font-size:14px}
.md-parts td{border-bottom:1px solid var(--border);padding:10px 0;vertical-align:top}
.md-parts strong{display:block;font-weight:600}
.md-parts small{display:block;font-size:12.5px;color:var(--t3)}
.md-parts .pill{margin-top:4px}
.md-parts .md-qty{width:70px;color:var(--t3);text-align:right;white-space:nowrap}
.md-parts .md-cost{width:90px;text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.md-parts tr.md-alt td{color:var(--t3)}
.md-parts tfoot td{font-weight:600;border-bottom:0;padding-top:12px}
.md-files{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.md-files a{display:flex;align-items:center;gap:11px;border:1px solid var(--border);border-radius:var(--r);padding:11px 13px}
.md-files a:hover{border-color:var(--border2);background:var(--surface2)}
.md-files svg{width:18px;height:18px;color:var(--t3);flex:none}
.md-files strong{display:block;font-size:14px;font-weight:600}
.md-files small{font-size:12.5px;color:var(--t3)}
.md-photos{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:8px}
.md-photos>span{aspect-ratio:4/3;border-radius:8px;background:var(--surface2) center/cover no-repeat}

/* --- forms --- */
.md-formpage{max-width:620px}
.md-formpage h1{font-size:22px;font-weight:700;letter-spacing:-.024em;margin:0 0 6px}
.md-lede{font-size:14px;color:var(--t2);margin:0 0 22px}
.md-f{margin-bottom:20px}
.md-f label{display:block;font-size:13.5px;font-weight:600;margin-bottom:7px}
.md-f .input{font-size:16px;height:auto;padding:13px 14px;border-radius:8px}
.md-f textarea.input{min-height:130px}
.md-hint{font-size:13px;color:var(--t3);margin-top:6px}
.md-picks{display:flex;flex-wrap:wrap;gap:8px}
.md-pick{position:relative;display:inline-flex;margin:0}
.md-pick input{position:absolute;opacity:0;width:0;height:0}
.md-pick span{display:inline-flex;align-items:center;border:1px solid var(--border2);border-radius:6px;
  padding:9px 16px;font-size:14px;color:var(--t2);min-height:40px;background:var(--surface)}
.md-pick input:checked+span{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:600}
.md-pick input:focus-visible+span{outline:2px solid var(--accent);outline-offset:2px}
.md-pick-wide{display:flex}
.md-formfoot{display:grid;grid-template-columns:1fr;gap:9px;padding-top:8px}
.md-formfoot .btn{width:100%;height:44px}
.md-quote{background:var(--surface2);border-radius:10px;padding:15px 16px;margin-bottom:22px}
.md-quote strong{display:block;font-size:15.5px;margin-bottom:5px}
.md-quote p{margin:0;font-size:14px;color:var(--t2)}

/* --- my mods (the page itself is css/17-my-mods.php; the row is shared) --- */
.md-row{position:relative;display:flex;align-items:flex-start;gap:12px;width:100%;
  border-bottom:1px solid var(--border);padding:13px 0;transition:background .12s var(--ease)}
.md-row:hover{background:var(--surface2)}
.md-row-img,.md-row-ph{width:68px;height:50px;border-radius:6px;flex:none;background:var(--surface2) center/cover no-repeat}
.md-row-ph{border:1px dashed var(--border2);display:flex;align-items:center;justify-content:center;color:var(--t3)}
.md-row-ph svg{width:19px;height:19px}
.md-row-t{flex:1;min-width:0}
.md-row-t strong{display:block;font-size:15px;font-weight:600;letter-spacing:-.013em;margin-bottom:2px}
.md-row-t small{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  font-size:13px;color:var(--t2)}
.md-row-meta{display:block;font-size:12.5px;color:var(--t3);margin-top:3px}
.md-row-side{flex:none;display:flex;align-items:center;gap:10px;align-self:center}
.md-row-side .md-go{display:none;width:17px;height:17px;color:var(--border2);flex:none}
.md-row:hover .md-go{color:var(--accent)}
.md-state{font-size:11.5px;font-weight:600;padding:3px 8px;border-radius:4px;white-space:nowrap}
.md-state-ready{background:var(--accent);color:var(--accent-ink)}
.md-state-need{background:var(--surface2);color:var(--t3);border:1px solid var(--border2)}
/* "Published" is the settled state, so it is the quietest of the three — and it
   sits on a photo, which is why it carries its own background rather than
   inheriting whatever is behind it. */
.md-state-live{background:var(--surface);color:var(--t2);border:1px solid var(--border2)}
.md-newrow:hover .md-row-ph{border-color:var(--accent);color:var(--accent)}

@media (min-width:880px){
  .md-head{padding:0 0 12px}
  .md-head h1{font-size:24px}
  .md-veh{width:186px;height:104px}
  .md-strip-s .md-veh{width:146px;height:88px}
  .md-strip-l .md-veh{width:248px;height:146px}
  .md-grid{grid-template-columns:repeat(auto-fill,minmax(310px,1fr));gap:16px}
  .md-detail h1{font-size:32px}
  .md-cover{aspect-ratio:16/6.5}
  .md-lead{font-size:16px}
  .md-actions{display:flex;flex-wrap:wrap}
  .md-actions .btn,.md-actions form{width:auto}
  .md-formpage h1{font-size:29px}
  .md-formfoot{display:flex}
  .md-formfoot .btn{width:auto;min-width:150px}
  .md-ask{align-items:center;flex-wrap:nowrap}
  .md-ask .btn{width:auto}
  .md-row{align-items:center;gap:15px;padding:15px 4px 15px 0}
  .md-row-img,.md-row-ph{width:82px;height:58px}
  .md-row-t strong{font-size:16px}
  .md-row-side .md-go{display:block}
}
@media (max-width:879px){
  .md-chip{min-height:42px;padding:10px 15px}
  .md-sort{min-height:40px;padding:8px 13px}
  .md-back{padding:10px 0;font-size:14px}
  .md-row{padding:15px 0}
  .md-know{padding:18px}
  .md-sh{margin:24px 0 10px}
}
/* Below this the fixed tile no longer leaves room for two across, and one car
   per row turns the strip into a column you scroll past. The pair shares the
   row instead and the name ellipsises, which is the cheaper loss. */
@media (max-width:479px){
  .md-veh,.md-strip-m .md-veh,.md-strip-l .md-veh{width:calc(50% - 5px)}
  .md-strip-s .md-veh{width:calc(33.333% - 6px)}
}
@media (prefers-reduced-motion:reduce){
  .md-tile:hover,.md-veh:hover{transform:none}
  .md-tile:hover .md-tile-img{transform:none}
}



/* ============================================================
   EVENTS — browse (list, calendar, map)
   ------------------------------------------------------------
   Everything here is drawn from the app's own tokens, so the whole
   section follows the light/dark toggle like the rest of the site
   (CONVENTIONS: one theme, not a second palette bolted on).

   The one addition is a colour per event kind. Meets, shows, track
   days and cruises have to be told apart at a glance on a map pin
   and a calendar chip, where there is no room for a word — so each
   kind gets a hue, defined once, in both themes.
   ============================================================ */
:root{
  --ev-show:var(--accent);      --ev-show-soft:var(--accent-soft);
  --ev-meet:#7C3AED;            --ev-meet-soft:#F5F1FE;
  --ev-track:#B45309;           --ev-track-soft:#FEF3E2;
  --ev-cruise:#0369A1;          --ev-cruise-soft:#E6F4FB;
  --ev-swap:#15803D;            --ev-swap-soft:#F0FDF4;
}
body.dark{
  --ev-meet:#A78BFA;            --ev-meet-soft:rgba(167,139,250,.12);
  --ev-track:#FBBF24;           --ev-track-soft:rgba(251,191,36,.12);
  --ev-cruise:#38BDF8;          --ev-cruise-soft:rgba(56,189,248,.12);
  --ev-swap:#4ADE80;            --ev-swap-soft:rgba(74,222,128,.12);
}
.pill-kind{border-color:transparent}
.pill-show  {background:var(--ev-show-soft);  color:var(--accent-fg)}
.pill-meet  {background:var(--ev-meet-soft);  color:var(--ev-meet)}
.pill-track {background:var(--ev-track-soft); color:var(--ev-track)}
.pill-race  {background:var(--ev-track-soft); color:var(--ev-track)}
.pill-cruise{background:var(--ev-cruise-soft);color:var(--ev-cruise)}
.pill-swap  {background:var(--ev-swap-soft);  color:var(--ev-swap)}
.pill-other {background:var(--surface2);      color:var(--t2)}

/* ---------- page bar: title, view tabs, primary action ---------- */
.evbar{position:sticky;top:var(--navh);z-index:44;display:flex;align-items:center;gap:12px;
  min-height:52px;padding:8px 0;margin-bottom:4px;
  background:color-mix(in srgb,var(--canvas) 92%,transparent);backdrop-filter:blur(12px);
  border-bottom:1px solid var(--border)}
.evbar h1{font-size:22px;letter-spacing:-.036em}
.evbar .cnt{font-size:12.5px;color:var(--t3);font-variant-numeric:tabular-nums}
.evtabs{display:flex;gap:2px;margin-left:10px;padding-left:14px;border-left:1px solid var(--border)}
.evtab{display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 11px;border-radius:var(--r);
  font-size:13px;font-weight:500;color:var(--t2);transition:background .14s,color .14s}
.evtab:hover{background:var(--surface2);color:var(--text)}
.evtab[aria-current]{background:var(--text);color:var(--canvas)}
.evtab svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round;flex:none}
.evbar .btn-primary{margin-left:auto}

/* ---------- browse shell: content, with a filter rail that slides ---------- */
.evbrowse{display:grid;grid-template-columns:0 minmax(0,1fr);gap:0;padding-top:20px;
  align-items:start;transition:grid-template-columns .24s var(--ease),gap .24s var(--ease)}
.evbrowse.open{grid-template-columns:224px minmax(0,1fr);gap:30px}
.evrail{position:sticky;top:calc(var(--navh) + 68px);
  max-height:calc(100vh - var(--navh) - 92px - var(--floor,0px));
  overflow-y:auto;overflow-x:hidden;min-width:0;padding-right:2px;transition:opacity .18s ease}
.evbrowse:not(.open) .evrail{opacity:0;visibility:hidden;pointer-events:none}
.evmain{min-width:0}
.evrail-h{display:flex;align-items:center;padding-bottom:11px;border-bottom:1px solid var(--border)}
.evrail-h b{font-size:10px;font-weight:600;letter-spacing:.11em;color:var(--t3);text-transform:uppercase}
.evrail-h .clr{margin-left:auto;font-size:12.5px;font-weight:500;color:var(--accent-fg)}
.evrail-h .x{margin-left:10px;width:24px;height:24px;border-radius:6px;display:grid;place-items:center;
  color:var(--t3);font-size:15px;line-height:1}
.evrail-h .x:hover{background:var(--surface2);color:var(--text)}
.evgroup{padding:14px 0;border-bottom:1px solid var(--border)}
.evgroup:last-child{border-bottom:0}
.evgroup h4{font-size:10px;font-weight:600;letter-spacing:.11em;color:var(--t3);margin:0 0 7px;
  text-transform:uppercase;font-family:var(--ui)}
.evopt{display:flex;align-items:center;gap:9px;margin:0 -8px;padding:6px 8px;border-radius:8px;
  font-size:13.5px;color:var(--t2);cursor:pointer;transition:background .12s,color .12s}
.evopt:hover{background:var(--surface2);color:var(--text)}
.evopt input{accent-color:var(--accent);width:15px;height:15px;margin:0;flex:none;cursor:pointer}
.evopt .n{margin-left:auto;font-size:12px;color:var(--t3);font-variant-numeric:tabular-nums}
.evopt .sw{width:26px;height:19px;border-radius:5px;flex:none;background:var(--surface3) center/cover no-repeat}
.evrail .slider{width:100%;accent-color:var(--accent);margin:8px 0 3px}
.evmiles{display:flex;justify-content:space-between;font-size:11.5px;color:var(--t3);
  font-variant-numeric:tabular-nums}
.evnote{font-size:11.5px;color:var(--t3);margin-top:6px}

/* ---------- results bar ---------- */
.evres{display:flex;align-items:center;gap:12px;padding-bottom:16px;flex-wrap:wrap;min-height:34px}
.evres .crit{font-size:13.5px;color:var(--t2)}
.evres .crit b{color:var(--text);font-weight:600}
.evres .sortsel{margin-left:auto;height:32px;width:auto;padding:0 10px;font-size:13px;font-weight:500}
.evfilterbtn[aria-expanded="true"]{background:var(--text);border-color:var(--text);color:var(--canvas)}
.evscrim{position:fixed;inset:0;background:rgba(8,8,12,.45);z-index:94;display:none}
.evscrim.on{display:block}

/* ---------- the featured event ---------- */
.evfeat{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(300px,.85fr);
  border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);
  box-shadow:var(--sh-sm);margin-bottom:18px;transition:box-shadow .2s,border-color .2s}
.evfeat:hover{box-shadow:var(--sh);border-color:var(--border2)}
.evfeat .photo{border-radius:0;min-height:330px;height:100%}
.evfeat-b{padding:22px;display:flex;flex-direction:column;gap:13px}
.evfeat-b h2{font-size:26px;letter-spacing:-.035em}
.evfeat-tags{display:flex;gap:7px;flex-wrap:wrap}
.evfeat-facts{display:grid;gap:8px}
.evfeat .cta{display:flex;gap:9px;flex-wrap:wrap;margin-top:auto;padding-top:6px}
.evbadge{position:absolute;top:14px;left:14px;z-index:3;display:inline-flex;align-items:center;gap:7px;
  height:28px;padding:0 12px;border-radius:8px;background:var(--surface);color:var(--accent-fg);
  border:1px solid var(--border);font-size:12.5px;font-weight:600;box-shadow:var(--sh-sm)}
.evbadge::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--accent)}

/* ---------- the stand-in cover ----------
   An event with no photo still needs to look like something. The hue comes
   from the event's own title (set inline as --h), so the page is varied and
   one event keeps its colour everywhere it appears. Real uploads replace this
   wholesale — nothing here leaks into a card that has a picture. */
.photo.evph{position:relative;overflow:hidden;isolation:isolate;
  background:linear-gradient(158deg,hsl(var(--h,210) 18% 94%),hsl(var(--h,210) 16% 83%))}
body.dark .photo.evph{background:linear-gradient(158deg,hsl(var(--h,210) 14% 22%),hsl(var(--h,210) 16% 13%))}
.photo.evph::before{content:"";position:absolute;inset:0;
  background:radial-gradient(110% 80% at 22% 8%,rgba(255,255,255,.5),transparent 62%)}
body.dark .photo.evph::before{background:radial-gradient(110% 80% at 22% 8%,rgba(255,255,255,.07),transparent 62%)}
/* The DIRECT child only. This used to read `.photo.evph svg`, which also
   caught the operator pencil's own icon — the picker drops that button inside
   this same .photo, so on every event with no cover the little edit glyph was
   blown up to 44% of the card, centred, faded and pointer-events:none. The
   artwork is always the immediate child; anything nested is somebody else's. */
.photo.evph > svg{position:absolute;left:50%;top:54%;translate:-50% -50%;
  width:44%;max-width:200px;min-width:70px;height:auto;display:block;z-index:1;
  fill:hsl(var(--h,210) 14% 50%);opacity:.32;pointer-events:none}
body.dark .photo.evph > svg{fill:hsl(var(--h,210) 12% 82%);opacity:.16}

/* ---------- event card additions ----------
   A column, so the going/host footer sits on the bottom edge and cards in the
   same grid row line up however much text each one carries. */
.evcard{position:relative;display:flex;flex-direction:column}
.evcard .body{flex:1}
.evcard .photo{aspect-ratio:16/10}
.evdatechip{position:absolute;top:12px;left:12px;z-index:3;background:var(--surface);border-radius:8px;
  border:1px solid var(--border);padding:6px 9px;text-align:center;box-shadow:var(--sh-sm);min-width:48px}
.evdatechip span{display:block;font-size:9.5px;font-weight:600;letter-spacing:.08em;color:var(--accent-fg)}
.evdatechip b{display:block;font-family:var(--dis);font-variant-numeric:tabular-nums;font-size:18px;
  font-weight:600;letter-spacing:-.035em;line-height:1.1}
.evdistchip{position:absolute;top:12px;right:12px;z-index:3;height:24px;padding:0 10px;border-radius:7px;
  display:inline-flex;align-items:center;background:rgba(8,8,12,.62);backdrop-filter:blur(8px);
  color:#fff;font-size:11.5px;font-weight:500}
.evwline{display:flex;align-items:center;gap:7px;font-size:12.5px;font-weight:500;color:var(--t2);margin-top:8px}
.evwline svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.7;flex:none;opacity:.8}
.evwline.restricted{color:var(--ev-track)}

/* the roll call: who is actually turning up */
.evroll{display:flex;align-items:center;gap:12px;padding:12px 16px;border-top:1px solid var(--border)}
.evroll-stack{display:flex}
.evroll-stack span{width:36px;height:36px;border-radius:8px;flex:none;margin-right:-8px;
  border:2px solid var(--surface);background:var(--surface3) center/cover no-repeat;
  box-shadow:var(--sh-sm);transition:transform .2s var(--ease)}
.evroll-stack span:hover{transform:translateY(-3px);z-index:5}
.evroll-more{display:grid;place-items:center;font-size:11px;font-weight:600;color:var(--t2);
  background:var(--surface2)!important}
.evroll-txt{margin-left:14px;font-size:12.5px;color:var(--t3);line-height:1.35}
.evroll-txt b{display:block;color:var(--text);font-weight:600;font-size:13px}
.evfeat .evroll{padding-left:0;padding-right:0}
.evfeat .evroll-stack span{width:42px;height:42px}

/* ---------- from your garage ---------- */
.evgarage{margin-top:34px;border:1px solid var(--border);border-radius:var(--r-lg);
  background:var(--surface2);padding:24px}
.evgarage-h{display:flex;align-items:flex-start;gap:20px;flex-wrap:wrap;margin-bottom:18px}
.evgarage-h h2{font-size:20px;letter-spacing:-.03em}
.evgarage-h p{color:var(--t2);font-size:13.5px;margin-top:5px;max-width:56ch}
.evgarage-h a{margin-left:auto;color:var(--accent-fg);font-weight:500;font-size:13.5px;white-space:nowrap}
/* auto-FILL, not auto-fit: with one car in the garage, auto-fit collapses the
   empty tracks and stretches that single tile to the full width — a garage of
   one should not render a metre-wide photo */
.evgarage-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:14px}
.evgcar{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);overflow:hidden}
.evgcar .th{display:block;width:100%;aspect-ratio:16/9;background:var(--surface3) center/cover no-repeat}
.evgcar-b{padding:12px 14px}
.evgcar-b h4{font-size:15px;letter-spacing:-.025em}
.evgcar-b p{font-size:12.5px;color:var(--t3);margin-top:3px}
.evgcar-s{display:flex;align-items:center;gap:7px;padding:10px 14px;border-top:1px solid var(--border);
  font-size:12.5px;font-weight:500}
.evgcar-s svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2.2;flex:none}
.evgcar-s.on{color:var(--green)} .evgcar-s.off{color:var(--t3)}

/* ---------- calendar ---------- */
.evcalwrap{overflow-x:auto}
.evcal{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);
  overflow:hidden;min-width:660px}
.evcal-h{display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid var(--border)}
.evcal-h h3{font-size:16px;letter-spacing:-.032em;min-width:172px;font-variant-numeric:tabular-nums}
.evcal-nav{display:flex;gap:6px}
.evcal-nav button{width:30px;height:30px;border:1px solid var(--border2);border-radius:8px;
  display:grid;place-items:center;color:var(--t2);background:var(--surface)}
.evcal-nav button:hover{background:var(--surface2);color:var(--text)}
.evcal-nav svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2.2}
.evcal-dow{display:grid;grid-template-columns:repeat(7,1fr);background:var(--surface2);
  border-bottom:1px solid var(--border)}
.evcal-dow span{padding:8px 10px;font-size:10px;font-weight:600;letter-spacing:.09em;color:var(--t3)}
.evcal-grid{display:grid;grid-template-columns:repeat(7,1fr)}
.evcal-cell{min-height:106px;padding:6px;display:flex;flex-direction:column;gap:3px;
  border-right:1px solid var(--border);border-bottom:1px solid var(--border)}
.evcal-cell:nth-child(7n){border-right:0}
.evcal-cell.out{background:var(--surface2)}
.evcal-cell.out .evcal-n{opacity:.4}
.evcal-n{font-size:12px;font-weight:600;color:var(--t2);width:22px;height:20px;display:grid;
  place-items:center;border-radius:5px;flex:none;font-variant-numeric:tabular-nums}
.evcal-cell.today .evcal-n{background:var(--accent);color:var(--accent-ink)}
.evcal-ev{display:block;text-align:left;padding:4px 6px 4px 7px;border-radius:5px;
  background:var(--surface2);border-left:2px solid var(--c);font-size:11px;line-height:1.32;overflow:hidden}
.evcal-ev:hover{background:var(--accent-soft)}
.evcal-ev b{display:block;font-weight:600;letter-spacing:-.015em;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.evcal-ev span{color:var(--t3);font-size:10.5px}
/* the days a multi-day event continues through, quieter than the day it starts */
.evcal-ev.span{background:transparent;opacity:.72;border-left-style:dotted}
.evcal-ev.span b{font-weight:500}
.evcal-legend{display:flex;gap:18px;flex-wrap:wrap;padding:12px 16px;border-top:1px solid var(--border);
  font-size:12px;color:var(--t2)}
.evcal-legend em{display:inline-flex;align-items:center;gap:7px;font-style:normal}
.evcal-legend i{width:10px;height:2px;border-radius:1px;display:block}

/* ---------- map view: the map IS the page here ---------- */
.evmapview{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:16px;align-items:start}
.evmapview .ev-map,.evmaplist{height:calc(100vh - var(--navh) - 168px - var(--floor,0px));min-height:460px}
.evmapview .ev-map{border-radius:var(--r-lg);border:1px solid var(--border)}
.evmaplist{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);overflow-y:auto}
.evmaph{position:sticky;top:0;z-index:2;padding:10px 15px;font-size:10px;font-weight:600;
  letter-spacing:.1em;color:var(--t3);border-bottom:1px solid var(--border);
  background:color-mix(in srgb,var(--surface) 94%,transparent);backdrop-filter:blur(8px)}
.evmrow{display:flex;gap:12px;padding:12px 15px;width:100%;text-align:left;align-items:center;
  border-bottom:1px solid var(--border);transition:background .13s}
.evmrow:hover{background:var(--surface2)}
.evmrow.on{background:var(--accent-soft)}
.evmrow-d{width:44px;flex:none;text-align:center;border:1px solid var(--border);border-radius:7px;
  padding:5px 0;background:var(--surface)}
.evmrow-d span{display:block;font-size:9.5px;font-weight:600;color:var(--accent-fg);letter-spacing:.06em}
.evmrow-d b{display:block;font-family:var(--dis);font-size:16px;font-weight:600;letter-spacing:-.035em;
  line-height:1.15;font-variant-numeric:tabular-nums}
.evmrow-t{min-width:0;flex:1}
.evmrow-t b{display:block;font-size:13.5px;font-weight:600;letter-spacing:-.025em;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.evmrow-t span{display:block;font-size:12px;color:var(--t3);margin-top:2px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.evmrow-c{flex:none;text-align:right}
.evmrow-c b{display:block;font-variant-numeric:tabular-nums;font-size:13px;font-weight:600;color:var(--accent-fg)}
.evmrow-c span{display:block;font-size:11px;color:var(--t3)}

@media (max-width:1080px){
  .evfeat{grid-template-columns:1fr}
  .evfeat .photo{min-height:0;aspect-ratio:16/9}
  .evmapview{grid-template-columns:1fr}
  .evmapview .ev-map{height:52vh;min-height:320px}
  .evmaplist{height:auto;max-height:44vh;min-height:0}
}
@media (max-width:960px){
  .evbrowse,.evbrowse.open{grid-template-columns:minmax(0,1fr);gap:0}
  .evrail{position:fixed;left:0;top:0;bottom:var(--floor,0px);width:290px;z-index:95;background:var(--surface);
    max-height:none;padding:18px;border-right:1px solid var(--border);overflow-y:auto;
    transform:translateX(-100%);transition:transform .22s var(--ease)}
  .evbrowse:not(.open) .evrail{opacity:1;visibility:hidden}
  .evbrowse.open .evrail{transform:none;visibility:visible;box-shadow:var(--sh-lg)}
}
@media (max-width:820px){
  .evbar{min-height:0;flex-wrap:nowrap;gap:8px}
  .evbar h1{font-size:19px}
  .evbar .cnt{display:none}
  .evtabs{margin-left:auto;padding-left:0;border-left:0;gap:1px}
  .evtab{padding:0 9px}
  .evtab .lbl{display:none}
  .evbar .btn-primary{margin-left:0;padding:0 10px}
  .evbar .btn-primary .lbl{display:none}
  .evgarage{padding:18px;margin-top:26px}
  .evgarage-grid{grid-template-columns:1fr}
  .evcal-cell{min-height:88px}
}


/* ============================================================
   EVENTS — one event
   ------------------------------------------------------------
   The hero, the facts strip and the side rail. Everything below
   reuses the app's .card / .pill / .btn, so this file only holds
   what an event page genuinely has and no other page does:
   the facts row, the "what's welcome" panel, and the run of show.
   ============================================================ */

/* ---------- the facts under the hero ---------- */
.evfacts{display:flex;flex-wrap:wrap;gap:14px 40px;padding:22px 0 24px;border-bottom:1px solid var(--border)}
.evfact{display:flex;gap:11px;align-items:flex-start}
.evfact > svg{width:19px;height:19px;stroke:var(--accent);fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;flex:none;margin-top:2px}
/* the other facts are accent STROKES; the car is a filled silhouette, so the
   accent has to arrive as colour for its currentColor fill to pick up. */
.evfact > svg.vehmark{color:var(--accent)}
.evfact b{display:block;font-size:14px;font-weight:600;letter-spacing:-.02em}
.evfact span{display:block;font-size:12.5px;color:var(--t2);margin-top:1px}

/* ---------- section headings inside the event ---------- */
.evsect{padding-bottom:26px;margin-bottom:26px;border-bottom:1px solid var(--border)}
.evsect:last-child{border-bottom:0;margin-bottom:0;padding-bottom:0}
.evsect-h{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:15px}
.evsect-h h2{font-size:19px;letter-spacing:-.03em}
.evsect-h .n{display:inline-flex;align-items:center;height:22px;padding:0 9px;border-radius:6px;
  background:var(--accent-soft);color:var(--accent-fg);font-size:12px;font-weight:600}
.evsect-h .right{margin-left:auto;font-size:12.5px;color:var(--t3)}
.evprose{color:var(--t2);font-size:14.5px;line-height:1.68;max-width:66ch;white-space:pre-wrap}

/* ---------- what's welcome ----------
   Only the class tiles and the year cutoff are machine-checked; the
   rules underneath are the host's own words. The header colour says
   which of those two the reader is looking at. */
.evwelcome{border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden;background:var(--surface)}
/* Base = any vehicle, but the host set conditions: neutral, because neither a
   green welcome nor a warning would be true. .restricted = the vehicle itself
   may not qualify, which is the only case worth colouring. */
.evwel-top{display:flex;align-items:center;gap:10px;padding:12px 15px;
  background:var(--surface2);color:var(--t2)}
.evwel-top.restricted{background:var(--ev-track-soft);color:var(--ev-track)}
.evgnote{font-size:11.5px;color:var(--t3);line-height:1.45;margin:8px 0 0;padding-top:9px;
  border-top:1px solid var(--border)}
.evwel-top svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2.2;flex:none}
.evwel-top b{font-size:14px;font-weight:600;letter-spacing:-.022em}
/* auto-fit, not a fixed count: the tiles are the vehicle_classes taxonomy
   minus whatever the events screens hide (EV_HIDE_CLASS), so the number of
   them is data. Three today; a hardcoded 4 left a gap, and a hardcoded 3
   would break the day the taxonomy moves. */
.evwtiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(92px,1fr));gap:1px;
  background:var(--border);border-top:1px solid var(--border)}
.evwtile{background:var(--surface);padding:14px 8px;text-align:center;position:relative}
/* sized off the tile, not fixed at 40x17: the car is the site's vehicle mark
   now (EV_CAR_MARK) and its wheel arches, windows and door handle fall under a
   pixel at the old size and fill in solid. The 200x78 viewBox holds the ratio,
   so `height:auto` keeps every class the same height as it scales down. */
.evwtile svg{width:100%;max-width:76px;height:auto;fill:var(--t2);opacity:.85;
  margin:0 auto 7px;display:block}
.evwtile b{display:block;font-size:11.5px;font-weight:600;letter-spacing:-.015em}
.evwtile.no{background:var(--surface2)}
.evwtile.no svg{opacity:.22}
.evwtile.no b{color:var(--t3)}
.evwtile.no::after{content:"";position:absolute;left:24%;right:24%;top:46%;height:1.5px;
  background:var(--t3);opacity:.6;transform:rotate(-13deg)}
/* the marques, named in full. The banner above collapses past four names to a
   count, so this is where the whole list lives — and it sits above the class
   tiles because it is the narrower fact and the one that turns people away. */
.evwmk{padding:13px 16px;border-top:1px solid var(--border)}
.evwmk h5{font-size:10px;font-weight:600;letter-spacing:.1em;color:var(--t3);margin:0 0 8px;
  text-transform:uppercase;font-family:var(--ui)}
.evwmk>div{display:flex;flex-wrap:wrap;gap:6px}
.evwmk span{font-size:12.5px;font-weight:600;letter-spacing:-.015em;padding:4px 10px;
  border-radius:999px;background:var(--accent-soft);color:var(--accent-fg)}
.evwrules{padding:14px 16px;border-top:1px solid var(--border);display:grid;gap:9px}
.evwrules div{display:flex;gap:10px;font-size:13.5px;color:var(--t2);line-height:1.5}
.evwrules svg{width:15px;height:15px;stroke:var(--accent);fill:none;stroke-width:2.2;flex:none;margin-top:3px}

/* your garage, checked against the rules above */
.evgcheck{border-top:1px solid var(--border);padding:13px 16px;background:var(--surface2)}
.evgcheck h5{font-size:10px;font-weight:600;letter-spacing:.1em;color:var(--t3);margin:0 0 4px;
  text-transform:uppercase;font-family:var(--ui)}
.evgrow{display:flex;align-items:center;gap:11px;padding:8px 0}
.evgrow .th{width:40px;height:30px;border-radius:6px;flex:none;background:var(--surface3) center/cover no-repeat}
.evgrow b{font-size:13.5px;font-weight:600;letter-spacing:-.022em}
.evgrow .why{font-size:12px;color:var(--t3);display:block;margin-top:1px}
.evgrow .st{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-size:12.5px;
  font-weight:600;flex:none}
.evgrow .st svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2.6}
.evgrow .st.ok{color:var(--green)} .evgrow .st.no{color:var(--t3)}

/* ---------- run of show ---------- */
.evrun{border:1px solid var(--border);border-radius:var(--r-lg);overflow:hidden}
.evrun-row{display:grid;grid-template-columns:104px 1fr;gap:18px;padding:14px 18px;
  border-bottom:1px solid var(--border);align-items:baseline}
.evrun-row:last-child{border-bottom:0}
.evrun-row:nth-child(odd){background:var(--surface2)}
.evrun-row time{font-size:12.5px;font-weight:600;color:var(--accent-fg)}
.evrun-row h4{font-size:14.5px;letter-spacing:-.02em}
.evrun-row p{color:var(--t2);font-size:13px;margin-top:2px;line-height:1.5}

/* ---------- vehicles attending: class tabs ---------- */
.evtabsline{display:flex;gap:22px;border-bottom:1px solid var(--border);margin-bottom:16px;
  overflow-x:auto;scrollbar-width:none}
.evtabsline::-webkit-scrollbar{display:none}
.evclstab{padding:9px 0 10px;font-size:13.5px;font-weight:500;color:var(--t2);white-space:nowrap;
  border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .14s}
.evclstab:hover{color:var(--text)}
.evclstab[aria-pressed="true"]{color:var(--text);border-bottom-color:var(--accent)}
.evclstab .n{margin-left:7px;font-size:12px;color:var(--t3);font-variant-numeric:tabular-nums}
.evclstab[aria-pressed="true"] .n{color:var(--accent-fg)}
.evempty{grid-column:1/-1;padding:32px;text-align:center;border:1px dashed var(--border2);
  border-radius:var(--r-lg);color:var(--t2);font-size:13.5px;background:var(--surface2)}
.evempty b{display:block;font-size:15px;color:var(--text);margin-bottom:5px}

/* ---------- who's going ---------- */
.evpeople{display:flex;flex-wrap:wrap;gap:8px}
.evchip{display:flex;align-items:center;gap:8px;padding:5px 13px 5px 5px;border-radius:var(--r);
  border:1px solid var(--border);background:var(--surface);font-size:13px;font-weight:500}
.evchip .av{flex:none}

/* ---------- side rail ---------- */
.evrsvp-top{display:flex;gap:14px;align-items:center;padding-bottom:14px;
  border-bottom:1px solid var(--border);margin-bottom:4px}
.evcal-chip{width:52px;flex:none;border:1px solid var(--border);border-radius:8px;overflow:hidden;
  text-align:center}
.evcal-chip span{display:block;background:var(--accent);color:var(--accent-ink);font-size:10px;font-weight:600;
  letter-spacing:.08em;padding:3px 0}
.evcal-chip b{display:block;font-family:var(--dis);font-size:21px;font-weight:600;letter-spacing:-.035em;
  padding:5px 0 6px;font-variant-numeric:tabular-nums}
.evrsvp-top .evwhen b{display:block;font-size:14.5px;font-weight:600;letter-spacing:-.025em}
.evrsvp-top .evwhen span{font-size:12.5px;color:var(--t2)}
.evrows{display:grid}
.evrow{display:flex;justify-content:space-between;gap:12px;padding:10px 0;
  border-bottom:1px solid var(--border);font-size:13.5px}
.evrow:last-child{border-bottom:0}
.evrow dt{color:var(--t2);margin:0} .evrow dd{margin:0;font-weight:500;text-align:right}
.evsubtle{display:flex;justify-content:center;gap:8px;font-size:12.5px;color:var(--t3);padding-top:10px}
.evsubtle a:hover{color:var(--accent-fg)}

/* ---------- the owner's editor: welcome picker + run of show rows ---------- */
.evwpick{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:7px}
.evwpick button{border:1px solid var(--border2);border-radius:var(--r);padding:11px 5px;
  background:var(--surface);text-align:center}
.evwpick button svg{width:100%;max-width:68px;height:auto;fill:var(--t3);opacity:.6;
  margin:0 auto 6px;display:block}
.evwpick button b{font-size:10.5px;font-weight:600;color:var(--t3)}
.evwpick button[aria-pressed="true"]{border-color:var(--accent);background:var(--accent-soft)}
.evwpick button[aria-pressed="true"] svg{fill:var(--accent);opacity:1}
.evwpick button[aria-pressed="true"] b{color:var(--accent-fg)}
/* the marque picker: a filter box over a wrapped set of chips. Ninety marques
   is far too many for the tile grid above, and a <select multiple> is unusable
   on a phone — this is one tap per marque and the picked ones sort to the top,
   so a VW show ticks three and never scrolls. */
.evmkpick{display:grid;gap:9px}
/* A real bordered box, not a bare wrap: ninety chips are taller than the
   modal can give them, so the list scrolls — and a row of chips sliced through
   the middle by an invisible edge reads as broken rather than as "there is
   more below". The frame is what says which of those two it is. */
.evmkchips{display:flex;flex-wrap:wrap;gap:6px;max-height:168px;overflow-y:auto;
  padding:9px;border:1px solid var(--border);border-radius:var(--r);background:var(--surface2)}
.evmkchips button{font-size:12.5px;font-weight:500;padding:5px 11px;border-radius:999px;
  border:1px solid var(--border2);background:var(--surface);color:var(--t2);flex:none;
  transition:border-color .14s,background .14s,color .14s}
.evmkchips button:hover{color:var(--text);background:var(--surface2)}
.evmkchips button[aria-pressed="true"]{border-color:var(--accent);background:var(--accent-soft);
  color:var(--accent-fg);font-weight:600}
.evmknone{font-size:11.5px;color:var(--t3);margin:0}
.evruleitem,.evschedrow{display:flex;align-items:center;gap:8px;margin-bottom:7px}
.evschedrow .at{width:110px;flex:none}
.evruleitem button,.evschedrow button{width:34px;height:34px;flex:none;border:1px solid var(--border2);
  border-radius:8px;display:grid;place-items:center;color:var(--t3);font-size:15px;background:var(--surface)}
.evruleitem button:hover,.evschedrow button:hover{background:var(--surface2);color:var(--text)}

@media (max-width:820px){
  .evfacts{gap:12px 20px;padding:18px 0 20px}
  .evrun-row{grid-template-columns:1fr;gap:3px}
  .evschedrow{flex-wrap:wrap}
  .evschedrow .at{width:100%}
}

#pg-mods .mm-head { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; padding: 4px 0px 0px }
#pg-mods .mm-head h1 { font-size: 29px; font-weight: 700; letter-spacing: -0.032em; margin: 0px; line-height: 1.05 }
#pg-mods .mm-who { margin: 5px 0px 0px; font-size: 13px; color: var(--t2) }
#pg-mods .mm-who b { color: var(--text); font-weight: 500 }
#pg-mods .mm-acts { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap }
#pg-mods .mm-needs { margin-top: 24px; border: 1px solid var(--border); border-radius: var(--r); background: var(--surface); overflow: hidden }
#pg-mods .mm-needs-h { display: flex; align-items: center; gap: 9px; padding: 10px 14px; border-bottom: 1px solid var(--border); background: var(--surface2) }
#pg-mods .mm-needs-h h2 { font-size: 12px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; margin: 0px; white-space: nowrap }
#pg-mods .mm-n { font-size: 11px; color: var(--t2); border: 1px solid var(--border2); padding: 0px 5px; border-radius: 3px; background: var(--surface) }
#pg-mods .mm-hint { margin-left: auto; font-size: 11.5px; color: var(--t3) }
#pg-mods .mm-fold > summary { list-style: none; cursor: pointer }
#pg-mods .mm-fold > summary::-webkit-details-marker { display: none }
#pg-mods .mm-needs-act { margin-left: auto; display: flex; align-items: center; gap: 2px; margin-right: -6px }
#pg-mods .mm-link { display: inline-flex; align-items: center; gap: 4px; border: 0px; background: transparent; color: var(--t3); font-size: 11.5px; padding: 3px 6px; border-radius: 4px }
#pg-mods .mm-link:hover { background: var(--surface3); color: var(--text) }
#pg-mods .mm-fold-c { width: 27px; height: 27px; display: grid; place-items: center; color: var(--t3); transition: transform 0.18s }
#pg-mods .mm-fold[open] > summary .mm-fold-c { transform: rotate(180deg) }
#pg-mods .mm-clear { background: transparent; border-style: dashed }
#pg-mods .mm-clear { display: flex; align-items: center; gap: 11px; padding: 11px 14px }
#pg-mods .mm-clear-t { width: 26px; height: 26px; flex: 0 0 auto; display: grid; place-items: center; border: 1px solid var(--green-line); border-radius: 5px; background: var(--green-soft); color: var(--green) }
#pg-mods .mm-clear b { display: block; font-size: 13.5px; font-weight: 600; letter-spacing: -0.01em }
#pg-mods .mm-clear span { display: block; font-size: 12px; color: var(--t3); margin-top: 1px }
#pg-mods .mm-bar { display: flex; align-items: center; gap: 12px; margin: 32px 0px 12px; flex-wrap: wrap }
#pg-mods .mm-bar h2 { font-size: 17px; font-weight: 700; letter-spacing: -0.02em; margin: 0px }
#pg-mods .mm-rule { flex: 1 1 0%; height: 1px; background: var(--border); min-width: 20px }
#pg-mods .mm-ctl { display: flex; align-items: center; gap: 8px; flex-wrap: wrap }
#pg-mods .mm-chips { display: inline-flex; border: 1px solid var(--border2); border-radius: var(--btn-r); background: var(--surface); overflow: hidden; flex-wrap: wrap }
#pg-mods .mm-chip { height: 27px; padding: 0px 9px; display: inline-flex; align-items: center; gap: 5px; color: var(--t2); font-size: 12px; font-weight: 500; text-decoration: none; border-right: 1px solid var(--border); transition: background 0.13s, color 0.13s }
#pg-mods .mm-chip:last-child { border-right: 0px }
#pg-mods .mm-chip:hover { background: var(--surface2); color: var(--text) }
#pg-mods .mm-chip.on { background: var(--surface3); color: var(--text); font-weight: 600 }
#pg-mods .mm-chip .num { opacity: 0.55 }
#pg-mods .mm-chip.mm-zero { color: var(--t3) }
#pg-mods .mm-chip.mm-zero.on { color: var(--text) }
#pg-mods .mm-sort { position: relative }
#pg-mods .mm-sort > summary { list-style: none; cursor: pointer; height: 27px; padding: 0px 9px; display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--border2); border-radius: var(--btn-r); background: var(--surface); color: var(--text); font-size: 12px; font-weight: 500 }
#pg-mods .mm-sort > summary::-webkit-details-marker { display: none }
#pg-mods .mm-sort > summary:hover { background: var(--surface2) }
#pg-mods .mm-sortm { position: absolute; right: 0px; top: calc(100% + 5px); z-index: 20; min-width: 190px; padding: 5px; background: var(--surface); border: 1px solid var(--border2); border-radius: 8px; box-shadow: var(--sh-lg) }
/* The vehicle menu is the one picker whose length is the member's garage, so it
   is the one that needs a ceiling: eight cars is a menu taller than the screen,
   and it opens from a control at the top of the page. */
#pg-mods .mm-vselm { min-width: 290px; max-height: 340px; overflow: auto }
#pg-mods .mm-sopt { display: block; padding: 7px 9px; border-radius: 5px; font-size: 12.5px; color: var(--text); text-decoration: none }
#pg-mods .mm-sopt:hover { background: var(--surface2) }
#pg-mods .mm-sopt.on { background: var(--accent-soft); color: var(--accent-fg); font-weight: 600 }
#pg-mods .mm-tag { font-size: 10px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; border: 1px solid var(--border2); color: var(--t2); padding: 2px 6px; border-radius: 3px; background: var(--surface); white-space: nowrap }
#pg-mods .mm-mtag { flex: 0 0 auto; font-family: var(--mono); font-size: 8.5px; font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase; padding: 2px 5px; border-radius: 4px; background: var(--warn,#A8630C); color: rgb(255, 255, 255); line-height: 1 }
body.dark #pg-mods .mm-mtag { background: var(--warn,#D99A4A); color: rgb(26, 26, 30) }
#pg-mods .mm-none { border: 1px dashed var(--border2); border-radius: var(--r); padding: 26px 18px; text-align: center; color: var(--t2) }
#pg-mods .mm-none b { display: block; font-size: 15px; font-weight: 600; color: var(--text) }
#pg-mods .mm-none p { margin: 5px 0px 0px; font-size: 13px; color: var(--t3) }
#pg-mods .mm-add { border: 1px dashed var(--border2); border-radius: var(--r); background: transparent; display: flex; align-items: center; gap: 12px; padding: 14px 16px; width: 100%; text-align: left; color: var(--t2); margin-top: 12px; transition: border-color 0.15s, background 0.15s, color 0.15s }
#pg-mods .mm-add:hover { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-fg) }
#pg-mods .mm-add-p { width: 30px; height: 30px; flex: 0 0 auto; background: var(--surface2); border: 1px solid var(--border2); border-radius: 6px; display: grid; place-items: center; color: var(--t2); transition: background 0.15s, color 0.15s, border-color 0.15s }
#pg-mods .mm-add:hover .mm-add-p { background: var(--accent); border-color: var(--accent); color: var(--accent-on) }
#pg-mods .mm-add-t { display: block; font-weight: 600; font-size: 14px; color: var(--text); letter-spacing: -0.01em }
#pg-mods .mm-add:hover .mm-add-t { color: var(--accent-fg) }
#pg-mods .mm-add-s { display: block; font-size: 12px; color: var(--t3); margin-top: 1px }
@media (max-width: 720px) {
  #pg-mods .mm-head h1 { font-size: 24px }
  #pg-mods .mm-acts { margin-left: 0px; width: 100% }
}
#pg-mods .mm-cols { display: grid; grid-template-columns: minmax(0px, 1fr) 340px; gap: 26px; align-items: start; margin-top: 22px }
#pg-mods .mm-col { min-width: 0px }
#pg-mods .mm-col > .mm-bar:first-child { margin-top: 0px }
#pg-mods .mm-rail { position: sticky; top: calc(var(--navh) + 14px); max-height: calc(100dvh - var(--navh) - var(--floor,0px) - 28px); overflow: auto; overscroll-behavior: contain; scrollbar-width: thin }
#pg-mods .mm-rail .mm-needs { margin-top: 0px }
#pg-mods .mm-rail .mm-needs-h { padding: 9px 8px 8px 12px; row-gap: 1px; flex-wrap: wrap; position: sticky; top: 0px; z-index: 2 }
#pg-mods .mm-rail .mm-hint { order: 3; flex: 1 1 100%; margin-left: 0px; font-size: 11px; line-height: 1.35 }
#pg-mods .mm-rail .mm-needs-act { order: 2 }
#pg-mods .mm-grp + .mm-grp { border-top: 1px solid var(--border) }
#pg-mods .mm-grp-h { display: flex; align-items: center; gap: 8px; padding: 11px 12px 0px }
#pg-mods .mm-grp-l { font-size: 10.5px; font-weight: 700; letter-spacing: 0.085em; text-transform: uppercase; color: var(--t2); white-space: nowrap }
#pg-mods .mm-grp-r { flex: 1 1 0px; height: 1px; background: var(--border); min-width: 10px }
#pg-mods .mm-grp-n { font-size: 11px; color: var(--t3) }
#pg-mods .mm-grp-w { padding: 2px 12px 8px; font-size: 11.5px; line-height: 1.4; color: var(--t3) }
#pg-mods .mm-need { display: flex; align-items: center; gap: 0px; padding: 0px 6px 0px 0px }
#pg-mods .mm-need + .mm-need { border-top: 1px solid var(--border) }
#pg-mods .mm-need:hover { background: var(--surface2) }
#pg-mods .mm-need-go { display: flex; align-items: center; gap: 10px; flex: 1 1 0px; min-width: 0px; padding: 9px 4px 9px 12px; color: inherit; text-align: left }
#pg-mods .mm-need-t { width: 26px; height: 26px; flex: 0 0 auto; display: grid; place-items: center; border: 1px solid var(--border2); border-radius: 5px; background: var(--surface2); color: var(--t2) }
#pg-mods .mm-need-t.is-mod { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent-fg) }
#pg-mods .mm-need-b { min-width: 0px; flex: 1 1 0px }
#pg-mods .mm-need-c { display: block; font-size: 13px; font-weight: 600; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis }
#pg-mods .mm-need-m { display: block; font-size: 11.5px; color: var(--t3); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis }
#pg-mods .mm-need-go::after { content: ""; flex: 0 0 auto; width: 6px; height: 6px; margin-left: 2px; border-right: 1.5px solid var(--t3); border-top: 1.5px solid var(--t3); transform: rotate(45deg); opacity: 0; transition: opacity 0.13s, transform 0.13s }
#pg-mods .mm-need:hover .mm-need-go::after { opacity: 1; transform: rotate(45deg) translate(1px, -1px) }
#pg-mods .mm-need-x { width: 27px; height: 27px; flex: 0 0 auto; margin: 0px; display: grid; place-items: center; border: 1px solid transparent; background: transparent; border-radius: var(--btn-r); color: var(--t3); opacity: 0.45; transition: opacity 0.13s, background 0.13s, color 0.13s, border-color 0.13s }
#pg-mods .mm-need:hover .mm-need-x, #pg-mods .mm-need:focus-within .mm-need-x { opacity: 1 }
#pg-mods .mm-need-x:hover { background: var(--surface2); color: var(--text); border-color: var(--border) }
#pg-mods .mm-need-x:focus-visible { opacity: 1 }
#pg-mods .mm-col .mm-bar { margin: 0px 0px 12px; row-gap: 10px; align-items: center }
#pg-mods .mm-col .mm-ctl { flex: 0 0 auto; margin-left: auto }
#pg-mods .mm-col .mm-chips { order: 1; flex: 1 1 100% }
@media (max-width: 1080px) {
  #pg-mods .mm-cols { grid-template-columns: minmax(0px, 1fr); gap: 0px }
  #pg-mods .mm-rail { position: static; max-height: none; overflow: visible; order: -1; margin-bottom: 26px }
  #pg-mods .mm-rail .mm-needs-h { position: static }
  #pg-mods .mm-rail .mm-hint { order: 0; flex: 1 1 auto; margin-left: auto; text-align: right }
  #pg-mods .mm-grp-n { order: 1 }
  #pg-mods .mm-grp-r { order: 2 }
  #pg-mods .mm-grp-rows { display: grid; grid-template-columns: repeat(3, minmax(0px, 1fr)) }
  #pg-mods .mm-grp-rows .mm-need { border-top: 1px solid var(--border) }
  #pg-mods .mm-grp-rows .mm-need:not(:nth-child(3n)) { border-right: 1px solid var(--border) }
  #pg-mods .mm-grp-rows .mm-need:last-child:nth-child(3n+1) { border-right: 0px }
}
@media (max-width: 1000px) {
  #pg-mods .mm-grp-rows { grid-template-columns: repeat(2, minmax(0px, 1fr)) }
  #pg-mods .mm-grp-rows .mm-need:not(:nth-child(3n)) { border-right: 0px }
  #pg-mods .mm-grp-rows .mm-need:nth-child(2n+1) { border-right: 1px solid var(--border) }
  #pg-mods .mm-grp-rows .mm-need:last-child:nth-child(2n+1) { border-right: 0px }
}
@media (max-width: 720px) {
  #pg-mods .mm-hint { display: none }
  #pg-mods .mm-grp-rows { grid-template-columns: minmax(0px, 1fr) }
  #pg-mods .mm-grp-rows .mm-need:nth-child(2n+1) { border-right: 0px }
  /* The filter bar wraps, and stops being a segmented control to do it — the
     garage's own rule, and this is the same control under a second namespace
     (views/app/css/08e-garage-rail.php carries the long note). One pill's
     drawing describes one row: wrapped, the hairline separators fall at the
     line breaks rather than between the chips and two rows touch inside a box
     that still has a radius. Each filter is its own pill here instead. */
  #pg-mods .mm-col .mm-chips { display: flex; gap: 6px; border: 0px; border-radius: 0px; background: transparent; overflow: visible }
  #pg-mods .mm-col .mm-chip,
  #pg-mods .mm-col .mm-chip:last-child { border: 1px solid var(--border2); border-radius: var(--btn-r); background: var(--surface) }
  #pg-mods .mm-add { padding: 12px }
}
@media (max-width: 760px) {
}
/* ---- mods page: grouped by the vehicle they were done to -------------
   The vehicle is the container, so each mod no longer has to say what it
   is attached to. Rows sit closed and open on demand. ----------------- */

#pg-mods #mm-groups { display:flex; flex-direction:column; gap:20px }
/* vehicle group header */
#pg-mods .vgh-grp { border:1px solid var(--border2); border-radius:12px; background:var(--surface); overflow:hidden; transition:border-color .15s,box-shadow .15s }
#pg-mods .vgh-grp:hover { border-color:var(--border2); box-shadow:var(--sh-sm) }
#pg-mods .vgh-grp[hidden] { display:none }
#pg-mods .vgh-fold > summary { list-style:none; cursor:pointer }
#pg-mods .vgh-fold > summary::-webkit-details-marker { display:none }

/* ---- THE BAND IS A DARK PLATE, IN BOTH THEMES ---------------------------
   The car is the container and the mods are its contents, and before this the
   two were the same material: a light head over a light list, told apart by a
   hairline. A group read as a section break rather than as a thing. So the
   band is dark and the mods sit on paper under it — the step the vehicle
   profile's own data slab makes, and for its reason.

   IN BOTH THEMES, which is what makes it a decision rather than a shade. Light
   mode mixes the ink colour with the surface rather than naming a grey, so an
   operator who repaints the site gets a band that follows; dark mode drops to
   --canvas, the one colour BELOW --surface, so the plate still reads as
   further back than what sits on it. Hover is a `filter` for the same reason:
   one rule brightens whatever the mix produced, where a second background
   would be a second copy of the colour to keep in step.

   Everything ON the plate is therefore stated in white, not in a token: --text
   and --t2/--t3 are the colours of ink on PAPER, and this is not paper. That is
   the one place on this page where a literal beats a token. */
#pg-mods .vgh-head { display:flex; align-items:center; gap:14px; padding:14px;
  background:color-mix(in srgb,var(--text) 87%,var(--surface)); transition:filter .15s }
body.dark #pg-mods .vgh-head { background:var(--canvas); border-bottom:1px solid rgba(255,255,255,.07) }
#pg-mods .vgh-head:hover { filter:brightness(1.3) }
body.dark #pg-mods .vgh-head:hover { filter:brightness(1.9) }
#pg-mods .vgh-shot { width:88px; height:60px; flex:0 0 auto; border-radius:7px;
  box-shadow:0 2px 8px rgba(0,0,0,.35); border:1px solid rgba(255,255,255,.14);
  background:var(--surface3) center/cover no-repeat }
#pg-mods .vgh-none { display:grid; place-items:center; color:rgba(255,255,255,.5);
  border-style:dashed; border-color:rgba(255,255,255,.22);
  background:rgba(255,255,255,.06); box-shadow:none }
#pg-mods .vgh-id { min-width:0; flex:1 1 0 }
#pg-mods .vgh-name { display:block; font-family:var(--dis); font-size:19.5px; font-weight:700;
  letter-spacing:-.028em; line-height:1.15; color:#fff;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
#pg-mods .vgh-sub { display:block; font-size:12.5px; color:rgba(255,255,255,.62); margin-top:3px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
#pg-mods .vgh-st { flex:0 0 auto; border-color:rgba(255,255,255,.22);
  color:rgba(255,255,255,.76); background:transparent }
/* The counts and the outstanding badge travel together — they are the one
   answer to "how is this car doing", and on a phone they wrap to their own
   line as a pair rather than one of them following the chevron. */
#pg-mods .vgh-meta { display:flex; align-items:center; gap:10px; flex:0 0 auto }
#pg-mods .vgh-n { font-size:12.5px; color:rgba(255,255,255,.55); white-space:nowrap }
#pg-mods .vgh-n b { font-weight:500; color:rgba(255,255,255,.92) }
/* The draft count keeps the amber it has everywhere else, lifted for the dark
   plate. !important because .vgh-n b above sets the colour of every bold
   figure in the line and this is the one that is not white. */
#pg-mods .vgh-n .mr-dn { color:#E8A85C!important }
#pg-mods .mr-dn { color:var(--warn,#A8630C)!important }
#pg-mods .vgh-c { flex:0 0 auto; display:grid; place-items:center; width:28px; height:28px; color:rgba(255,255,255,.6); transition:transform .18s }
#pg-mods .vgh-fold[open] > summary .vgh-c { transform:rotate(180deg) }
#pg-mods .vgh-list { padding:0 }
/* a closed mod row */
#pg-mods .mr { border-bottom:1px solid var(--border) }
#pg-mods .mr[hidden] { display:none }
#pg-mods .mr > summary { list-style:none; cursor:pointer }
#pg-mods .mr > summary::-webkit-details-marker { display:none }
#pg-mods .mr-head { display:flex; align-items:center; gap:10px; padding:10px 12px; transition:background .13s }
#pg-mods .mr-head:hover { background:var(--surface2) }
#pg-mods .mr.is-draft { border-left:2px solid var(--warn,#A8630C) }
#pg-mods .mr-ic { width:34px; height:34px; flex:0 0 auto; display:grid; place-items:center; border-radius:5px; background:var(--surface2); border:1px solid var(--border); color:var(--accent-fg) }
#pg-mods .mr-ic .cat-ic { width:21px; height:21px }
#pg-mods .mr-ic-ph { background:var(--surface3) center/cover no-repeat; border-color:var(--border2) }
#pg-mods .mr.is-draft .mr-ic { color:var(--warn,#A8630C) }
#pg-mods .mr-id { min-width:0; flex:1 1 0 }
#pg-mods .mr-t { font-size:14.5px; font-weight:600; letter-spacing:-.015em; color:var(--text); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display:block }
#pg-mods .mr-head:hover .mr-t { color:var(--accent-fg) }
#pg-mods .mr-blurb { display:block; font-size:12px; color:var(--t3); margin-top:1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
#pg-mods .mr-blurb.is-none { font-style:italic; opacity:.8 }
#pg-mods .mr[open] .mr-blurb { display:none }
#pg-mods .mr-cat { flex:0 0 auto; display:inline-flex; align-items:center; gap:2px; font-size:9.5px; font-weight:700; letter-spacing:.085em; text-transform:uppercase; color:var(--t2); background:transparent; border:1px solid transparent; border-radius:4px; padding:2px 5px; cursor:pointer; transition:background .13s,border-color .13s,color .13s; white-space:nowrap }
#pg-mods .mr-cat .ic { opacity:.45; transition:opacity .13s }
#pg-mods .mr-cat:hover { background:var(--surface3); border-color:var(--border2); color:var(--text) }
#pg-mods .mr-cat:hover .ic { opacity:1 }
#pg-mods .mr.is-draft .mr-cat { color:var(--warn,#A8630C) }
/* the count sits beside the arrow; grey when there is nothing to do */
#pg-mods .mr-miss, #pg-mods .vgh-miss { flex:0 0 auto; min-width:20px; height:20px; padding:0 5px; display:grid; place-items:center; border-radius:4px; background:var(--warn-soft,#FDF1E0); border:1px solid var(--warn-line,#EED6AB); color:var(--warn,#A8630C); font-family:var(--mono); font-size:10.5px; font-weight:600; line-height:1; cursor:default }
#pg-mods .mr-miss.is-zero, #pg-mods .vgh-miss.is-zero { background:var(--surface2); border-color:var(--border2); color:var(--t3) }
body.dark #pg-mods .mr-miss, body.dark #pg-mods .vgh-miss { background:rgba(217,154,74,.13); border-color:rgba(217,154,74,.32); color:#D99A4A }
body.dark #pg-mods .mr-miss.is-zero, body.dark #pg-mods .vgh-miss.is-zero { background:var(--surface2); border-color:var(--border2); color:var(--t3) }
/* ON THE BAND IT IS THE SAME BADGE ON A DARK PLATE, in BOTH themes — so it is
   stated after the two rules above rather than inside either. The light-theme
   amber they set is ink for paper and disappears into the plate; these are the
   same two colours lifted for it. */
#pg-mods .vgh-miss { background:rgba(232,168,92,.18); border-color:rgba(232,168,92,.38); color:#E8A85C }
#pg-mods .vgh-miss.is-zero { background:rgba(255,255,255,.08); border-color:rgba(255,255,255,.18); color:rgba(255,255,255,.5) }
/* drafts: the garage stamp, scaled up, on a highlighted row */
#pg-mods .mr-stamp { display:inline-flex; align-items:center }
#pg-mods .mr-stamp .mm-mtag { font-size:10px; letter-spacing:.12em; padding:5px 9px; border-radius:4px }
#pg-mods .mr.is-draft { border-left:3px solid var(--warn,#A8630C) }
#pg-mods .mr.is-draft > .mr-head { background:var(--warn-soft,#FDF1E0) }
#pg-mods .mr.is-draft > .mr-head:hover, #pg-mods .mr.is-draft[open] > .mr-head { background:color-mix(in srgb,var(--warn,#A8630C) 11%,var(--surface)) }
#pg-mods .mr.is-draft .mr-ic { border-style:dashed; border-color:var(--warn-line,#EED6AB); background:var(--surface); color:var(--warn,#A8630C) }
#pg-mods .mr.is-draft:hover .mr-ic { border-style:solid; border-color:var(--warn,#A8630C) }
#pg-mods .mr.is-draft .mr-blurb { color:color-mix(in srgb,var(--warn,#A8630C) 55%,var(--t2)) }
body.dark #pg-mods .mr.is-draft > .mr-head { background:rgba(217,154,74,.10) }
body.dark #pg-mods .mr.is-draft > .mr-head:hover, body.dark #pg-mods .mr.is-draft[open] > .mr-head { background:rgba(217,154,74,.17) }
body.dark #pg-mods .mr.is-draft .mr-ic { border-color:rgba(217,154,74,.32); background:var(--surface) }
/* the meta cluster lines up into columns down the list */
#pg-mods .mr-cat { width:118px; justify-content:flex-end; text-align:right }
#pg-mods .mr-tag { width:96px; display:flex; align-items:center }
#pg-mods .mr-tag { flex:0 0 auto }
#pg-mods .mr-c { flex:0 0 auto; display:grid; place-items:center; width:22px; height:22px; color:var(--t3); transition:transform .18s }
#pg-mods .mr[open] > summary .mr-c { transform:rotate(180deg) }
#pg-mods .mr[open] > summary { background:var(--surface2) }
/* drafts, per vehicle */
#pg-mods .mr-dhead { display:flex; align-items:center; gap:9px; padding:8px 12px 7px; background:var(--surface2); border-top:1px solid var(--border) }
#pg-mods .mr-dhead > span:first-child { font-family:var(--mono); font-size:10px; font-weight:600; letter-spacing:.12em; text-transform:uppercase; padding:5px 9px; border-radius:4px; background:var(--warn,#A8630C); color:#fff; line-height:1 }
body.dark #pg-mods .mr-dhead > span:first-child { background:var(--warn,#D99A4A); color:#1A1A1E }
#pg-mods .mr-drule { flex:1 1 0; height:1px; background:var(--border) }
#pg-mods .mr-dhead .num { font-size:11px; color:var(--t3) }
/* ---- the opened row -------------------------------------------------
   Open marks the row (accent edge, accent title) and drops a recessed
   drawer beneath it. The drawer is grey; the checklist sits on it as a
   white card, so there is a real figure/ground change. ---------------- */
#pg-mods .mr[open] > .mr-head { background:var(--surface); box-shadow:inset 3px 0 0 var(--accent) }
#pg-mods .mr[open] > .mr-head .mr-t { color:var(--accent-fg) }
#pg-mods .mr.is-draft[open] > .mr-head { box-shadow:none }
#pg-mods .mr-body { display:grid; grid-template-columns:210px minmax(0,1fr); grid-template-areas:"gal detail" "tabs tabs" "foot foot"; gap:16px 20px; padding:16px; background:var(--surface3); box-shadow:inset 0 10px 12px -12px rgba(12,12,16,.45),inset 0 1px 0 var(--border) }
body.dark #pg-mods .mr-body { box-shadow:inset 0 10px 14px -12px rgba(0,0,0,.8),
  inset 0 1px 0 var(--border) }
#pg-mods .mr[open] > .mr-body { animation:mrOpen .24s var(--ease) }
@keyframes mrOpen {
  from { opacity:.35; clip-path:inset(0 0 100% 0) }
  to { opacity:1; clip-path:inset(0 0 0 0) }
}
@media (prefers-reduced-motion:reduce) {
  #pg-mods .mr[open] > .mr-body { animation:none }
}
#pg-mods .mr-gal { grid-area:gal; display:flex; flex-direction:column; gap:8px; min-width:0; align-self:stretch }
#pg-mods .mr-big { position:relative; display:block; width:100%; aspect-ratio:4/3; height:100%; min-height:150px; border-radius:8px; overflow:hidden; border:1px solid var(--border2); background:var(--surface2); box-shadow:var(--sh-sm) }
#pg-mods .mr-big img { width:100%; height:100%; object-fit:cover; display:block; transition:transform .35s,filter .2s,opacity .2s }
#pg-mods .mr-big:hover img { transform:scale(1.03) }
#pg-mods .mr-big.is-borrowed img { filter:grayscale(.4); opacity:.92 }
#pg-mods .mr-big.is-borrowed:hover img { filter:none; opacity:1 }
#pg-mods .mr-big-none { display:grid; place-items:center; color:var(--t3); border-style:dashed; background:var(--surface); box-shadow:none }
#pg-mods .mr-ribbon { position:absolute; left:7px; bottom:7px; font-size:9px; font-weight:600; letter-spacing:.07em; text-transform:uppercase; background:rgba(8,8,10,.72); color:#fff; padding:3px 6px; border-radius:3px }
#pg-mods .mr-detail { grid-area:detail; min-width:0; background:var(--surface); border:1px solid var(--border); border-radius:9px; box-shadow:var(--sh-sm); padding:14px 16px }
#pg-mods .mr-say { position:relative; padding-right:34px }
#pg-mods .mr-desc { margin:0; font-size:14.5px; line-height:1.6; color:var(--text); max-width:62ch }
#pg-mods .mr-say-e { position:absolute; top:-4px; right:-6px; width:28px; height:28px; display:grid; place-items:center; border:1px solid transparent; border-radius:var(--btn-r); background:transparent; color:var(--t3); opacity:0; cursor:pointer; transition:opacity .13s,background .13s,color .13s }
#pg-mods .mr-say:hover .mr-say-e, #pg-mods .mr-say-e:focus-visible { opacity:1 }
#pg-mods .mr-say-e:hover { background:var(--surface2); border-color:var(--border); color:var(--text) }
#pg-mods .mr-say-add { display:flex; align-items:center; gap:7px; width:100%; padding:11px 12px; border:1px dashed var(--border2); border-radius:var(--btn-r); background:transparent; color:var(--t2); font-size:13px; font-weight:500; cursor:pointer; transition:border-color .13s,background .13s,color .13s }
#pg-mods .mr-say-add:hover { border-style:solid; border-color:var(--accent); background:var(--accent-soft); color:var(--accent-fg) }
#pg-mods .mr-facts { margin:14px 0 0; padding-top:13px; border-top:1px solid var(--border); display:grid; grid-template-columns:74px minmax(0,1fr); gap:8px 14px; font-size:12.5px; align-items:baseline; max-width:520px }
#pg-mods .mr-facts dt { font-size:10.5px; font-weight:600; letter-spacing:.06em; color:var(--t3); white-space:nowrap; text-transform:uppercase }
#pg-mods .mr-facts dd { margin:0; color:var(--t2); font-weight:500; min-width:0; display:flex; align-items:center; gap:6px; overflow:hidden }
#pg-mods .mr-facts dd i { font-style:normal; color:var(--t3); font-weight:400 }
#pg-mods .mr-fsub { color:var(--t3); font-weight:400; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
#pg-mods .mr-fic { display:grid; place-items:center; flex:0 0 auto; color:var(--accent-fg) }
#pg-mods .mr-fic .cat-ic { width:15px; height:15px }
#pg-mods .mr-fthumb { width:24px; height:16px; flex:0 0 auto; border-radius:3px; border:1px solid var(--border2); background:var(--surface3) center/cover no-repeat }
/* inline edit affordance */
#pg-mods [data-ed] { cursor:text; border-radius:5px; margin:-2px -6px; padding:2px 6px; border:1px solid transparent; transition:background .12s,border-color .12s }
#pg-mods [data-ed]:hover { background:var(--surface2); border-color:var(--border) }
#pg-mods [data-ed="select"] { cursor:pointer }
#pg-mods [data-ed]:focus-visible { outline:2px solid var(--accent); outline-offset:1px }
#pg-mods .mr-ed { width:100%; font:inherit; color:var(--text); background:var(--surface); border:1px solid var(--accent); border-radius:6px; padding:7px 9px; box-shadow:0 0 0 3px var(--accent-soft) }
#pg-mods .mr-ed:focus { outline:none }
#pg-mods textarea.mr-ed { min-height:74px; resize:vertical; line-height:1.6; font-size:14px }
#pg-mods select.mr-ed { padding:5px 8px; font-size:12.5px; width:auto; min-width:150px }
/* tabs: cycle through what a mod is made of */
#pg-mods .mr-tabs { grid-area:tabs; background:var(--surface); border:1px solid var(--border); border-radius:9px; overflow:hidden; box-shadow:var(--sh-sm) }
#pg-mods .mr-tabbar { display:flex; gap:2px; padding:0 6px; background:var(--surface2); border-bottom:1px solid var(--border); overflow-x:auto; scrollbar-width:none }
#pg-mods .mr-tabbar::-webkit-scrollbar { display:none }
#pg-mods .mr-tab { display:inline-flex; align-items:center; gap:6px; flex:0 0 auto; height:38px; padding:0 12px; border:0; border-bottom:2px solid transparent; background:transparent; font-size:12.5px; font-weight:600; letter-spacing:-.01em; color:var(--t2); cursor:pointer; transition:color .13s,border-color .13s }
#pg-mods .mr-tab:hover { color:var(--text) }
#pg-mods .mr-tab.is-on { color:var(--text); border-bottom-color:var(--accent) }
#pg-mods .mr-tabn { min-width:17px; height:16px; padding:0 4px; display:grid; place-items:center; border-radius:3px; background:var(--surface3); color:var(--t2); font-family:var(--mono); font-size:9.5px; font-weight:600; line-height:1 }
#pg-mods .mr-tab.is-on .mr-tabn { background:var(--accent-soft); color:var(--accent-fg) }
#pg-mods .mr-tabn.is-zero { color:var(--t3) }
#pg-mods .mr-panes { padding:14px }
#pg-mods .mr-empty { display:flex; flex-direction:column; align-items:center; gap:5px; padding:20px 14px; text-align:center }
#pg-mods .mr-empty-ic { width:34px; height:34px; display:grid; place-items:center; border-radius:8px; border:1px dashed var(--border2); background:var(--surface2); color:var(--t3); margin-bottom:3px }
#pg-mods .mr-empty b { font-size:13.5px; font-weight:600; color:var(--text) }
#pg-mods .mr-empty > span { font-size:12px; color:var(--t3); max-width:44ch }
#pg-mods .mr-empty .btn { margin-top:7px }
#pg-mods .mr-phgrid { display:grid; grid-template-columns:repeat(auto-fill,minmax(118px,1fr)); gap:10px }
#pg-mods .mr-ph { position:relative; margin:0; aspect-ratio:4/3; border-radius:7px; overflow:hidden; border:1px solid var(--border2); background:var(--surface2) }
#pg-mods .mr-ph img { width:100%; height:100%; object-fit:cover; display:block }
#pg-mods .mr-ph.is-borrowed img { filter:grayscale(.4); opacity:.9 }
#pg-mods .mr-ph figcaption { position:absolute; left:0; right:0; bottom:0; padding:14px 7px 5px; font-size:9.5px; font-weight:600; letter-spacing:.05em; text-transform:uppercase; color:#fff; background:linear-gradient(transparent,rgba(8,8,10,.78)) }
#pg-mods .mr-ph-add { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:5px; border:1px dashed var(--border2); background:transparent; color:var(--t3); font-size:11.5px; font-weight:600; cursor:pointer; transition:border-color .13s,background .13s,color .13s }
#pg-mods .mr-ph-add:hover { border-style:solid; border-color:var(--accent); background:var(--accent-soft); color:var(--accent-fg) }
#pg-mods .mr-note { margin:10px 0 0; font-size:11.5px; color:var(--t3) }
/* the action bar that comes up when you open a row */
#pg-mods .mr-foot { grid-area:foot; display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding-top:14px; border-top:1px solid var(--border2) }
#pg-mods .mr-foot-n { margin-left:auto; font-size:11.5px; color:var(--t3) }
#pg-mods .mr-open { margin-left:0 }
/* add bar */
#pg-mods .mr-add { display:flex; align-items:center; gap:7px; padding:10px 12px; font-size:12.5px; font-weight:500; color:var(--t3); border-top:1px dashed var(--border2); transition:background .13s,color .13s }
#pg-mods .mr-add:hover { background:var(--accent-soft); color:var(--accent-fg) }
#pg-mods .vgh-zero { color:rgba(255,255,255,.45) }
#pg-mods .mm-veh-o { display:flex; align-items:center; gap:9px; padding:6px 8px }
#pg-mods .mm-veh-p { width:40px; height:27px; flex:0 0 auto; border-radius:4px; border:1px solid var(--border); background:var(--surface3) center/cover no-repeat }
#pg-mods .mm-veh-all { background:var(--surface3) }
#pg-mods .mm-veh-l { font-size:12.5px; font-weight:500; min-width:0; flex:1 1 0; line-height:1.25 }
#pg-mods .mm-veh-s { display:block; font-size:11px; font-weight:400; color:var(--t3) }
#pg-mods .mm-veh-n { font-size:11px; color:var(--t3); flex:0 0 auto }
#pg-mods .mm-veh-o.mm-zero { opacity:.5 }
#pg-mods .mm-sort .mm-sopt { display:flex; align-items:center; gap:8px }
#pg-mods .mm-sopt-i { width:17px; height:17px; flex:0 0 auto; display:grid; place-items:center; color:var(--t3) }
#pg-mods .mm-sopt-i .cat-ic { width:17px; height:17px }
#pg-mods .mm-sopt.on .mm-sopt-i { color:var(--accent-fg) }
#pg-mods .mm-sopt-n { margin-left:auto; font-size:11px; color:var(--t3) }
#pg-mods .mm-none[hidden] { display:none }
@media (max-width: 720px) {
  /* The band wraps rather than shrinking to nothing: the car and its picture
     keep the first line, the chevron follows them, and the counts take a line
     of their own with the outstanding badge pushed to the far edge. Shrinking
     instead is how the name ends up ellipsed to three characters beside four
     figures nobody can read. */
  #pg-mods .vgh-head { gap:11px; padding:11px 10px; flex-wrap:wrap; row-gap:9px }
  #pg-mods .vgh-id { flex:1 1 0; min-width:0 }
  #pg-mods .vgh-c { order:2 }
  #pg-mods .vgh-meta { order:4; flex:1 1 100% }
  #pg-mods .vgh-miss { margin-left:auto }
  #pg-mods .vgh-shot { width:66px; height:45px }
  #pg-mods .vgh-name { font-size:16.5px }
  #pg-mods .vgh-sub { font-size:11.5px }
  #pg-mods .vgh-st { display:none }
  #pg-mods .vgh-n { font-size:11px }
  #pg-mods .mm-ctl { flex-wrap:wrap; width:100%; margin-left:0 }
  #pg-mods .mm-ctl > * { flex:0 0 auto }
  #pg-mods .mr-head { flex-wrap:wrap; gap:6px 8px; padding:9px 10px }
  #pg-mods .mr-ic { width:30px; height:30px }
  #pg-mods .mr-id { flex:1 1 calc(100% - 74px) }
  #pg-mods .mr-t { white-space:normal }
  #pg-mods .mr-blurb { white-space:normal; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical }
  #pg-mods .mr-cat { order:3; width:auto; padding-left:0; justify-content:flex-start; text-align:left }
  #pg-mods .mr-tag { order:4; width:auto; margin-left:auto }
  #pg-mods .mr-miss { order:5 }
  #pg-mods .mr-body { grid-template-columns:minmax(0,1fr); gap:14px; padding:13px 10px 15px; grid-template-areas:"gal" "detail" "tabs" "foot" }
  #pg-mods .mr-panes { padding:11px }
  #pg-mods .mr-tab { padding:0 9px; font-size:12px }
  #pg-mods .mr-phgrid { grid-template-columns:repeat(auto-fill,minmax(96px,1fr)) }
  #pg-mods .mr-facts { grid-template-columns:70px minmax(0,1fr); gap:6px 10px }
  #pg-mods .mr-foot-n { margin-left:auto; font-size:11.5px; color:var(--t3) }
  #pg-mods .mr-open { margin-left:0 }
}#pg-mods .mm-sopt-l { flex: 1 1 0%; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }

/* ---- an editable fact: the display, and the control under it ------------- */
#pg-mods .mr-fv { display: inline-flex; align-items: center; gap: 6px; min-width: 0 }
#pg-mods .mr-facts dd[data-ed] { cursor: pointer; border-radius: 4px }
#pg-mods .mr-facts dd[data-ed]:hover .mr-fv { color: var(--accent-fg) }
#pg-mods .mr-facts dd[data-ed]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px }
/* A REVEALED CONTROL LOOKS LIKE IT IS TAKING INPUT. It only exists while
   somebody is editing, so it carries the accent and its focus ring at all
   times rather than waiting for :focus — the ring IS how you find the one
   field that is open on a row of four facts. */
#pg-mods .mr-ed { width: 100%; font: inherit; color: var(--text);
  background: var(--surface); border: 1px solid var(--accent); border-radius: 6px;
  padding: 7px 9px; box-shadow: 0 0 0 3px var(--accent-soft) }
#pg-mods .mr-ed:focus { outline: none }
#pg-mods textarea.mr-ed { min-height: 74px; resize: vertical; line-height: 1.6; font-size: 14px }
/* An edit that is saving must not accept a second one — the row is one write
   at a time, and a select left live during the PATCH is how two land out of
   order and the later answer loses. */
#pg-mods .mr-ed[disabled] { opacity: .6 }
#pg-mods .mr-say.is-busy, #pg-mods .mr-facts dd.is-busy { opacity: .55 }

/* ---- Updates: the log --------------------------------------------------- */
#pg-mods .mr-loglist { list-style: none; margin: 0; padding: 0; display: flex;
  flex-direction: column; gap: 1px }
#pg-mods .mr-log a { display: grid; grid-template-columns: 1fr auto; gap: 2px 10px;
  padding: 8px 10px; border-radius: 6px; color: inherit; text-decoration: none }
#pg-mods .mr-log a:hover { background: var(--surface2) }
#pg-mods .mr-log b { font-size: 13px; font-weight: 600; letter-spacing: -.01em; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
#pg-mods .mr-log-d { font-size: 11.5px; color: var(--t3); font-variant-numeric: tabular-nums }
#pg-mods .mr-log-b { grid-column: 1 / -1; font-size: 12px; color: var(--t2); line-height: 1.45 }

/* ---- Parts: the bill of materials --------------------------------------- */
#pg-mods .mr-parts { list-style: none; margin: 0; padding: 0 }
#pg-mods .mr-part { display: flex; align-items: baseline; gap: 10px; padding: 7px 10px;
  font-size: 12.5px }
#pg-mods .mr-part + .mr-part { border-top: 1px solid var(--border) }
#pg-mods .mr-part-t { flex: 1 1 0%; min-width: 0; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
#pg-mods .mr-part-b { color: var(--t3) }
#pg-mods .mr-part-q, #pg-mods .mr-part-c { flex: 0 0 auto; color: var(--t2) }
/* A part already in hand is struck through the way a checked line on a paper
   list is — the column it comes from is literally called `have`. */
#pg-mods .mr-part.is-have .mr-part-t { color: var(--t3); text-decoration: line-through }

/* ---- "see all N", shared by both lists ---------------------------------- */
#pg-mods .mr-more { display: inline-block; margin: 8px 0 0 10px; font-size: 12px;
  color: var(--t2) }
#pg-mods .mr-more:hover { color: var(--accent-fg) }

/* ---- the pane box ------------------------------------------------------- */
#pg-mods .mr-pane { min-height: 60px }
/* The comments tab is the site's ONE thread renderer dropped in whole
   (ams_feed_comments), so it arrives already styled by views/app/css/20-feed-card.php.
   All it needs here is not to be squeezed by the tab box around it. */
#pg-mods .mr-pane[data-pane="comments"] { padding: 2px 0 }
#pg-mods .mr-pane .fc-cmts { margin: 0 }
#pg-mods .mr-edrow { display: flex; gap: 7px; margin-top: 8px }

/* ---- the three "start a mod" controls are BUTTONS, not links -------------
   /post/mod is not a screen (index.php redirects it to /feed), so a mod is the
   one kind whose control cannot be an anchor — test/mod-add-popup.php refuses
   one. What an <a> gave them for free has to be said here instead. */
#pg-mods .mm-add, #pg-mods .mr-add { font: inherit; cursor: pointer; border-width: 0 }
#pg-mods .mm-add { border: 1px dashed var(--border2) }
#pg-mods .mr-add { width: 100%; text-align: left; background: transparent;
  border-top: 1px dashed var(--border2) }


/* ============================================================================
   THE HEADER'S RIGHT-HAND CLUSTER
   ----------------------------------------------------------------------------
   Search, Create, Messages, Notifications, You. It used to be five controls in
   five shapes — a 214px bordered pill, a bordered small button, two bare 26px
   glyphs with a dot hung off them, and an avatar — sharing nothing but the flex
   row they sat in. Every one of them has been the odd one out at some point.

   They are one set now: 36px squares, one radius, one hover, with exactly two
   exceptions that earn it — the Create button, which is the only thing here you
   are being ASKED to press, so it is the only coloured thing; and the avatar,
   which is a picture of a person and cannot be a glyph.

   Anything filled with the accent takes `--accent-ink`, never a literal #fff —
   here and in the forty-odd other places on the site that fill with the accent.
   The token is white; it exists so an operator who sets a pale brand colour
   does not get white on white. See its note in 00-tokens-and-buttons.php.

   The dropdowns are `.nb-dd` from the tabs' stylesheet, driven by the one
   mechanism in js/01-nav.php. Nothing here opens or closes anything.
   ========================================================================= */

/* The cluster sits centred in the bar, not stretched: a full-height hover
   target is right for a TAB (the rail is the header's bottom edge) and wrong
   for a 36px square, which would grow a 60px hit area with 24px of nothing
   above and below the glyph. */
.navauth .nb-dd,.nb-dd.usermenu-wrap{align-self:center}

/* ---------- the icon controls ---------- */
.nb-ic{position:relative;display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:36px;height:36px;border-radius:9px;color:var(--t2);
  transition:background .12s,color .12s}
.nb-ic:hover,.nb-dd.open>.nb-ic{background:var(--surface2);color:var(--text)}
.nb-ic svg{flex:none}

/* ---------- the count badge ----------
   Cut to the brand hexagon, because a round pill beside a hexagonal logo is a
   second shape language for no reason. The four drop-shadows are the ring: a
   border cannot follow a clip-path, and a 1.25px shadow in the header's own
   colour in each direction traces the six edges exactly. --canvas rather than a
   flat white, so it stays a ring in dark mode too. */
.nb-badge{position:absolute;top:1px;right:-1px;min-width:19px;height:16px;padding:0 4px;
  clip-path:var(--hex);background:var(--badge);color:var(--badge-fg);
  font:700 10px/1 var(--ui);display:flex;align-items:center;justify-content:center;
  font-variant-numeric:tabular-nums;pointer-events:none;
  filter:drop-shadow(1.25px 0 0 var(--canvas)) drop-shadow(-1.25px 0 0 var(--canvas))
         drop-shadow(0 1.25px 0 var(--canvas)) drop-shadow(0 -1.25px 0 var(--canvas))}

/* ---------- Create: one shape, two controls ----------
   The seam is a 1px gap showing the header through, not a border: a border
   would darken one edge of an orange button and read as a bevel.

   The two halves do two different things, deliberately: Create opens the TILES
   and the chevron opens this MENU, which is the same list as words for somebody
   who already knows what they want. See views/app/chrome/02-header.php. */
.nb-createdd{flex:none}
.nb-split{display:flex;flex:none}
.nb-go,.nb-chevbtn{height:36px;display:inline-flex;align-items:center;justify-content:center;
  background:var(--accent);color:var(--accent-ink);font-weight:600;font-size:14px;
  transition:filter .12s}
.nb-go{gap:6px;padding:0 13px;border-radius:9px 0 0 9px}
.nb-chevbtn{width:28px;border-radius:0 9px 9px 0;margin-left:1px}
.nb-go:hover,.nb-chevbtn:hover,.nb-dd.open .nb-chevbtn{filter:brightness(1.07)}
.nb-go svg{flex:none}
.nb-chevbtn .nb-chev{opacity:.9;margin:0}
.nb-createmenu{min-width:266px}
/* The one row in here that MAKES nothing (Drafts). It is a way back, so it sits
   under a hairline rather than in the run of things you can start — the same
   separation the account menu draws around its make-something band. */
.nb-createmenu .nb-mi-resume{border-top:1px solid var(--border);margin-top:4px;padding-top:9px}
/* The label is the first thing to go when the bar tightens: the plus and the
   colour already say what it is, and the menu beside it says it in words. */
@media(max-width:900px){ .nb-go .lbl{display:none} .nb-go{padding:0 11px} }

/* ---------- you ----------
   The avatar keeps the 36px slot so it lines up with the glyphs, but the
   picture inside it is 31px — a bubble drawn edge to edge in a row of glyphs
   that all have air around them reads as bigger than its neighbours, not as
   the same size. */
.nb-av{position:relative;display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:36px;height:36px;border-radius:50%}
.nb-av .av{width:31px;height:31px;font-size:11px;transition:box-shadow .12s}
.nb-av:hover .av,.nb-dd.open>.nb-av .av{box-shadow:0 0 0 2px var(--surface3)}
/* Presence. Drawn only under body.presence-on, which the identity call sets
   from the session — an unconditional green dot is a light that always says
   "online" and therefore says nothing. */
.nb-pres{display:none;position:absolute;right:2px;bottom:2px;width:9px;height:9px;border-radius:50%;
  background:#1FA84F;box-shadow:0 0 0 2px var(--canvas)}
body.presence-on .nb-pres{display:block}
body.dark .nb-pres{background:#2FCB61}

/* ---------- a panel ----------
   Wider than a menu and scrollable, because it holds CONTENT rather than a list
   of destinations. It is the same surface, radius and shadow as .nb-menu — a
   panel is a menu that happens to be full of sentences, not a new kind of
   thing. */
.nb-panel{position:absolute;top:calc(100% + 8px);right:-4px;width:392px;max-width:calc(100vw - 24px);
  z-index:90;display:none;overflow:hidden;
  background:var(--surface);border:1px solid var(--border);border-radius:14px;
  box-shadow:var(--sh-lg)}
.nb-panel.flip,.nb-menu.flip{left:auto;right:-4px}
/* Same pointer bridge the menus use — see .nb-menu::before. */
.nb-panel::before{content:"";position:absolute;left:0;right:0;top:-10px;height:10px}
.nb-dd.open>.nb-panel{display:block;animation:nbpop .15s var(--ease)}
/* No `html:not(.js)` hover rule here, unlike .nb-menu. A menu is markup and is
   complete with the bundle dead; a panel is a shell the bundle FILLS, so
   opening one without it shows "Loading…" and nothing else, forever. Better not
   to open. /messages is a real link in the account menu and the drawer either
   way, and a notification is only ever a pointer at something the site already
   shows you somewhere else. */

.np-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:13px 15px 9px}
.np-head b{font-size:15px;font-weight:600;letter-spacing:-.01em}
.np-act{font-size:12.5px;font-weight:520;color:var(--accent-fg)}
.np-act:hover{text-decoration:underline}

.np-tabs{display:flex;gap:3px;padding:0 11px 8px}
.np-tab{height:28px;padding:0 11px;border-radius:8px;font-size:12.5px;font-weight:520;color:var(--t2)}
.np-tab:hover{background:var(--surface2)}
.np-tab[aria-selected="true"]{background:var(--surface3);color:var(--text)}

.np-list{max-height:min(430px,60vh);overflow-y:auto;padding:4px 6px 6px}
.np-row{display:flex;gap:11px;padding:10px;border-radius:10px;color:inherit}
.np-row:hover{background:var(--surface2)}
/* Unread is a tint of the accent rather than a fill of it: every row in this
   list is a thing you have not dealt with, so the mark has to be quiet enough
   that five of them in a row is still a list. */
.np-row.unread{background:var(--accent-soft)}
.np-row .av{width:34px;height:34px;flex:none;font-size:11px}
.np-avi{width:34px;height:34px;flex:none;border-radius:50%;background:var(--surface3);color:var(--t2);
  display:flex;align-items:center;justify-content:center}
.np-bd{flex:1;min-width:0;font-size:13.5px;font-weight:450;color:var(--t2);line-height:1.42}
.np-bd b{font-weight:580;color:var(--text)}
.np-tm{display:block;font-size:11.5px;color:var(--t3);margin-top:3px}
.np-pv{display:block;color:var(--t3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.np-on{display:inline-block;width:7px;height:7px;border-radius:50%;background:#1FA84F;margin-left:6px;
  vertical-align:middle}
.np-n{flex:none;align-self:center;min-width:18px;height:18px;padding:0 5px;border-radius:99px;
  background:var(--accent);color:var(--accent-ink);font:700 10.5px/18px var(--ui);text-align:center;
  font-variant-numeric:tabular-nums}
/* Answering a friend request without leaving the panel is the whole reason the
   Requests tab exists — a tab that only tells you there is something to do and
   then sends you elsewhere to do it has not saved anybody a step. */
.np-acts{display:flex;gap:7px;margin-top:8px}
.np-acts button{height:29px;padding:0 12px;border-radius:8px;font-size:12.5px;font-weight:540}
.np-yes{background:var(--accent);color:var(--accent-ink)}
.np-yes:hover{filter:brightness(1.07)}
.np-no{background:var(--surface3);color:var(--t2)}
.np-no:hover{color:var(--text)}
.np-empty{padding:26px 16px;text-align:center;font-size:13px;color:var(--t3);margin:0}

.np-foot{padding:9px;border-top:1px solid var(--border)}
.np-foot a{display:block;padding:9px;border-radius:9px;text-align:center;
  font-size:13px;font-weight:540;color:var(--t2)}
.np-foot a:hover{background:var(--surface2);color:var(--text)}

/* ---------- the account menu, on the shared mechanism ----------
   It was a `.pop` toggled by its own click handler; it is a `.nb-menu` now, so
   it opens, closes, flips and answers Escape through the same code as
   everything else in this bar. These are the rules that were specific to it. */
.usermenu{min-width:268px;max-width:calc(100vw - 2*var(--pad));left:auto;right:-4px;
  padding:7px;max-height:min(78vh,560px);overflow-y:auto}
.umhead{display:flex;align-items:center;gap:11px;padding:9px 10px;border-radius:10px;color:inherit}
.umhead:hover{background:var(--surface2)}
.umhead .av{width:40px;height:40px;font-size:14px}
.umhead .nm{font-size:14.5px;font-weight:600;line-height:1.2}
.umhead .mt{font-size:11.5px;color:var(--t3)}
.umrow{display:flex;align-items:center;gap:11px;padding:9px 10px;border-radius:8px;
  color:var(--t2);font-size:14px;font-weight:470}
.umrow:hover{background:var(--surface2);color:var(--text)}
.umrow svg{color:var(--t3);flex:none}
.umrow:hover svg{color:var(--t2)}
.umrow.on{color:var(--text);font-weight:540}

/* ---------- the fold ----------
   Below the tablet step the bar has handed its links to the drawer, and what is
   left is six controls in a row: menu, brand, search, create, messages,
   notifications, you.

   ONE SIZE, ONE RHYTHM. This is the whole of it, in one place, because the last
   arrangement was written in three: 01 sized the burger at 36, a mobile-tap
   audit in the VENDORS stylesheet raised `.burger,.nb-ic` to 42, and this file
   then set `.nb-ic` to 36 from further down the cascade — so the audit's rule
   reached the burger and nothing else, and the bar opened with one 42px control
   beside five 36px ones. 42 is the right answer (44pt is the tap guidance and
   36 is a desktop number), so everything here is 42 and the burger stops being
   the odd one out.

   AND ONE GAP. `.navauth` ran at 2px while `.wrap` ran at 10px and the brand
   took the slack as a 32px auto margin — so the left half of the bar was airy,
   the right half was jammed, and the notification badge, which overhangs its
   button by a pixel, landed on the avatar. Every gap is 4px now and the brand
   still takes what is left over. */
@media(max-width:760px){
  /* A PANEL IS PINNED TO THE SCREEN, NOT TO ITS BUTTON.
     Anchored `right:-4px` off the bell — which is the correct thing on a
     desktop — a 366px panel on a 390px phone opened THIRTY PIXELS OFF THE LEFT
     EDGE and stayed there: the heading read "otifications" and the All tab was
     half a tab. There is no room to hang something nearly screen-wide off a
     control near the right edge, so at this width it stops trying and spans the
     gutters under the header instead. `position:fixed` because that is what it
     now is — a sheet at a fixed place on the screen, not a thing beside a
     button — and it also means a long list scrolls itself rather than the page
     behind it.
     `.flip`, which the JS adds when a menu would run off the right, has nothing
     left to correct here and must not put the panel back where it was. */
  .nb-panel,.nb-panel.flip,.nb-menu.usermenu{position:fixed;
    top:calc(var(--navh) + env(safe-area-inset-top) + 6px);
    left:max(var(--pad),env(safe-area-inset-left));
    right:max(var(--pad),env(safe-area-inset-right));
    width:auto;min-width:0;max-width:none;
    max-height:min(72vh,calc(100vh - var(--navh) - 20px - env(safe-area-inset-top) - var(--floor,0px)))}
  .navauth .nb-dd{align-self:center}

  .burger,.nb-ic,.nb-av,.nb-go{width:42px;height:42px}
  .burger{margin:0;border-radius:10px}
  .nav .wrap{gap:0}
  .nav .logo{margin-left:6px;margin-right:auto}
  .navauth{gap:4px;margin-left:6px}

  /* CREATE SHEDS ITS CHEVRON. The split is a desktop affordance: it buys you
     the five destinations without a page load. On a phone it spent 67px — a
     sixth of the bar — and made its own second half a 28px target, well under
     everything around it. The five are all in the drawer and on /post itself,
     which is where this button goes. */
  .nb-chevbtn{display:none}
  .nb-go{padding:0;justify-content:center;border-radius:10px}
  .nb-go .lbl{display:none}

  /* The picture keeps its size while the target grows around it, so the row
     reads as one set of glyphs rather than one photograph and five icons — and
     the presence dot rides the bubble's edge, not the box's. */
  .nb-av .av{width:34px;height:34px}
  .nb-pres{right:4px;bottom:4px}

  /* The glyphs grow with their boxes. Left at the desktop 18px they read as
     small marks floating in 42px of nothing, which is what makes a phone bar
     look sparse rather than roomy. */
  .burger svg,.nb-ic svg,.nb-go svg{width:20px;height:20px}
}

/* The smallest screens still in use cannot have both a 42px target and all six
   controls: at 320px that row is 10px wider than the viewport, and what fell
   off the end was the avatar. Nothing is hidden — a control you cannot find is
   worse than one that is a little smaller — so they step back to the desktop
   36px, which is what they were before this and is still a usable target. */
@media(max-width:359px){
  .burger,.nb-ic,.nb-av,.nb-go{width:36px;height:36px}
  .nb-av .av{width:31px;height:31px}
  .nb-pres{right:2px;bottom:2px}
  .burger svg,.nb-ic svg,.nb-go svg{width:18px;height:18px}
  /* The badge overhangs its button by a pixel, which is right where there is
     room beside it and one pixel too many where there is not. */
  .nb-badge{right:1px}
  /* The gap stays 4px. At 2px the notification badge, which overhangs its
     button by a pixel, sat on the avatar — and the row is what it costs, not
     the space between things in it. */
  .navauth{margin-left:4px}
  .nav .logo{margin-left:2px}
}


/* =========================================================================
   THE FEED — the page the site is arranged around.
   =========================================================================
   Three rules the whole design rests on, and they are visible in the rules
   below rather than only in the markup:

     1. ONE hue carries fitment, at two weights (plus absence). Green means an
        owner published it and the system matched it against a car you own.
        Nothing else in this file is allowed that colour — a sponsored card
        borrowing it is how the one honest signal on the page stops meaning
        anything.
     2. Mono (`.num`) means "measured figure" and nothing else: a price, a
        duration, a mileage, a count. "Make an offer" sits in a price's slot and
        is deliberately NOT mono, because it is not a figure.
     3. Every card gets ONE metadata line, not four — and a card with two facts
        is short, rather than padded out to match its neighbours.

   The palette is the site's own (00-tokens-and-buttons.php). Only --fit is new:
   the feed needed a second hue that is not the accent, because the accent is
   already carrying Create, the rail and the active tab, and a fourth orange
   thing in that span stops being a signal.
   ========================================================================= */
:root{
  --fit:#2E7049; --fit-soft:#EAF3ED; --fit-line:#C6DFCF;
}
body.dark{
  --fit:#6FC08E; --fit-soft:rgba(111,192,142,.12); --fit-line:rgba(111,192,142,.26);
}

/* ---- the frame ---------------------------------------------------------
   The rail is fixed; the feed takes what is left. The column caps at --col
   with every other page (§11): the feed used to stand on a rung of its own at
   1040px, which put its edge 90px inside /mods' on the same window. The rail
   beside it still takes 280px of that. .fc has no measure of its OWN, so its
   body text now spans the full column: if that reads too wide, the fix is a ch
   cap on the text (§11), not a narrower page. */
.fdw{display:grid; grid-template-columns:280px minmax(0,1fr); gap:20px; align-items:start;
  max-width:var(--col)}
.fdm{min-width:0}
/* One column beside the feed — the garage, then what is around you. It sticks,
   and scrolls on its own if it outgrows the window. Two rails were taking the
   feed's width, so there is one.
   The two blocks are separate elements rather than one, because on a phone they
   go to DIFFERENT places (see the narrow rules at the foot of this file). */
/* The cap is the window MINUS the chrome at both ends: the header above
   (--navh) and whatever owns the bottom edge below (--floor — the admin bar,
   the phone's tab bar). Without the second the rail ran its full height and an
   operator's bar covered the foot of it, which is the bottom of "Events coming
   up": the last event, the Going button and the "All N events" link were all
   behind the bar with no way to scroll to them, because the rail believed it
   had already shown everything. */
.fdside{position:sticky; top:calc(var(--navh) + 14px); display:flex; flex-direction:column; gap:16px;
  max-height:calc(100vh - var(--navh) - 28px - var(--floor,0px)); overflow-y:auto; overscroll-behavior:contain;
  scrollbar-width:none; padding-bottom:2px}
.fdside::-webkit-scrollbar{display:none}
.fdside > *{flex:none}
.fdr{display:flex; flex-direction:column; gap:16px}
.fdr > *{flex:none}

/* ---- rail modules ------------------------------------------------------ */
.fdr-m{background:var(--surface); border:1px solid var(--border); border-radius:var(--r);
  overflow:hidden}
.fdr-m--garage{padding:4px 0}
.fdr-hd{display:flex; align-items:center; gap:8px; padding:8px 12px 4px}
/* SCOPED, like every other selector in this file. Unscoped, `.lbl` is a name
   the header was already using: the Create button's label is a `.lbl`, and this
   rule reached across and drew it 10.5px uppercase in --t3 — grey on the orange
   fill, 1.20:1, the least legible text on the site. A page stylesheet that
   claims a two-letter generic class is claiming it everywhere. */
.fdr-hd .lbl{flex:1;font-size:10.5px; font-weight:600; letter-spacing:.07em;
  text-transform:uppercase; color:var(--t3)}
.fdr-n{font-family:var(--mono); font-size:10px; color:var(--t3); font-variant-numeric:tabular-nums}
.fdr-ft{padding:6px 12px 10px}
.fdr-ft--line{border-top:1px solid var(--border)}
.fdr-lk{display:inline-flex; align-items:center; gap:5px; font-size:12.5px; font-weight:600; color:var(--t3)}
.fdr-lk:hover{color:var(--accent)}
.fdr-lk svg{flex:none}

/* the garage: a shortcut list, and the feed's navigation. Every row is a real
   link — a feed is an address (§12), so this keeps working when the bundle
   does not. */
.fdg{display:flex; align-items:center; gap:8px; padding:4px 8px; margin:0 4px;
  border-radius:8px; width:calc(100% - 8px); position:relative}
.fdg:hover{background:var(--surface2)}
.fdg.on{background:var(--accent-soft)}
.fdg.on .fdg-nm, .fdg.on .fdg-n{color:var(--accent-fg); opacity:1}
.fdg--me{margin-bottom:2px}
.fdg--me .fdg-mt{color:var(--t3)}
.fdg--me .av{width:30px; height:30px; font-size:12px}
.fdg-img,.fdg-ph{width:30px; height:30px; border-radius:4px; flex:none; background:var(--surface2);
  object-fit:cover}
.fdg-ph{display:grid; place-items:center; font-size:10px; font-weight:600; color:var(--t3);
  letter-spacing:.04em}
.fdg-tx{min-width:0; flex:1; padding:4px 0}
.fdg-nm{display:block; font-size:13px; font-weight:600; letter-spacing:-.015em; color:var(--text);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.fdg-mt{display:block; font-size:10.5px; color:var(--t3); margin-top:2px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.fdg-mt .num{font-size:10px}
/* Every number in this column is "how many published mods fit this car",
   counted by Mods::fitsCount() — the SAME function the Mods page's garage strip
   puts on each car, so the two pages cannot tell a member two different things
   about one car. A car with nothing fitting shows a grey zero rather than being
   hidden: an absent row reads as a missing car. */
.fdg-n{flex:none; font-family:var(--mono); font-size:10.5px; color:var(--t3);
  font-variant-numeric:tabular-nums; padding-left:4px}
.fdg-n--0{opacity:.55}

/* events near you */
/* Discover: the one rail row that is not a car and carries no number. Its
   placeholder holds an icon rather than initials or a count. */
.fdg-ph--ic{display:grid; place-items:center; color:var(--t3)}
.fdg--disc.on .fdg-ph--ic,.fdg--disc:hover .fdg-ph--ic{color:var(--accent-fg)}

/* ---- which feed (phones): the garage as a dropdown ---------------------
   The rail's column has nowhere to go on a 360px screen. What stood in for it
   was a sideways strip of tiles, and a strip is the wrong shape for
   navigation: you dragged through it to find a car you own, every name was cut
   off at 120px, and the row you were ON could be scrolled out of sight — so
   the one thing navigation has to say (where am I) was the one thing it did
   not. This says it in the closed state, and opens the whole garage.

   It is a real <details>: it opens with no script, and every row inside is a
   real <a href> (§12). The panel is ABSOLUTE, not fixed — `.page.on` carries a
   300ms enter animation, and a transformed ancestor becomes the containing
   block for a fixed descendant, which is the bug 06b-feed/06-float.php exists
   to work around. There is nothing to work around if it never goes fixed. */
.fdpick{display:none; position:relative; z-index:30; margin-bottom:10px}
/* The <summary> itself stays a BLOCK and the flex row is one span inside it.
   Safari spent years breaking the disclosure toggle outright when a summary was
   given `display:flex` — the element still looked right and simply stopped
   opening, which is the one failure mode a rendering check cannot see and the
   one a phone-only control cannot afford. The span costs nothing. */
.fdpick-b{padding:8px 12px; cursor:pointer; background:var(--surface);
  border:1px solid var(--border); border-radius:var(--r); list-style:none}
.fdpick-b::-webkit-details-marker{display:none}
.fdpick-b::marker{content:""}
.fdpick-in{display:flex; align-items:center; gap:10px}
.fdpick-cur{display:flex; align-items:center; gap:10px; flex:1; min-width:0}
.fdpick-in > svg{flex:none; color:var(--t3); transition:transform .16s var(--ease)}
.fdpick[open] .fdpick-b{border-color:var(--border2); border-bottom-left-radius:0; border-bottom-right-radius:0}
.fdpick[open] .fdpick-in > svg{transform:rotate(180deg)}
/* The closed button holds a rail row verbatim, so it is raised here rather
   than in a second copy of the row's markup. */
.fdpick-cur .fdg-img,.fdpick-cur .fdg-ph,.fdpick-cur .av{width:38px; height:38px}
.fdpick-cur .fdg-nm{font-size:15px; letter-spacing:-.02em}
.fdpick-cur .fdg-mt{font-size:12px}
.fdpick-cur .fdg-n{font-size:12px}

.fdpick-m{position:absolute; left:0; right:0; top:100%; z-index:1;
  background:var(--surface); border:1px solid var(--border2); border-top:0;
  border-radius:0 0 var(--r) var(--r); padding:4px; box-shadow:var(--sh-lg);
  max-height:min(62vh, 460px); overflow-y:auto; overscroll-behavior:contain}
.fdpick-lbl{display:block; font-size:10.5px; font-weight:600; letter-spacing:.07em;
  text-transform:uppercase; color:var(--t3); padding:8px 10px 4px}
.fdo{display:flex; align-items:center; gap:10px; padding:8px 10px; border-radius:8px}
.fdo:hover{background:var(--surface2)}
.fdo-bd{display:flex; align-items:center; gap:10px; flex:1; min-width:0}
.fdo .fdg-img,.fdo .fdg-ph,.fdo .av{width:38px; height:38px}
.fdo .fdg-nm{font-size:14.5px; letter-spacing:-.02em}
.fdo .fdg-mt{font-size:12px}
.fdo .fdg-n{font-size:12px}
/* The tick is the only thing that says which row you are on once the panel is
   open, so it holds its slot on every row rather than shifting the rows that
   do not have it. */
.fdo > svg{flex:none; color:var(--accent-fg); opacity:0}
.fdo[aria-current="page"] > svg{opacity:1}
.fdo[aria-current="page"] .fdg-nm,.fdo[aria-current="page"] .fdg-n{color:var(--accent-fg); opacity:1}
.fdo[aria-current="page"] .fdg-ph--ic{color:var(--accent-fg)}
.fdo--add{border-top:1px solid var(--border); border-radius:0 0 8px 8px; margin-top:4px}
.fdo--add .fdg-nm{color:var(--t2)}

/* what Discover IS, at the head of it — a reader who lands on a shuffled river
   of strangers' cars with no explanation reads it as their own feed gone wrong */
.fdd{display:flex; align-items:center; gap:11px; padding:12px; margin-bottom:10px;
  background:var(--surface); border:1px solid var(--border); border-radius:var(--r)}
.fdd-ic{width:38px; height:38px; border-radius:8px; flex:none; display:grid;
  place-items:center; background:var(--surface2); color:var(--t2)}
.fdd-tx{flex:1; min-width:0}
.fdd-t{font-family:var(--dis); font-size:16px; font-weight:600; letter-spacing:-.025em;
  color:var(--text); line-height:1.25}
.fdd-p{font-size:12.5px; color:var(--t3); margin-top:2px; line-height:1.45}
.fdd-p b{color:var(--t2); font-weight:600}
@media(max-width:600px){
  .fdd{padding:10px}
  .fdd-ic{display:none}
}

/* the tile is a row: the link, and Going beside it as a sibling (see the view) */
.fde-row{display:flex; align-items:center}
.fde-row:hover{background:var(--surface2)}
.fde{display:flex; align-items:center; gap:10px; padding:7px 12px; flex:1; min-width:0}
/* Text, not a pill. A bordered button with an icon took ~70px out of a 280px
   tile and started truncating the event's own name and place — and the name is
   what the tile is FOR. The word survives; the chrome does not.
   The tick appears only once you are going, where it is confirmation rather
   than decoration, and it is the same green the card's Going button and every
   fitment phrase use, because it means the same thing. */
.fde-go{flex:none; display:flex; align-items:center; gap:4px; padding:4px 12px 4px 4px;
  font-size:11.5px; font-weight:600; color:var(--t3); background:none; border:0}
.fde-go:hover{color:var(--accent-fg); text-decoration:underline}
.fde-go svg{flex:none; display:none}
.fde-go[aria-pressed="true"]{color:var(--fit)}
.fde-go[aria-pressed="true"]:hover{color:var(--fit)}
.fde-go[aria-pressed="true"] svg{display:block}
.fde-go[disabled]{opacity:.55}
.fde-d{flex:none; width:34px; text-align:center; border:1px solid var(--border); border-radius:6px;
  padding:3px 0; background:var(--surface2)}
.fde-m{display:block; font-size:8.5px; font-weight:700; letter-spacing:.08em; color:var(--t3)}
.fde-n{display:block; font-family:var(--mono); font-size:14px; font-weight:500; color:var(--text);
  line-height:1.1; font-variant-numeric:tabular-nums}
.fde-tx{min-width:0; flex:1}
.fde-nm{display:block; font-size:12.5px; font-weight:600; letter-spacing:-.015em; color:var(--text);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.fde-pl{display:block; font-size:11px; color:var(--t3); margin-top:1px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.fde-mi{margin-left:4px}

/* a person or a group, with one action */
.fdp{display:flex; align-items:center; gap:10px; padding:8px 12px}
.fdp + .fdp{border-top:1px solid var(--border)}
.fdp-sq{width:32px;height:32px;border-radius:5px;flex:none;background:var(--surface2);
  display:grid;place-items:center;color:var(--t3);overflow:hidden}
.fdp-sq img{width:100%;height:100%;object-fit:cover}
.fdp-tx{min-width:0; flex:1}
.fdp-nm{font-size:12.5px; font-weight:600; letter-spacing:-.015em; color:var(--text);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.fdp-mt{font-size:11px; color:var(--t3); margin-top:1px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.fdp-ac{display:flex; align-items:center; gap:6px; flex:none}

/* ---- the status box ----------------------------------------------------
   One box. It is a single row until you type in it; then it grows, and the
   footer with Post appears. Anything with FIELDS comes from Create in the nav,
   so this never has to pretend to be five editors. */
.fdc{background:var(--surface); border:1px solid var(--border); border-radius:var(--r);
  padding:10px; margin-bottom:10px}
.fdc:focus-within{border-color:var(--accent-line); box-shadow:0 0 0 3px var(--accent-soft)}
.fdc-row{display:flex; align-items:flex-start; gap:10px}
.fdc-ta{flex:1; min-width:0; border:0; background:transparent; resize:none; overflow:hidden;
  padding:7px 0 0; font:400 15px/1.5 var(--ui); color:var(--text); letter-spacing:-.008em;
  min-height:32px}
.fdc-ta::placeholder{color:var(--t3)}
.fdc-ta:focus{outline:none}
/* The footer is VISIBLE by default and the bundle collapses it — not the other
   way round. With the bundle dead nothing sets data-open, so a hidden-by-default
   footer would leave a text box with no way to send it; this way the working
   state is the one that needs no script, and the tidier state is the
   enhancement. */
.fdc-ft{display:flex; align-items:center; gap:8px; margin-top:8px; padding-top:8px;
  border-top:1px solid var(--border)}
.fdc[data-open="false"] .fdc-ft{display:none}
.fdc-hint{flex:1; min-width:0; font-size:12.5px; color:var(--t3);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.fdc-hint b{color:var(--t2); font-weight:600}

/* ---- the two feeds ----------------------------------------------------- */
.fdt{display:flex; gap:4px; margin-bottom:10px; overflow-x:auto; scrollbar-width:none;
  border-bottom:1px solid var(--border)}
.fdt::-webkit-scrollbar{display:none}
.fdt a{height:36px; padding:0 10px; border-bottom:2px solid transparent; margin-bottom:-1px;
  color:var(--t2); font-size:13px; font-weight:500; white-space:nowrap;
  display:flex; align-items:center; justify-content:center; gap:6px}
.fdt a:hover{color:var(--text)}
.fdt a[aria-selected="true"]{color:var(--accent-fg); border-bottom-color:var(--accent); font-weight:600}
.fdt .ct{font-family:var(--mono); font-size:10.5px; opacity:.7; font-variant-numeric:tabular-nums}
.fdt-v{width:18px;height:18px;border-radius:4px;object-fit:cover;flex:none;background:var(--surface2)}

/* ---- the car at the head of its own feed ------------------------------- */
.fdv{display:flex; align-items:flex-start; gap:12px; padding:12px; margin-bottom:10px;
  background:var(--surface); border:1px solid var(--border); border-radius:var(--r)}
.fdv-img,.fdv-ph{width:64px;height:64px;border-radius:8px;object-fit:cover;flex:none;
  background:var(--surface2)}
.fdv-ph{display:grid;place-items:center;font-family:var(--mono);font-size:13px;font-weight:600;color:var(--t3)}
.fdv-tx{flex:1; min-width:0}
.fdv-top{display:flex; align-items:flex-start; gap:10px}
.fdv-nm{flex:1; min-width:0; font-family:var(--dis); font-size:16px; font-weight:600;
  letter-spacing:-.025em; line-height:1.3; color:var(--text)}
.fdv-nm em{font-style:normal; font-weight:500; color:var(--t3)}
.fdv-ac{display:flex; gap:6px; flex:none}
.fdv-ac .btn{flex:none}
.fdv-mt{font-size:12px; color:var(--t3); margin-top:3px; line-height:1.5}
.fdv-mt .num{font-size:11.5px; color:var(--t2)}
.fdv-fig{font-size:12px; color:var(--t3); margin-top:2px; line-height:1.5}
.fdv-fig b{color:var(--t2); font-weight:600}
.fdv .sep{margin:0 4px}

/* The pane while a switch is in flight. Deliberately faint and deliberately
   NOT a spinner over an empty column: the feed you are leaving stays on screen
   and dims, because a blank screen for 200ms reads as broken where a dimmed one
   reads as working. */
#fd-pane[data-loading]{opacity:.55; transition:opacity .12s var(--ease)}
#fd-pane[data-loading] *{pointer-events:none}

/* ---- end of the feed, and empty ---------------------------------------- */
.fdend{background:var(--surface); border:1px solid var(--border); border-radius:var(--r);
  padding:20px 16px; text-align:center; margin-top:10px}
.fdend--none{margin-top:0}
.fdend-t{font-family:var(--dis); font-size:15px; font-weight:600; letter-spacing:-.02em; color:var(--text)}
.fdend-p{font-size:13px; color:var(--t3); margin-top:4px; line-height:1.55}
.fdend-p .num{color:var(--t2)}
.fdend-row{display:flex; gap:8px; justify-content:center; margin-top:14px; flex-wrap:wrap}

/* ---- narrow ------------------------------------------------------------
   On a phone the garage becomes a DROPDOWN above the feed, so it is never
   hidden — it IS the navigation, and the tabs cannot do that job on a 360px
   screen. What is around you follows the feed instead.

   It was a sideways strip of tiles first, and that was the wrong shape: a
   garage is a list you pick one row out of, and a scroller made you drag to
   find a car you own, cut every name off at 120px, and could carry the row you
   were ON off the side of the screen. */
/* Under the breakpoint the sticky column stops being a column: `display:contents`
   dissolves it so the garage and "around you" become grid items of the page in
   their own right, and can be ordered independently. The garage goes ABOVE the
   feed — it is the navigation, and navigation you have to scroll past a whole
   feed to reach is hidden — and what is around you goes below it. Ordering the
   wrapper instead is what put the garage strip at the very bottom of the page. */
@media(max-width:1000px){
  .fdw{grid-template-columns:1fr}
  .fdside{display:contents}
  .fdr-m--garage{order:1}
  .fdm{order:2}
  .fdr{order:3; margin-top:16px}
}
@media(max-width:720px){
  /* One switcher, never two. The rail's list and the dropdown are the same
     destinations (02-rail.php builds both from one array), so exactly one of
     them is drawn at any width — showing both would be two answers to "which
     feed am I in", and the pair could then disagree about which is lit. */
  .fdr-m--garage{display:none}
  .fdpick{display:block; order:1}
  .fdv-top{flex-direction:column; gap:8px}
  .fdv-ac{width:100%}
}


/* =========================================================================
   THE FEED CARD — one frame, every type.
   =========================================================================
   head · body · media · stats · bar · thread. What changes between types is
   which facts are true of the thing, never how the card is put together, so
   almost everything here is shared and the per-type rules at the bottom are
   short on purpose. If a new type needs a block of its own, that is the signal
   to ask whether it is really a new type (§0).
   ========================================================================= */
.fc{background:var(--surface); border:1px solid var(--border); border-radius:var(--r);
  margin-bottom:10px; overflow:hidden; transition:box-shadow .16s var(--ease)}
.fc:hover{box-shadow:var(--sh)}
.fc .sep{color:var(--border2)}

/* ---- head: who, when, and the two tools -------------------------------- */
.fc-hd{display:flex; align-items:flex-start; gap:10px; padding:10px 12px 0}
.fc-who{flex:1; min-width:0}
.fc-nm{font-size:13.5px; font-weight:600; letter-spacing:-.015em; color:var(--text); line-height:1.35}
.fc-nm a:hover{text-decoration:underline}
.fc-nm em{font-style:normal; font-weight:400; color:var(--t2)}
.fc-ctx{font-size:12px; color:var(--t3); margin-top:1px; display:flex; align-items:center;
  gap:6px; flex-wrap:wrap; line-height:1.5}
.fc-ctx .dt{white-space:nowrap}

/* the machine talking, and dressed as it: an icon instead of a bubble and a
   tinted strip. A notice dressed as a person is what members learn to distrust,
   and once they do they distrust the cards beside it too. */
.fc-sys{display:flex; align-items:center; gap:8px; padding:8px 12px;
  background:var(--surface2); border-bottom:1px solid var(--border)}
.fc-sys-ic{width:26px;height:26px;border-radius:5px;flex:none;display:grid;place-items:center;
  background:var(--accent-soft); color:var(--accent-fg)}
.fc-sys-t{font-size:12px; font-weight:600; letter-spacing:.01em; color:var(--text)}
.fc-sys-w{flex:1; font-size:11.5px; color:var(--t3)}
.fc-sys-ln{padding:10px 12px 0; font-size:13.5px; color:var(--t2)}
.fc-sys-ln em{font-style:normal; font-weight:600; color:var(--text)}
/* a paid slot is neutral type — never the fitment green (see 19-feed.php) */
.fc-sys--ad .fc-sys-t{color:var(--t2); font-weight:600; letter-spacing:.06em;
  text-transform:uppercase; font-size:10.5px}
.fc[data-fc="sponsored"]{border-style:dashed}

.fc-tools{display:flex; gap:2px; flex:none; margin:-2px -4px 0 0; position:relative}
.fc-t{width:28px;height:28px;border-radius:8px;display:grid;place-items:center;color:var(--t3)}
.fc-t:hover{background:var(--surface2); color:var(--text)}
.fc-t[aria-pressed="true"]{color:var(--accent-fg)}
.fc-t[aria-pressed="true"] svg{fill:var(--accent-soft)}
.fc-menu{position:absolute; top:32px; right:0; z-index:40; min-width:236px; padding:5px;
  background:var(--surface); border:1px solid var(--border2); border-radius:var(--r);
  box-shadow:var(--sh-lg); display:none}
.fc-menu[data-open="1"]{display:block}
.fc-menu-i{display:flex; align-items:flex-start; gap:10px; width:100%; padding:8px 9px;
  border-radius:8px; text-align:left; font-size:13px; font-weight:500; color:var(--text)}
.fc-menu-i:hover{background:var(--surface2)}
.fc-menu-i svg{flex:none; margin-top:1px; color:var(--t3)}
.fc-menu-i small{display:block; font-size:11.5px; font-weight:400; color:var(--t3); margin-top:1px}
.fc-menu-i--warn{color:var(--danger,#AE3428)}
.fc-menu-i--warn svg{color:inherit}
.fc-menu-hr{display:block; height:1px; background:var(--border); margin:4px 6px}

/* ---- a panel inside a card is clipped by the card ---------------------- */
/* `.fc` clips its own overflow so a photo stays inside the rounded corners —
   and that cut every panel that opens inside a card. Measured on the real
   feed: the ··· menu lost 79-132px of its 188-207px on EVERY card, so Follow,
   Save and Report were simply not on screen; the fitment panel is 258px wide
   and anchored to a ~140px button, so it opened 99px past the card's LEFT
   edge and lost its heading and its first car. Widening the card's overflow
   is the wrong trade — the clip is what the rounded corners are made of.
   So while a panel is open js/06b-feed/06-float.php MOVES it to the body and
   positions it from its trigger's rect. `position:fixed` alone would not do:
   a transformed ancestor becomes the containing block for its fixed children,
   and `.page.on` carries a 300ms enter animation that translates the whole
   section — a panel opened during it landed ~5,800px down the page.

   `top` and `left` are set inline by that file, which is why only the axes it
   never writes are !important: a stylesheet's !important beats an inline rule,
   so marking all four would pin every panel to one corner.

   The z-index sits above the FAB (1200) and the bug tip (1300) and below the
   admin bar (1900) and the modals (2000) — a panel somebody just opened
   outranks a button that is always there, and does not outrank the operator's
   own chrome. It is !important because `.fc-menu`/`.fc-fitpop` set their own
   further down this file at equal specificity, where the later rule wins. */
.fc-float{position:fixed !important; z-index:1400 !important;
  bottom:auto !important; right:auto !important; margin:0 !important;
  max-width:calc(100vw - 20px)}

/* ---- body: title, ONE metadata line, the text -------------------------- */
.fc-bd{padding:6px 12px 0}
.fc-ttl{font-family:var(--dis); font-size:16px; font-weight:600; letter-spacing:-.028em;
  line-height:1.25; margin:0; color:var(--text)}
.fc-ttl a:hover{color:var(--accent-fg)}
/* the single metadata line: the category, then the measured figures. A gap
   stays a gap — the line is BUILT from what is true, never padded with empty
   slots (ams_feed_meta drops them). */
.fc-meta{font-size:12px; color:var(--t3); margin-top:3px; display:flex; align-items:center;
  gap:6px; flex-wrap:wrap; line-height:1.5}
.fc-meta .num{font-size:11.5px; color:var(--t2)}
.fc-meta b{font-weight:600; color:var(--t2)}
/* not a measured figure, and set in the body face for exactly that reason,
   even though it sits in a price's slot */
.fc-offer{font-family:var(--dis); font-weight:600; color:var(--t2)}
.fc-open{color:var(--accent-fg); font-weight:600}
.fc-x{font-size:13.5px; color:var(--t2); line-height:1.5; margin:6px 0 0}
/* The fold. Only a text past AMS_FEED_MORE_MIN is wrapped in .fc-clamp, and it
   is wrapped ONLY when the See more beside it is drawn too — the renderers emit
   the pair or neither (app/render-feed-cards.php). A clamp on its own would cut
   a card off with nothing to press, so never style .fc-clamp onto anything the
   button does not reach. */
.fc-clamp{display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden}
.fc-x[data-open="1"] .fc-clamp{display:block; -webkit-line-clamp:none}
.fc-x[data-open="1"] .fc-more{display:none}
.fc-more{display:inline-block; padding:0; margin-top:2px; font-size:12.5px; font-weight:600; color:var(--t3)}
.fc-more:hover{color:var(--accent-fg); text-decoration:underline}
.fc-hint{padding:8px 12px 0; font-size:12.5px; color:var(--t3); line-height:1.5}
.fc-hint a{color:var(--accent-fg); font-weight:600}

/* ---- media ------------------------------------------------------------- */
.fc-media{width:100%; margin-top:10px; object-fit:cover; background:var(--surface2);
  aspect-ratio:2.4/1}
.fc-media--tall{aspect-ratio:2/1}
/* the body-style default is a DRAWING, not a photograph. It keeps the slot and
   the height so the feed's rhythm holds, and is contained rather than cropped —
   covering it blows a 300px-wide silhouette up to card width and cuts its
   wheels off. */
.fc-media--draw{object-fit:contain; padding:14px 0; background:var(--surface2)}
/* a placeholder where a photo would be: the type's own icon, never a broken
   frame and never a card that suddenly stands half as tall */
.fc-ph{display:grid; place-items:center; gap:6px; background:var(--surface2); color:var(--t3);
  width:100%; aspect-ratio:2.8/1}
.fc-ph span{font-size:12px; font-weight:600}
.fc-ph--sale{width:80px;height:80px;aspect-ratio:auto;border-radius:8px;flex:none;
  border:1px dashed var(--border2)}
.fc-ph--ev{border-bottom:1px solid var(--border)}
/* THE PICTURE IS A WAY IN. A card's photograph is the biggest thing on it and
   the most obvious thing to press, and until this it went nowhere — the title
   and the verb on the bar were the only routes to the mod, the car or the
   event, and both of them are small. It is a real <a href> (§12), so the rule
   here only has to stop the anchor changing the layout the picture already had:
   block, with no line box of its own under the image. */
.fc-medial{display:block; line-height:0; color:inherit}
.fc-medial > img{display:block}
.fc-medial:hover > img{filter:brightness(.94)}
.fc-medial:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
/* the sale thumbnail is a flex child, and the anchor takes its place in the row */
.fc-sale > .fc-medial{flex:none}

/* ---- the inline preview of something else ------------------------------ */
.fc-prev{display:flex; align-items:center; gap:10px; margin:10px 12px 0; padding:8px;
  border:1px solid var(--border); border-radius:8px; background:var(--surface2)}
.fc-prev:hover{border-color:var(--border2); background:var(--surface)}
.fc-prev-img{width:56px;height:56px;border-radius:5px;object-fit:cover;flex:none;background:var(--border)}
.fc-prev-ph{display:grid;place-items:center;color:var(--t3)}
.fc-prev-tx{min-width:0; flex:1}
.fc-prev-who{display:block; font-size:11.5px; color:var(--t3)}
.fc-prev-t{display:block; font-size:13.5px; font-weight:600; letter-spacing:-.02em; color:var(--text);
  line-height:1.3; margin-top:1px}
.fc-prev-m{display:flex; align-items:center; gap:6px; flex-wrap:wrap; font-size:11.5px;
  color:var(--t3); margin-top:2px}
.fc-prev-m .num{color:var(--t2)}
.fc-prev-go{flex:none; color:var(--t3)}
.fc-quote{margin:10px 12px 0; position:relative}
.fc-unshare{position:absolute; top:4px; right:4px; width:22px;height:22px;border-radius:6px;
  display:grid;place-items:center;color:var(--t3);background:var(--surface)}
.fc-unshare:hover{color:var(--danger,#AE3428)}

/* ---- event cover and date tile ----------------------------------------- */
.fc-evc{position:relative; margin-top:10px}
.fc-evc img{width:100%; aspect-ratio:2.8/1; object-fit:cover; background:var(--surface2);
  border-bottom:1px solid var(--border)}
/* The tile sits OVER the cover and is not a control. Letting a press on it fall
   through to the link underneath is what makes the whole cover one target
   rather than one with a 44px hole punched in the corner of it. */
.fc-evd{position:absolute; left:12px; bottom:12px; width:44px; text-align:center;
  border-radius:8px; padding:4px 0; background:var(--surface); box-shadow:var(--sh);
  pointer-events:none}
.fc-evd-m{display:block; font-size:9px; font-weight:700; letter-spacing:.08em; color:var(--accent-fg)}
.fc-evd-d{display:block; font-family:var(--mono); font-size:17px; font-weight:500; color:var(--text);
  line-height:1.1; font-variant-numeric:tabular-nums}
.fc-bring{display:inline-flex; align-items:center; gap:7px; margin:10px 12px 0; padding:5px 9px;
  border:1px solid var(--border); border-radius:99px; font-size:12.5px; color:var(--t2)}
.fc-bring:hover{border-color:var(--border2)}
.fc-bring img{width:20px;height:20px;border-radius:4px;object-fit:cover}
.fc-bring b{color:var(--text); font-weight:600}

/* ---- part for sale ------------------------------------------------------ */
.fc-sale{display:flex; gap:12px; padding:8px 12px 0}
.fc-sale-img{width:80px;height:80px;border-radius:8px;object-fit:cover;flex:none;background:var(--surface2)}
.fc-sale-tx{min-width:0; flex:1}

/* ---- the failure distribution on a known issue -------------------------
   Absent mileages mean no strip at all — the card says why instead, because
   the only thing that makes it better is more owners pressing its button. */
.fc-onset{padding:10px 12px 0}
.fc-onset-t{display:flex; align-items:center; gap:6px; font-size:11.5px; color:var(--t3)}
.fc-onset-n{margin-left:auto}
.fc-onset-b{display:block; position:relative; height:22px; margin-top:5px; border-radius:5px;
  background:var(--surface2)}
.fc-onset-b i{position:absolute; top:4px; width:2px; height:14px; margin-left:-1px; border-radius:1px;
  background:var(--t3); opacity:.5}
.fc-onset-b b{position:absolute; top:0; width:2px; height:22px; margin-left:-1px; background:var(--accent)}

/* ---- stats: counts live HERE and nowhere else -------------------------- */
.fc-stats{display:flex; align-items:center; gap:8px; padding:8px 12px 5px; font-size:12px;
  color:var(--t3); min-height:30px}
.fc-sp{flex:1}
.fc-stats .fc-b{display:inline-flex; align-items:center; white-space:nowrap}
.fc-stats .num{color:var(--t2)}
.fc-stats button{padding:0; font-size:12.5px; color:var(--t3); white-space:nowrap}
.fc-stats button:hover{color:var(--text); text-decoration:underline}
/* What this fits: a CONTROL, at the foot of the card, beside the counts.
   It states the fact in the fewest words that carry it and opens UPWARD to name
   the cars — the names never repeat down the page, the number does the work.
   Computed (Api::stampFitment), never typed by the poster. */
.fc-fitw{position:relative; flex:none}
/* the counts and the control sit together on the right; on a phone the
   control wraps to a line of its own and this `·` would be left hanging */
.fc-sep-fit{flex:none}
.fc-fitb{padding:0; font-size:12px; font-weight:500; color:var(--fit); white-space:nowrap}
.fc-fitb:hover,.fc-fitb[aria-expanded="true"]{text-decoration:underline}
.fc-fitb .num{color:inherit; font-weight:600}
/* an advert is aimed at your car, not matched to it — grey, never the green */
.fc-fitb--ad{color:var(--t3)}
.fc-fitpop{position:absolute; right:0; bottom:24px; z-index:40; width:258px; padding:7px;
  background:var(--surface); border:1px solid var(--border2); border-radius:var(--r);
  box-shadow:var(--sh-lg); display:none}
.fc-fitpop[data-open="1"]{display:block}
.fc-fitpop-t{display:block; font-size:9.5px; font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--t3); padding:3px 6px 7px}
.fc-fitcar{display:flex; align-items:center; gap:9px; padding:5px 6px; border-radius:8px}
.fc-fitcar:hover{background:var(--surface2)}
.fc-fitcar img,.fc-fitcar-ph{width:34px; height:26px; border-radius:4px; object-fit:cover;
  background:var(--surface2); flex:none}
.fc-fitcar-ph{display:grid; place-items:center; color:var(--t3)}
.fc-fitcar > span{min-width:0}
.fc-fitcar b{display:block; font-size:12.5px; font-weight:600; color:var(--text); line-height:1.25}
.fc-fitcar i{display:block; font-style:normal; font-size:11px; color:var(--t3); margin-top:1px;
  white-space:nowrap}
.fc-fitcar i .num{color:var(--t2)}
/* the RSVP car picker — the fitment panel's shape, because it is the same
   object (your garage, one row each) asking a different question */
.fd-rsvpop .fc-fitcar{width:100%; border:0; background:transparent; text-align:left;
  font:inherit; cursor:pointer}
.fd-rsvpskip{width:100%; margin-top:4px; padding:7px 6px; border-top:1px solid var(--border);
  border-radius:0; font-size:12px; color:var(--t3); text-align:left}
.fd-rsvpskip:hover{color:var(--text)}
/* the rail's group line keeps the written form — it names one thing, once */
.fdp-mt .fc-fit{font-size:11px; color:var(--fit)}

/* ---- bar: verbs live HERE and nowhere else ----------------------------- */
.fc-bar{display:grid; grid-auto-flow:column; grid-auto-columns:1fr; padding:0 6px 3px;
  border-top:1px solid var(--border); margin-top:3px}
.fc-a{display:flex; align-items:center; justify-content:center; gap:8px; height:34px;
  border-radius:8px; font-size:13px; font-weight:600; color:var(--t2);
  transition:background .13s var(--ease)}
.fc-a:hover{background:var(--surface2); color:var(--text)}
.fc-a svg{flex:none}
.fc-a[aria-pressed="true"]{color:var(--fit)}
.fc-a[aria-pressed="true"] svg{fill:var(--fit-soft)}
.fc-bar .fc-a:last-child{color:var(--accent-fg)}
.fc-bar .fc-a:last-child:hover{background:var(--accent-soft)}

/* ---- the thread, folded until asked for -------------------------------- */
.fc-cmts{padding:8px 12px 12px; border-top:1px solid var(--border)}
.fc-cmts[hidden]{display:none}
.fc-cmts-bar{display:flex; align-items:center; gap:12px; padding-bottom:8px}
.fc-cmts-all,.fc-cmts-hide{padding:0; font-size:12.5px; font-weight:600; color:var(--t3)}
/* Load more carries the one glyph on this bar (§15). It sits ON the text
   baseline rather than beside it: the row is 12.5px type and a 14px box on a
   flex line would set the bar's height off the icon instead. */
.fc-cmts-all{display:inline-flex; align-items:center; gap:5px}
/* §15 puts the size in the stylesheet, not the call site. These rows are 12.5px
   and 11.5px type, well below the button ladder's 14px, so the glyph is sized
   here rather than by ams_icon()'s second argument — one opinion per row about
   how big a mark in it is. */
.fc-cmts-all > svg{flex:0 0 auto; width:14px; height:14px}
.fc-cmts-hide{font-weight:500}
.fc-cmts-all:hover,.fc-cmts-hide:hover{color:var(--accent-fg)}
.fc-cmts-none{font-size:12.5px; color:var(--t3); padding:2px 0 8px}
.fc-cmts-none a{color:var(--accent-fg); font-weight:600}
.fc-cmt{display:flex; gap:8px; padding:8px 0 10px; border-top:1px solid var(--border)}
.fc-cmt:first-of-type{border-top:0; padding-top:0}
.fc-cmt-w{min-width:0; flex:1}
.fc-cmt-nm{font-size:12.5px; font-weight:600; letter-spacing:-.015em; color:var(--text)}
.fc-cmt-nm:hover{text-decoration:underline}
/* "Owner" is worth a word: on a mod thread it is the difference between an
   opinion and the person who did the work answering for it. */
.fc-cmt-own{font-size:9.5px; font-weight:600; letter-spacing:.04em; text-transform:uppercase;
  color:var(--fit); margin-left:6px}
.fc-cmt-x{font-size:13.5px; color:var(--t2); line-height:1.45; margin-top:1px}
.fc-cmt-ac{display:flex; align-items:center; gap:12px; margin-top:4px; font-size:11.5px; color:var(--t3)}
.fc-cmt-ac button{padding:0; font-size:11.5px; font-weight:600; color:var(--t3);
  display:inline-flex; align-items:center; gap:4px}
.fc-cmt-ac button > svg{flex:0 0 auto; width:13px; height:13px}
.fc-cmt-ac button:hover{color:var(--accent-fg)}
.fc-cmt-ac button[disabled]{opacity:.5; pointer-events:none}
/* Helpful is a TOGGLE, so it has to draw which side of it you are on — a
   count that goes up and a button that looks identical afterwards reads as the
   press not having landed. The accent is the site's, not a colour of its own,
   so it moves when an operator repaints. */
.fc-cmt-help.on{color:var(--accent-fg)}
/* Delete is the one control in this row that takes something away, and it says
   so on hover rather than at rest: a red word sitting under every comment you
   wrote reads as a warning about the comment. */
.fc-cmt-del:hover{color:var(--danger,#AE3428) !important}
/* "edited" is a fact about the comment, in the time slot's own weight — the
   same size as the timestamp beside it, because it is that kind of fact and
   not a badge. An edit that leaves no mark is how a conversation stops being a
   record of what was said. */
.fc-cmt-ed{font-size:11.5px; color:var(--t3); font-style:italic}
.fc-cmt-ed::before{content:'· '; font-style:normal}

/* A REMOVED COMMENT, which only an operator who moderates content ever sees
   (Social::commentScope filters it out for everybody else). Struck through and
   dimmed, with the words still readable: this row exists precisely so somebody
   can find out what was said, so hiding the body here would leave the cost of
   keeping it and none of the value. Nothing in it is a control — there is
   nothing left to vote on, reply to or take down. */
.fc-cmt--gone .fc-cmt-x{color:var(--t3); text-decoration:line-through;
  text-decoration-color:var(--border)}
.fc-cmt--gone .av{opacity:.55}
.fc-cmt-gone{font-size:9.5px; font-weight:600; letter-spacing:.04em; text-transform:uppercase;
  color:var(--t3); margin-left:6px}

/* THE EDITOR, drawn by PHP in the comment's own place. It is the comment's own
   type and indent so the words do not move when you press Edit — a box that
   reflows what you are correcting is a box you have to re-find your place in. */
.fc-cmt-in{width:100%; margin-top:2px; padding:7px 10px; resize:vertical; min-height:56px;
  border:1px solid var(--accent-line); border-radius:10px; background:var(--surface);
  font:inherit; font-size:13.5px; line-height:1.45; color:var(--text)}
.fc-cmt-in:focus{outline:none; border-color:var(--accent)}
.fc-cmt-save{color:var(--accent-fg) !important}
.fc-reply{display:flex; align-items:center; gap:8px; margin-top:8px}
.fc-reply-in{flex:1; height:34px; border:1px solid var(--border); border-radius:99px;
  background:var(--surface2); padding:0 14px; font-size:13.5px; color:var(--text)}
.fc-reply-in:focus{outline:none; border-color:var(--accent-line); background:var(--surface)}
.fc-reply-go{width:32px;height:32px;border-radius:99px;display:grid;place-items:center;
  color:var(--t3); flex:none}
.fc-reply-go:hover{background:var(--accent-soft); color:var(--accent-fg)}

@media(max-width:600px){
  .fc-stats{flex-wrap:wrap; row-gap:2px}
  .fc-sep-fit{display:none}
  .fc-fitw{flex:1 0 100%; text-align:right}
  .fc-fitb{display:inline-block}
  /* a 258px popover is a desktop shape: on a phone both panels are sheets, and
     the sheet wins over whatever 06-float.php last positioned (it stops
     placing below this width, but a resize can leave stale inline values). */
  /* `--floor` is what the bottom edge is worth — the admin bar, the tab bar,
     AND the home indicator — a sheet that opens behind any of them is the same
     "cut off" bug one storey up. It carries the indicator already (§6), so the
     padding below is a plain 8px: `calc(8px + env(safe-area-inset-bottom))` on
     a sheet already standing on --floor counts the indicator twice, and the
     rows float that far up out of a sheet that looks unanchored. */
  .fc-menu,.fc-fitpop{position:fixed !important; left:0 !important; right:0 !important;
    top:auto !important; bottom:var(--floor,0px) !important; width:auto !important;
    max-width:none; min-width:0; border-radius:14px 14px 0 0; border-bottom:0;
    z-index:1400 !important;
    max-height:72vh; overflow-y:auto; padding:8px;
    box-shadow:0 -12px 40px rgba(0,0,0,.18)}
  .fc-sale-img,.fc-ph--sale{width:64px;height:64px}
}

/* =====================================================================
   THE SHARE SHEET — one popup for every share, on every surface.

   IT SITS AFTER 20-feed-card.php ON PURPOSE, and this is the one rule in
   this file that has already cost real bugs twice. `.fc-float` — the class
   the shared panel mechanism puts on a panel it has lifted to the body —
   sets `max-width:calc(100vw - 20px)`, `bottom:auto !important` and
   `right:auto !important` at the same specificity as a bare `.shs`, and
   order is the cascade. Written before it, the panel came out 424px wide
   against its own cap and the phone sheet fell out of fixed positioning
   and landed 7,266px down the page. Every pair below is `.shs.fc-float`
   for the same reason: a floated panel wears two classes and matching one
   of them is not enough.

   It is not in the vehicle profile's stylesheet, where the first version
   of this was written. The feed, the profile, a mod, a garage and the
   vehicle page all open it; a component half a dozen surfaces open does
   not belong in one page's file (§10 — one file, one scope).
   ===================================================================== */
.shs,.shs.fc-float{
  width:min(380px, calc(100vw - 20px));min-width:300px;max-width:380px;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg,14px);
  box-shadow:var(--sh-lg);overflow:hidden;z-index:90}
.shs-wait{margin:0;padding:16px 14px;font-size:13px;color:var(--t3)}

/* ---- the head: which step, and what this is about ---- */
.shs-hd{display:flex;align-items:center;gap:8px;padding:10px 10px 10px 13px;
  border-bottom:1px solid var(--border)}
.shs-hd .shs-hg{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.shs-hd .shs-n{font:600 14px/1.2 var(--dis,var(--ui));letter-spacing:-.02em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* WHAT IS BEING SHARED stays on screen through every step. The second and
   third screens are about WHERE it goes, and a picker with no memory of its
   subject is how somebody sends the wrong car to the right person. */
.shs-hd .shs-s{font-size:12px;line-height:1.2;color:var(--t3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.shs-nav{width:30px;height:30px;flex:none;display:grid;place-items:center;
  border:0;border-radius:8px;background:transparent;color:var(--t3);cursor:pointer;
  transition:background .12s,color .12s}
.shs-nav:hover{background:var(--surface2);color:var(--text)}

.shs-bd{padding:8px}
.shs-step{display:block}
/* WHICH WAY THE STEP WENT, so a panel that never moves still reads as one
   screen sliding onto another rather than as its contents being replaced. The
   classes are prefixed because a bare `.in` / `.back` is a claim on those words
   across the whole bundle (§12) — the site already has three scoped `.in` rules
   and a `.back`, and the next one to be written unscoped would land here.

   Under prefers-reduced-motion there is no animation at all: the direction is a
   nicety, and the panel is perfectly legible without it. */
@media(prefers-reduced-motion:no-preference){
  .shs-step.shs-in{animation:shs-slide .18s cubic-bezier(.32,.72,0,1)}
  .shs-step.shs-back{animation:shs-slideb .18s cubic-bezier(.32,.72,0,1)}
}
@keyframes shs-slide{from{opacity:0;transform:translateX(12px)}to{opacity:1;transform:none}}
@keyframes shs-slideb{from{opacity:0;transform:translateX(-12px)}to{opacity:1;transform:none}}

/* ---- step 1: the lanes ---- */
.shs-lanes{display:flex;flex-direction:column;gap:2px}
.shs-lane{display:flex;align-items:center;gap:12px;width:100%;padding:10px;
  border:0;border-radius:11px;background:transparent;color:var(--text);
  text-align:left;cursor:pointer;transition:background .12s}
.shs-lane:hover{background:var(--surface2)}
.shs-li{width:36px;height:36px;flex:none;display:grid;place-items:center;
  border-radius:10px;background:var(--surface2);color:var(--t2)}
/* Each destination gets its own tint, and every colour here is a TOKEN THE
   SITE ALREADY DEFINES rather than a hex written in this file. --fit is the
   feed's own fitment green, borrowed here because it means the same thing in
   both places; --green is the site's confirmation green, which is a different
   idea and stays a different colour. Three grey squares would make the first
   screen a list rather than a choice. */
.shs-lane--convs .shs-li{background:color-mix(in srgb, var(--accent) 11%, transparent);color:var(--accent)}
.shs-lane--places .shs-li{background:var(--fit-soft);color:var(--fit)}
.shs-lane--feed .shs-li{background:color-mix(in srgb, var(--t2) 13%, transparent);color:var(--t2)}
.shs-lane .shs-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.shs-lane .shs-n{font:600 14px/1.2 var(--ui);letter-spacing:-.012em}
.shs-lane .shs-w{font-size:12.5px;line-height:1.25;color:var(--t3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* GREEN MEANS THE SYSTEM MATCHED IT, here as everywhere else on the site: the
   subject's generation is one this person or this group actually runs. It is
   never typed and never carried from the sharer (§1, app/Share/ShareDest.php).

   IT IS `.shs-on`, NOT `.fit`, and the name is load-bearing. There is a bare
   global `.fit` (css/03-ymm-finder-and-combo.php) that is a green PILL —
   inline-flex, background, border, padding — so a `.shs-w.fit` inherited all
   of it and the line came out as a chip inside a row that already had one.
   Every modifier in this file is namespaced for that reason: `.mono` is global
   too, and so is enough else that an un-prefixed word is a coin toss. */
.shs-lane .shs-w.shs-url{font:400 11px/1.3 var(--mono)}
.shs-ch{flex:none;color:var(--t3);transition:transform .14s,color .14s}
.shs-lane:hover .shs-ch{transform:translateX(2px);color:var(--t2)}

/* The placeholders that hold the lanes' height while they load. They are the
   shape of a lane and nothing more — no spinner, no word — because the panel is
   already readable and what is missing arrives in a moment. */
.shs-wait2{pointer-events:none}
.shs-wait2 .shs-li{background:var(--surface2)}
.shs-bar{display:block;height:10px;border-radius:5px;background:var(--surface2)}
.shs-bar.w1{width:44%}.shs-bar.w2{width:62%}.shs-bar.w3{width:52%}
@media(prefers-reduced-motion:no-preference){
  .shs-wait2 .shs-li,.shs-bar{animation:shs-pulse 1.4s ease-in-out infinite}
}
@keyframes shs-pulse{0%,100%{opacity:1}50%{opacity:.55}}

.shs-split{height:1px;background:var(--border);margin:8px 10px}
.shs-lane--copy.done .shs-li{background:var(--green-soft);color:var(--green)}
.shs-lane--copy.done .shs-n{color:var(--green)}
.shs-done{display:flex;align-items:center;gap:8px;margin:0 0 8px;padding:10px 11px;
  border:1px solid var(--green-line);border-radius:11px;background:var(--green-soft);
  color:var(--green);font-size:13px;line-height:1.3}
.shs-done svg{flex:none}
.shs-gate{margin:8px 10px 4px;font-size:12.5px;line-height:1.5;color:var(--t3)}
.shs-gate a{color:var(--accent)}

/* ---- step 2: the picker ---- */
.shs-q{position:relative;margin-bottom:8px}
.shs-q svg{position:absolute;left:11px;top:50%;transform:translateY(-50%);
  color:var(--t3);pointer-events:none}
.shs-q input{width:100%;height:38px;padding:0 12px 0 34px;
  border:1px solid var(--border2);border-radius:var(--r,10px);
  background:var(--surface2);color:var(--text);font:400 13.5px var(--ui)}
.shs-q input:focus{background:var(--surface);outline:none;border-color:var(--accent)}
.shs-list{max-height:246px;overflow-y:auto;display:flex;flex-direction:column;gap:2px;
  margin:0 -3px;padding:0 3px}
.shs-row{display:flex;align-items:center;gap:11px;width:100%;padding:7px 8px;
  border:0;border-radius:10px;background:transparent;color:var(--text);
  text-align:left;cursor:pointer;transition:background .12s}
.shs-row:hover{background:var(--surface2)}
.shs-row .shs-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.shs-row .shs-n{font:500 14px/1.15 var(--ui);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.shs-row .shs-w{font-size:12px;line-height:1.2;color:var(--t3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* A GROUP IS A SQUARE AND A PERSON IS A CIRCLE. Both are AMSR.avatar() — one
   bubble on this site (§1) — and the shape is the only thing that says at a
   glance which pool you are looking at when the two steps are otherwise
   identical. */
.shs-row .av.shs-sq{border-radius:9px}
.shs-row .av.shs-sq .av-img{border-radius:9px}
.shs-box{width:20px;height:20px;flex:none;display:grid;place-items:center;
  border:1.5px solid var(--border2);border-radius:6px;color:transparent;
  transition:background .12s,border-color .12s}
.shs-row[aria-pressed="true"] .shs-box{background:var(--accent);border-color:var(--accent);color:#fff}
.shs-none{margin:0;padding:16px 10px;font-size:13px;line-height:1.6;color:var(--t3)}

/* THE FIT LINE IS WRITTEN HERE, AFTER BOTH ROW RULES, AND SCOPED LIKE THEM.
   It was `.shs-w.shs-on` up beside the lane rules, and it lost: `.shs-lane
   .shs-w` and `.shs-row .shs-w` are two-class selectors too, they set
   `color:var(--t3)`, and they come later in the file. Equal specificity, order
   is the cascade, both rules valid — and the one green line on the panel came
   out the same grey as everything round it, which reads as the sheet simply not
   knowing about fitment rather than as a CSS bug. */
.shs-lane .shs-w.shs-on,.shs-row .shs-w.shs-on{color:var(--fit);font-weight:500}

/* ---- the note, on both picker steps and on My feed ---- */
.shs-note{margin-top:9px}
.shs-note textarea{width:100%;height:38px;min-height:38px;max-height:96px;resize:none;
  padding:9px 12px;border:1px solid var(--border2);border-radius:var(--r,10px);
  background:var(--surface2);color:var(--text);font:400 13.5px/1.5 var(--ui)}
.shs-note textarea.shs-tall{height:84px}
.shs-note textarea:focus{background:var(--surface);outline:none;border-color:var(--accent)}

/* ---- My feed: the card that is about to be posted ---- */
.shs-prev .share-sub{display:block;border:1px solid var(--border);border-radius:12px;
  padding:12px;text-decoration:none;color:inherit;overflow:hidden}
.shs-prev .photo{display:block;aspect-ratio:16/7;margin:-12px -12px 11px;
  background-size:cover;background-position:center}
.shs-prev h4{margin:0;font-size:14.5px;font-weight:600;line-height:1.3}
.shs-prev p{margin:5px 0 0;font-size:13px;line-height:1.5;color:var(--t2)}

/* ---- the foot: what this will do, and the verb ----
   THE SENTENCE IS THE POINT. "Private to Ryan" and "Visible in S30 Owners" are
   different promises, and the button beside them is the only thing that keeps
   them. A verb with no statement of who will see it is how somebody posts a
   car to a club meaning to send it to one person. */
.shs-ft{display:flex;align-items:center;gap:12px;padding:10px 10px 10px 13px;
  border-top:1px solid var(--border);background:var(--surface2)}
.shs-h{flex:1;min-width:0;display:flex;align-items:center;gap:7px;
  font-size:12px;line-height:1.3;color:var(--t3)}
.shs-h svg{flex:none}
.shs-h span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.shs-h b{font-weight:600;color:var(--t2)}
.shs-h.pub,.shs-h.pub b{color:var(--accent)}
.shs-ft .btn{flex:none}

@media(max-width:600px){
  /* On a phone it is a sheet across the bottom, which is where the feed's own
     panels go at this width and for the same reason: a 380px dropdown anchored
     to a button near the right edge has nowhere to be.

     EVERY ONE OF THESE NEEDS !important, and that is not laziness. `.fc-float`
     sets `bottom:auto !important; right:auto !important; margin:0 !important`
     so it can position an anchored dropdown from top/left — correct for what it
     was written for, and exactly wrong for a sheet pinned to three edges. */
  .shs.fc-float{position:fixed !important;
    left:0 !important; right:0 !important; bottom:var(--floor,0px) !important;
    top:auto !important; width:auto !important; min-width:0 !important; max-width:none !important;
    border-radius:var(--r-lg,14px) var(--r-lg,14px) 0 0}
  /* And nothing here adds the home indicator back. --floor already carries it
     (§6), so the sheet is standing above it before a single pixel of padding is
     applied; `calc(4px + env(safe-area-inset-bottom))` counted it a SECOND time
     — and with both the body and the footer doing it, a third — so the lanes
     and the buttons somebody is reaching for floated ~68px up out of a sheet
     pinned to the bottom of the screen. */
  .shs-bd{padding:8px 8px 4px}
  .shs-ft{padding-bottom:10px}
  .shs-lane{padding:12px 10px}
  .shs-row{padding:9px 8px}
  /* Shorter, because the phone keyboard takes the bottom half of the window the
     moment the search box has the caret and a 246px list under it puts the
     first row off screen. */
  .shs-list{max-height:min(246px, 34vh)}
}

/* ============================================================================
   THE THUMB ZONE — the phone's navigation
   ----------------------------------------------------------------------------
   On a phone the nav moves off the top bar and comes down here. The reasoning
   is the whole design: the top of a phone screen is the part your thumb cannot
   reach, and the navigation was the thing up there you press most. So the top
   bar keeps what you REACH FOR — search, messages, notifications, you — and the
   bottom keeps what you NAVIGATE with.

   It is drawn from the same $NAV table as the bar and the drawer
   (views/app/chrome/03-tabbar.php), and its dropdowns are `.nb-dd`s driven by
   the one mechanism in js/01-nav.php, marked `data-click` because there is no
   hover on a phone to open them with.

   THREE BARS CAN WANT THIS EDGE. The tab bar, the operator's #adminbar, and the
   phone's own home indicator. --abh is the admin bar's height, --floor is what
   the bottom edge is worth ALTOGETHER, and this file is the only one that knows
   whether the thumb zone is on screen — so it raises --floor by the tab bar and
   every page, menu, toast and flyout on the site clears all three without
   knowing any of them by name.
   ========================================================================= */

:root{ --tabh:56px; --safe-b:env(safe-area-inset-bottom,0px); }

/* WHAT THE TAB BAR ITSELF STANDS ON, and it is --floor-modal. The bar sits on
   it and its menus clear it; --floor is then that plus this bar's own height,
   raised below, and it is --floor the page pads past. --floor-modal is the
   admin bar — whose --abh ALREADY carries the safe-area inset at phone width,
   so adding the inset again here would push the tab bar up by the home
   indicator twice — or that inset alone with no bar on screen.

   It was declared here, privately, as --tb-base. It is the same number a modal
   sheet ends at, for the same reason: it is what is left of the bottom edge
   once the tab bar itself is out of the question. So it is declared once, in
   css/08-announcement-and-admin-bar.php beside --floor, and read here — two
   names for one number is how the two come to disagree (§1). */

/* Desktop has the bar; the thumb zone is a phone thing and does not exist. */
.tabbar,.tb-scrim{display:none}

@media(max-width:1040px){
  .tabbar{display:block;position:fixed;left:0;right:0;z-index:88;
    bottom:var(--floor-modal);
    background:var(--surface);box-shadow:inset 0 1px 0 var(--border),0 -8px 24px rgba(10,10,12,.06)}
  body.dark .tabbar{box-shadow:inset 0 1px 0 var(--border),0 -8px 24px rgba(0,0,0,.4)}
  /* The bar itself is edge to edge; the ROW inside it is capped, so the tabs
     stay thumb-width on a tablet instead of stretching to 1040px. */
  .tb-in{display:flex;align-items:stretch;height:var(--tabh);max-width:520px;margin:0 auto;
    padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}
  .tb-slot{flex:1 1 0;display:flex;align-items:stretch;min-width:0;position:relative}

  .tb{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;
    justify-content:center;gap:3px;min-width:0;color:var(--t3);
    font-size:10px;font-weight:530;letter-spacing:.004em;line-height:1}
  .tb span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tb-i{width:22px;height:22px;flex:none}
  /* The rail is on the TOP edge here — the header's rail turned to face the
     content it belongs to, which is above the bar rather than below it. */
  .tb::after{content:"";position:absolute;top:0;left:50%;transform:translateX(-50%);
    width:34px;height:2px;border-radius:0 0 2px 2px;background:transparent;transition:background .14s}
  .tb.on,.nb-dd.here>.tb,.tb[aria-current="page"]{color:var(--text);font-weight:600}
  .tb.on::after,.nb-dd.here>.tb::after,.tb[aria-current="page"]::after{background:var(--accent)}
  /* No hover state: there is no pointer. What there is instead is the press,
     and it has to be visible because a tap has no other feedback. */
  .tb:active{background:var(--surface2)}
  .nb-dd.open>.tb{color:var(--text);background:var(--surface2)}

  /* CREATE, cut to the brand hexagon. It is the one control down here that
     makes something rather than going somewhere, so it is the one that is not
     a glyph over a word. */
  .tb-plus{flex:1;display:flex;align-items:center;justify-content:center;background:none}
  .tb-hex{width:48px;height:41px;clip-path:var(--hex);background:var(--accent);
    color:var(--accent-ink);display:flex;align-items:center;justify-content:center;
    transition:filter .12s}
  .tb-plus:active .tb-hex{filter:brightness(.94)}

  /* A MENU RISES FROM THE BAR. Anchored under its button the way the header's
     are, it would open off the bottom of the screen — there is nothing below
     the bar but the edge of the phone. So these are pinned to the gutters and
     grow upward from the bar's own top edge, and they are capped so a long one
     scrolls itself rather than running under the header. */
  .tabbar .nb-menu{position:fixed;top:auto;left:var(--pad);right:var(--pad);
    bottom:calc(var(--floor-modal) + var(--tabh) + 9px);
    width:auto;min-width:0;max-width:none;border-radius:14px;padding:7px;
    max-height:calc(100dvh - var(--navh) - var(--floor-modal) - var(--tabh) - 28px);
    overflow-y:auto;overscroll-behavior:contain}
  .nb-dd.open>.tb-menu{animation:tbrise .18s var(--ease)}
  @keyframes tbrise{from{opacity:0;transform:translateY(8px)}}
  /* Rows are a thumb's width apart, not a pointer's. */
  .tabbar .nb-mi{padding:12px 11px}
  .tabbar .nb-mi strong{font-size:15px}
  .tabbar .nb-mi small{font-size:12.5px}
  .tabbar .nb-mi.on::before,.tabbar .nb-mi[aria-current="page"]::before{top:12px;bottom:12px}

  /* One scrim under whichever is open. There is no pointer to "click away"
     with, so the tap target for closing has to be the page itself — and the
     dimming is what says the page behind is not the thing you are talking to. */
  .tb-scrim{display:block;position:fixed;inset:0;z-index:87;background:rgba(10,10,12,.32);
    opacity:0;pointer-events:none;transition:opacity .16s}
  body.tb-open .tb-scrim{opacity:1;pointer-events:auto}

  /* The bar's own nav is down here now, so the top bar sheds the burger it used
     to open the drawer with — Menu is the fifth tab — and it sheds Create,
     which is the hexagon in the middle of the thumb zone. What is left up top
     is what you REACH FOR rather than navigate with. */
  .burger{display:none!important}
  body.member .nb-createdd{display:none!important}
  /* Content clears the bar, and so does everything else pinned to the bottom of
     the window. Both read --floor (css/08-announcement-and-admin-bar.php), so
     the tab bar is ADDED to whatever the admin bar was already worth rather
     than replacing it — one number, raised here, and the padding rule and every
     fixed element downstream follow without knowing this file exists. */
  body,body.has-adminbar{--floor:calc(var(--floor-modal) + var(--tabh))}
}

/* A SHORT VIEWPORT CANNOT AFFORD THREE BARS. A phone in landscape has ~380px of
   height; a header, a tab bar and an admin bar leave almost nothing for the
   page. The thumb zone folds away and the burger comes back, which is the
   arrangement this site had before and is still complete. */
@media(max-width:1040px) and (max-height:520px){
  .tabbar,.tb-scrim{display:none}
  /* The top bar is the whole chrome again here, so everything it handed to the
     thumb zone comes back to it — the burger for the drawer, and Create, which
     would otherwise exist nowhere but /post. */
  .burger{display:flex!important}
  body.member .nb-createdd{display:inline-flex!important}
  /* With the thumb zone gone the floor is the bar alone again — which is
     exactly --floor-modal, so this is one rule rather than the two cases (--abh
     already carries the home-indicator pad for an operator, and adding
     --safe-b to it would pad past the indicator twice). Nothing re-declares
     --floor-modal here: it does not change when the tab bar folds away, which
     is the whole reason it is a number of its own. */
  body,body.has-adminbar{--floor:var(--floor-modal)}
}


/* =========================================================================
   THE 404 — one page, two shells.
   =========================================================================
   Every rule here is prefixed `nf-` and every one of them is loaded twice: the
   app bundles this file (views/app/styles.php), and views/404.php — the
   standalone shell that loads no app CSS — includes it verbatim with the
   `` tags stripped, exactly the way app/Assets.php does. So there is one
   stylesheet for the 404, not one per shell.

   It is written entirely in the app's tokens, which is what makes that work:
   the standalone shell repeats the same token block at the top of its own
   `` and nothing here has to know which of the two it is in. It also
   means body.dark moves the whole page for free — except the dial, which is an
   instrument and is dark-faced in both themes on purpose.
   ========================================================================= */

.nf-cluster{display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;padding-bottom:clamp(18px,3vh,34px)}

/* ---------------- the fault line ---------------- */
.nf-telltale{display:inline-flex;align-items:center;gap:9px;margin-bottom:clamp(10px,1.8vh,18px)}
.nf-tt-txt{font-family:var(--mono);font-size:11.5px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--t3)}
.nf-tt-txt b{color:var(--accent-fg);font-weight:700}

/* ---------------- the dial ----------------
   A control, so it takes a pointer, a focus ring and the two keys a button
   takes. The needle's transform-origin is on the fill box rather than the
   viewport, which is what lets the sweep survive the SVG being scaled. */
.nf-dial{width:clamp(230px,34vh,380px);aspect-ratio:1;flex:0 0 auto;border-radius:50%;
  filter:drop-shadow(0 26px 44px rgba(12,12,16,.26));cursor:pointer;
  -webkit-tap-highlight-color:transparent;
  transition:transform .22s var(--ease),filter .22s}
.nf-dial:hover{transform:scale(1.018);filter:drop-shadow(0 30px 50px rgba(12,12,16,.3))}
.nf-dial:active{transform:scale(.992)}
.nf-dial:focus-visible{outline:none;box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 30%,transparent)}
.nf-gauge{width:100%;height:100%;display:block;pointer-events:none}
.nf-needle{transform-box:fill-box;transform-origin:50% 84.6%;transform:rotate(-135deg)}
.nf-needle.rev{animation:nf-sweep 2s linear var(--nf-revdelay,.35s) forwards}
/* Sweep to the stop, bounce off it twice, fall back and settle — a needle has
   mass, and a linear return reads as a slider rather than an instrument. */
@keyframes nf-sweep{
  0%{transform:rotate(-135deg);animation-timing-function:cubic-bezier(.16,.84,.34,1)}
  30%{transform:rotate(133deg);animation-timing-function:ease-out}
  40%{transform:rotate(119deg);animation-timing-function:ease-in-out}
  47%{transform:rotate(129deg);animation-timing-function:ease-in-out}
  55%{transform:rotate(123deg);animation-timing-function:cubic-bezier(.55,0,.3,1)}
  86%{transform:rotate(-127.48deg);animation-timing-function:ease-out}
  93%{transform:rotate(-119.48deg);animation-timing-function:ease-in-out}
  100%{transform:rotate(-122.88deg)}}

.nf-hint{margin:12px 0 0;font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.1em;
  text-transform:uppercase;color:var(--t3);display:inline-flex;align-items:center;gap:8px}
.nf-hint kbd{font-family:var(--mono);font-size:10px;font-weight:600;letter-spacing:.06em;
  border:1px solid var(--border2);border-bottom-width:2px;background:var(--surface);
  border-radius:5px;padding:3px 7px;color:var(--t2)}

/* ---------------- the message ---------------- */
.nf-headline{font-family:var(--dis);font-weight:700;letter-spacing:-.042em;line-height:1;
  font-size:clamp(34px,4.4vw,56px);margin:clamp(16px,2.6vh,26px) 0 14px}
.nf-headline em{font-style:normal;color:var(--accent-fg);white-space:nowrap}
.nf-cel{display:inline-block;width:1.03em;height:.755em;margin-right:.3em;vertical-align:.045em;
  color:var(--accent);animation:nf-flick 2.6s steps(1,end) infinite;
  filter:drop-shadow(0 0 12px color-mix(in srgb,var(--accent) 34%,transparent))}
.nf-cel svg{width:100%;height:100%;display:block}
@keyframes nf-flick{0%,88%{opacity:1} 90%{opacity:.25} 93%{opacity:1} 96%{opacity:.4} 100%{opacity:1}}
.nf-lede{font-size:16.5px;color:var(--t2);margin:0 auto clamp(18px,2.8vh,26px);line-height:1.55;max-width:50ch}

/* ---------------- search ----------------
   The results list is the only thing on this page drawn in JS, because it is
   the only thing that does not exist until somebody types. Every row in it is
   a real <a href> to a real page (§12), built by AMSR.searchHref — the same
   builder the site's own search palette uses. */
.nf-findwrap{position:relative;z-index:30;width:min(460px,100%);margin:0 auto 14px;text-align:left}
.nf-find{display:flex;align-items:center;background:var(--surface);border:1px solid var(--border2);
  border-radius:var(--r);box-shadow:var(--sh-sm);overflow:hidden;
  transition:box-shadow .16s,border-color .16s}
.nf-find:focus-within{border-color:var(--accent-line);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 22%,transparent)}
.nf-fi{display:flex;align-items:center;padding-left:14px;color:var(--t3)}
.nf-fi svg{width:18px;height:18px}
.nf-find input{flex:1 1 auto;min-width:0;border:none;outline:none;background:transparent;
  font-family:var(--ui);font-size:15px;color:var(--text);padding:13px 10px}
.nf-find input::placeholder{color:var(--t3)}
.nf-find button{flex:0 0 auto;margin:5px;border:none;cursor:pointer;background:var(--accent);
  color:var(--accent-ink);font-weight:560;font-size:14px;padding:9px 16px;border-radius:7px;
  transition:filter .16s}
.nf-find button:hover{filter:brightness(.95)}

.nf-sugg{position:absolute;top:calc(100% + 8px);left:0;right:0;z-index:40;display:none;
  background:var(--surface);border:1px solid var(--border2);border-radius:var(--r-lg);
  box-shadow:var(--sh);overflow:hidden;max-height:334px;overflow-y:auto}
.nf-sugg.on{display:block}
.nf-sh{display:flex;align-items:center;justify-content:space-between;padding:9px 13px;
  border-bottom:1px solid var(--border);font-family:var(--mono);font-size:10px;font-weight:600;
  letter-spacing:.13em;text-transform:uppercase;color:var(--t3);background:var(--surface2)}
.nf-si{display:flex;align-items:center;gap:11px;padding:10px 13px;
  border-bottom:1px solid var(--border);transition:background .12s}
.nf-si:last-child{border-bottom:none}
.nf-si:hover,.nf-si.cur{background:var(--accent-soft)}
.nf-si-b{min-width:0;flex:1 1 auto}
.nf-si-t{display:block;font-size:14px;font-weight:540;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nf-si-t mark{background:transparent;color:var(--accent-fg);font-weight:700}
.nf-si-s{display:block;font-size:12px;color:var(--t3);margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nf-si-go{flex:0 0 auto;color:var(--t3);font-size:11px;font-family:var(--mono)}
.nf-empty{padding:18px 14px;font-size:13.5px;color:var(--t2);text-align:center}
.nf-empty b{color:var(--text)}

/* ---------------- the kind pill ----------------
   What a search suggestion IS, in one word. Mono, uppercase, and never
   carrying a figure — a count belongs in a stats row, not in a label (the feed
   card's rule, and this page keeps it). The variants are the kinds
   `GET /api/search` can return; anything unmapped falls to the grey. */
.nf-tp{flex:0 0 auto;font-family:var(--mono);font-size:9.5px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;padding:4px 7px;border-radius:5px;border:1px solid;line-height:1}
.nf-tp--vehicle{color:var(--accent-fg);background:var(--accent-soft);border-color:var(--accent-line)}
.nf-tp--mod{color:var(--violet);background:var(--violet-soft);border-color:var(--violet-line)}
.nf-tp--event{color:var(--green);background:var(--green-soft);border-color:var(--green-line)}
.nf-tp--member,.nf-tp--vendor,.nf-tp--part,.nf-tp--group{color:var(--t2);background:var(--surface2);
  border-color:var(--border2)}

/* ---------------- the way out ---------------- */
.nf-acts{display:flex;align-items:center;justify-content:center;gap:14px;flex-wrap:wrap}
.nf-cta{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:42px;
  padding:0 18px;border-radius:var(--r);font-size:14.5px;font-weight:560;
  background:var(--accent);color:var(--accent-ink);border:1px solid transparent;
  box-shadow:var(--sh-btn);transition:filter .16s,transform .12s var(--ease)}
.nf-cta svg{width:17px;height:17px}
.nf-cta:hover{filter:brightness(.95);transform:translateY(-1px)}
.nf-alt{font-size:14px;color:var(--t2)}
.nf-alt b{font-weight:560;color:var(--accent-fg);border-bottom:1px solid var(--accent-line)}
.nf-alt:hover b{border-bottom-color:var(--accent-fg)}

/* ---------------- motion ----------------
   The cluster arrives in order behind the dial's own pop, so the eye lands on
   the instrument and reads outward from it. */
@keyframes nf-rise{from{opacity:0;transform:translateY(12px)} to{opacity:1;transform:none}}
@keyframes nf-pop{from{opacity:0;transform:scale(.94)} to{opacity:1;transform:none}}
.nf-an{opacity:0;animation:nf-rise .6s var(--ease) forwards}
.nf-a1{animation-delay:.05s}.nf-a2{animation-delay:.75s}.nf-a3{animation-delay:.85s}
.nf-a4{animation-delay:.95s}.nf-a5{animation-delay:1.05s}
.nf-dial{opacity:0;animation:nf-pop .7s var(--ease) .1s forwards}

/* ---------------- responsive ---------------- */
@media(max-width:600px){
  .nf-dial{width:min(290px,72vw)}
  .nf-headline{font-size:clamp(32px,8.4vw,42px)}
  .nf-cta{flex:1 1 auto}
}
@media(prefers-reduced-motion:reduce){
  .nf-an,.nf-dial{animation:none;opacity:1}
  .nf-needle,.nf-needle.rev{animation:none;transform:rotate(-122.88deg)}
  .nf-cel{animation:none}
  .nf-cta:hover,.nf-dial:hover{transform:none}
}

/* =====================================================================
   THE MEMBER PROFILE
   A cover the identity rides on, a rail of facts, tabs that are addresses,
   and a column of feed cards.

   THE CARDS ARE NOT DEFINED HERE. Everything in the column is drawn by
   AMSR.feedItem() — the one card renderer, twinned with ams_feed_item() —
   and wears `.fc*` from 20-feed-card.php. A profile with its own card
   styles is the drift §1 exists to stop: the same mod would read one way
   on /feed and another on /u/kestrel, and only one of them would get
   fixed. What this file owns is the page AROUND them.

   Tokens are the site's, deliberately: --surface not --panel, --t3 not
   --ink3. The design was drawn against its own ladder and mapping it here
   once is what keeps the profile moving when the palette does.
   ===================================================================== */

/* ---- the cover, and the identity that rides on it ---------------------- */
/* The cover scales with the window rather than sitting at one height, so a
   wide screen gets a banner and a phone does not lose half its first screen
   to one. The floor is what keeps the avatar's 56px overhang from eating it. */
.pp-cover{position:relative;z-index:0;height:clamp(260px,30vw,400px);background:var(--surface2);
  overflow:hidden}
/* SQUARE. The generic `.photo` carries border-radius:12px because it is
   normally a thumbnail inside a card — and the cover is a photo layer, so it
   inherited it and the banner came up with rounded corners against the page
   edge. Every other full-bleed use of .photo turns it off the same way
   (.pcard, .vcard, .mcard, .vhero); this is the profile's. */
.pp-cover>.pe-host,.pp-cover .photo{position:absolute;inset:0;border-radius:0}
/* THE COVER'S BUTTON LINES UP WITH THE CONTENT, not the window. The cover is
   full-bleed, so `.pedit`'s right:12px put Edit cover 126px further out than
   Edit profile directly below it. This is the same edge the identity block
   and the feed column end on — the max() is for a window narrower than the
   column, where the gutter is all there is. */
.pp-cover .pedit{right:max(var(--pad),calc((100% - var(--col))/2 + var(--pad)))}
.pp-cover img{width:100%;height:100%;object-fit:cover;display:block}

.pp-id{max-width:var(--col);margin:0 auto;padding:0 var(--pad) 18px;position:relative;z-index:2}
.pp-id__row{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;
  flex-wrap:wrap;padding-left:calc(112px + 16px);min-height:62px}
/* z-index 40, not 3. The avatar's own controls open UPWARD — the editor menu
   sits above the camera button and the reposition bar hangs below it — so they
   land over the cover, and at 3 the banner won and the menu was unreachable
   (elementFromPoint returned the cover's photo layer, not the menu). The cover
   gets an explicit 0 rather than `auto` so this is a stated order instead of
   one that depends on document position. 40 stays under the nav's 60. */
.pp-av{position:absolute;top:-56px;left:var(--pad);width:112px;height:112px;z-index:40}
.pp-av .pe-host,.pp-av .av{width:100%;height:100%;border-radius:var(--r-lg);
  border:4px solid var(--canvas);background:var(--surface2);overflow:hidden;box-shadow:var(--sh-lg)}
/* …except once the photo editor is on it. The clip above is for a plain
   <img> avatar; the editor replaces that with a background the radius clips
   by itself, and its menu and bar both open outside this box. */
.pp-av .av.pe-avatar{overflow:visible}
.pp-av img{width:100%;height:100%;object-fit:cover;display:block}

.pp-name{flex:1 1 220px;min-width:0;padding-bottom:4px}
.pp-name h1{font-family:var(--dis);font-size:23px;font-weight:700;letter-spacing:-.033em;
  margin:0;line-height:1.12;display:flex;align-items:center;gap:5px;flex-wrap:wrap}
.pp-meta{display:flex;align-items:center;gap:7px;flex-wrap:wrap;font-size:13px;
  color:var(--t3);margin-top:5px;line-height:1.5}
.pp-meta em{font-style:normal;color:var(--border2)}
.pp-meta a{color:var(--accent-fg);font-weight:500}

/* ---- VERIFIED ---------------------------------------------------------
   The site's green "• Verified" pill (AMSR.verifiedPill) stays everywhere
   else — on a comment or a card a marker is all there is room for. The
   PROFILE is the one screen where somebody asks what it means, so it is the
   brand hexagon in accent with a check through it, and it says so when you
   hover or tab to it. One mark, one explanation, on the page that owes one. */
.pp-vmark{display:inline-flex;position:relative;margin-left:4px;color:var(--accent);cursor:default}
.pp-vmark>svg{width:28px;height:28px;display:block}
.pp-vpop{position:absolute;top:calc(100% + 11px);left:50%;width:240px;
  transform:translateX(-50%) translateY(6px);opacity:0;pointer-events:none;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  box-shadow:var(--sh-lg);padding:12px;display:flex;gap:11px;align-items:center;
  text-align:left;z-index:60;transition:opacity .17s var(--ease),transform .17s var(--ease)}
.pp-vmark:hover .pp-vpop,.pp-vmark:focus-visible .pp-vpop{opacity:1;transform:translateX(-50%) translateY(0)}
.pp-vpop::before{content:"";position:absolute;bottom:100%;left:50%;transform:translateX(-50%);
  border:7px solid transparent;border-bottom-color:var(--border)}
.pp-vpop::after{content:"";position:absolute;bottom:calc(100% - 1.5px);left:50%;transform:translateX(-50%);
  border:6px solid transparent;border-bottom-color:var(--surface)}
.pp-vpop-ic{flex:none;width:36px;height:36px;border-radius:9px;background:var(--accent-soft);
  display:grid;place-items:center}
.pp-vpop-ic svg{width:21px;height:21px}
.pp-vpop-tx{display:flex;flex-direction:column;gap:3px;min-width:0}
.pp-vpop-tx b{font-family:var(--dis);font-size:13.5px;font-weight:700;color:var(--text);line-height:1.1}
.pp-vpop-tx span{font-size:11.5px;color:var(--t3);line-height:1.45}

/* A standing — Founder, First user. TEXT, not a pill: the mark beside it is
   already a badge, and a second enclosed shape next to it turns the name row
   into a row of chrome. Uppercase and tracked so it reads as a label without
   needing a box drawn round it to say so.

   IT SITS CLOSE TO THE MARK, and that is why the h1's `gap` is 5px with the
   mark paying 4px back as its own margin-left. The row has ONE gap and the two
   joins in it are not the same join: the name and the mark are two separate
   things standing apart, while the mark and the standing are one label the mark
   belongs to — and the hexagon carries ~4px of empty svg on each side, so an
   equal gap reads wider after it than before it. Written the other way round
   (9px gap, -4px here) it measures identically and breaks on a wrap: a standing
   that lands at the start of its own line would hang 4px off the left edge.
   (The space in the markup does nothing either way — whitespace between flex
   items is discarded.) */
.pp-title{display:inline-flex;align-items:center;color:var(--accent-fg);
  font:700 11px var(--ui);letter-spacing:.09em;text-transform:uppercase;white-space:nowrap}
/* the name row must not clip the popover it opens */
.pp-name h1{overflow:visible}

/* The actions sit on the cover, above the fold of the identity block. */
.pp-acts{position:absolute;top:-44px;right:var(--pad);z-index:4;display:flex;gap:8px;
  align-items:center;flex-wrap:wrap;justify-content:flex-end}

/* ---- the ··· menu ------------------------------------------------------ */
.pp-more{position:relative}
.pp-more__list{position:absolute;top:calc(100% + 6px);right:0;min-width:196px;z-index:20;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  box-shadow:var(--sh-lg);padding:5px}
.pp-more__list[hidden]{display:none}
.pp-more__i{display:flex;align-items:center;gap:9px;width:100%;text-align:left;border:0;
  background:transparent;color:var(--text);font:500 13px var(--ui);padding:8px 10px;
  border-radius:8px;cursor:pointer;white-space:nowrap}
.pp-more__i:hover{background:var(--surface2)}
.pp-more__i--warn{color:var(--danger,#AE3428)}
.pp-more__i--warn:hover{background:rgba(174,52,40,.08)}

/* ---- the two columns --------------------------------------------------- */
.pp-shell{max-width:var(--col);margin:0 auto;padding:18px var(--pad) 40px;
  display:grid;grid-template-columns:300px minmax(0,1fr);gap:20px;align-items:start}
.pp-rail{position:sticky;top:calc(var(--navh) + 12px);display:grid;gap:12px}
.pp-mod{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:14px 16px 16px;box-shadow:var(--sh-sm)}
.pp-mod__hd{display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-bottom:9px}
.pp-mod__n{font:600 10.5px var(--ui);letter-spacing:.09em;text-transform:uppercase;color:var(--t3)}
.pp-bio{margin:0;font-size:13.5px;line-height:1.55;color:var(--t2)}
.pp-site{display:inline-flex;align-items:center;gap:7px;margin-top:12px;font-size:13px;
  font-weight:500;color:var(--accent-fg)}
.pp-site:hover{text-decoration:underline}

/* Six figures, two up. `.num` is the site's mono, and it means a measured
   figure — which every one of these is. */
.pp-stats{display:grid;grid-template-columns:1fr 1fr;gap:12px 10px}
.pp-stat b{display:block;font:600 19px var(--mono);letter-spacing:-.02em;color:var(--text);
  line-height:1.1}
.pp-stat span{display:block;font-size:11.5px;color:var(--t3);margin-top:2px}
.pp-statfoot{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  margin-top:14px;padding-top:12px;border-top:1px solid var(--border);
  font-size:12.5px;color:var(--t3)}
.pp-statfoot b{font:500 12.5px var(--mono);color:var(--t2)}

/* ---- the tabs. Each one is a real <a href> ----------------------------- */
.pp-tabs{display:flex;gap:2px;border-bottom:1px solid var(--border);margin-bottom:14px;
  overflow-x:auto;scrollbar-width:none}
.pp-tabs::-webkit-scrollbar{display:none}
.pp-tab{display:inline-flex;align-items:center;gap:6px;padding:10px 13px 11px;
  font:600 13.5px var(--ui);color:var(--t2);border-bottom:2px solid transparent;
  margin-bottom:-1px;white-space:nowrap}
.pp-tab:hover{color:var(--text)}
.pp-tab .ct{font:500 11.5px var(--mono);color:var(--t3)}
.pp-tab[aria-current="page"]{color:var(--accent-fg);border-bottom-color:var(--accent)}
.pp-tab[aria-current="page"] .ct{color:var(--accent-fg)}

/* ---- the garage grid, for the Vehicles tab ----------------------------- */
.pp-gtools{display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin-bottom:12px}
.pp-gcount{font-size:13px;color:var(--t3)}
.pp-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:12px}

/* ---- the people, for the Friends tab ---------------------------------- */
.pp-people{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:10px}
.pp-person{display:flex;align-items:center;gap:11px;padding:10px 12px;min-width:0;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--sh-sm);color:var(--text);transition:border-color .16s var(--ease),
  box-shadow .16s var(--ease),transform .16s var(--ease)}
.pp-person:hover{border-color:var(--border2);box-shadow:var(--sh);transform:translateY(-1px)}
.pp-person .av{flex:none;width:42px;height:42px;font-size:15px}
.pp-person__t{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:1px}
.pp-person__t b{font:600 13.5px var(--ui);letter-spacing:-.012em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pp-person__t i{font-style:normal;font-size:12px;color:var(--t3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

@media(max-width:900px){
  .pp-shell{grid-template-columns:minmax(0,1fr)}
  .pp-rail{position:static}
}
/* On a phone the actions cannot stay on the cover — there is no room beside a
   name at this width. They drop below it, which means they have to come AFTER
   the name in the flow: they are written before it (so they can be positioned
   on the cover on a wide screen), and left alone they landed on top of the
   avatar. `order` moves them without moving the markup. */
@media(max-width:560px){
  .pp-id{display:flex;flex-direction:column;padding-bottom:14px}
  .pp-av{width:84px;height:84px;top:-42px}
  .pp-id__row{order:1;padding-left:0;padding-top:48px;min-height:0}
  .pp-acts{order:2;position:static;width:100%;margin-top:14px;justify-content:flex-start}
  .pp-acts .btn{flex:1 1 auto}
  .pp-more{flex:0 0 auto}
  .pp-tabs{margin-left:calc(var(--pad) * -1);margin-right:calc(var(--pad) * -1);
    padding-left:var(--pad);padding-right:var(--pad)}
}

/* The dark theme is a class on <body> (00-tokens), and every colour above is
   a token, so this is only the two places a literal was unavoidable. */
body.dark .pp-av .pe-host,body.dark .pp-av .av{border-color:var(--canvas)}
body.dark .pp-more__i--warn:hover{background:rgba(174,52,40,.16)}

/* ---- the editor's preview --------------------------------------------- */
/* It shows the page while you type, so the bio you are writing is read at
   the width and weight it will actually be read at. */
.pe-prev{background:var(--surface2);border:1px solid var(--border);border-radius:var(--r);
  padding:14px 16px;margin-bottom:16px}
.pe-prev__nm b{font-family:var(--dis);font-size:18px;font-weight:700;letter-spacing:-.028em;
  color:var(--text)}
.pe-prev__meta{font-size:12.5px;color:var(--t3);margin-top:2px}
.pe-prev__meta em{font-style:normal}
.pe-prev__bio{margin:9px 0 0;font-size:13.5px;line-height:1.55;color:var(--t2);
  white-space:pre-wrap;min-height:1.2em}
.amsmodal-f{display:flex;align-items:center;justify-content:flex-end;gap:8px;margin-top:16px}
.amsmodal-f .amsmodal-err{margin-right:auto}

/* ===================== the image picker =====================
   The sheet an operator opens from the pencil on a tile, plus the pencil
   itself. Everything here is operator chrome: a member never sees a rule in
   this file, because the markup it styles is only ever drawn behind
   amsCanEditImages().

   Tokens only — no literal colours — so the sheet follows the member's own
   light/dark choice like every other surface (CONVENTIONS §11).

   AND THEY HAVE TO BE THIS SITE'S TOKENS. This file was written against
   --card/--line/--muted/--ink/--bg2, which are the CATALOGUE page's private
   names (views/app/css/10-catalogue-browse.php sets them on #pg-catalogue and
   nowhere else). Outside that scope every one of them is undefined, and an
   undefined custom property does not fall back — the whole declaration is
   dropped. So the pencil over a tile had no background and no border colour of
   its own, and the sheet's own chrome was drawn by whatever the modal shell
   happened to inherit. It looked deliberate, which is why it survived: nothing
   throws, nothing is missing, it is just quietly the wrong grey. The names
   below are the ones :root actually defines. */

/* --- the button over a tile ---
   It SAYS what it does. A bare pencil is a guess on a photograph and a guess on
   an empty rectangle, so it carries its own words, in the same tokens as every
   other control on the site — never a literal colour, or it would be the one
   button on the page that ignores the member's own theme (CONVENTIONS §11).
   `z-index` is above the placeholder artwork, which is z-index:1. */
.imgp-edit{
  position:absolute; top:8px; right:8px; z-index:3;
  display:inline-flex; align-items:center; gap:6px;
  min-height:28px; padding:0 10px;
  border:1px solid var(--border); border-radius:999px;
  background:var(--surface); color:var(--text);
  font:500 12px/1 var(--ui); white-space:nowrap;
  cursor:pointer; opacity:0; transition:opacity .12s ease, color .12s ease, border-color .12s ease;
  box-shadow:0 1px 4px rgba(0,0,0,.18);
}
/* The icon is the button's own, and small. It sits inside hosts that style
   their own artwork by tag (the events placeholder drew EVERY svg in the tile
   at 44% of the card, this one included), so it states its size rather than
   inheriting one. */
.imgp-edit svg{ width:14px; height:14px; flex:none; display:block; }
.imgp-edit-t{ display:inline-block; }
/* A tile with no room for words — the vendor row's thumbnail is 78x60. The
   button keeps its accessible name; only the visible label goes. */
.imgp-edit-sm{ width:26px; min-height:26px; padding:0; border-radius:7px;
  justify-content:center; color:var(--t2); }
.imgp-edit-sm .imgp-edit-t{ display:none; }
/* Visible on hover, and ALWAYS visible to the keyboard — an affordance that
   only exists under a pointer is one a keyboard operator cannot reach at all.
   A tile with NO picture shows it outright: there is nothing there to reveal on
   hover, and an empty rectangle you have to guess is clickable is the state
   this whole feature exists to end. */
.vd-row:hover .imgp-edit,
.vd-rthumb:hover .imgp-edit,
/* `.evcard`, not `.ev-card` — the hyphenated one has never been a class this
   site draws, so on an event the button only surfaced once the pointer was
   over the PICTURE itself (the .imgp-host rule below), which on a wide
   featured card is a small part of it. */
.evcard:hover .imgp-edit,
.evfeat:hover .imgp-edit,
.bhero:hover .imgp-edit,
.imgp-host:hover .imgp-edit,
.imgp-edit-add,
.imgp-edit:focus-visible{ opacity:1; }
.imgp-edit:hover{ color:var(--accent); border-color:var(--accent); }
.imgp-edit:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
/* The button is positioned against its tile, so the tile must be a containing
   block. Anything that hosts one carries .imgp-host. */
.imgp-host{ position:relative; }

/* --- the sheet --- */
.imgp{ display:flex; flex-direction:column; gap:0; width:100%; min-width:0; }
/* The shared .amsmodal is capped at 520px, which is right for a form of six
   fields and far too narrow for a grid of thumbnails — the picker forced its
   own min-width instead and simply overflowed the dialog, clipping the address
   box and both buttons. The modal is what needs to be wider, so widen THAT,
   only when it is holding a picker. */
.amsmodal.amsmodal-wide{ max-width:760px; }

.imgp-tabs{ display:flex; gap:4px; border-bottom:1px solid var(--border); padding-bottom:0; margin-bottom:14px; }
.imgp-tab{
  display:inline-flex; align-items:center; gap:7px;
  padding:9px 13px; border:0; background:none; cursor:pointer;
  color:var(--t2); font:inherit; font-size:14px;
  border-bottom:2px solid transparent; margin-bottom:-1px; border-radius:6px 6px 0 0;
}
.imgp-tab:hover{ color:var(--text); background:var(--surface2); }
.imgp-tab.on{ color:var(--text); border-bottom-color:var(--accent); font-weight:600; }
.imgp-tab:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }
.imgp-tab svg{ flex:0 0 auto; }
@media (max-width:560px){ .imgp-tab span{ display:none; } .imgp-tab{ padding:9px 14px; } }

/* The way out to a bulk screen, where the subject has one. Under the tabs
   rather than in the foot: the foot is where you commit to a picture, and a
   link that leaves the sheet does not belong beside Save. */
.imgp-bulk{ display:block; margin:-6px 0 12px; font-size:13px; color:var(--accent); }
.imgp-bulk:hover{ text-decoration:underline; }

.imgp-body{ min-height:220px; max-height:46vh; overflow-y:auto; overflow-x:hidden; }

/* --- the candidate grid --- */
.imgp-grid{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(132px, 1fr));
  gap:10px; padding:2px;
}
.imgp-tile{
  display:flex; flex-direction:column; gap:0; padding:0; cursor:pointer;
  border:1px solid var(--border); border-radius:9px; overflow:hidden;
  background:var(--surface); text-align:left; font:inherit;
}
.imgp-tile img{
  width:100%; aspect-ratio:4/3; object-fit:contain; display:block;
  /* contain, not cover: this is a grid for JUDGING pictures, and a cover crop
     hides exactly the letterboxing and wrong aspect that make a tile look bad.
     The chequer shows up a transparent PNG that would vanish on a white tile. */
  background:
    linear-gradient(45deg, var(--surface2) 25%, transparent 25%, transparent 75%, var(--surface2) 75%) 0 0/16px 16px,
    linear-gradient(45deg, var(--surface2) 25%, transparent 25%, transparent 75%, var(--surface2) 75%) 8px 8px/16px 16px,
    var(--surface);
}
.imgp-tile:hover{ border-color:var(--accent); }
.imgp-tile:focus-visible{ outline:2px solid var(--accent); outline-offset:1px; }
.imgp-tile.on{ border-color:var(--accent); box-shadow:0 0 0 2px var(--accent) inset; }
.imgp-cap{
  display:block; padding:6px 8px 7px; font-size:11.5px; line-height:1.35; color:var(--t2);
  border-top:1px solid var(--border);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.imgp-dim{ display:block; font-style:normal; font-size:10.5px; opacity:.75; }
.imgp-lic{ display:block; font-style:normal; font-size:10.5px; color:var(--accent); }

/* --- notes, warnings, waiting --- */
.imgp-note{ padding:22px 4px; color:var(--t2); font-size:14px; line-height:1.55; margin:0; }
.imgp-busy::after{ content:''; display:inline-block; width:11px; }
.imgp-warn{
  margin:0 0 10px; padding:9px 11px; border-radius:7px; font-size:13px; line-height:1.45;
  background:var(--surface2); border:1px solid var(--border); color:var(--text);
}

/* --- search + url panes --- */
.imgp-search{ display:flex; gap:8px; margin-bottom:12px; }
.imgp-search .input{ flex:1; min-width:0; }
.imgp-lab{ display:block; font-size:13px; color:var(--t2); margin-bottom:4px; }
.imgp-lab .input{ display:block; width:100%; margin-top:5px; }
.imgp-upv{ margin-top:10px; }
.imgp-upvimg{ max-width:100%; max-height:210px; border-radius:8px; border:1px solid var(--border); display:block; }

/* --- upload pane --- */
.imgp-drop{
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:5px;
  padding:34px 18px; border:2px dashed var(--border); border-radius:11px;
  background:var(--surface2); cursor:pointer; color:var(--t2); text-align:center;
}
.imgp-drop b{ color:var(--text); font-size:15px; }
.imgp-drop span{ font-size:13px; }
.imgp-drop:hover, .imgp-drop.over{ border-color:var(--accent); color:var(--text); }
.imgp-drop:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }

/* --- the before/after foot --- */
.imgp-foot{
  display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap;
  border-top:1px solid var(--border); margin-top:14px; padding-top:13px;
}
.imgp-cmp{ display:flex; align-items:center; gap:11px; }
.imgp-cmp figure{ margin:0; display:flex; flex-direction:column; gap:4px; align-items:center; }
.imgp-cmp figure span{ font-size:10.5px; letter-spacing:.07em; text-transform:uppercase; color:var(--t2); }
.imgp-cmp img{
  width:62px; height:47px; object-fit:contain; border:1px solid var(--border);
  border-radius:7px; background:var(--surface2); display:block;
}
.imgp-none{
  width:62px; height:47px; display:grid; place-items:center; font-style:normal; font-size:10.5px;
  color:var(--t2); border:1px dashed var(--border); border-radius:7px; text-align:center; line-height:1.2;
}
.imgp-arrow{ color:var(--t2); font-size:17px; }
.imgp-acts{ display:flex; gap:8px; margin-left:auto; }
@media (max-width:560px){
  .imgp{ min-width:0; }
  .imgp-foot{ flex-direction:column; align-items:stretch; }
  .imgp-acts{ margin-left:0; }
  .imgp-acts .btn{ flex:1; }
}


/* ===================== /events/pictures =====================
   The operator's bulk picture screen. Tokens only, and this site's tokens —
   --surface/--border/--text/--t2/--t3 — because a screen written against names
   :root does not define is a screen whose colours are whatever it happened to
   inherit (see the note at the top of 24-image-picker.php, where exactly that
   had happened).

   It is a LIST YOU WORK DOWN: one row per event, the picture large enough to
   recognise, and the two verbs that matter on the right. Nothing here animates
   or reflows on hover — the row you are aiming at must not move. */

#pg-evpics .wrap{ max-width:var(--col); }

.evpc-head{ display:flex; align-items:flex-start; gap:20px; padding:28px 0 4px; }
.evpc-head h1{ font-size:clamp(24px,3vw,32px); letter-spacing:-.032em; }
.evpc-head p{ margin:8px 0 0; max-width:70ch; line-height:1.55; }
.evpc-head .btn{ margin-left:auto; flex:none; }

/* The filters are ADDRESSES (§12), so they are links and they look like tabs
   rather than like buttons that toggle something in memory. */
.evpc-tabs{ display:flex; gap:4px; border-bottom:1px solid var(--border); margin:18px 0 0; flex-wrap:wrap; }
.evpc-tab{ display:inline-flex; align-items:center; gap:8px; padding:10px 14px;
  font-size:14px; color:var(--t2); border-bottom:2px solid transparent; margin-bottom:-1px; }
.evpc-tab:hover{ color:var(--text); }
.evpc-tab.on{ color:var(--text); font-weight:600; border-bottom-color:var(--accent); }
.evpc-tab i{ font-style:normal; font-size:12px; font-variant-numeric:tabular-nums;
  color:var(--t3); background:var(--surface2); border-radius:99px; padding:1px 7px; }
.evpc-cap{ margin:12px 0 0; font-size:13px; color:var(--t2); }

/* The bulk bar is always drawn, and says what it is FOR when nothing is picked
   — a bar that appears only once you have selected something is a bar nobody
   discovers, and this screen exists for the thing it does. */
.evpc-bulk{ position:sticky; top:calc(var(--navh,60px) + 6px); z-index:4;
  display:flex; align-items:center; gap:12px; margin:14px 0 0;
  padding:10px 14px; border:1px solid var(--border); border-radius:12px;
  background:var(--surface); box-shadow:var(--sh-sm); }
.evpc-bulk.on{ border-color:var(--accent-line); background:var(--accent-soft); }
.evpc-bulkt{ font-size:13.5px; color:var(--t2); }
.evpc-bulk.on .evpc-bulkt{ color:var(--text); font-weight:500; }
.evpc-bulk .btn{ margin-left:auto; }

.evpc-list{ margin-top:14px; }
.evpc-grp{ margin-top:22px; border:1px solid var(--border); border-radius:14px; overflow:hidden; }
.evpc-ghead{ display:flex; align-items:center; gap:14px; padding:12px 14px;
  background:var(--surface2); border-bottom:1px solid var(--border); }
.evpc-ghead b{ font-size:14.5px; }
.evpc-ghead p{ margin:2px 0 0; }
.evpc-ghead .btn{ margin-left:auto; flex:none; }

.evpc-row{ display:flex; align-items:center; gap:14px; padding:12px 14px;
  border-bottom:1px solid var(--border); }
.evpc-list .evpc-row:first-child{ border-top:1px solid var(--border); }
.evpc-grp .evpc-row:last-child{ border-bottom:0; }
.evpc-row:hover{ background:var(--surface2); }

/* 96x64: big enough to tell two photographs apart, which is the whole job. */
.evpc-th{ width:96px; height:64px; flex:none; border-radius:9px; overflow:hidden;
  background:var(--surface3) center/cover no-repeat; display:block; position:relative; }
/* The stand-in is the SAME artwork the card and the hero draw, so what you see
   here is what clearing this row would leave behind — a grey "none" box would
   hide that clearing is usually an improvement. */
.evpc-th.evpc-none{ display:block; }
.evpc-th.evph > svg{ width:64%; }

.evpc-meta{ flex:1; min-width:0; }
.evpc-t{ display:block; font-weight:600; font-size:15px; letter-spacing:-.015em;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.evpc-meta p{ margin:3px 0 0; }
.evpc-src{ font-size:12.5px; color:var(--t3); display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
/* The count is the finding, so it is the one thing on the row drawn in a
   colour: nineteen events wearing one logo is what you came here to see. */
.evpc-dupe{ font-weight:600; color:var(--accent-fg); background:var(--accent-soft);
  border:1px solid var(--accent-line); border-radius:99px; padding:1px 8px; font-size:11.5px; }

.evpc-acts{ display:flex; align-items:center; gap:7px; flex:none; }
.evpc-pick{ display:grid; place-items:center; flex:none; width:20px; }
.evpc-pick input{ width:16px; height:16px; accent-color:var(--accent); cursor:pointer; }
.evpc-pick span{ display:none; }
/* An upload is a person's file and is never cleared in bulk, so its row has no
   checkbox at all — the space stays, or every row below it shifts. */
.evpc-lock{ width:20px; flex:none; display:grid; place-items:center; color:var(--t3); }

@media(max-width:760px){
  .evpc-head{ flex-direction:column; gap:12px; }
  .evpc-head .btn{ margin-left:0; }
  .evpc-row{ flex-wrap:wrap; }
  .evpc-acts{ width:100%; padding-left:130px; }
  .evpc-ghead{ flex-wrap:wrap; }
  .evpc-ghead .btn{ margin-left:0; width:100%; }
}


/* ============================================================
   THE CHAT DOCK — chat as bubbles along the bottom of every page.

   The dock is on every screen because a conversation is not a place you go,
   it is something you are in the middle of. /messages is still the address
   (§12) and still does everything; this is the half of it you want while you
   are reading a build thread — and because every navigation on this site is a
   real page load, the dock has to survive one, which is why what is open lives
   in localStorage and is redrawn here rather than kept in a variable.

   THE FAN IS ANCHORED TO THE RIGHT EDGE. The New message button holds the
   corner itself — it is the one thing here that is drawn when nothing is open,
   so it is what the corner has to be — and the fan hangs one slot in from it,
   each further chat opening to the LEFT. The fan still grows out of one fixed
   point, and the chat you opened first never moves to make room. It was centred
   at first, and moved to this side so the BUG/CHANGE button could have the left
   corner to itself: two things sharing one corner is how a button ends up under
   a panel. On a PHONE they do share it, deliberately — the report button stacks
   directly above the New-message button rather than taking the far corner,
   because one hand reaches one side — and what makes that safe is that it
   stands on --cd-top below rather than on a copy of this dock's height.

     --cx   how far LEFT of the corner this bubble sits, set by the JS: -i*step,
            so bubble 0 is flush against the gutter and 0 is the origin every
            other one is measured from.
     --cz   the stack. The corner is on top and each one behind it sits lower,
            so an overlapping fan (which is what a narrow window forces) reads
            as a stack opening away from the edge.

   All three are transitioned, which is what makes "fan out with each chat"
   something you SEE happen rather than a layout you arrive at.
   ============================================================ */

/* --cd-bub is the bubble, and the one number the rest of the dock measures
   from — the fan's height, where the window's bottom edge sits, and the gap
   the composer leaves. Never write 46px anywhere below (§6's rule about --abh,
   for the same reason: two copies is two answers).

   THE THREE NUMBERS ARE ON `body`, NOT ON THE HOST, AND THAT IS WHAT LETS THE
   REPORT BUTTON STAND ON THIS CORNER. On a phone .ams-fab is no longer on the
   other side of the screen — it sits directly above the New-message button —
   so it has to know where the top of this dock is. A custom property declared
   on #ams-chatdock is visible to the dock and to nothing else, so the button
   would have had to carry its own copy of 46/42/20/10, which is four copies of
   four numbers that already exist here (§6, --abh's rule). Declared on `body`
   they are inherited by both, and the dock's own JS still reads them off the
   host — getComputedStyle returns an inherited custom property exactly as it
   returns a declared one. --floor is on `body` too, which is why --cd-top can
   be written here at all. */
body{
  --cd-bub:46px;
  /* The gutter the fan and its window both hang off. Same 20px the BUG/CHANGE
     button uses, which on a phone is this same corner. */
  --cd-edge:20px;
  /* +10px so the fan does not sit flush on the window's edge — the arc
     lifts the OUTER bubbles, so the centre one is the lowest thing on the
     page and had its shadow cut off by the viewport. */
  --cd-lift:10px;
  /* WHERE THE TOP OF THIS DOCK IS, published for whatever stands on it. It is
     the floor, the lift off it, and the bubble — the three above, added once
     here rather than at each reader. */
  --cd-top:calc(var(--floor) + var(--cd-lift) + var(--cd-bub));
}
#ams-chatdock{
  --cd-w:322px; --cd-h:min(430px, calc(100vh - var(--navh) - var(--floor) - 96px));
  position:fixed; left:0; right:0; bottom:calc(var(--floor) + var(--cd-lift));
  /* Above the feedback FAB (1200) — a chat somebody opened outranks a button
     that is always there — and below the operator's own bar (1900). §6. */
  z-index:1250;
  /* Explicit, because `.member-only` in css/01 sets display:inline-flex on
     everything wearing it and this is a fixed layer, not a nav chip. The id
     out-specifies it in both directions — shown and hidden. */
  display:block; height:var(--cd-bub); pointer-events:none;
}
#ams-chatdock[hidden]{display:none}
/* A PANEL THAT OWNS THE SCREEN PUTS THE DOCK AWAY. Anything that dims the page
   behind a scrim has already said the page is not what you are looking at —
   and the dock, being fixed at z-1250, went on floating over the dimmed page
   fully lit and fully clickable. Worse, it is pinned to the same corner those
   panels put their Save in: the vehicle profile's edit drawer had its Save
   button underneath this dock's New message button at every desktop width, so
   the one control the drawer exists for could not be pressed. The class is set
   by whichever panel is open (views/app/js/07-live-data/02c-vehicle-drawer.php),
   never by the dock, so a new panel is one line there and none here.

   THE OTHER CORNER IS THE REPORT BUTTON'S, and it is in this rule for exactly
   the same reason. .ams-fab is z-1200 and every sheet on this site is below
   it, so on a phone — where a sheet goes full width and its footer runs to
   both gutters — the bug button and this dock sat squarely on top of the
   sheet's Cancel and Save. The garage's "Add photos" sheet was the worst of
   them: the chat bubble covered the word "photos" on the only button that
   finishes the job. Two corners, one sentence, one rule; the FAB's own
   stylesheet points here rather than keeping a second copy.

   The four flags are one fact — a panel is over the page — under four names,
   because each sheet already had a lock class of its own before this rule
   existed. A fifth sheet adds its name here or, better, sets
   panel-owns-screen and adds nothing. */
body.panel-owns-screen #ams-chatdock,
body.gg-locked #ams-chatdock,
body.mc-locked #ams-chatdock,
body.mk-locked #ams-chatdock,
body.panel-owns-screen .ams-fab,
body.gg-locked .ams-fab,
body.mc-locked .ams-fab,
body.mk-locked .ams-fab{display:none}

/* The fan's origin: zero-width, pinned one slot in from the right gutter. A
   bubble hangs its RIGHT edge on it, so --cx of 0 means "first in the fan" and
   every other value is a distance leftward. One chat costs no arithmetic. */
/* THE CORNER IS THE NEW-MESSAGE BUTTON'S, and the fan opens to its left.
   It is the only thing in the dock that is there when nothing is open, so it
   is what the corner has to hold: a fan that started in the corner would put
   the first chat you opened on top of the one control that is always drawn.
   --cd-slot is that button plus the gap, written once and read by the fan, the
   window and the picker — three things measuring from one number (§6). */
#ams-chatdock{--cd-slot:calc(var(--cd-bub) + 12px)}
.cd-fan{position:absolute;right:calc(var(--cd-edge) + var(--cd-slot));bottom:0;width:0;height:var(--cd-bub)}

/* The compose button. Round like a bubble because it belongs to the fan, and
   accented because it is the verb among a row of faces. */
.cd-new{
  position:absolute;right:var(--cd-edge);bottom:0;
  width:var(--cd-bub);height:var(--cd-bub);padding:0;border:0;border-radius:999px;
  background:var(--accent);color:var(--accent-on);cursor:pointer;pointer-events:auto;
  display:grid;place-items:center;z-index:200;
  box-shadow:var(--sh-lg);transition:transform .16s ease, box-shadow .16s ease;
}
.cd-new:hover,.cd-new:focus-visible{transform:translateY(-2px);box-shadow:var(--sh-lg),0 0 0 2px var(--accent-line)}
.cd-new svg{width:20px;height:20px}
.cd-new.on{box-shadow:var(--sh-lg),0 0 0 3px var(--accent-line)}

.cd-b{
  position:absolute;right:0;bottom:0;width:var(--cd-bub);height:var(--cd-bub);
  padding:0;border:0;border-radius:999px;background:var(--surface);
  box-shadow:var(--sh-lg),0 0 0 1px var(--border);
  cursor:pointer;pointer-events:auto;display:grid;place-items:center;
  /* X ONLY — the fan is FLAT. Bubbles used to lift on a quarter-sine as they
     ran out from the corner, which made the row's bottom edge a curve climbing
     away from the New button it starts beside; everything else pinned to the
     bottom of this site sits on one line (--floor, §6) and a row of faces
     drifting up out of it read as the dock coming loose. */
  transform:translateX(var(--cx,0px));
  z-index:var(--cz,1);
  transition:transform .34s cubic-bezier(.2,.9,.25,1), box-shadow .16s ease;
}
/* A bubble ARRIVING rises out of the corner the fan opens from, so a new chat
   and a re-laid-out fan are the same motion. */
/* An arriving bubble still rises INTO the line — the motion is what says a
   chat appeared. It ends on the baseline like every other one. */
@keyframes cd-pop{from{transform:translate(0,10px) scale(.4);opacity:0}}
.cd-b.new{animation:cd-pop .3s cubic-bezier(.2,.9,.25,1) both}
.cd-b:hover,.cd-b:focus-visible{box-shadow:var(--sh-lg),0 0 0 2px var(--accent)}
.cd-b.on{box-shadow:var(--sh-lg),0 0 0 2px var(--accent)}
.cd-b>.av{width:calc(var(--cd-bub) - 6px);height:calc(var(--cd-bub) - 6px);font-size:14px}

/* The count, not a dot: "3" is how many replies are waiting, and a dot is only
   ever "something". Same blue as every other count on the site (--badge). */
.cd-n{
  position:absolute;top:-2px;right:-2px;min-width:18px;height:18px;padding:0 5px;
  border-radius:999px;background:var(--badge);color:var(--badge-fg);
  font-weight:700;font-size:10.5px;line-height:18px;text-align:center;
  box-shadow:0 0 0 2px var(--surface);
}
/* Closing a bubble is a press on the bubble, so it may not be a nested button
   (a <button> inside a <button> does not parse) — it is a span the JS hit-tests
   for. It appears on hover, and on touch it is always there: there is no hover
   on a phone and a bubble you cannot get rid of is the worst thing the dock
   could be. */
.cd-x{
  position:absolute;top:-4px;left:-4px;width:19px;height:19px;border-radius:999px;
  background:var(--surface3);color:var(--t2);display:grid;place-items:center;
  box-shadow:0 0 0 1px var(--border);opacity:0;transition:opacity .12s ease;
}
.cd-x svg{width:11px;height:11px}
/* The mark that says this bubble answers under a mod rather than in an inbox.
   Bottom-RIGHT, opposite the close and clear of the count in the other top
   corner — three things on one 46px circle and every one of them needs to be
   readable on its own. */
.cd-tag{
  position:absolute;bottom:-2px;right:-2px;width:17px;height:17px;border-radius:999px;
  background:var(--accent);color:var(--accent-on);display:grid;place-items:center;
  box-shadow:0 0 0 2px var(--surface);
}
.cd-tag svg{width:10px;height:10px}
.cd-b:hover .cd-x,.cd-b:focus-within .cd-x{opacity:1}
@media (hover:none){.cd-x{opacity:1}}

/* ---------------- the window ---------------- */
/* Anchored to the bubble it belongs to (the JS writes --cd-wx as a distance
   from the centre, and clamps it so the panel stays inside the window — §6's
   rule for any panel opened off a trigger). */
.cd-win{
  position:absolute;bottom:calc(var(--cd-bub) + 10px);right:calc(var(--cd-edge) + var(--cd-slot));
  transform:translateX(var(--cd-wx,0px));
  width:min(var(--cd-w), calc(100vw - 24px));height:var(--cd-h);
  display:flex;flex-direction:column;overflow:hidden;pointer-events:auto;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--sh-lg);
  transition:transform .28s cubic-bezier(.2,.9,.25,1);
  transform-origin:100% 100%;
}
.cd-win[hidden]{display:none}
@keyframes cd-rise{from{opacity:0;transform:translateX(var(--cd-wx,0px)) translateY(12px) scale(.96)}}
.cd-win.new{animation:cd-rise .22s ease-out both}

.cd-head{display:flex;align-items:center;gap:8px;padding:8px 8px 8px 10px;
  border-bottom:1px solid var(--border);background:var(--surface2);flex:none}
.cd-who{display:flex;flex-direction:column;min-width:0;flex:1;gap:1px}
.cd-t{font-size:13px;font-weight:650;color:var(--text);text-decoration:none;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
a.cd-t:hover{text-decoration:underline}
.cd-s{font-size:11px;color:var(--t3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cd-s.on{color:var(--green)}
.cd-ib{width:26px;height:26px;flex:none;display:grid;place-items:center;padding:0;
  border:0;background:none;border-radius:6px;color:var(--t2);cursor:pointer;text-decoration:none}
.cd-ib:hover{background:var(--surface3);color:var(--text)}

.cd-stream{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding:10px 10px 4px;display:flex;flex-direction:column;gap:6px}
/* A short thread sits ON the composer, not at the top of 300px of nothing —
   `margin-top:auto` on the first child and NOT justify-content:flex-end, which
   is the version of this that clips the top of the thread the moment it
   overflows and cannot be scrolled back to. */
.cd-stream > :first-child{margin-top:auto}
.cd-sys{margin:2px 0 6px;text-align:center;font-size:11px;color:var(--t3);
  display:flex;align-items:center;justify-content:center;gap:4px}
.cd-req{margin:0 0 6px;padding:8px 10px;border-radius:var(--r);font-size:11.5px;
  line-height:1.5;color:var(--t2);background:var(--surface2);border:1px solid var(--border)}
.cd-req a{color:var(--accent-fg)}
.cd-lc{display:flex;align-items:center;gap:6px;padding:7px 9px;margin-bottom:4px;
  border:1px solid var(--border);border-radius:var(--r);background:var(--surface2);
  font-size:11.5px;color:var(--t2);text-decoration:none}
.cd-lc span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cd-lc b{color:var(--text)}

.cd-g{display:flex;align-items:flex-end;gap:6px;max-width:100%}
.cd-g.me{flex-direction:row-reverse}
.cd-mav{flex:none;margin-bottom:2px}
.cd-bub{
  max-width:78%;padding:7px 10px 5px;border-radius:14px;
  background:var(--surface2);color:var(--text);font-size:12.5px;line-height:1.45;
  word-break:break-word;overflow-wrap:anywhere;
}
.cd-g.me .cd-bub{background:var(--accent);color:var(--accent-on)}
/* The clock is INSIDE the bubble, not under it. At this width a line of
   metadata under every message is a second column of noise down a 300px panel,
   and the read tick belongs to the message rather than to the gap after it. */
.cd-tm{display:flex;align-items:center;justify-content:flex-end;gap:3px;
  margin-top:2px;font-size:9.5px;opacity:.62}

/* ═══ a shared thing, arriving in the dock ═══
   The card is ams_share_subject() — the same twin the feed and the page draw
   (§1), so these are only the rules that fit it into a 300px panel.

   A message carrying a card WRAPS: .cd-g is a row of avatar-then-bubble and a
   card is neither, so without this the card is squeezed into whatever the
   bubble left and comes out about 80px wide. `has-sh` is stamped by the
   renderer rather than guessed from a child selector, because the row also has
   to know when there is a note ABOVE the card. */
.cd-g.has-sh{flex-wrap:wrap}
.cd-sh{width:calc(100% - 30px);max-width:260px;margin-top:4px}
.cd-g.me .cd-sh{margin-left:auto}
.cd-g.has-sh .cd-bub{max-width:100%}
.cd-sh .share-sub{display:block;border:1px solid var(--border);border-radius:12px;
  background:var(--surface);padding:9px 10px;text-decoration:none;color:inherit;overflow:hidden}
.cd-sh .share-sub:hover{border-color:var(--border2)}
.cd-sh .photo{display:block;aspect-ratio:16/9;margin:-9px -10px 8px;
  background-size:cover;background-position:center}
.cd-sh .share-kind{margin-bottom:5px;font-size:9px;line-height:1.6;padding:1px 6px}
.cd-sh h4{margin:0;font-size:12.5px;font-weight:600;line-height:1.3}
.cd-sh p{margin:3px 0 0;font-size:11.5px;line-height:1.4;color:var(--t2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cd-sh .share-by{margin-top:5px;font-size:10.5px}

.cd-comp{display:flex;align-items:flex-end;gap:6px;flex:none;
  padding:8px;border-top:1px solid var(--border);background:var(--surface)}
.cd-comp textarea{
  flex:1;min-width:0;resize:none;max-height:96px;
  padding:8px 10px;border:1px solid var(--border2);border-radius:16px;
  background:var(--surface2);color:var(--text);font:inherit;font-size:12.5px;line-height:1.4;
}
.cd-comp textarea:focus{outline:none;border-color:var(--accent);background:var(--surface)}
.cd-send{width:32px;height:32px;flex:none;display:grid;place-items:center;padding:0;
  border:0;border-radius:999px;background:var(--accent);color:var(--accent-on);cursor:pointer}
.cd-send:disabled{opacity:.5;cursor:default}
.cd-gate{margin:0;flex:none;padding:10px;border-top:1px solid var(--border);
  font-size:11.5px;line-height:1.5;color:var(--t2);display:flex;align-items:flex-start;gap:5px}
.cd-gate a{color:var(--accent-fg)}
/* A refused send, above the composer, with what was typed left exactly where
   it is — the same rule msgShowErr() follows on /messages, and for the same
   reason: there is a draft to lose. */
.cd-err{margin:0;flex:none;padding:7px 10px;font-size:11.5px;line-height:1.45;
  color:#B42318;background:rgba(180,35,24,.08);border-top:1px solid var(--border);
  display:flex;align-items:flex-start;gap:5px}
body.dark .cd-err{color:#FDA29B;background:rgba(253,162,155,.1)}

/* ---------------- the picker ----------------
   Who to write to. It hangs off the New button rather than off the fan, and it
   is a panel with a filter and a list — not a search: the list is friends and
   the people already in the inbox, both of which the server sent in one read,
   so the filtering is a substring over what is already here. */
.cd-pick{
  position:absolute;bottom:calc(var(--cd-bub) + 10px);right:var(--cd-edge);
  width:min(300px, calc(100vw - 24px));max-height:min(400px, calc(100vh - var(--navh) - var(--floor) - 96px));
  display:flex;flex-direction:column;overflow:hidden;pointer-events:auto;z-index:300;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--sh-lg);
}
.cd-pick[hidden]{display:none}
.cd-pick.new{animation:cd-rise .18s ease-out both}
.cd-pick-h{display:flex;align-items:center;gap:8px;padding:9px 10px;flex:none;
  border-bottom:1px solid var(--border);background:var(--surface2)}
.cd-pick-h b{font-size:13px;font-weight:650;color:var(--text);flex:1}
.cd-pick-f{flex:none;padding:8px 10px;border-bottom:1px solid var(--border)}
.cd-pick-f input{width:100%;height:32px;padding:0 10px;font:inherit;font-size:12.5px;
  border:1px solid var(--border2);border-radius:99px;background:var(--surface2);color:var(--text)}
.cd-pick-f input:focus{outline:none;border-color:var(--accent);background:var(--surface)}
.cd-pick-l{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:4px}
.cd-p{display:flex;align-items:center;gap:9px;width:100%;padding:6px 8px;border:0;border-radius:var(--r);
  background:none;cursor:pointer;text-align:left;text-decoration:none;color:inherit}
.cd-p:hover,.cd-p:focus-visible{background:var(--surface2);outline:none}
.cd-p-w{display:flex;flex-direction:column;min-width:0;gap:1px}
.cd-p-n{font-size:12.5px;font-weight:600;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cd-p-s{font-size:11px;color:var(--t3)}
.cd-p-none{padding:14px 12px;margin:0;font-size:12px;color:var(--t3);text-align:center}

/* ---------------- an arrival ----------------
   A message landing raises its bubble; this is what makes that VISIBLE. The
   bubble alone is a face appearing in a row of faces on a page somebody is
   reading — the whole point of a dock is that you do not have to be looking at
   it. So the flag says who and what, for a few seconds, and opens the thread
   when pressed. It never steals the screen: no panel over what is being read,
   which is the thing chat heads exist to avoid. */
.cd-pop{
  position:absolute;bottom:calc(var(--cd-bub) + 10px);right:calc(var(--cd-edge) + var(--cd-slot));
  transform:translateX(var(--cd-px,0px));
  width:min(268px, calc(100vw - 24px));padding:8px 10px;
  display:flex;align-items:flex-start;gap:8px;text-align:left;pointer-events:auto;z-index:280;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  box-shadow:var(--sh-lg);cursor:pointer;
  /* Its own keyframes: cd-rise animates translateX back to --cd-wx, which is
     the WINDOW's offset and not this one's, so borrowing it would slide the
     flag sideways out from under the bubble it belongs to. */
  animation:cd-prise .2s ease-out both;
}
@keyframes cd-prise{from{opacity:0;transform:translateX(var(--cd-px,0px)) translateY(12px) scale(.96)}}
.cd-pop[hidden]{display:none}
.cd-pop-w{display:flex;flex-direction:column;min-width:0;gap:1px;flex:1}
.cd-pop-n{font-size:12px;font-weight:650;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cd-pop-b{font-size:11.5px;line-height:1.4;color:var(--t2);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.cd-pop-x{flex:none;width:18px;height:18px;display:grid;place-items:center;color:var(--t3)}
.cd-pop-x svg{width:11px;height:11px}

/* ---------------- a comment thread in the window ----------------
   The body is the feed card's own `.fc-cmts` box, verbatim, so every comment
   handler in the bundle works in here untouched. Only two things are told they
   are somewhere smaller now: the box's own padding, and Hide comments — the
   dock's head already carries a close, and pressing that one would empty the
   window rather than shut it. */
.cd-cav{display:grid;place-items:center;width:32px;height:32px;border-radius:8px;flex:none;
  background:var(--accent-soft);color:var(--accent-fg)}
.cd-cwrap{padding:0;display:block}
.cd-cwrap .fc-cmts{padding:10px;border-top:0}
.cd-cwrap .fc-cmts-hide{display:none}
.cd-cwrap .fc-reply{position:sticky;bottom:0;margin-top:10px;padding-top:8px;
  background:var(--surface);border-top:1px solid var(--border)}

@media (max-width:760px){
  /* On `body` with its sibling declarations above, not on the host: --cd-top
     is resolved on body, so a bubble redeclared on the dock would leave the
     published top edge 4px out and the report button standing on it wrong. */
  body{--cd-bub:42px}
  .cd-pop{right:10px;transform:none;width:calc(100vw - 20px)}
  /* On a phone the window is the screen's width less a gutter, so there is
     nothing to anchor: it spans from edge to edge and the fan underneath is
     what says which chat it belongs to. */
  .cd-win{right:10px;transform:none;width:calc(100vw - 20px)}
  @keyframes cd-rise{from{opacity:0;transform:translateY(12px) scale(.96)}}
}
@media (prefers-reduced-motion:reduce){
  .cd-b,.cd-win{transition:none}
  .cd-b.new,.cd-win.new{animation:none}
}


/* ============================================================
   THE PROFILE HOVER CARD — a small /profile, over a user bubble.

   Pointing at somebody's bubble asks one question — "who is this, and do I
   know them?" — and the site's only answer was a page load. This is that
   answer without leaving the sentence you were reading: cover, avatar
   breaking the seam, name + verified mark + standing, @handle · role ·
   location, what you have in common, the bio, the headline car, then the
   same friend and message buttons the profile header carries.

   IT DEFINES NO COLOUR OF ITS OWN. Every --hc-* below resolves to a token
   :root already publishes, which is the whole reason the block exists: the
   accent is OPERATOR-CONFIGURABLE from the Appearance screen, and a card
   carrying #f05a24 would have been the one orange thing on the site that did
   not move when somebody repainted it. It is also why there is no
   `body.dark .hc` block — the tokens flip one element up, and a second dark
   palette here would be the copy that drifts. The lesson is
   24-image-picker.php's, which was written against a page's PRIVATE names and
   had no background at all outside that page: use tokens :root defines.

   IT IS A CHILD OF <body>, NEVER OF THE CARD IT OPENED FROM. `.fc` clips its
   own overflow and `.page.on` carries a transform, which makes a transformed
   ancestor the containing block for anything fixed inside it — the feed's
   panels landed ~5,800px down the page before they were lifted out (see
   js/06b-feed/06-float.php). This is lifted for the same reason.
   ============================================================ */

.hc{
  /* the palette, borrowed rather than declared */
  --hc-panel:var(--surface);
  --hc-sunken:var(--surface2);
  --hc-line:var(--border);
  --hc-line-2:var(--border2);
  --hc-ink:var(--text);
  --hc-ink-2:var(--t2);
  --hc-ink-3:var(--t3);
  --hc-accent:var(--accent-fg);
  --hc-wash:var(--accent-soft);
  --hc-shadow:var(--sh-lg);
  --hc-skel:linear-gradient(90deg,var(--surface2) 25%,var(--surface3) 37%,var(--surface2) 63%);
  --hc-r:var(--r-lg);
  --hc-pad:14px;
  --hc-cover:108px;
  --hc-lift:26px;
  /* THE GAP THE POINTER CROSSES, in one number. The bridge below and the
     offset the positioner uses are the same distance by construction — two
     numbers would leave a dead strip the width of the difference, and a card
     that vanishes mid-reach reads as the site being broken. */
  --hc-gap:10px;

  position:fixed;
  top:0; left:0;
  z-index:9000;
  width:364px;
  box-sizing:border-box;
  background:var(--hc-panel);
  color:var(--hc-ink);
  border:1px solid var(--hc-line);
  border-radius:var(--hc-r);
  box-shadow:var(--hc-shadow);
  font:400 13px/1.45 var(--ui);
  -webkit-font-smoothing:antialiased;
  opacity:0;
  transform:translateY(6px) scale(.988);
  transform-origin:top center;
  transition:opacity .13s ease, transform .16s var(--ease);
}
.hc *,.hc *::before,.hc *::after{ box-sizing:border-box }
.hc[data-side="top"]{ transform:translateY(-6px) scale(.988); transform-origin:bottom center }
.hc[hidden]{ display:none !important }
.hc.is-in{ opacity:1; transform:none }
.hc.is-out{ pointer-events:none }

/* WHAT THE BOTTOM EDGE IS WORTH, measured rather than remembered. The card is
   fixed and the admin bar is 46px of chrome across the floor (§6), so a card
   opened from a bubble near the bottom would end up behind it. The positioner
   reads this probe's height instead of carrying its own copy of --floor —
   the stylesheet stays the one place the number lives. */
.hc-floor{ position:absolute; left:0; bottom:0; width:0; height:var(--floor); pointer-events:none }

/* THE BRIDGE. Between the bubble and the card is --hc-gap of page, and a
   pointer crossing it leaves both — so without this the card closed on the
   way to being used. It is an invisible strip on the card's own side of the
   gap, which makes the whole reach one continuous hover. */
.hc::after{ content:""; position:absolute; left:0; right:0; height:var(--hc-gap) }
.hc[data-side="bottom"]::after{ top:calc(var(--hc-gap) * -1) }
.hc[data-side="top"]::after{ bottom:calc(var(--hc-gap) * -1) }

.hc-in{
  border-radius:inherit;
  overflow:hidden auto;
  scrollbar-width:thin;
}

/* ---- Cover --------------------------------------------------------------- */

.hc-cover{
  position:relative;
  height:var(--hc-cover);
  background:var(--hc-ink-3);
  overflow:hidden;
}
.hc-cover img{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:cover; object-position:50% 50%;
  display:block;
}
/* no cover on file: the avatar's own colour carries the band, so an
   unphotographed member gets their colour rather than a grey slab */
.hc-cover::before{
  content:""; position:absolute; inset:0;
  background:linear-gradient(118deg, rgba(255,255,255,.14), rgba(0,0,0,.16));
}
.hc-cover::after{
  content:""; position:absolute; inset:0;
  box-shadow:inset 0 -1px 0 rgba(12,12,16,.10);
}
body.dark .hc-cover::after{ box-shadow:inset 0 -1px 0 rgba(255,255,255,.07) }

/* ---- Identity ------------------------------------------------------------ */

.hc-body{ padding:0 var(--hc-pad) 13px }

.hc-avrow{
  display:flex; align-items:flex-end; justify-content:space-between;
  gap:10px;
  margin-top:calc(var(--hc-lift) * -1);
}
/* The bubble is AMSR.avatar()'s, so it is the same element, the same palette
   and the same presence dot the reader has already seen this person wearing
   (§1) — this only says how big it is here and rings it against the cover. */
.hc-avrow .av{
  width:54px; height:54px; font-size:19px; border-radius:999px;
  box-shadow:0 0 0 3px var(--hc-panel), 0 2px 8px rgba(0,0,0,.2);
}
.hc-avrow .av > .av-pres{ box-shadow:0 0 0 2.5px var(--hc-panel) }

.hc-tools{ position:relative; flex:0 0 auto; margin-right:-4px }
.hc-t{
  width:28px; height:28px;
  display:grid; place-items:center;
  border:0; border-radius:var(--btn-r);
  background:none; color:var(--hc-ink-3);
  cursor:pointer;
}
.hc-t > svg,.hc-t > .ic{ width:16px; height:16px }
.hc-t:hover{ background:var(--hc-sunken); color:var(--hc-ink) }
.hc-t:focus-visible{ outline:2px solid var(--accent); outline-offset:1px }

/* Name gets the full width, the way <h1> does on the profile. */
.hc-who{ margin-top:9px; min-width:0 }
.hc-nm{
  display:flex; align-items:center; gap:6px;
  font:600 17px/1.2 var(--dis);
  letter-spacing:-.018em;
  color:var(--hc-ink);
  text-decoration:none;
}
.hc-nm > span:first-child{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.hc-nm:hover > span:first-child{ text-decoration:underline; text-underline-offset:2px }
/* THE PROFILE'S OWN MARK, at this card's size. ppVmark() draws it — the card
   knows neither the hexagon's six points nor what verification means — and it
   is built for an <h1>, so it arrived 28px tall beside 17px type and read as a
   badge stuck on the name. Its explanation popup goes too: on the profile it
   is "the one screen where somebody stops to ask", and a panel that opens on
   hover INSIDE a panel that opened on hover is not that screen. */
.hc-nm .pp-vmark{ margin-left:0 }
.hc-nm .pp-vmark > svg{ width:15px; height:15px }
.hc-nm .pp-vpop{ display:none }
.hc-title{
  flex:0 0 auto;
  padding:2px 6px;
  border-radius:4px;
  background:var(--hc-sunken);
  border:1px solid var(--hc-line);
  font:500 9px/1.5 var(--mono);
  letter-spacing:.07em; text-transform:uppercase;
  color:var(--hc-ink-2);
}
.hc-chip{
  display:inline-flex; align-items:center; gap:3px;
  flex:0 0 auto;
  padding:2px 6px;
  border-radius:999px;
  background:var(--hc-wash); color:var(--hc-accent);
  font:500 9px/1.5 var(--mono);
  letter-spacing:.06em; text-transform:uppercase;
}
.hc-hd{
  display:block; margin-top:5px;
  font:400 11px/1.4 var(--mono);
  color:var(--hc-ink-3);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

/* ---- Why you'd care ------------------------------------------------------ */

.hc-signals{ display:flex; flex-wrap:wrap; gap:4px 10px; margin-top:10px }
.hc-sig{
  display:inline-flex; align-items:center; gap:5px;
  min-width:0; max-width:100%;
  font-size:11.5px; font-weight:500;
  color:var(--hc-ink-2);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.hc-sig > svg,.hc-sig > .ic{ flex:0 0 auto; width:12px; height:12px; color:var(--hc-accent) }

.hc-bio{
  margin:9px 0 0;
  font-size:12.5px; line-height:1.5;
  color:var(--hc-ink-2);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden;
}
.hc-site{
  display:inline-flex; align-items:center; gap:5px;
  margin-top:7px; max-width:100%;
  font-size:11.5px; font-weight:500;
  color:var(--hc-accent); text-decoration:none;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.hc-site:hover{ text-decoration:underline; text-underline-offset:2px }
.hc-site > svg,.hc-site > .ic{ flex:0 0 auto; width:13px; height:13px }

/* ---- Garage: the headline car, then the way through ---------------------- */

.hc-sec{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:10px; margin:14px 0 8px;
}
.hc-eyebrow{
  flex:0 0 auto;
  font:400 9px/1 var(--mono);
  letter-spacing:.15em; text-transform:uppercase;
  color:var(--hc-ink-3);
}
.hc-all{
  min-width:0;
  font-size:11.5px; font-weight:500;
  color:var(--hc-accent); text-decoration:none;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.hc-all:hover{ text-decoration:underline; text-underline-offset:2px }
.hc-all > svg,.hc-all > .ic{ width:12px; height:12px; vertical-align:-1px; margin-left:2px }

.hc-feat{
  display:flex; align-items:center; gap:12px;
  margin:0 -8px; padding:6px 8px;
  border-radius:8px;
  text-decoration:none; color:inherit;
  transition:background .12s ease;
}
.hc-feat:hover{ background:var(--hc-sunken) }
.hc-feat:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px }

.hc-shot{
  position:relative; flex:0 0 auto;
  width:92px; height:62px;
  border-radius:6px;
  overflow:hidden;
  background:var(--hc-sunken);
  box-shadow:inset 0 0 0 1px rgba(12,12,16,.12);
}
body.dark .hc-shot{ box-shadow:inset 0 0 0 1px rgba(255,255,255,.1) }
.hc-shot img{ width:100%; height:100%; object-fit:cover; display:block }
.hc-shot--none{ display:grid; place-items:center; color:var(--hc-ink-3) }
.hc-shot--none > svg,.hc-shot--none > .ic{ width:22px; height:22px }

.hc-vtx{ min-width:0; flex:1 1 auto }
.hc-vt{
  display:block;
  font-size:13.5px; font-weight:600; line-height:1.3;
  letter-spacing:-.008em;
  color:var(--hc-ink);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.hc-vy,
.hc-vs{
  display:block; margin-top:3px;
  font:400 10.5px/1.3 var(--mono);
  color:var(--hc-ink-3);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.hc-vs{ margin-top:2px }

.hc-empty{
  margin:12px 0 0; padding:10px 11px;
  border:1px dashed var(--hc-line-2);
  border-radius:var(--btn-r);
  font-size:12px; color:var(--hc-ink-3);
}

/* ---- Actions -------------------------------------------------------------
   The BUTTONS are the site's own — friendBtnHTML() builds the first and the
   ladder in css/00b-buttons.php paints it, so Add Friend here and Add Friend
   on the profile are one control with one write path. All this says is how
   they sit in a 364px card. */

.hc-act{ display:flex; gap:6px; margin-top:12px }
.hc-act > .btn{ flex:1 1 auto; min-width:0; height:34px; white-space:nowrap }
.hc-act > .btn:first-child{ flex:1.3 1 auto }

/* ---- Overflow menu ------------------------------------------------------- */

.hc-menu{
  position:absolute; top:29px; right:0;
  min-width:196px; padding:4px;
  background:var(--hc-panel);
  border:1px solid var(--hc-line);
  border-radius:var(--btn-r);
  box-shadow:var(--hc-shadow);
  z-index:3;
}
.hc-menu[hidden]{ display:none }
.hc-mi{
  display:flex; align-items:center; gap:9px;
  width:100%; padding:7px 8px;
  border:0; border-radius:6px;
  background:none; color:var(--hc-ink);
  font:400 12.5px/1 var(--ui);
  text-align:left; cursor:pointer; text-decoration:none;
}
.hc-mi > svg,.hc-mi > .ic{ flex:0 0 auto; width:15px; height:15px; color:var(--hc-ink-3) }
.hc-mi span{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.hc-mi:hover{ background:var(--hc-sunken) }
.hc-mi:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px }
.hc-mi--warn,.hc-mi--warn > svg{ color:var(--accent-fg) }
.hc-mhr{ height:1px; margin:4px 2px; background:var(--hc-line); border:0 }

/* ---- Partial state -------------------------------------------------------
   Cover, avatar, name and handle are harvested off the bubble the reader is
   already pointing at, so the card is never blank and only what sits BELOW
   them is ever pending. */

.hc-sk{
  display:block;
  background:var(--hc-skel); background-size:340% 100%;
  border-radius:5px;
  animation:hc-sh 1.15s linear infinite;
}
@keyframes hc-sh{ to{ background-position:-340% 0 } }
.hc-sk--bio{ height:10px; margin-top:14px }
.hc-sk--bio2{ height:10px; width:62%; margin-top:7px }
.hc-sk--eye{ height:9px; width:112px; margin-top:20px }
.hc-sk--feat{ height:62px; margin-top:12px; border-radius:6px }
.hc-sk--btn{ height:34px; border-radius:var(--btn-r) }

.hc-err{ padding-top:4px }
.hc-err p{ margin:12px 0; font-size:13px; color:var(--hc-ink) }

/* ---- Touch: the same card, as a sheet ------------------------------------
   There is no hover on a phone, so a long press opens it centred over a
   scrim. It is the same markup — a second mobile layout would be a second
   card to keep true. */

.hc-scrim{
  position:fixed; inset:0; z-index:8999;
  background:rgba(12,12,16,.46);
  opacity:0; transition:opacity .17s ease;
}
.hc-scrim.is-in{ opacity:1 }
.hc-scrim[hidden]{ display:none }
.hc--sheet{ width:auto; left:14px !important; right:14px; max-width:396px; margin:0 auto }
.hc--sheet::after{ display:none }

@media (max-width:404px){ .hc{ width:min(364px, calc(100vw - 28px)) } }

@media (prefers-reduced-motion:reduce){
  .hc,.hc-feat,.hc-scrim{ transition:none }
  .hc{ transform:none }
  .hc-sk{ animation:none }
}
@media (prefers-contrast:more){
  .hc{ border-color:var(--hc-ink-3) }
  .hc-sig,.hc-vs,.hc-hd{ color:var(--hc-ink-2) }
}


/* ══════════════════════════════════════════════════════════════════════
   THE PARTS MARKETPLACE — /parts
   ══════════════════════════════════════════════════════════════════════

   IT DEFINES NO COLOUR OF ITS OWN. Every --mk-* below resolves to a token
   :root already publishes, for the reason 27-hover-card.php gives: the accent
   is OPERATOR-CONFIGURABLE from the Appearance screen, and a marketplace
   carrying #f05a24 would be the one orange surface on the site that did not
   move when somebody repainted it. It is also why there is no `body.dark`
   block down here: the tokens flip one element up, and a second dark palette
   in this file is the copy that drifts.

   THE TOKENS ARE ON <body>, NOT ON :root. A custom property is substituted
   where it is DECLARED, so `--mk-panel:var(--surface)` written on :root takes
   :root's LIGHT --surface — every dark value is redefined one element down, on
   body.dark — and hands that finished white to the whole page. That is the
   drawer's bug (00-tokens-and-buttons.php) and this file would have shipped it
   again. Declared here they resolve against the element carrying the dark
   values. The three overlays need them too and are children of <body> rather
   than of #pg-parts, so this is also the only place all four can read.

   EVERY CLASS IS PREFIXED `mk-`. The design this was ported from named its
   classes .card, .grid, .tag, .chip, .av, .rail and .toast — every one of which
   already means something on this site. `.shs-on` in the share sheet is the
   same lesson: a bare `.fit` inherited a green pill from
   03-ymm-finder-and-combo.php and a fitment line came out as a chip inside a
   row that already had one.                                                  */
body{
  --mk-panel:var(--surface);
  --mk-sunken:var(--surface2);
  --mk-line:var(--border);
  --mk-line-strong:var(--border2);
  --mk-ink:var(--text);
  --mk-ink-2:var(--t2);
  --mk-ink-3:var(--t3);
  --mk-good:var(--green);
  /* There is no --danger on this site. An error line is the accent's own
     foreground, which is the colour every other refusal on the site is written
     in, rather than a red this file would be the only owner of. */
  --mk-bad:var(--accent-fg);
  /* the catalogue plate: a drawing on graph paper, and the ink it is drawn in */
  --mk-plate:var(--t3);
  --mk-grid:color-mix(in srgb,var(--text) 5%,transparent);
  --mk-tick:color-mix(in srgb,var(--text) 19%,transparent);
  /* the card radii — the marketplace's shapes are tighter than the site's
     --r (10px), because a grid of forty tiles at 10px reads as a bag of
     pebbles. One rung, stated once. */
  --mk-r:6px; --mk-r-ctl:5px; --mk-r-sm:4px; --mk-r-pill:5px;
  /* ── WHERE THE OVERLAYS SIT IN THE STACK ──────────────────────────────
     All three are aria-modal dialogs, and they shipped at 55/60/70 — which
     is UNDER every piece of floating chrome this site puts on a page. The
     "Spot a bug?" button is z-index 1200 and the chat dock is 1250, and both
     are pinned to the bottom corners: they landed exactly on the sell
     page's Close/Publish row and on the listing sheet's own bar. A modal
     with the page's furniture punched through it is not a modal, and the
     two things poking through were both BUTTONS, one of them over Publish.

     The ceiling is the admin bar (1900), and staying under it is deliberate
     and already stated in 04-overlays.php: --floor is what the bottom edge
     of the window is worth (§6), and an operator's bar is chrome the
     marketplace does not get to cover.

     One rung each, so the three cannot be re-ordered by accident: the sell
     page is a screen, the listing sheet opens over the grid, and the little
     dialogs open over either. */
  --mk-z-sell:1300; --mk-z-page:1310; --mk-z-dialog:1320;
  /* the fitment band's height, which the fitment COVER measures its own
     bottom edge from — two numbers here would leave the cover overlapping
     the band it slides out from by the difference */
  --mk-bandh:34px;
  /* the tile, and the rail. Both are switched by one declaration each, which
     is what makes S/M/L a single class on <body> rather than three grids. */
  --mk-tile:clamp(176px,15.5vw,222px);
  --mk-tile-gap:clamp(10px,1.1vw,16px);
  --mk-rail-w:228px;
  /* the vehicle's own colour, and the three shades read off it. --mk-vc is set
     inline per element from the car's paint_hex; these three are how it is used
     so no call site mixes its own. */
  --mk-vc:var(--t3);
  --mk-vwash:color-mix(in srgb,var(--mk-vc) 12%,var(--mk-panel));
  --mk-vtext:color-mix(in srgb,var(--mk-vc) 78%,#000);
  --mk-vline:color-mix(in srgb,var(--mk-vc) 42%,var(--mk-line));
}
body.dark{
  --mk-vwash:color-mix(in srgb,var(--mk-vc) 24%,var(--mk-panel));
  --mk-vtext:color-mix(in srgb,var(--mk-vc) 52%,#fff);
  --mk-vline:color-mix(in srgb,var(--mk-vc) 50%,var(--mk-line));
}
/* Tile size is ONE token, so S/M/L is one switch rather than three grids. */
body.mk-sz-s{--mk-tile:clamp(142px,11.6vw,172px);--mk-tile-gap:clamp(8px,.8vw,12px);--mk-bandh:30px}
body.mk-sz-l{--mk-tile:clamp(232px,20.5vw,296px);--mk-tile-gap:clamp(14px,1.5vw,20px);--mk-bandh:38px}
/* An overlay owns the scroll while it is open. Prefixed, because `locked` on
   <body> is exactly the kind of name two features quietly share. */
body.mk-locked{overflow:hidden}

/* ══ page head — the title, the search, and the one way in ═════════════ */
#pg-parts .mk-head{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  max-width:var(--col);margin:0 auto;padding:0 var(--pad) 14px;
}
#pg-parts .mk-head h1{font-size:21px;flex:none}
#pg-parts .mk-head .mk-cnt{font-family:var(--mono);font-size:11.5px;color:var(--mk-ink-3);flex:none;margin-left:-4px}
#pg-parts .mk-head .mk-sp{flex:1}
#pg-parts .mk-search{
  flex:1;min-width:200px;max-width:520px;display:flex;align-items:center;gap:8px;height:36px;padding:0 11px;
  background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r-ctl);
  transition:border-color .12s ease;
}
#pg-parts .mk-search:focus-within{border-color:var(--mk-line-strong)}
#pg-parts .mk-search svg{color:var(--mk-ink-3);flex:none}
#pg-parts .mk-search input{flex:1;min-width:0;border:0;background:none;font:inherit;font-size:13.5px;color:inherit;outline:none}
#pg-parts .mk-search input::placeholder{color:var(--mk-ink-3)}

/* ══ tabs — Browse · Saved · Selling ═══════════════════════════════════
   Each is a real <a href> to a real address (§12), so they middle-click and
   still work with the bundle dead. The bundle intercepts and swaps in place. */
#pg-parts .mk-tabbar{border-bottom:1px solid var(--mk-line);margin-bottom:4px}
#pg-parts .mk-tabs{display:flex;gap:22px;max-width:var(--col);margin:0 auto;padding:0 var(--pad)}
#pg-parts .mk-tabs a{
  padding:12px 0 11px;cursor:pointer;font-size:14px;color:var(--mk-ink-2);
  border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .12s ease;
}
#pg-parts .mk-tabs a:hover{color:var(--mk-ink)}
#pg-parts .mk-tabs a[aria-selected="true"]{color:var(--mk-ink);font-weight:600;border-bottom-color:var(--accent)}
#pg-parts .mk-tabs .mk-ct{font-family:var(--mono);font-size:11px;color:var(--mk-ink-3);margin-left:5px}

/* ══ the shell: rail · grip · stage ════════════════════════════════════ */
#pg-parts .mk-body{
  display:grid;grid-template-columns:var(--mk-rail-w) 17px minmax(0,1fr);
  align-items:start;padding:20px 0 40px;
}
#pg-parts .mk-grip{
  position:sticky;top:calc(var(--navh) + 14px);height:calc(100vh - var(--navh) - 60px);
  display:flex;align-items:center;justify-content:center;
  cursor:col-resize;background:none;border:0;padding:0;touch-action:none;
}
#pg-parts .mk-grip::before{content:"";width:1px;height:100%;background:var(--mk-line);transition:background .12s ease,width .12s ease}
#pg-parts .mk-grip:hover::before,#pg-parts .mk-grip:focus-visible::before{width:2px;background:var(--accent)}
body.mk-resizing{cursor:col-resize;user-select:none}
body.mk-resizing #pg-parts .mk-grip::before{width:2px;background:var(--accent)}
#pg-parts .mk-grip:focus-visible{outline:none}
#pg-parts .mk-stage{padding-left:clamp(14px,1.8vw,22px);min-width:0}

/* ══ the stage's toolbar — the garage, the sort, the two view toggles ══ */
#pg-parts .mk-tools{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding:0 0 14px;margin-bottom:18px;border-bottom:1px solid var(--mk-line);
}
#pg-parts .mk-tools .mk-div{flex:none;width:1px;height:24px;background:var(--mk-line)}
#pg-parts .mk-tools .mk-sp{flex:1}
#pg-parts .mk-tools .mk-lbl{font-size:12px;color:var(--mk-ink-3)}
#pg-parts .mk-sel{
  height:38px;min-width:158px;width:auto;padding:0 30px 0 10px;appearance:none;cursor:pointer;
  background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r-ctl);
  font:inherit;font-size:12.5px;color:var(--mk-ink);
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 15px) 17px,calc(100% - 11px) 17px;background-size:4px 4px,4px 4px;background-repeat:no-repeat;
}
#pg-parts .mk-sel:hover{border-color:var(--mk-line-strong)}
#pg-parts .mk-vtog{display:flex;border:1px solid var(--mk-line);border-radius:var(--mk-r-ctl);overflow:hidden;background:var(--mk-panel);box-shadow:var(--sh-sm)}
#pg-parts .mk-vtog button{
  display:flex;align-items:center;justify-content:center;width:40px;height:38px;
  border:0;background:none;cursor:pointer;color:var(--mk-ink-3);
  transition:background .12s ease,color .12s ease;
}
#pg-parts .mk-vtog button + button{border-left:1px solid var(--mk-line)}
#pg-parts .mk-vtog button:hover{background:var(--mk-sunken);color:var(--mk-ink)}
#pg-parts .mk-vtog button[aria-pressed="true"]{background:var(--mk-sunken);color:var(--mk-ink)}
#pg-parts .mk-sztog button{width:34px}
/* The size glyphs are drawn at the stylesheet's size, not at one baked into
   every call (ams_icon()'s null) — three buttons in a 34px column that have to
   agree with each other, which is exactly what a rule is for. */
#pg-parts .mk-sztog svg{width:15px;height:15px}
#pg-parts .mk-sztog button[aria-pressed="true"]{color:var(--mk-ink)}

/* ══ the garage picker — the primary axis, and it sits in the toolbar ══ */
#pg-parts .mk-gsel{position:relative;flex:none}
#pg-parts .mk-gselbtn{
  display:flex;align-items:center;gap:12px;height:54px;padding:0 14px 0 10px;
  background:var(--mk-panel);border:1px solid var(--mk-line-strong);border-radius:var(--mk-r);
  box-shadow:var(--sh-sm);cursor:pointer;transition:background .12s ease,border-color .12s ease;
}
#pg-parts .mk-gselbtn:hover{background:var(--mk-sunken)}
#pg-parts .mk-gselbtn .mk-slot,#pg-parts .mk-gopt .mk-slot{
  display:flex;align-items:center;justify-content:center;flex:none;width:46px;height:34px;
  border-radius:6px;background:var(--mk-sunken);color:var(--mk-ink-3);overflow:hidden;
}
#pg-parts .mk-gopt .mk-slot{width:52px}
#pg-parts .mk-slot img{width:100%;height:100%;object-fit:cover}
#pg-parts .mk-gselbtn .mk-tx{display:flex;flex-direction:column;align-items:flex-start;gap:2px;line-height:1.15;min-width:0}
#pg-parts .mk-gselbtn .mk-nm{font-family:var(--dis);font-size:16px;font-weight:600;letter-spacing:-.015em;white-space:nowrap}
#pg-parts .mk-gselbtn .mk-mt{font-size:12px;color:var(--mk-ink-3);white-space:nowrap}
#pg-parts .mk-gselbtn .mk-cv{flex:none;color:var(--mk-ink-3);transition:transform .14s ease}
#pg-parts .mk-gsel.mk-on .mk-gselbtn{border-color:var(--mk-ink-3)}
#pg-parts .mk-gsel.mk-on .mk-gselbtn .mk-cv{transform:rotate(180deg)}
/* scoped to one car, the button wears that car's colour — the same colour the
   cards it matches are about to be outlined in */
#pg-parts .mk-gselbtn.mk-scoped{background:var(--mk-vwash);border-color:var(--mk-vc);box-shadow:inset 0 0 0 1px var(--mk-vc)}
#pg-parts .mk-gselbtn.mk-scoped .mk-nm{color:var(--mk-vtext)}
#pg-parts .mk-gselbtn.mk-scoped .mk-mt,#pg-parts .mk-gselbtn.mk-scoped .mk-cv{color:var(--mk-vtext);opacity:.8}
#pg-parts .mk-gmenu{
  position:absolute;z-index:34;top:calc(100% + 8px);left:0;width:min(372px,86vw);max-height:460px;overflow:auto;
  background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r);
  box-shadow:var(--sh-lg);padding:6px;display:none;
}
#pg-parts .mk-gsel.mk-on .mk-gmenu{display:block}
#pg-parts .mk-gmenu .mk-glbl{
  display:block;font-size:10.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--mk-ink-3);padding:10px 10px 6px;
}
#pg-parts .mk-gmenu hr{border:0;border-top:1px solid var(--mk-line);margin:5px 2px}
#pg-parts .mk-gopt{
  display:flex;align-items:center;gap:13px;width:100%;padding:10px;border:0;border-radius:var(--mk-r-ctl);
  background:none;cursor:pointer;text-align:left;color:var(--mk-ink-2);
  transition:background .1s ease,box-shadow .12s ease;
}
#pg-parts .mk-gopt:hover{background:var(--mk-sunken)}
#pg-parts .mk-gopt[aria-selected="true"]{background:var(--mk-vwash);box-shadow:inset 0 0 0 1px var(--mk-vline)}
#pg-parts .mk-gopt .mk-tx{flex:1;min-width:0}
#pg-parts .mk-gopt .mk-nm{display:block;font-family:var(--dis);font-size:15px;font-weight:600;letter-spacing:-.015em;color:var(--mk-ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#pg-parts .mk-gopt .mk-mt{display:block;font-size:12.5px;color:var(--mk-ink-3);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#pg-parts .mk-gopt .mk-n{flex:none;font-family:var(--mono);font-size:13px;color:var(--mk-ink-3)}
/* A count of nothing is DIMMED, never hidden: "0 parts fit the Eurovan" is an
   answer, and a row that vanishes is a car the member thinks we lost. */
#pg-parts .mk-gopt .mk-n.mk-zero{opacity:.4}
/* Which row is in force is SAID, not only tinted. Every row in this menu wears
   its own car's paint already, so one more colour would be the least legible
   signal on the panel. */
#pg-parts .mk-gtick{
  flex:none;display:none;align-items:center;justify-content:center;width:18px;height:18px;
  border-radius:50%;background:var(--mk-vc);color:#fff;
}
#pg-parts .mk-gopt[aria-selected="true"] .mk-gtick{display:flex}
/* the grip is a separator, not a button — it still takes the keyboard */
#pg-parts .mk-grip:focus-visible::before{width:2px;background:var(--accent)}


/* ══ the rail — categories, fitment, condition, delivery ═══════════════
   Every row carries a live count of what WOULD be there if you pressed it,
   counted over the pool with that row's own filter lifted (base('cat') and
   friends in the bundle). A count that included its own filter would read
   zero for every unpressed row the moment you pressed one. */
#pg-parts .mk-rail{
  position:sticky;top:calc(var(--navh) + 14px);
  max-height:calc(100vh - var(--navh) - 60px);
  overflow-y:auto;overscroll-behavior:contain;padding:0 8px 24px 0;margin-right:-8px;min-width:0;
}
#pg-parts .mk-rail-lbl{
  display:flex;align-items:center;gap:9px;font-size:10.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--mk-ink-3);margin:0 0 9px;font-weight:600;
}
#pg-parts .mk-rail-lbl::after{content:"";flex:1;height:1px;background:var(--mk-line)}
#pg-parts .mk-rail-grp{margin-bottom:22px}
#pg-parts .mk-rail-grp:last-child{margin-bottom:0}

#pg-parts .mk-cats{display:flex;flex-direction:column;gap:1px}
#pg-parts .mk-cat{
  display:flex;align-items:center;gap:9px;width:calc(100% + 16px);margin:0 -8px;padding:6px 8px;
  border:0;border-radius:6px;background:none;cursor:pointer;text-align:left;
  font-size:13px;color:var(--mk-ink-2);transition:background .1s ease,color .1s ease;
}
#pg-parts .mk-cat:hover{background:var(--mk-sunken);color:var(--mk-ink)}
#pg-parts .mk-cat svg{flex:none;color:var(--mk-ink-3)}
#pg-parts .mk-cat .mk-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#pg-parts .mk-cat .mk-n{font-family:var(--mono);font-size:11px;color:var(--mk-ink-3)}
#pg-parts .mk-cat[aria-pressed="true"]{background:var(--accent-soft);color:var(--mk-ink)}
#pg-parts .mk-cat[aria-pressed="true"] svg{color:var(--accent)}
#pg-parts .mk-cat.mk-zero{opacity:.42}

#pg-parts .mk-seg{display:flex;border:1px solid var(--mk-line);border-radius:var(--mk-r-ctl);overflow:hidden;background:var(--mk-panel);box-shadow:var(--sh-sm)}
#pg-parts .mk-seg button{
  flex:1;appearance:none;background:none;border:0;padding:7px 0;cursor:pointer;
  font-size:12.5px;font-weight:600;color:var(--mk-ink-2);
  display:flex;align-items:center;justify-content:center;gap:5px;
  transition:background .12s ease,color .12s ease;
}
#pg-parts .mk-seg button + button{border-left:1px solid var(--mk-line)}
#pg-parts .mk-seg button:hover{background:var(--mk-sunken)}
#pg-parts .mk-seg button[aria-pressed="true"]{background:var(--mk-sunken);color:var(--mk-ink);font-weight:500}
#pg-parts .mk-seg .mk-n{font-family:var(--mono);font-size:11px;color:var(--mk-ink-3)}

#pg-parts .mk-frow{
  display:flex;align-items:center;gap:9px;margin:0 -8px;padding:6px 8px;border-radius:6px;
  cursor:pointer;font-size:12.5px;color:var(--mk-ink-2);transition:background .1s ease,color .1s ease;
}
#pg-parts .mk-frow:hover{background:var(--mk-sunken);color:var(--mk-ink)}
#pg-parts .mk-frow input{
  appearance:none;flex:none;width:15px;height:15px;margin:0;cursor:pointer;
  border:1px solid var(--mk-line-strong);border-radius:4px;background:var(--mk-panel);
  display:grid;place-content:center;transition:background .1s ease,border-color .1s ease;
}
#pg-parts .mk-frow input:checked{background:var(--accent);border-color:var(--accent)}
#pg-parts .mk-frow input:checked::after{content:"";width:8px;height:5px;border:2px solid var(--accent-on);border-top:0;border-right:0;transform:rotate(-45deg) translate(1px,-1px)}
#pg-parts .mk-frow .mk-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#pg-parts .mk-frow .mk-n{font-family:var(--mono);font-size:11px;color:var(--mk-ink-3)}
#pg-parts .mk-frow input:checked + .mk-t{color:var(--mk-ink);font-weight:500}

#pg-parts .mk-recent{display:flex;gap:6px}
#pg-parts .mk-recent a{
  position:relative;flex:1;min-width:0;max-width:46px;aspect-ratio:1;padding:0;overflow:hidden;
  border:1px solid var(--mk-line);border-radius:6px;background:var(--mk-sunken);display:block;
}
#pg-parts .mk-recent a:hover{border-color:var(--mk-line-strong)}
#pg-parts .mk-recent svg{position:absolute;inset:8%;width:84%;height:84%;color:var(--mk-plate);opacity:.7}
#pg-parts .mk-recent img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

#pg-parts .mk-railcta{margin-top:26px;padding:14px;background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r)}
#pg-parts .mk-railcta b{display:block;font-family:var(--dis);font-size:13.5px;font-weight:500;letter-spacing:-.012em}
#pg-parts .mk-railcta span{display:block;font-size:12px;color:var(--mk-ink-3);line-height:1.55;margin:4px 0 11px}
#pg-parts .mk-railcta .mk-btn{width:100%}

/* ══ the chips over the results — what is currently narrowing them ═════ */
#pg-parts .mk-chips{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 14px}
#pg-parts .mk-chips:empty{display:none}
#pg-parts .mk-chip{
  display:inline-flex;align-items:center;gap:2px;height:27px;padding:0 4px 0 10px;
  border:1px solid var(--mk-line-strong);border-radius:var(--mk-r-pill);background:var(--mk-panel);font-size:12px;
}
#pg-parts .mk-chip b{font-weight:500}
#pg-parts .mk-chip .mk-k{color:var(--mk-ink-3);margin-right:4px}
#pg-parts .mk-chip button{display:flex;align-items:center;justify-content:center;width:19px;height:19px;border:0;border-radius:50%;background:none;color:var(--mk-ink-3);cursor:pointer}
#pg-parts .mk-chip button:hover{background:var(--mk-sunken);color:var(--mk-ink)}
#pg-parts .mk-chip-clear{height:27px;padding:0 11px;border:1px dashed var(--mk-line-strong);border-radius:var(--mk-r-pill);background:none;cursor:pointer;font-size:12px;color:var(--mk-ink-2)}
#pg-parts .mk-chip-clear:hover{color:var(--mk-ink);border-color:var(--mk-ink-3)}

/* THE BUTTON LADDER CARRIES NO PAGE ID, for the reason 02-card.php gives at
   length: these are drawn in the grid, in the three overlays AND at
   /parts/{slug}, which is #pg-part and not #pg-parts. Written as
   `#pg-parts .mk-btn, .mk-ov .mk-btn` the listing page got neither, so "Edit
   this listing" and Save rendered as bare text and a loose glyph — a page that
   looked broken while every rule in it was correct for the two places it had
   been written for. The `mk-` prefix IS the namespace. */
.mk-btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  height:38px;padding:0 14px;border:1px solid var(--mk-line-strong);border-radius:var(--mk-r-ctl);
  background:var(--mk-panel);cursor:pointer;font-size:12.5px;font-weight:600;white-space:nowrap;
  box-shadow:var(--sh-sm);color:var(--mk-ink);
  transition:background .12s ease,border-color .12s ease,transform .08s ease;
}
.mk-btn:hover{background:var(--mk-sunken)}
.mk-btn:active{transform:scale(.985)}
.mk-btn-accent{background:var(--accent);border-color:var(--accent);color:var(--accent-on)}
.mk-btn-accent:hover{background:var(--accent);filter:brightness(1.07)}
.mk-btn-sm{height:30px;padding:0 10px;font-size:12px}
.mk-btn-lg{height:42px;padding:0 18px;font-size:13.5px}
.mk-btn[disabled]{opacity:.45;cursor:not-allowed}
.mk-ico{
  display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:32px;height:32px;border:1px solid var(--mk-line);border-radius:var(--mk-r-ctl);
  background:var(--mk-panel);cursor:pointer;color:var(--mk-ink-2);
  transition:background .12s ease,border-color .12s ease,color .12s ease,transform .08s ease;
}
.mk-ico:hover{border-color:var(--mk-line-strong);color:var(--mk-ink);background:var(--mk-sunken)}
.mk-ico:active{transform:scale(.94)}


/* ══════════════════════════════════════════════════════════════════════
   THE CARD, AND WHY THESE RULES CARRY NO PAGE ID.

   The rest of this stylesheet is scoped by `#pg-parts`, because a rail and a
   toolbar are page furniture. The CARD is not: the very same markup is drawn
   in the grid, inside the listing overlay's "also fits" band, AND as the sell
   page's live preview — and the last two are children of <body>, not of the
   page. Written as `#pg-parts .x, .mk-ov .x` it was one list to keep in step
   and the first pair to fall out of it was silent: the preview came up with
   its shipping tooltip permanently on and its fitment cover slid open, because
   two rules out of forty had only the page half.

   Every class here is `mk-`-prefixed, and that prefix IS the namespace. A page
   id on top of it adds nothing but a second place to forget.
   ══════════════════════════════════════════════════════════════════════ */
/* ══ the catalogue plate ═══════════════════════════════════════════════
   A listing with no photograph is not an empty box: it is a drawing on graph
   paper, with the figure number and the part number set in it. The plate is
   what makes a grid of un-photographed parts still read as a parts counter.
   The drawing is the part's CATEGORY glyph — the one already on the rail —
   rather than a per-part illustration nobody could draw for every part. */
.mk-plate{
  position:relative;aspect-ratio:4/3;overflow:hidden;background:var(--mk-sunken);
  background-image:linear-gradient(var(--mk-grid) 1px,transparent 1px),linear-gradient(90deg,var(--mk-grid) 1px,transparent 1px);
  background-size:15px 15px;background-position:center;
}
/* THE DRAWING IS A MARK ON THE SHEET, NOT A POSTER. These are the site's own
   24-grid stroke glyphs, and a stroke drawn for 16px does not become a
   technical illustration at 340 — it becomes a scribble, which is what filling
   the plate with it looked like. It is capped and centred instead, so a grid of
   un-photographed parts reads as a parts catalogue rather than as a wall of
   enormous icons. */
.mk-plate > svg{
  position:absolute;left:50%;top:50%;
  width:clamp(44px,30%,96px);height:auto;aspect-ratio:1;
  color:var(--mk-plate);opacity:.62;
  transform:translate(-50%,-50%);transition:transform .34s var(--ease);
}
.mk-plate-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;background:var(--mk-sunken);transition:transform .34s var(--ease)}
.mk-card:hover .mk-plate-img{transform:scale(1.035)}
/* the glyph is centred by a translate, so its hover keeps it */
.mk-card:hover .mk-plate > svg{transform:translate(-50%,-50%) scale(1.05)}
/* the four registration marks a drawing sheet carries */
.mk-pmark{
  position:absolute;inset:9px;pointer-events:none;
  background:
    linear-gradient(var(--mk-tick),var(--mk-tick)) left top/9px 1px no-repeat,
    linear-gradient(var(--mk-tick),var(--mk-tick)) left top/1px 9px no-repeat,
    linear-gradient(var(--mk-tick),var(--mk-tick)) right top/9px 1px no-repeat,
    linear-gradient(var(--mk-tick),var(--mk-tick)) right top/1px 9px no-repeat,
    linear-gradient(var(--mk-tick),var(--mk-tick)) left bottom/9px 1px no-repeat,
    linear-gradient(var(--mk-tick),var(--mk-tick)) left bottom/1px 9px no-repeat,
    linear-gradient(var(--mk-tick),var(--mk-tick)) right bottom/9px 1px no-repeat,
    linear-gradient(var(--mk-tick),var(--mk-tick)) right bottom/1px 9px no-repeat;
}
.mk-plate-fig,.mk-plate-pn{
  position:absolute;z-index:1;font-family:var(--mono);font-size:9px;letter-spacing:.06em;color:var(--mk-ink-3);opacity:.7;
}
.mk-plate-fig{left:14px;top:12px}
.mk-plate-pn{right:14px;bottom:11px}
/* a real photograph displaces the drawing's furniture — a figure number over
   somebody's photo of a strut is a caption for a diagram that is not there */
.mk-plate-img ~ .mk-plate-pn,.mk-plate-img ~ .mk-plate-fig,.mk-plate-img ~ .mk-pmark
.mk-plate-img ~ .mk-plate-pn,.mk-plate-img ~ .mk-plate-fig,.mk-plate-img ~ .mk-pmark{display:none}

/* ══ the grid, and the card ════════════════════════════════════════════ */
.mk-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--mk-tile),1fr));gap:var(--mk-tile-gap)}
.mk-sect{margin-bottom:clamp(20px,2.6vw,32px)}
.mk-sect:last-child{margin-bottom:0}

.mk-card{
  position:relative;display:flex;flex-direction:column;background:var(--mk-panel);
  border:1px solid var(--mk-line);border-radius:var(--mk-r);overflow:hidden;box-shadow:var(--sh-sm);
  transition:border-color .14s ease,box-shadow .14s ease,transform .14s ease;
}
.mk-card:hover{border-color:var(--mk-line-strong);box-shadow:var(--sh);transform:translateY(-1px)}
.mk-card.mk-fits{border-color:var(--mk-vline)}
.mk-card.mk-open{border-color:var(--accent);box-shadow:var(--sh);transform:none}
@keyframes mk-settle{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.mk-grid.mk-anim > *{animation:mk-settle .26s var(--ease) backwards}
.mk-rows.mk-anim > .mk-lrow:not(.mk-lhead){animation:mk-settle .22s var(--ease) backwards}
.mk-grid.mk-anim > *:nth-child(1){animation-delay:0ms}
.mk-grid.mk-anim > *:nth-child(2){animation-delay:22ms}
.mk-grid.mk-anim > *:nth-child(3){animation-delay:44ms}
.mk-grid.mk-anim > *:nth-child(4){animation-delay:66ms}
.mk-grid.mk-anim > *:nth-child(5){animation-delay:88ms}
.mk-grid.mk-anim > *:nth-child(n+6){animation-delay:105ms}

/* THE WHOLE CARD IS A LINK, and it is a real <a href> to /parts/{slug} (§12),
   so it middle-clicks, shows its target and still opens the listing when the
   bundle never arrives. The bundle intercepts it to open the overlay and
   pushes that very address. */
.mk-card-open{position:absolute;inset:0;z-index:1;border:0;background:none;cursor:pointer;display:block}
.mk-card-open:focus-visible{outline-offset:-3px}

.mk-shot{position:relative;aspect-ratio:3/2;overflow:hidden;background:var(--mk-sunken)}
.mk-shot .mk-plate{position:absolute;inset:0;aspect-ratio:auto}
.mk-shot > img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .4s var(--ease)}
.mk-card:hover .mk-shot > img{transform:scale(1.04)}
.mk-pscrim{
  position:absolute;inset:auto 0 0 0;z-index:2;padding:34px 12px 10px;
  display:flex;align-items:flex-end;gap:10px;pointer-events:none;
  background:linear-gradient(transparent,rgba(12,11,10,.26) 32%,rgba(12,11,10,.8));
}
.mk-pscrim .mk-price{
  display:flex;align-items:baseline;gap:1px;flex:1;min-width:0;
  font-family:var(--mono);font-size:22px;font-weight:500;letter-spacing:-.03em;
  color:#fff;text-shadow:0 1px 10px rgba(0,0,0,.4);
}
.mk-pscrim .mk-cur{font-size:.6em;font-weight:400;opacity:.72;transform:translateY(-.3em)}
.mk-pscrim .mk-dist{
  display:flex;align-items:center;gap:5px;flex:none;
  font-size:11.5px;font-weight:500;color:rgba(255,255,255,.9);text-shadow:0 1px 8px rgba(0,0,0,.45);
}
/* NO PHOTOGRAPH, NO SCRIM. The gradient exists to keep a price legible over
   somebody's picture of a strut; over the catalogue plate there is nothing to
   be legible against, and it came out as a grey wash over the bottom third of
   the drawing. The price is set in the page's own ink instead, over a fade to
   the plate's own ground — which is what makes an un-photographed listing read
   as a catalogue entry rather than as a photo that failed to load. */
.mk-shot.mk-noshot .mk-pscrim{
  background:linear-gradient(transparent,color-mix(in srgb,var(--mk-sunken) 82%,transparent) 46%,var(--mk-sunken));
}
.mk-shot.mk-noshot .mk-pscrim .mk-price{color:var(--mk-ink);text-shadow:none}
.mk-shot.mk-noshot .mk-pscrim .mk-cur{color:var(--mk-ink-2);opacity:1}
.mk-shot.mk-noshot .mk-pscrim .mk-dist{color:var(--mk-ink-3);text-shadow:none}
/* delivery is information so it stays on; Save sits beside it. No overflow
   clip on the pair — the tooltip has to escape it. */
.mk-acts{position:absolute;right:8px;top:8px;z-index:3;display:flex;filter:drop-shadow(0 2px 8px rgba(0,0,0,.22))}
.mk-acts button,.mk-acts .mk-shipbtn{
  position:relative;width:32px;height:32px;display:flex;align-items:center;justify-content:center;
  border:0;background:rgba(255,255,255,.95);color:#0A0A0C;cursor:pointer;transition:background .12s ease;
}
body.dark .mk-acts button{background:rgba(30,29,27,.95);color:#FAFAFA}
.mk-acts button:hover{background:#fff}
body.dark .mk-acts button:hover{background:#252523}
.mk-acts > *:first-child{border-radius:var(--mk-r-sm) 0 0 var(--mk-r-sm)}
.mk-acts > *:last-child{border-radius:0 var(--mk-r-sm) var(--mk-r-sm) 0}
.mk-acts .mk-shipbtn{cursor:help}
.mk-savebtn[aria-pressed="true"]{color:var(--accent)}
.mk-savebtn[aria-pressed="true"] svg{fill:currentColor}
@keyframes mk-pop{0%{transform:scale(1)}42%{transform:scale(1.3)}100%{transform:scale(1)}}
.mk-savebtn.mk-poping svg{animation:mk-pop .32s var(--ease)}
.mk-tip{
  position:absolute;top:calc(100% + 7px);right:0;z-index:6;
  padding:5px 9px;border-radius:var(--mk-r-sm);background:var(--mk-ink);color:var(--canvas);
  font-size:11.5px;font-weight:600;white-space:nowrap;box-shadow:var(--sh);
  opacity:0;pointer-events:none;transform:translateY(-3px);transition:opacity .14s ease,transform .14s ease;
}
.mk-shipbtn:hover .mk-tip,.mk-shipbtn:focus-visible .mk-tip{opacity:1;transform:none}

/* the vehicle's thumbnail, tinted by its own paint when there is no photo */
.mk-vthumb{
  position:relative;flex:none;overflow:hidden;border-radius:var(--mk-r-sm);
  background:color-mix(in srgb,var(--mk-vc) 22%,var(--mk-panel));
  display:flex;align-items:center;justify-content:center;color:var(--mk-vc);
}
.mk-vthumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* ams_icon(…, null) means "the stylesheet decides", and this is where it does.
   Without it the fallback car drew at the browser's default 300px inside a
   32×20 box — which is not a small picture of a car, it is nothing at all. */
.mk-vthumb svg{width:66%;height:66%}
.mk-vthumb--band{width:32px;height:20px}
.mk-vthumb--row{width:46px;height:32px}
.mk-vthumb--s{width:26px;height:16px}

.mk-card-bd{padding:11px 12px 12px;display:flex;flex-direction:column;flex:1}
.mk-card-ttl{
  font-family:var(--dis);font-size:15px;font-weight:600;line-height:1.28;letter-spacing:-.015em;margin:0;
  /* two lines are reserved so prices line up across a row; a long title runs
     to three rather than being cut off mid-word */
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;min-height:2.56em;
}
.mk-card-meta{margin:6px 0 0;font-size:12.5px;color:var(--mk-ink-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mk-tag{
  display:inline-flex;align-items:center;gap:5px;height:20px;padding:0 7px;border-radius:var(--mk-r-sm);
  background:var(--mk-sunken);border:1px solid var(--mk-line);font-size:10.5px;font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--mk-ink-2);white-space:nowrap;
}
.mk-sep{color:var(--mk-ink-3);opacity:.7}
.mk-card-seller{display:flex;align-items:center;gap:9px;margin-top:auto;padding-top:11px;border-top:1px solid var(--mk-line);min-width:0}
.mk-card-seller .mk-tx{flex:1;min-width:0;line-height:1.25}
.mk-seller-nm{display:block;font-size:12.5px;font-weight:500;color:var(--mk-ink-2);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-seller-mt{display:block;font-size:11.5px;color:var(--mk-ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-card-msg{
  position:relative;z-index:2;flex:none;height:29px;padding:0 12px;
  border:1px solid var(--accent);border-radius:var(--mk-r-sm);background:var(--accent);color:var(--accent-on);
  cursor:pointer;font-size:12px;font-weight:600;box-shadow:var(--sh-sm);
  transition:filter .12s ease,transform .08s ease;
}
.mk-card-msg:hover{filter:brightness(1.08)}
.mk-card-msg:active{transform:scale(.97)}
.mk-card-msg--mine{background:var(--mk-panel);border-color:var(--mk-line-strong);color:var(--mk-ink-2)}
.mk-card-msg--mine:hover{background:var(--mk-sunken);filter:none}

/* the size ladder — the card SCALES with the tile rather than just widening */
body.mk-sz-s .mk-card-bd{padding:10px 10px 11px}
body.mk-sz-s .mk-card-ttl{font-size:13.5px}
body.mk-sz-s .mk-card-meta{font-size:11.5px;margin-top:5px}
body.mk-sz-s .mk-card-seller{padding-top:9px;gap:7px}
body.mk-sz-s .mk-pscrim{padding:26px 10px 8px}
body.mk-sz-s .mk-pscrim .mk-price{font-size:18px}
body.mk-sz-s .mk-pscrim .mk-dist{font-size:10.5px}
body.mk-sz-s .mk-acts{right:6px;top:6px}
body.mk-sz-s .mk-acts button,body.mk-sz-s .mk-acts .mk-shipbtn{width:28px;height:28px}
body.mk-sz-s .mk-fitbar{padding-right:8px}
body.mk-sz-s .mk-fitbar .mk-t{font-size:9.5px;letter-spacing:.05em}
body.mk-sz-s .mk-fitbar .mk-vthumb{width:26px;height:17px;margin-left:7px}
/* At 145px there is no room for a lead-in, a city and a button. Small is for
   scanning, so the seller keeps their name and gives up the rest — the whole
   card still opens the listing. */
body.mk-sz-s .mk-fitbar .mk-lead{display:none}
body.mk-sz-s .mk-seller-mt{display:none}
body.mk-sz-s .mk-card-msg{display:none}
body.mk-sz-l .mk-card-bd{padding:15px 16px 16px}
body.mk-sz-l .mk-card-ttl{font-size:17px}
body.mk-sz-l .mk-card-meta{font-size:13.5px;margin-top:8px}
body.mk-sz-l .mk-pscrim{padding:40px 14px 12px}
body.mk-sz-l .mk-pscrim .mk-price{font-size:27px}
body.mk-sz-l .mk-pscrim .mk-dist{font-size:12.5px}
body.mk-sz-l .mk-acts button,body.mk-sz-l .mk-acts .mk-shipbtn{width:36px;height:36px}
body.mk-sz-l .mk-fitbar .mk-t{font-size:11.5px}
body.mk-sz-l .mk-fitbar .mk-vthumb{width:38px;height:24px}
body.mk-sz-l .mk-card-seller{padding-top:13px;gap:10px}
body.mk-sz-l .mk-seller-nm{font-size:13.5px}
body.mk-sz-l .mk-seller-mt{font-size:12.5px}
body.mk-sz-l .mk-card-msg{height:33px;font-size:13px;padding:0 14px}


/* ══ the fitment band, and the cover it opens ══════════════════════════
   The band is the one line on a card that answers "is this for MY car", and
   it is at the foot because that is the last thing read before the decision.
   Pressing it slides a cover over the card with the whole answer on it —
   which of your cars, and what the seller actually declared. */
.mk-fitbar{
  position:relative;z-index:6;display:flex;align-items:center;gap:9px;width:100%;
  height:var(--mk-bandh);padding:0 10px 0 0;flex:none;
  border:0;border-top:1px solid var(--mk-vline);background:var(--mk-vwash);color:var(--mk-vtext);
  cursor:pointer;text-align:left;font:inherit;transition:background .12s ease;
}
.mk-fitbar::before{content:"";flex:none;align-self:stretch;width:3px;background:var(--mk-vc)}
.mk-fitbar:hover{background:color-mix(in srgb,var(--mk-vc) 18%,var(--mk-panel))}
body.dark .mk-fitbar:hover{background:color-mix(in srgb,var(--mk-vc) 32%,var(--mk-panel))}
.mk-fitbar .mk-vthumb{margin-left:8px}
.mk-fitbar .mk-t{
  flex:1;min-width:0;font-size:10.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.mk-fitbar .mk-lead{font-style:normal}
.mk-fitbar .mk-n{flex:none;font-family:var(--mono);font-size:11px;opacity:.75}
.mk-fitbar .mk-cv{flex:none;opacity:.75;transition:transform .24s var(--ease)}
.mk-card.mk-open .mk-fitbar .mk-cv{transform:rotate(180deg)}
.mk-fitbar .mk-icn{margin-left:9px;flex:none;opacity:.85}
.mk-fitbar--no{background:var(--mk-sunken);color:var(--mk-ink-3);border-top-color:var(--mk-line)}
.mk-fitbar--no::before{background:var(--mk-line-strong)}
.mk-fitbar--no:hover,.mk-fitbar--uni:hover{background:var(--mk-line)}
.mk-fitbar--uni{background:var(--mk-sunken);color:var(--mk-ink);border-top-color:var(--mk-line-strong)}
.mk-fitbar--uni::before{background:var(--mk-ink)}
/* open is an ACTION state, so it takes the accent rather than the vehicle's
   colour — the colour returns the moment it closes */
.mk-card.mk-open .mk-fitbar,.mk-card.mk-open .mk-fitbar:hover{background:var(--accent);color:var(--accent-on);border-top-color:var(--accent)}
.mk-card.mk-open .mk-fitbar::before{background:color-mix(in srgb,var(--accent) 62%,#000)}
.mk-card.mk-open .mk-fitbar .mk-n,.mk-card.mk-open .mk-fitbar .mk-cv,.mk-card.mk-open .mk-fitbar .mk-icn{color:var(--accent-on);opacity:.9}
.mk-card.mk-open .mk-fitbar .mk-vthumb{background:rgba(255,255,255,.24);color:var(--accent-on)}

.mk-fitcover{
  position:absolute;left:0;right:0;top:0;bottom:var(--mk-bandh);z-index:5;
  background:var(--mk-panel);overflow-y:auto;overscroll-behavior:contain;
  transform:translateY(101%);visibility:hidden;
  transition:transform .28s var(--ease),visibility 0s linear .28s;
  box-shadow:0 -10px 26px rgba(12,12,16,.09);
}
body.dark .mk-fitcover{box-shadow:0 -10px 26px rgba(0,0,0,.4)}
.mk-card.mk-open .mk-fitcover{transform:none;visibility:visible;transition-delay:0s}
.mk-fc-hd{
  position:sticky;top:0;z-index:2;display:flex;align-items:center;gap:9px;
  padding:10px 8px 10px 12px;background:var(--mk-panel);border-bottom:1px solid var(--mk-line);
}
.mk-fc-hd h4{flex:1;min-width:0;margin:0;font-size:10.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--mk-ink-3)}
.mk-fc-x{flex:none;width:26px;height:26px;display:flex;align-items:center;justify-content:center;border:0;border-radius:var(--mk-r-sm);background:none;color:var(--mk-ink-3);cursor:pointer}
.mk-fc-x:hover{background:var(--mk-sunken);color:var(--mk-ink)}
.mk-fd{padding:9px 12px;border-bottom:1px solid var(--mk-line)}
.mk-fd:last-child{border-bottom:0}
.mk-fd h5{font-size:9.5px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--mk-ink-3);margin:0 0 7px}
.mk-fd-v{display:flex;align-items:center;gap:10px;padding:6px 0}
.mk-fd-v + .mk-fd-v{border-top:1px solid var(--mk-line)}
.mk-fd-v .mk-tx{flex:1;min-width:0}
.mk-fd-v .mk-nm{display:block;font-size:12.5px;font-weight:600;color:var(--mk-vtext);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-fd-v .mk-mt{display:block;font-size:11px;color:var(--mk-ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-fd-v .mk-ok{flex:none;color:var(--mk-vc)}
.mk-fd-none{font-size:12.5px;color:var(--mk-ink-2);margin:0;line-height:1.55}
.mk-fd-r{display:flex;align-items:baseline;gap:10px;padding:5px 0;font-size:12.5px;color:var(--mk-ink-2)}
.mk-fd-r + .mk-fd-r{border-top:1px solid var(--mk-line)}
.mk-fd-r .mk-m{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-fd-r .mk-y{flex:none;font-family:var(--mono);font-size:11.5px;color:var(--mk-ink-3)}
.mk-fd-pn{display:flex;align-items:baseline;gap:10px;font-size:11.5px;color:var(--mk-ink-3);margin:0}
.mk-fd-pn b{margin-left:auto;font-family:var(--mono);font-size:11.5px;font-weight:400;color:var(--mk-ink-2)}

/* ══ list view — the parts-counter table ═══════════════════════════════ */
.mk-rows{border:1px solid var(--mk-line);border-radius:var(--mk-r);overflow:hidden;background:var(--mk-panel);box-shadow:var(--sh-sm)}
.mk-lrow{
  display:grid;grid-template-columns:52px minmax(0,2.2fr) 118px 104px 96px 92px minmax(0,1fr) 34px;
  align-items:center;gap:12px;padding:9px 12px;border-bottom:1px solid var(--mk-line);position:relative;
}
.mk-lrow:last-child{border-bottom:0}
.mk-lrow:hover{background:var(--mk-sunken)}
.mk-lrow.mk-fits::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--mk-vc)}
.mk-lhead{
  background:var(--mk-sunken);font-size:10.5px;font-weight:600;letter-spacing:.08em;
  text-transform:uppercase;color:var(--mk-ink-3);padding-top:8px;padding-bottom:8px;
}
.mk-lhead:hover{background:var(--mk-sunken)}
.mk-lrow .mk-open{position:absolute;inset:0;border:0;background:none;cursor:pointer;display:block}
.mk-lthumb{position:relative;width:52px;aspect-ratio:4/3;border-radius:5px;overflow:hidden;background:var(--mk-sunken);border:1px solid var(--mk-line)}
.mk-lthumb svg{position:absolute;inset:14%;width:72%;height:72%;color:var(--mk-plate)}
.mk-lthumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.mk-lname{min-width:0}
.mk-lname b{display:block;font-size:13.5px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-lname small{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--mk-ink-3);margin-top:2px}
.mk-lname small .mk-pn{font-family:var(--mono)}
.mk-lfit{display:flex;align-items:center;gap:4px;flex-wrap:wrap}
.mk-lfit .mk-none{font-size:11.5px;color:var(--mk-ink-3)}
.mk-lcell{font-size:12.5px;color:var(--mk-ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-lprice{font-family:var(--mono);font-size:15px;font-weight:500;letter-spacing:-.02em;text-align:right}
.mk-lprice .mk-cur{font-size:10px;color:var(--mk-ink-2);margin-right:1px}
.mk-lseller{display:flex;align-items:center;gap:7px;min-width:0}
.mk-lseller .mk-tx{min-width:0;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-lsave{position:relative;z-index:2;width:30px;height:30px;border:0;border-radius:6px;background:none;cursor:pointer;color:var(--mk-ink-3)}
.mk-lsave:hover{background:var(--mk-panel);color:var(--mk-ink)}
.mk-lsave[aria-pressed="true"]{color:var(--accent)}
.mk-lsave[aria-pressed="true"] svg{fill:currentColor}
@media(max-width:1180px){
  .mk-lrow{grid-template-columns:52px minmax(0,2fr) 110px 96px 92px 34px}
  .mk-l-hide{display:none}
}
@media(max-width:760px){
  .mk-lrow{grid-template-columns:44px minmax(0,1fr) 88px 34px}
  .mk-l-hide2{display:none}
  .mk-lthumb{width:44px}
}

/* ══ show-more, empty states and the first-paint skeleton ══════════════ */
.mk-more{
  display:flex;align-items:center;gap:12px;width:100%;margin-top:clamp(12px,1.4vw,16px);
  padding:14px 18px;background:none;cursor:pointer;text-align:left;
  border:1px dashed var(--mk-line-strong);border-radius:var(--mk-r);color:var(--mk-ink-2);font-size:13.5px;
  transition:border-color .14s ease,color .14s ease,background .14s ease;
}
.mk-more:hover{border-color:var(--mk-ink-3);color:var(--mk-ink);background:var(--mk-panel)}
.mk-more b{font-weight:500;color:var(--mk-ink)}
.mk-more .mk-rule{flex:1;height:1px;background:var(--mk-line)}
.mk-more .mk-n{font-family:var(--mono);font-size:12px;color:var(--mk-ink-3)}

.mk-empty{border:1px dashed var(--mk-line-strong);border-radius:var(--mk-r);padding:clamp(30px,4.4vw,46px) 24px;text-align:center}
.mk-empty > svg{width:52px;height:52px;color:var(--mk-plate);opacity:.5;margin:0 auto 14px;display:block}
.mk-empty h3{font-size:16px;margin-bottom:5px}
.mk-empty p{font-size:13px;color:var(--mk-ink-2);margin:0 auto 16px;max-width:400px}

@keyframes mk-shimmer{100%{background-position:200% 0}}
.mk-sk{border:1px solid var(--mk-line);border-radius:var(--mk-r);background:var(--mk-panel);overflow:hidden}
.mk-sk-ph{aspect-ratio:4/3;background:var(--mk-sunken)}
.mk-sk-bd{padding:12px 13px 13px}
.mk-sk-l{height:10px;border-radius:5px;margin-bottom:9px;background:linear-gradient(90deg,var(--mk-sunken) 25%,var(--mk-line) 50%,var(--mk-sunken) 75%) 0 0/200% 100%;animation:mk-shimmer 1.4s linear infinite}
.mk-sk-l.mk-w70{width:70%}
.mk-sk-l.mk-w40{width:40%}
.mk-sk-l.mk-w55{width:55%}

/* ══ responsive ════════════════════════════════════════════════════════ */
.mk-railtog{display:none}
@media(max-width:1000px){
  .mk-body{grid-template-columns:minmax(0,1fr);padding-top:12px}
  .mk-grip{display:none}
  .mk-rail{position:static;max-height:none;margin-bottom:16px;padding-right:0;margin-right:0}
  .mk-stage{padding-left:0}
  .mk-railtog{display:flex;align-items:center;gap:7px;width:100%;height:38px;padding:0 12px;background:var(--mk-panel);border:1px solid var(--mk-line-strong);border-radius:var(--mk-r-ctl);cursor:pointer;font-size:13.5px;color:var(--mk-ink)}
  .mk-railtog .mk-n{margin-left:auto;font-family:var(--mono);font-size:11px;color:var(--mk-ink-3)}
  .mk-rail-inner{display:none;padding-top:16px}
  .mk-rail.mk-on .mk-rail-inner{display:block}
}
@media(prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important}
}


/* ══ THE THREE OVERLAYS ════════════════════════════════════════════════
   All three are children of <body>, never of #pg-parts, and that is not a
   preference. `.page.on` carries an enter transform, and a transformed
   ancestor becomes the containing block for anything `position:fixed` inside
   it — the feed's own panels landed ~5,800px down the page before they were
   lifted out (js/06b-feed/06-float.php). Every rule below is therefore scoped
   by `.mk-ov`, the class all three share, rather than by the page's id.

   They sit under the admin bar rather than over it: --floor is what the bottom
   edge of the window is worth (§6), and an operator's bar is chrome the
   marketplace does not get to cover.                                        */

/* ── the listing page ─────────────────────────────────────────────────
   /parts/{slug} is a real address and the server answers it in full. This is
   that same listing opened WITHOUT losing the grid behind it, and the bundle
   pushes the very address the card already pointed at — so Back returns to the
   scroll position, and the link in the address bar is the one to send. */
/* IT STARTS BELOW THE NAV. It used to start at 0 with a 28px pad, so its own
   bar — the crumb, and the × that is the only control that closes it — was
   drawn UNDER the site header and could not be pressed. Escape and the browser
   Back were the whole way out of a dialog that draws a close button. */
/* IT ENDS AT --floor-modal, NOT --floor. Its scrim covers the phone's tab
   bar, so leaving room for that bar holds a band of unusable navigation
   open under the sheet — 90px of scrimmed page on an operator's phone.
   What a scrim cannot cover is #adminbar (z-1900) and the home
   indicator, and --floor-modal is exactly those two (§6). */
.mk-pg{position:fixed;inset:var(--navh) 0 var(--floor-modal,0px) 0;z-index:var(--mk-z-page);display:flex;align-items:center;justify-content:center;padding:clamp(0px,2.4vh,28px) clamp(0px,2.4vw,28px)}
.mk-pg[hidden]{display:none}
.mk-pg-scrim{position:absolute;inset:0;background:rgba(12,12,16,.5);opacity:0;transition:opacity .22s ease}
.mk-pg.mk-on .mk-pg-scrim{opacity:1}
.mk-pg-doc{
  position:relative;width:100%;max-width:1180px;height:100%;
  background:var(--canvas);border:1px solid var(--mk-line);border-radius:14px;overflow:hidden;
  display:flex;flex-direction:column;box-shadow:var(--sh-lg);
  transform:translateY(16px) scale(.985);opacity:0;
  transition:transform .24s var(--ease),opacity .2s ease;
}
.mk-pg.mk-on .mk-pg-doc{transform:none;opacity:1}
.mk-pg-bar{flex:none;display:flex;align-items:center;gap:10px;height:54px;padding:0 12px 0 16px;background:var(--mk-panel);border-bottom:1px solid var(--mk-line)}
.mk-pg-crumb{display:flex;align-items:center;gap:9px;min-width:0;font-size:12.5px;color:var(--mk-ink-3)}
.mk-pg-crumb .mk-fig{font-family:var(--mono);font-size:11px;letter-spacing:.06em;flex:none}
.mk-pg-crumb .mk-nm{color:var(--mk-ink-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-pg-bar .mk-sp{flex:1}
.mk-pg-bar .mk-kbd{font-family:var(--mono);font-size:10.5px;color:var(--mk-ink-3);border:1px solid var(--mk-line);border-radius:4px;padding:2px 5px}
.mk-pg-scroll{flex:1;overflow:auto}

.mk-pg-top{display:grid;grid-template-columns:minmax(0,1.12fr) minmax(0,1fr);gap:clamp(18px,3vw,38px);padding:clamp(16px,2.6vw,30px)}
.mk-pg-plate{border:1px solid var(--mk-line);border-radius:var(--mk-r);overflow:hidden}
.mk-pg-thumbs{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap}
.mk-pg-thumbs button{position:relative;width:64px;aspect-ratio:4/3;padding:0;overflow:hidden;cursor:pointer;border:1px solid var(--mk-line);border-radius:6px;background:var(--mk-sunken)}
.mk-pg-thumbs button[aria-pressed="true"]{border-color:var(--mk-ink);box-shadow:0 0 0 1px var(--mk-ink)}
/* A ring around a thumbnail is hard to see against a photograph of a dark
   part, so the one showing carries a mark of its own. */
.mk-shotmark{
  position:absolute;right:3px;bottom:3px;z-index:2;display:none;
  align-items:center;justify-content:center;width:17px;height:17px;
  border-radius:50%;background:var(--mk-ink);color:var(--canvas);
}
.mk-pg-thumbs button[aria-pressed="true"] .mk-shotmark{display:flex}
.mk-pg-thumbs button svg{position:absolute;inset:14%;width:72%;height:72%;color:var(--mk-plate)}
.mk-pg-thumbs button img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

.mk-pg-eye{display:flex;align-items:center;gap:7px;margin-bottom:9px;flex-wrap:wrap}
.mk-pg-ttl{font-size:clamp(21px,2.5vw,29px);line-height:1.18;margin:0}
.mk-pg-pn{font-family:var(--mono);font-size:12.5px;color:var(--mk-ink-3);margin:9px 0 0}
.mk-pg-price{display:flex;align-items:baseline;gap:11px;margin:18px 0 0;flex-wrap:wrap}
.mk-pg-price b{font-family:var(--mono);font-size:clamp(28px,3.4vw,38px);font-weight:500;letter-spacing:-.035em;display:flex;align-items:baseline;gap:2px}
.mk-pg-price b .mk-cur{font-size:.55em;font-weight:400;color:var(--mk-ink-2);transform:translateY(-.5em)}
.mk-pg-price .mk-ship{font-size:13px;color:var(--mk-ink-2)}
.mk-pg-actions{display:flex;gap:9px;margin:20px 0 0}
.mk-pg-actions .mk-btn-lg{flex:1}
.mk-pg-actions .mk-ico{width:42px;height:42px}
.mk-pg-actions .mk-ico[aria-pressed="true"]{color:var(--accent);border-color:var(--accent)}
.mk-pg-actions .mk-ico[aria-pressed="true"] svg{fill:currentColor}
.mk-pg-seller{display:flex;align-items:center;gap:12px;margin-top:20px;padding:13px;background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r)}
.mk-pg-seller .mk-tx{flex:1;min-width:0}
.mk-pg-seller .mk-nm{display:block;font-size:14px;font-weight:500}
.mk-pg-seller .mk-mt{display:block;font-size:12px;color:var(--mk-ink-3)}
.mk-pg-spec{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--mk-line);border:1px solid var(--mk-line);border-radius:var(--mk-r-ctl);overflow:hidden;margin-top:16px}
.mk-pg-spec div{background:var(--mk-panel);padding:10px 12px}
.mk-pg-spec .mk-k{display:block;font-size:12px;color:var(--mk-ink-3)}
.mk-pg-spec .mk-v{display:block;font-family:var(--mono);font-size:12.5px;font-weight:500;margin-top:3px;color:var(--mk-ink)}
.mk-pg-desc{margin-top:16px;font-size:13.5px;line-height:1.65;color:var(--mk-ink-2);white-space:pre-wrap}

/* the fitment band — every one of your cars answered, not just the matches.
   A grid of only the hits cannot tell you the answer was checked. */
.mk-pg-band{padding:clamp(18px,2.6vw,30px);border-top:1px solid var(--mk-line);background:var(--mk-panel)}
.mk-pg-band + .mk-pg-band{background:var(--canvas)}
.mk-pg-band-hd{display:flex;align-items:baseline;gap:11px;margin-bottom:4px;flex-wrap:wrap}
.mk-pg-band-hd h3{font-size:16px}
.mk-pg-band-hd .mk-n{font-family:var(--mono);font-size:12px;color:var(--mk-ink-3)}
.mk-pg-band > p.mk-lede{font-size:13px;color:var(--mk-ink-2);margin:0 0 16px;max-width:70ch}
.mk-fitgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(196px,1fr));gap:10px}
.mk-fitcell{display:flex;align-items:center;gap:10px;padding:10px;border-radius:var(--mk-r);background:var(--mk-vwash);border:1px solid var(--mk-vline)}
.mk-fitcell .mk-tx{flex:1;min-width:0}
.mk-fitcell .mk-nm{display:block;font-size:13px;font-weight:500;color:var(--mk-vtext);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-fitcell .mk-mt{display:block;font-size:11.5px;color:var(--mk-vtext);opacity:.75;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-fitcell .mk-mark{flex:none;display:flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;background:var(--mk-vc);color:#fff}
.mk-fitcell--no{background:var(--mk-sunken);border-color:var(--mk-line);border-style:dashed}
.mk-fitcell--no .mk-vthumb{filter:grayscale(1);opacity:.45}
.mk-fitcell--no .mk-nm{color:var(--mk-ink-3);font-weight:400}
.mk-fitcell--no .mk-mt{color:var(--mk-ink-3);opacity:.7}
.mk-fitcell--no .mk-mark{background:none;color:var(--mk-ink-3);opacity:.6}
.mk-fitpill{display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 9px 0 5px;border-radius:var(--mk-r-pill);background:var(--mk-vc);color:#fff;font-size:10.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}
.mk-declared{display:flex;flex-wrap:wrap;gap:7px;margin-top:16px;padding-top:14px;border-top:1px solid var(--mk-line)}
.mk-declared .mk-lbl{font-size:12px;color:var(--mk-ink-3);align-self:center;margin-right:2px}
.mk-declared .mk-rng{display:inline-flex;align-items:center;gap:7px;padding:4px 10px;border-radius:var(--mk-r-pill);background:var(--mk-sunken);border:1px solid var(--mk-line);font-size:12.5px}
.mk-declared .mk-rng span{font-family:var(--mono);font-size:11.5px;color:var(--mk-ink-3)}
.mk-pg-more{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:12px;margin-top:4px}
@media(max-width:880px){
  .mk-pg{padding:0}
  .mk-pg-doc{max-width:none;border:0;border-radius:0}
  .mk-pg-top{grid-template-columns:minmax(0,1fr)}
  .mk-pg-spec{grid-template-columns:1fr}
}

/* ── THE SAME LISTING, AT ITS OWN ADDRESS ──────────────────────────────
   /parts/{slug} draws ams_listing_view() into #pg-part, and the sheet above
   fetches that same markup. So every rule for the listing's insides is written
   ONCE, unscoped, and both places read it — the trap this file already fell
   into with the card (see 02-card.php) and is not falling into twice. What
   differs is only the frame: the page has a crumb and a column, the sheet has
   a bar and a scroller. */
#pg-part .mk-pg-page{padding-bottom:40px}
#pg-part .mk-pg-top{padding:clamp(14px,2vw,24px) 0}
#pg-part .mk-pg-band{border-radius:var(--mk-r);border:1px solid var(--mk-line);margin-bottom:14px}
.mk-pg-crumb--page{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--mk-ink-3);margin:0 0 4px;flex-wrap:wrap}
.mk-pg-crumb--page a{display:inline-flex;align-items:center;gap:4px;color:var(--mk-ink-2)}
.mk-pg-crumb--page a:hover{color:var(--mk-ink)}
.mk-pg-crumb--page .mk-nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* A listing that is not live says so, to the one person who can see it. */
.mk-pg-flag{
  display:flex;align-items:center;gap:8px;margin:12px 0 0;padding:9px 11px;
  background:var(--accent-soft);border:1px solid var(--accent-line);border-radius:var(--mk-r-ctl);
  font-size:12.5px;color:var(--mk-ink-2);
}
.mk-pg-flag svg{flex:none;color:var(--accent)}
.mk-declared .mk-rng:hover{border-color:var(--mk-line-strong);color:var(--mk-ink)}
/* "Also fits your garage" — a row of small cards, not the full tile */
.mk-alsocard{
  display:flex;align-items:center;gap:10px;padding:9px;background:var(--mk-panel);
  border:1px solid var(--mk-line);border-radius:var(--mk-r);min-width:0;
  transition:border-color .12s ease,transform .1s ease;
}
.mk-alsocard:hover{border-color:var(--mk-line-strong);transform:translateY(-1px)}
.mk-alsoshot{
  position:relative;flex:none;width:52px;height:40px;border-radius:5px;overflow:hidden;
  background:var(--mk-sunken);border:1px solid var(--mk-line);
  display:flex;align-items:center;justify-content:center;color:var(--mk-plate);
}
.mk-alsoshot img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.mk-alsoshot svg{width:60%;height:60%}
.mk-alsotx{min-width:0;display:flex;flex-direction:column;gap:2px}
.mk-alsotx b{font-size:12.5px;font-weight:500;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.mk-alsopr{font-family:var(--mono);font-size:12.5px;color:var(--mk-ink-2)}
.mk-alsopr .mk-cur{font-size:.75em;color:var(--mk-ink-3)}

/* ── the message sheet ────────────────────────────────────────────────
   It opens a real conversation through the site's own messaging — there is no
   marketplace inbox, and a second one would be a second place a seller has to
   remember to look. */
.mk-scrim{position:fixed;inset:0 0 var(--floor-modal,0px) 0;z-index:var(--mk-z-dialog);background:rgba(12,12,16,.44);display:flex;align-items:center;justify-content:center;padding:20px;opacity:0;transition:opacity .16s ease}
.mk-scrim[hidden]{display:none}
.mk-scrim.mk-on{opacity:1}
.mk-sheet{width:100%;max-width:430px;background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r);box-shadow:var(--sh-lg);overflow:hidden;transform:scale(.96);transition:transform .16s var(--ease)}
.mk-scrim.mk-on .mk-sheet{transform:none}
.mk-sheet-hd{display:flex;align-items:center;gap:11px;padding:14px;border-bottom:1px solid var(--mk-line)}
.mk-thumb{position:relative;flex:none;width:46px;height:46px;border-radius:6px;overflow:hidden;background:var(--mk-sunken);border:1px solid var(--mk-line);display:flex;align-items:center;justify-content:center;color:var(--mk-plate)}
.mk-thumb img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.mk-thumb svg{width:70%;height:70%}
.mk-sheet-hd .mk-tx{flex:1;min-width:0}
.mk-sheet-hd .mk-nm{display:block;font-size:14px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-sheet-hd .mk-pr{font-family:var(--mono);font-size:12.5px;color:var(--mk-ink-2)}
.mk-sheet-bd{padding:14px}
.mk-sheet-to{display:flex;align-items:center;gap:9px;margin-bottom:11px}
.mk-sheet-err{display:none;font-size:12.5px;color:var(--mk-bad);margin:7px 0 0}
.mk-sheet-err.mk-on{display:block}
.mk-sheet-ft{display:flex;align-items:center;gap:9px;padding:12px 14px;border-top:1px solid var(--mk-line);background:var(--mk-sunken);flex-wrap:wrap}
.mk-sheet-ft .mk-note{flex:1;min-width:120px;font-size:11.5px;color:var(--mk-ink-3)}

/* the marketplace's own fields, in all three overlays and in the composer */
.mk-ov textarea,.mk-ov input[type=text],.mk-ov input[type=number],.mk-ov input[type=search]{
  width:100%;padding:9px 10px;font:inherit;font-size:13.5px;color:inherit;
  background:var(--mk-sunken);border:1px solid var(--mk-line);border-radius:var(--mk-r-ctl);
}
.mk-ov textarea{min-height:96px;resize:vertical}
.mk-ov textarea:focus,.mk-ov input:focus{outline:none;border-color:var(--accent);background:var(--mk-panel)}


/* ══ SELL A PART — a page over the app, not a tab in it ════════════════
   The composer at /post/part is still the address and still works with no
   bundle at all. This is the same act with the answer drawn beside it: the
   card as it will appear in Browse, and the honest count of how many cars in
   the member's own garage the fitment they have picked actually reaches.

   It sits BELOW the nav so the site's chrome is never covered, and above the
   admin bar's floor for the reason every sticky thing on this site does (§6). */
/* IT ENDS AT --floor-modal, NOT --floor. Its scrim covers the phone's tab
   bar, so leaving room for that bar holds a band of unusable navigation
   open under the sheet — 90px of scrimmed page on an operator's phone.
   What a scrim cannot cover is #adminbar (z-1900) and the home
   indicator, and --floor-modal is exactly those two (§6). */
.mk-sell{position:fixed;inset:var(--navh) 0 var(--floor-modal,0px) 0;z-index:var(--mk-z-sell);display:flex;flex-direction:column;background:var(--canvas);animation:mk-sellin .22s var(--ease)}
.mk-sell[hidden]{display:none}
@keyframes mk-sellin{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
/* THE HEAD IS flex:none ABOVE THE SCROLLER, so the form moves under it and the
   way out never scrolls off. The screen opened with no heading at all — a form
   that either creates a listing or overwrites a live one, giving no sign of
   which — and with its only exit at the bottom of a form taller than the
   window. The corner is where a person looks to leave a dialog; the footer is
   where the ACTIONS are, which is why Close is on both on a wide screen and
   only here on a phone.

   The BAR is full width and its CONTENTS line up with the form under it —
   --col and --pad are what the body is measured with, so a head that used the
   padding alone put the title at the window edge and the first field 180px in,
   which reads as two screens stacked rather than one. */
.mk-sellhd{
  flex:none;background:var(--mk-panel);border-bottom:1px solid var(--mk-line);
}
.mk-sellhd-in{
  display:flex;align-items:baseline;gap:11px;flex-wrap:wrap;
  max-width:var(--col);margin:0 auto;padding:13px var(--pad);
}
.mk-sellhd-t{font-size:16px;font-weight:600;margin:0;letter-spacing:-.01em}
.mk-sellhd-s{font-size:12.5px;color:var(--mk-ink-3)}
.mk-sellhd .mk-sp{flex:1}
.mk-sellhd-x{
  align-self:center;display:flex;align-items:center;justify-content:center;
  width:32px;height:32px;border-radius:var(--mk-r-ctl);
  border:1px solid var(--mk-line);background:var(--mk-panel);color:var(--mk-ink-2);cursor:pointer;
  transition:border-color .12s ease,color .12s ease,background .12s ease;
}
.mk-sellhd-x:hover{border-color:var(--mk-line-strong);color:var(--mk-ink);background:var(--mk-sunken)}
.mk-sellscroll{flex:1;overflow-y:auto}
.mk-sellbody{
  display:grid;grid-template-columns:minmax(0,1fr) 330px;gap:clamp(20px,3vw,44px);
  max-width:var(--col);margin:0 auto;padding:clamp(18px,2.6vw,30px) var(--pad) 60px;
}
.mk-sell-lede{font-size:13.5px;color:var(--mk-ink-2);margin:0 0 20px;max-width:64ch;line-height:1.6}

/* PROGRESS READS AS TWO THINGS, BECAUSE THEY ARE TWO THINGS: the part you
   cannot skip, and the part that only makes the listing work harder. One bar
   for both would make "done" and "could be better" look like the same state.

   Full-width bar, contents on the form's own column — the head's rule, for the
   head's reason: a progress bar starting at the window edge under a centred
   form reads as furniture belonging to something else. */
.mk-sellfoot{flex:none;background:var(--mk-panel);border-top:1px solid var(--mk-line)}
.mk-sellfoot-in{display:flex;align-items:center;gap:14px;max-width:var(--col);margin:0 auto;padding:11px var(--pad)}
/* The status takes what is left and truncates; the actions never shrink and
   never wrap apart from each other. */
.mk-sellfoot-in .mk-prog{flex:1 1 auto;min-width:0}
.mk-sellfoot-acts{flex:none;display:flex;align-items:center;gap:10px}
.mk-prog{display:flex;align-items:center;gap:11px;min-width:0}
.mk-prog-track{display:flex;align-items:center;gap:5px;flex:none}
.mk-prog-seg{height:5px;border-radius:2px;background:var(--mk-sunken);overflow:hidden}
.mk-prog-seg.mk-req{width:46px}
.mk-prog-seg.mk-opt{width:104px}
.mk-prog-seg i{display:block;height:100%;width:0;border-radius:2px;transition:width .32s var(--ease)}
.mk-prog-seg.mk-req i{background:var(--accent)}
.mk-prog-seg.mk-req.mk-done i{background:var(--mk-good)}
.mk-prog-seg.mk-opt i{background:var(--mk-ink-3)}
.mk-prog-tx{font-size:12.5px;color:var(--mk-ink-3);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-prog-tx b{color:var(--mk-ink);font-weight:600}
.mk-prog-tx .mk-ok{color:var(--mk-good)}

/* ── sections that open and close ─────────────────────────────────── */
.mk-acc{position:relative;background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r);margin-bottom:12px;box-shadow:var(--sh-sm)}
.mk-acc-hd{display:flex;align-items:center;gap:11px;width:100%;padding:13px 14px;border:0;background:none;cursor:pointer;text-align:left;font:inherit;border-radius:var(--mk-r);color:var(--mk-ink)}
.mk-acc-hd:hover{background:var(--mk-sunken)}
.mk-acc.mk-open .mk-acc-hd{border-bottom:1px solid var(--mk-line);border-radius:var(--mk-r) var(--mk-r) 0 0}
.mk-acc-n{flex:none;display:flex;align-items:center;justify-content:center;width:22px;height:22px;border:1px solid var(--mk-line-strong);border-radius:var(--mk-r-sm);font-family:var(--mono);font-size:11px;color:var(--mk-ink-3)}
.mk-acc-n.mk-done{background:var(--mk-good);border-color:var(--mk-good);color:#fff}
.mk-acc-n:empty{border-style:dashed}
.mk-acc-t{flex:1;min-width:0;font-family:var(--dis);font-size:15px;font-weight:600;letter-spacing:-.015em}
.mk-acc-sum{display:block;font-family:var(--ui);font-size:12.5px;font-weight:400;letter-spacing:0;color:var(--mk-ink-3);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-acc-opt,.mk-acc-req{flex:none;font-size:10px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;border:1px solid var(--mk-line);border-radius:var(--mk-r-sm);padding:2px 6px;color:var(--mk-ink-3)}
.mk-acc-req{background:var(--accent);border-color:var(--accent);color:var(--accent-on)}
/* the one section you cannot skip carries the accent down its edge */
.mk-acc--req{border-color:color-mix(in srgb,var(--accent) 34%,var(--mk-line));overflow:hidden}
.mk-acc--req::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--accent)}
.mk-acc--req .mk-acc-hd,.mk-acc--req .mk-acc-bd{padding-left:17px}
.mk-acc-cv{flex:none;color:var(--mk-ink-3);transition:transform .2s var(--ease)}
.mk-acc.mk-open .mk-acc-cv{transform:rotate(180deg)}
.mk-acc-bd{display:none;padding:16px 14px 18px}
.mk-acc.mk-open .mk-acc-bd{display:block}

.mk-fld{margin-bottom:18px}
.mk-fld:last-child{margin-bottom:0}
.mk-fld > label,.mk-fld-lbl{display:block;font-size:13px;font-weight:500;margin-bottom:3px}
.mk-fld .mk-help{display:block;font-size:12.5px;color:var(--mk-ink-3);margin-bottom:9px;max-width:60ch;line-height:1.5}
.mk-fld-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:12px}
.mk-errline{font-size:12.5px;color:var(--mk-bad);margin:10px 0 0}
.mk-errline:empty{display:none}

/* ── the live preview, and the reach it reports ───────────────────── */
.mk-pv{position:sticky;top:clamp(14px,2vw,22px);align-self:start;max-height:calc(100vh - var(--navh) - 130px);overflow-y:auto;overscroll-behavior:contain}
.mk-pv-lbl{display:flex;align-items:center;gap:9px;font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--mk-ink-3);margin:0 0 11px;font-weight:600}
.mk-pv-lbl::after{content:"";flex:1;height:1px;background:var(--mk-line)}
.mk-pv-note{font-size:12px;color:var(--mk-ink-3);margin:12px 0 0;line-height:1.6}
.mk-pv-reach{margin-top:14px;padding:12px 13px;background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r)}
.mk-pv-reach .mk-k{font-size:11.5px;color:var(--mk-ink-3)}
.mk-pv-reach .mk-v{display:flex;align-items:baseline;gap:6px;margin-top:4px}
.mk-pv-reach .mk-v b{font-family:var(--mono);font-size:22px;font-weight:500}
.mk-pv-reach .mk-v span{font-size:12.5px;color:var(--mk-ink-2)}
.mk-pv-sil{display:flex;gap:5px;margin-top:10px;flex-wrap:wrap}
@media(max-width:980px){
  .mk-sellbody{grid-template-columns:minmax(0,1fr)}
  .mk-pv{position:static;max-width:340px;max-height:none}
}

/* ── the action bar on a phone ────────────────────────────────────────
   Three buttons and a progress line wrapped onto two ragged rows and took
   155px of an 844px screen — a fifth of the phone, with Publish orphaned at
   the left of its own line and the status sentence clipped mid-word.

   So on a phone it becomes what an action bar on a phone is: the status on
   its own line, then ONE full-width primary action. Close is dropped here
   and nowhere else — the head's × is on screen the whole time and is the
   exit people reach for; keeping a second one beside Publish is how a
   mis-tap ends a listing somebody was still writing. Save draft stays,
   because abandoning a half-written listing is the thing a phone gets
   interrupted into doing. */
@media(max-width:620px){
  .mk-sellfoot-in{flex-wrap:wrap;gap:9px;padding:10px var(--pad)}
  .mk-sellfoot-in .mk-prog{flex:1 0 100%}
  .mk-sellfoot-acts{flex:1 0 100%}
  .mk-sellfoot-acts #mk-sell-x{display:none}
  .mk-sellfoot-acts #mk-publish{flex:1;justify-content:center}
}

/* ── the fitment picker, the heart of the composer ────────────────── */
.mk-fitpick{display:grid;grid-template-columns:repeat(auto-fill,minmax(168px,1fr));gap:10px}
.mk-fitopt{
  position:relative;display:flex;align-items:center;gap:10px;padding:9px 10px;cursor:pointer;
  background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r);text-align:left;color:var(--mk-ink);
  transition:border-color .14s ease,background .14s ease,transform .1s ease;
}
.mk-fitopt:hover{transform:translateY(-1px);border-color:var(--mk-vline)}
.mk-fitopt[aria-pressed="true"]{background:var(--mk-vwash);border-color:var(--mk-vc);box-shadow:0 0 0 1px var(--mk-vc)}
.mk-fitopt .mk-tx{flex:1;min-width:0}
.mk-fitopt .mk-nm{display:block;font-size:13px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-fitopt .mk-mt{display:block;font-size:11.5px;color:var(--mk-ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mk-fitopt[aria-pressed="true"] .mk-nm{color:var(--mk-vtext)}
.mk-fitopt[aria-pressed="true"] .mk-mt{color:var(--mk-vtext);opacity:.75}
.mk-fitopt .mk-tick{position:absolute;right:8px;top:8px;width:17px;height:17px;border-radius:50%;background:var(--mk-vc);color:#fff;display:none;align-items:center;justify-content:center}
.mk-fitopt[aria-pressed="true"] .mk-tick{display:flex}
.mk-fitcustom{margin-top:14px;padding:13px;border:1px dashed var(--mk-line-strong);border-radius:var(--mk-r)}
.mk-fitcustom h4{font-size:13px;font-weight:500;margin:0 0 3px}
.mk-fitcustom p{font-size:12.5px;color:var(--mk-ink-3);margin:0 0 11px;line-height:1.5}
.mk-fitcustom label{display:block;font-size:11.5px;color:var(--mk-ink-3);margin-bottom:4px}
.mk-customlist{display:flex;flex-wrap:wrap;gap:6px;margin-top:11px}
.mk-customlist:empty{display:none}
.mk-customlist .mk-chip{display:inline-flex;align-items:center;gap:2px;height:27px;padding:0 4px 0 10px;border:1px solid var(--mk-line-strong);border-radius:var(--mk-r-pill);background:var(--mk-panel);font-size:12px}
.mk-customlist .mk-chip .mk-k{color:var(--mk-ink-3);margin-left:5px}
.mk-customlist .mk-chip button{display:flex;align-items:center;justify-content:center;width:19px;height:19px;border:0;border-radius:50%;background:none;color:var(--mk-ink-3);cursor:pointer}
.mk-statement{display:flex;gap:11px;padding:13px 14px;margin-top:18px;background:var(--mk-sunken);border:1px solid var(--mk-line);border-radius:var(--mk-r)}
.mk-statement .mk-ic{flex:none;color:var(--mk-ink-3);margin-top:1px}
.mk-statement .mk-tx{font-size:13px;line-height:1.6;color:var(--mk-ink-2)}
.mk-statement .mk-tx b{color:var(--mk-ink);font-weight:500}
.mk-statement .mk-tx em{font-style:normal;color:var(--mk-ink-3)}

.mk-catpick{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px}
.mk-catopt{
  display:flex;align-items:center;gap:9px;padding:10px;cursor:pointer;text-align:left;
  background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r-ctl);
  font-size:12.5px;color:var(--mk-ink-2);transition:border-color .12s ease,background .12s ease,transform .1s ease;
}
.mk-catopt:hover{transform:translateY(-1px);border-color:var(--mk-line-strong);color:var(--mk-ink)}
.mk-catopt svg{flex:none;color:var(--mk-ink-3)}
.mk-catopt[aria-pressed="true"]{background:var(--accent-soft);border-color:var(--accent);color:var(--mk-ink);font-weight:500}
.mk-catopt[aria-pressed="true"] svg{color:var(--accent)}

.mk-condseg{display:flex;flex-wrap:wrap;gap:7px}
.mk-condseg button{height:34px;padding:0 13px;border:1px solid var(--mk-line);border-radius:var(--mk-r-pill);background:var(--mk-panel);cursor:pointer;font-size:13px;color:var(--mk-ink-2)}
.mk-condseg button:hover{border-color:var(--mk-line-strong);color:var(--mk-ink)}
.mk-condseg button[aria-pressed="true"]{background:var(--mk-ink);border-color:var(--mk-ink);color:var(--canvas);font-weight:500}

.mk-photoslots{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:8px;margin-top:10px}
.mk-pslot{position:relative;aspect-ratio:4/3;border:1px dashed var(--mk-line-strong);border-radius:var(--mk-r-ctl);background:var(--mk-sunken);display:flex;align-items:center;justify-content:center;color:var(--mk-ink-3);cursor:pointer;overflow:hidden}
.mk-pslot:hover{border-color:var(--mk-ink-3);color:var(--mk-ink-2)}
.mk-pslot.mk-filled{border-style:solid;border-color:var(--mk-line);background:var(--mk-panel)}
.mk-pslot img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.mk-pslot .mk-rm{position:absolute;right:4px;top:4px;z-index:2;width:20px;height:20px;border-radius:50%;background:var(--mk-panel);border:1px solid var(--mk-line);color:var(--mk-ink-3);cursor:pointer;display:flex;align-items:center;justify-content:center}
.mk-pslot.mk-busy{opacity:.55;pointer-events:none}
/* the bar under a slot whose photo is still going up — --mk-pct is written on
   the tile by the renderer, so nothing here has to know how far it got */
.mk-pbar{position:absolute;left:0;right:0;bottom:0;height:3px;background:rgba(0,0,0,.16);border-radius:0 0 8px 8px;overflow:hidden}
.mk-pbar > i{display:block;height:100%;width:var(--mk-pct,0%);background:var(--accent);transition:width .15s linear}

/* ── listing strength: what actually makes a listing findable ─────── */
.mk-strength{margin-top:16px;padding:14px;background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r)}
.mk-strength-hd{display:flex;align-items:baseline;gap:8px;margin-bottom:9px}
.mk-strength-hd b{font-size:13px;font-weight:500}
.mk-strength-hd .mk-pct{font-family:var(--mono);font-size:13px;margin-left:auto;font-weight:500}
.mk-strength-bar{height:5px;border-radius:3px;background:var(--mk-sunken);overflow:hidden}
.mk-strength-bar i{display:block;height:100%;border-radius:3px;background:var(--accent);transition:width .3s var(--ease)}
.mk-strength-bar i.mk-good{background:var(--mk-good)}
.mk-strength-list{margin:12px 0 0;display:flex;flex-direction:column;gap:7px}
.mk-sitem{display:flex;align-items:flex-start;gap:8px;font-size:12.5px;color:var(--mk-ink-3);line-height:1.45}
.mk-sitem .mk-mk{flex:none;display:flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;border:1px solid var(--mk-line-strong);color:var(--mk-ink-3);margin-top:1px}
.mk-sitem.mk-on{color:var(--mk-ink-2)}
.mk-sitem.mk-on .mk-mk{background:var(--mk-good);border-color:var(--mk-good);color:#fff}
.mk-sitem b{color:var(--mk-ink);font-weight:500}

/* ══ the selling table ═════════════════════════════════════════════════ */
#pg-parts .mk-mine{padding:20px 0 40px;max-width:1080px}
#pg-parts .mk-mine-hd{display:flex;align-items:flex-start;gap:14px;margin-bottom:18px;flex-wrap:wrap}
#pg-parts .mk-mine-hd h2{font-size:clamp(17px,2vw,21px)}
#pg-parts .mk-mine-hd p{font-size:13px;color:var(--mk-ink-2);margin:3px 0 0;max-width:52ch}
#pg-parts .mk-mine-hd .mk-btn{margin-left:auto}
#pg-parts .mk-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;margin-bottom:18px}
#pg-parts .mk-scell{background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r);padding:11px 13px;box-shadow:var(--sh-sm)}
#pg-parts .mk-scell .mk-k{display:block;font-size:11.5px;color:var(--mk-ink-3)}
#pg-parts .mk-scell .mk-v{display:block;font-family:var(--mono);font-size:21px;font-weight:500;margin-top:3px}
#pg-parts .mk-stable{background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r);overflow:hidden;box-shadow:var(--sh-sm)}
#pg-parts .mk-strow{display:grid;grid-template-columns:minmax(0,1fr) 140px 100px 56px 56px 72px 78px 78px 40px;align-items:center;gap:10px;padding:9px 13px;border-bottom:1px solid var(--mk-line)}
#pg-parts .mk-strow:last-child{border-bottom:0}
#pg-parts .mk-stable > div > .mk-strow:hover{background:var(--mk-sunken)}
#pg-parts .mk-sthead{background:var(--mk-sunken);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--mk-ink-3);font-weight:600}
#pg-parts .mk-sthead:hover{background:var(--mk-sunken)}
#pg-parts .mk-sitem-row{display:flex;align-items:center;gap:10px;min-width:0;background:none;border:0;padding:0;cursor:pointer;text-align:left;color:var(--mk-ink)}
#pg-parts .mk-sitem-row .mk-thumb{width:42px;height:32px;border-radius:5px}
#pg-parts .mk-stt{min-width:0}
#pg-parts .mk-stt b{display:block;font-size:13px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#pg-parts .mk-stt small{display:block;font-size:11px;color:var(--mk-ink-3);font-family:var(--mono)}
#pg-parts .mk-fitmini{display:flex;gap:4px;flex-wrap:wrap}
#pg-parts .mk-fitmini .mk-none{font-size:11.5px;color:var(--mk-ink-3)}
#pg-parts .mk-sprice{height:30px;padding:0 8px;font-family:var(--mono);font-size:13px;background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:6px;width:100%}
#pg-parts .mk-smetric{font-family:var(--mono);font-size:13px;text-align:right;color:var(--mk-ink-2)}
#pg-parts .mk-smetric.mk-hot{color:var(--accent);font-weight:500}
#pg-parts .mk-sstate{font-size:11.5px;color:var(--mk-ink-3);text-align:right}
#pg-parts .mk-sedit{
  display:inline-flex;align-items:center;justify-content:center;gap:5px;
  height:28px;padding:0 9px;border:1px solid var(--mk-line);border-radius:var(--mk-r-ctl);
  background:var(--mk-panel);cursor:pointer;font-size:12px;color:var(--mk-ink-2);
  transition:border-color .12s ease,color .12s ease,background .12s ease;
}
#pg-parts .mk-sedit:hover{border-color:var(--mk-line-strong);color:var(--mk-ink);background:var(--mk-sunken)}
/* THE COLUMN COUNT AND THE HIDE CLASSES ARE ONE DECISION. NINE cells are
   drawn; each breakpoint hides some and the grid has to name exactly what is
   left, or the row silently shifts one cell along — a Status under the Price
   heading, which reads as data being wrong rather than as a layout bug. The
   ninth is the ··· menu, and adding it without adding a column is exactly
   what this comment warned about: the cell wrapped to a line of its own and
   sat under the row, which looks like a stray control rather than a grid one
   short. The HEAD carries an empty span for it, because a header with one
   fewer cell than its rows is the same bug from the other end. */
@media(max-width:1000px){                        /* drops Saves → eight */
  #pg-parts .mk-strow{grid-template-columns:minmax(0,1fr) 120px 96px 52px 64px 74px 74px 38px}
  #pg-parts .mk-s-md{display:none}
}
@media(max-width:760px){                         /* drops Views, Offers and Fits → five */
  #pg-parts .mk-strow{grid-template-columns:minmax(0,1fr) 88px 68px 44px 38px}
  #pg-parts .mk-s-sm,#pg-parts .mk-s-fit{display:none}
  /* the word goes, the glyph and its accessible name stay */
  #pg-parts .mk-sedit span{display:none}
  #pg-parts .mk-sedit{padding:0;justify-content:center}
}


/* ══ OFFERS ════════════════════════════════════════════════════════════
   The rows a seller reads, and the one line a buyer gets back about their own.
   Unscoped like the rest of the listing view: this is drawn at /parts/{slug}
   AND in the sheet over the grid, which are two different ancestors. */
.mk-offers{display:flex;flex-direction:column;gap:8px}
.mk-offer{
  display:flex;align-items:center;gap:10px;padding:10px 11px;flex-wrap:wrap;
  background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r);
}
.mk-offer--pending{border-color:var(--accent-line);background:var(--accent-soft)}
.mk-offer--declined,.mk-offer--withdrawn{opacity:.62}
.mk-otx{flex:1;min-width:120px;display:flex;flex-direction:column;gap:2px}
.mk-onm{font-size:13px;font-weight:500}
.mk-onm i{font-style:normal;font-weight:400;color:var(--mk-ink-3)}
.mk-omsg{font-size:12.5px;color:var(--mk-ink-2);line-height:1.5}
.mk-oamt{flex:none;font-family:var(--mono);font-size:17px;font-weight:500;letter-spacing:-.02em}
.mk-oamt i{font-style:normal;font-size:.7em;color:var(--mk-ink-3);margin-left:3px}
.mk-oact{flex:none;display:flex;gap:6px;flex-wrap:wrap}
.mk-ostate{flex:none;font-size:11.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--mk-ink-3)}
.mk-offer--accepted .mk-ostate{color:var(--mk-good)}

/* The offer YOU made, said back to you. It is a strip and not a button,
   because there is nothing to press while it is with the seller — except
   taking it back, which is the one control on it. */
.mk-myoffer{
  display:flex;align-items:center;gap:9px;margin-top:12px;padding:9px 11px;
  border:1px solid var(--mk-line);border-radius:var(--mk-r-ctl);
  background:var(--mk-sunken);font-size:12.5px;color:var(--mk-ink-2);flex-wrap:wrap;
}
.mk-myoffer .mk-tx{flex:1;min-width:0}
.mk-myoffer b{font-family:var(--mono);color:var(--mk-ink)}
.mk-myoffer svg{flex:none;color:var(--mk-ink-3)}
.mk-myoffer--accepted{background:var(--green-soft);border-color:var(--green-line)}
.mk-myoffer--accepted svg{color:var(--mk-good)}
.mk-myoffer--pending svg{color:var(--accent)}

/* the amount, typed with the currency mark alongside rather than inside */
.mk-offamt{display:flex;align-items:center;gap:6px}
.mk-offamt > span{font-family:var(--mono);font-size:20px;color:var(--mk-ink-3)}
.mk-offamt input{font-family:var(--mono);font-size:20px;height:44px}
.mk-offscrim .mk-sheet-hd{align-items:flex-start}
.mk-offscrim .mk-help{margin:8px 0 0}

/* ══ the questions, which are the site's own comment thread ═══════════
   .fc-cmts brings its own rules from 20-feed-card.php. All this does is give
   it the room the band's padding would otherwise not leave it. */
.mk-pg-qa .fc-cmts{margin-top:10px}

/* ══ the verbs on a Selling row ═══════════════════════════════════════ */
#pg-parts .mk-smenu-wrap{display:flex;justify-content:flex-end}
#pg-parts .mk-smenu-btn{
  display:inline-flex;align-items:center;justify-content:center;
  width:30px;height:28px;border:1px solid transparent;border-radius:var(--mk-r-ctl);
  background:none;cursor:pointer;color:var(--mk-ink-3);
}
#pg-parts .mk-smenu-btn:hover,#pg-parts .mk-smenu-btn[aria-expanded="true"]{
  border-color:var(--mk-line);color:var(--mk-ink);background:var(--mk-panel);
}
/* LIFTED TO THE BODY. The table clips its own overflow, which is what cut the
   feed's panels down to a strip before they were floated out — same mechanism,
   same reason (js/06b-feed/06-float.php). */
.mk-smenu{
  position:fixed;z-index:80;min-width:190px;padding:5px;
  background:var(--mk-panel);border:1px solid var(--mk-line);border-radius:var(--mk-r);
  box-shadow:var(--sh-lg);display:flex;flex-direction:column;gap:1px;
}
.mk-smenu button,.mk-smenu a{
  display:flex;align-items:center;gap:9px;width:100%;padding:8px 9px;
  border:0;border-radius:var(--mk-r-ctl);background:none;cursor:pointer;
  text-align:left;font-size:13px;color:var(--mk-ink-2);
}
.mk-smenu button:hover,.mk-smenu a:hover{background:var(--mk-sunken);color:var(--mk-ink)}
.mk-smenu svg{flex:none;color:var(--mk-ink-3)}

/* ══ the photographs: which one leads ═════════════════════════════════ */
.mk-pslot.mk-cover{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}
.mk-coverflag{
  position:absolute;left:4px;top:4px;z-index:2;padding:1px 6px;border-radius:var(--mk-r-sm);
  background:var(--accent);color:var(--accent-on);
  font-size:9.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;
}
.mk-pmove{
  position:absolute;left:0;right:0;bottom:0;z-index:2;display:flex;justify-content:center;gap:2px;
  padding:3px;background:linear-gradient(transparent,rgba(12,11,10,.62));
  opacity:0;transition:opacity .12s ease;
}
.mk-pslot:hover .mk-pmove,.mk-pslot:focus-within .mk-pmove{opacity:1}
.mk-pmove button{
  display:flex;align-items:center;justify-content:center;width:22px;height:22px;
  border:0;border-radius:var(--mk-r-sm);background:rgba(255,255,255,.92);color:#0A0A0C;cursor:pointer;
}
.mk-pmove button:hover{background:#fff}
/* A touch screen has no hover, so the controls are simply always there. */
@media(hover:none){ .mk-pmove{opacity:1} }

/* ══ the featured band ════════════════════════════════════════════════
   It says what it is. A promoted row that reads as an ordinary result is the
   thing a marketplace loses trust over — and it never wears the fitment
   green, which is the feed's own rule about its sponsored slot. */
#pg-parts .mk-featsect{margin-bottom:clamp(22px,2.8vw,34px)}
#pg-parts .mk-feathd{
  display:flex;align-items:center;gap:9px;margin:0 0 11px;
  font-size:10.5px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--mk-ink-3);
}
#pg-parts .mk-feathd svg{color:var(--accent)}
#pg-parts .mk-feathd .mk-rule{flex:1;height:1px;background:var(--mk-line)}
#pg-parts .mk-feathd .mk-n{font-family:var(--mono);font-size:11px}


/* ════════════════════════════════════════════════════════════════════════
   LOG A MOD — the sheet.  Markup: views/app/mod-composer.php
                           Behaviour: views/app/js/07g-mod-composer/

   IT DEFINES NO COLOUR OF ITS OWN THAT THE SITE ALREADY PUBLISHES. Every
   --mc-* below resolves to a :root token, for the reason the hover card gives:
   the accent is operator-configurable from the Appearance screen, and a sheet
   carrying #EA580C would be the one orange thing on the site that did not move
   when somebody repainted it.

   The two exceptions are red and amber, and they are exceptions because :root
   does not publish them — --danger and --warn exist only inside .mdp,
   #pg-catalogue and .su, which are page shells this sheet opens on top of
   rather than inside. They are written as var(--danger, <the value .mdp uses>),
   so the day the ladder grows a root red this picks it up and the literal
   stops being read. Do not spell either of them out again anywhere in here.
   ════════════════════════════════════════════════════════════════════════ */
.mc{
  --mc-panel:var(--surface); --mc-sunken:var(--surface2);
  --mc-line:var(--border); --mc-line2:var(--border2);
  --mc-ink:var(--text); --mc-ink2:var(--t2); --mc-ink3:var(--t3);
  --mc-acc:var(--accent); --mc-acc-ink:var(--accent-fg);
  --mc-acc-wash:var(--accent-soft); --mc-acc-line:var(--accent-line);
  --mc-ok:var(--green); --mc-ok-wash:var(--green-soft);
  --mc-err:var(--danger,#B4342C); --mc-err-wash:var(--danger-wash,#FBEBE9); --mc-err-line:var(--danger-line,#F3C4BF);
  --mc-warn:var(--warn,#A8630C); --mc-warn-wash:var(--warn-wash,#FDF1E0); --mc-warn-line:var(--warn-line,#EED6AB);
}
body.dark .mc{
  --mc-err:var(--danger,#E2766C); --mc-err-wash:var(--danger-wash,rgba(226,118,108,.13)); --mc-err-line:var(--danger-line,rgba(226,118,108,.32));
  --mc-warn:var(--warn,#D99A4A); --mc-warn-wash:var(--warn-wash,rgba(217,154,74,.13)); --mc-warn-line:var(--warn-line,rgba(217,154,74,.32));
}

/* ── the shell ─────────────────────────────────────────────────────────────
   IT SETTLES WITH NO TRANSFORM, AND THAT IS STRUCTURAL RATHER THAN TIDY.
   A transformed element becomes the containing block for every `position:fixed`
   descendant, and the three dropdowns are the site's own themed select, whose
   popover is fixed and positioned from `getBoundingClientRect()` — i.e. in
   VIEWPORT coordinates. Centred with `translate(-50%,-50%)` the sheet was
   offset by -310px, so every list opened 331px to the right of the button that
   opened it: visible only by measuring, which is what test/mod-composer.js
   does. It is the same failure that put the feed's own panels ~5,800px down the
   page (views/app/js/06b-feed/06-float.php) and that the marketplace's three
   overlays are children of <body> to avoid.

   So the centring is `inset` + `margin:auto`, which needs no transform, and the
   entrance is an ANIMATION with no fill mode — it interpolates FROM a shifted,
   slightly small state to the element's own computed style, and when it ends
   the computed transform is `none` again. A transition cannot do that: there is
   no way to transition TO `none`, and `transform:translate(0,0)` still creates
   a containing block.

   The z-order is the marketplace's ladder (--mk-z-*, 1300-1320): above the chat
   dock's 1250, which otherwise floats its New-message bubble over the Publish
   button on a phone, and below the admin bar's 1900, which the sheet never
   reaches because it stops at --floor. */
.mc-scrim{position:fixed;inset:0;z-index:1300;background:rgba(10,12,16,.5);
  backdrop-filter:blur(3px);opacity:0;transition:opacity .24s var(--ease)}
.mc-scrim.on{opacity:1}
/* IT ENDS AT --floor-modal, NOT --floor. Its scrim covers the phone's tab
   bar, so leaving room for that bar holds a band of unusable navigation
   open under the sheet — 90px of scrimmed page on an operator's phone.
   What a scrim cannot cover is #adminbar (z-1900) and the home
   indicator, and --floor-modal is exactly those two (§6). */
.mc-sheet{position:fixed;inset:0 0 var(--floor-modal,0px) 0;margin:auto;z-index:1310;
  width:min(620px,calc(100vw - 40px));
  height:fit-content;
  max-height:min(880px,calc(100vh - 72px - var(--floor-modal,0px)));
  display:flex;flex-direction:column;
  background:var(--surface);border:1px solid var(--border);border-radius:16px;
  box-shadow:var(--sh-lg);
  opacity:0;transition:opacity .2s var(--ease)}
.mc-sheet.on{opacity:1;animation:mc-in .24s var(--ease)}
@keyframes mc-in{from{opacity:0;transform:translateY(10px) scale(.985)}}
.mc{position:relative;display:flex;flex-direction:column;min-height:0;flex:1}
body.mc-locked{overflow:hidden}

/* ── head ──────────────────────────────────────────────────────────────── */
.mc-head{display:flex;align-items:center;gap:12px;padding:14px 12px 14px 17px;
  border-bottom:1px solid var(--mc-line);flex-shrink:0}
.mc-htxt{display:flex;flex-direction:column;gap:1px;min-width:0;flex-shrink:1}
.mc-head h3{margin:0;font-family:var(--dis);font-size:15.5px;font-weight:600;
  letter-spacing:-.022em;color:var(--mc-ink);white-space:nowrap}
.mc-head small{font-size:11.5px;color:var(--mc-ink3);line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mc-req{display:inline-flex;align-items:center;gap:7px;height:26px;padding:0 11px;border-radius:999px;flex-shrink:1;
  background:var(--mc-err-wash);border:1px solid var(--mc-err-line);font-size:11.5px;font-weight:600;
  color:var(--mc-err);white-space:nowrap;min-width:0;overflow:hidden;text-overflow:ellipsis;
  transition:background .2s,border-color .2s,color .2s}
.mc-req .mc-d{width:6px;height:6px;border-radius:50%;background:currentColor;flex-shrink:0}
/* THE ELLIPSIS BELONGS TO THE TEXT, NOT TO THE PILL. text-overflow acts on a
   box's own inline content, and this pill's content is a <span> — so with the
   rule only on the pill a squeezed sentence was CLIPPED rather than trimmed,
   and ran out over the title and the close button beside it. */
.mc-req > span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.mc-req.ready{background:var(--mc-ok-wash);border-color:color-mix(in srgb,var(--mc-ok) 38%,transparent);color:var(--mc-ok)}
/* THE WAY BACK. Same 30px target as the close button, and it sits at the head
   of the row rather than beside it — a back arrow anywhere but the leading edge
   reads as one more verb instead of the way out of a step. The negative margin
   is optical only: .mc-head's 17px left padding is set for TEXT, and a centred
   glyph inside a 30px box needs the box to overhang it to line the arrow up
   with the title's own left edge. It is hidden unless the chooser handed off,
   so a head with no way back is laid out exactly as it always was. */
.mc-back{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;
  color:var(--mc-ink3);flex-shrink:0;margin-left:-7px;margin-right:-4px;border:0;background:none;
  cursor:pointer;transition:background .14s,color .14s}
.mc-back:hover{background:var(--mc-sunken);color:var(--mc-ink)}
.mc-x{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;
  color:var(--mc-ink3);flex-shrink:0;margin-left:auto;border:0;background:none;cursor:pointer;
  transition:background .14s,color .14s}
.mc-x:hover{background:var(--mc-sunken);color:var(--mc-ink)}

/* ── the vehicle bar: full width, expands in place ─────────────────────── */
.mc-vbar{position:relative;z-index:30;flex-shrink:0;border-bottom:1px solid var(--mc-line);
  background:var(--mc-sunken)}
.mc-vbtn{display:flex;align-items:center;gap:13px;width:100%;padding:13px 16px;text-align:left;
  border:0;background:none;cursor:pointer;color:inherit;font:inherit;transition:background .16s}
.mc-vbtn:hover{background:color-mix(in srgb,var(--mc-panel) 55%,transparent)}
.mc-vt{width:46px;height:35px;border-radius:8px;flex-shrink:0;border:1px solid var(--mc-line);
  background:var(--mc-panel) center/cover no-repeat;
  display:flex;align-items:center;justify-content:center;color:var(--mc-ink3)}
.mc-vt.has{border-color:transparent}
/* NO CAR IS AN EMPTY SLOT, NOT A PICTURE OF A CAR. The design draws the
   unchosen thumbnail as `t none` — a dashed rectangle with nothing in it, so
   the tile reads as somewhere a photograph is going to go. Ours put the family
   car glyph in a solid box, which reads as a vehicle that has been chosen and
   simply has no photo — the one thing the empty bar must not look like, since
   that state exists three inches away for a car with no picture. */
.mc-vt.none{border-style:dashed;background:var(--mc-panel)}
.mc-vt.has .ic,.mc-vt.none .ic{display:none}
.mc-vc{flex:1;min-width:0}
.mc-vc b{display:block;font-size:14px;font-weight:600;letter-spacing:-.018em;color:var(--mc-ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mc-vc small{display:block;font-size:11.5px;color:var(--mc-ink3);margin-top:1px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mc-cv{opacity:.5;flex-shrink:0;transition:transform .2s var(--ease)}
.mc-vbar.on .mc-cv{transform:rotate(180deg)}
/* NOTHING CHOSEN — the one state that has to argue for itself.
   THE MODIFIER IS `mc-empty`, NEVER A BARE `empty`. There is a global
   `.empty` in css/05-vehicle-spine-and-part-detail.php — centred text, 40px of
   padding, a 1.5px dashed border and a big radius — and the bar was picking
   the whole declaration up the moment it went empty: 150px tall against the
   design's 69, wearing a rounded dashed outline nothing here asked for. The
   design's own class is `.vbar.empty`, so this is a name that is safe inside
   a prototype and unsafe inside a site. It is the share sheet's `.fit`/`.shs-on`
   lesson exactly (see css/20b-share-sheet.php), and the reason every modifier
   in this file carries the prefix. Two bare names survive on purpose because
   they were measured and leak nothing that shows: `.sel` (a global in
   04-shop-by-vehicle-bar) and `.live` (one in 00-tokens-and-buttons) each hand
   over `position:relative` and are then out-specified here. If either global
   ever grows a box property, they become this bug again — check them before
   trusting that sentence. */
.mc-vbar.mc-empty{background:var(--mc-acc-wash);box-shadow:inset 3px 0 0 var(--mc-acc)}
.mc-vbar.mc-empty .mc-vc b,.mc-vbar.mc-empty .mc-vc small{color:var(--mc-acc-ink)}
.mc-vbar.mc-empty .mc-vc small{opacity:.8}
.mc-vbar.mc-empty .mc-cv{opacity:.8;color:var(--mc-acc-ink)}
.mc-vbar.on{background:var(--mc-panel)}
.mc-vbar.on .mc-vbtn{box-shadow:inset 0 -1px 0 var(--mc-line)}
.mc-vlist{position:absolute;left:0;right:0;top:100%;z-index:60;display:none;padding:6px;
  background:var(--mc-panel);border:1px solid var(--mc-line);border-top:0;border-radius:0 0 13px 13px;
  box-shadow:var(--sh);max-height:262px;overflow-y:auto}
.mc-vbar.on .mc-vlist{display:block;animation:mcdrop .16s var(--ease)}
@keyframes mcdrop{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.mc-vopt{display:flex;align-items:center;gap:12px;width:100%;padding:9px 10px;border-radius:9px;
  text-align:left;font-size:14px;color:var(--mc-ink2);border:0;background:none;cursor:pointer}
.mc-vopt:hover{background:var(--mc-sunken);color:var(--mc-ink)}
.mc-vopt.sel{background:var(--mc-acc-wash);color:var(--mc-acc-ink)}
.mc-vopt .mc-vt{width:42px;height:32px;border-radius:7px}
.mc-vopt b{font-size:13.5px;font-weight:600;display:block}
.mc-vopt small{font-size:11.5px;color:var(--mc-ink3);display:block}
.mc-vopt.sel small{color:var(--mc-acc-ink);opacity:.75}
.mc-vopt .mc-tk{margin-left:auto;opacity:0;flex-shrink:0}
.mc-vopt.sel .mc-tk{opacity:1}
.mc-vsep{height:1px;background:var(--mc-line);margin:6px 4px}
/* A real <a href> to /post/vehicle, not a button: adding a car is an address
   (§12), and it middle-clicks out of a half-written mod rather than losing it. */
.mc-vadd{display:flex;align-items:center;gap:12px;width:100%;padding:9px 10px;border-radius:9px;
  font-size:14px;font-weight:600;color:var(--mc-acc-ink);text-decoration:none}
.mc-vadd:hover{background:var(--mc-acc-wash);color:var(--mc-acc-ink)}
.mc-vadd .p{width:42px;height:32px;border-radius:7px;flex-shrink:0;border:1px dashed var(--mc-acc-line);
  display:flex;align-items:center;justify-content:center}

/* ── fields ────────────────────────────────────────────────────────────── */
.mc-scroll{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain}
.mc-fields{padding:18px 16px}
.mc-lab{display:flex;align-items:baseline;gap:9px;margin-bottom:7px;flex-wrap:wrap}
.mc-eyebrow{font-family:var(--mono);font-size:10px;font-weight:500;letter-spacing:.16em;
  text-transform:uppercase;color:var(--mc-ink3)}
.mc-lab i{font-style:normal;font-size:11.5px;color:var(--mc-ink3);font-family:var(--ui)}
.mc-f-title{padding:0 2px 14px;border-bottom:1px solid var(--mc-line);margin-bottom:18px}
.mc-tin{width:100%;border:0;background:none;outline:none;padding:0;font-family:var(--dis);
  font-size:19px;font-weight:600;letter-spacing:-.024em;line-height:1.35;color:var(--mc-ink)}
.mc-tin::placeholder{color:var(--mc-ink3);font-weight:500}
/* A MARK ON A FIELD YOU ARE ALREADY STANDING IN HAS TO BE SEEN WITHOUT LOOKING
   FOR IT. The title holds the caret from the moment the sheet opens, so this
   was the only thing "Take me there" could change — and one hairline going
   grey to red under a field already on screen is not a change anybody notices.
   Two signals now, the rule and the label, and the padding gives back the
   pixel the thicker rule takes so nothing below it moves. */
.mc-f-title.bad{border-bottom:2px solid var(--mc-err);padding-bottom:13px}
.mc-f-title.bad .mc-eyebrow,.mc-f-desc.bad .mc-eyebrow{color:var(--mc-err)}
.mc-dbox{border:1px solid var(--mc-line);border-radius:10px;background:var(--mc-sunken);padding:13px;
  transition:border-color .14s,box-shadow .14s,background .14s}
.mc-dbox:focus-within{border-color:var(--mc-acc);box-shadow:0 0 0 3px var(--mc-acc-wash);background:var(--mc-panel)}
.mc-f-desc.bad .mc-dbox{border-color:var(--mc-err)}
.mc-din{width:100%;border:0;background:none;outline:none;resize:none;padding:0;font-size:14.5px;
  line-height:1.62;color:var(--mc-ink2);min-height:100px;max-height:400px;display:block;font-family:var(--ui)}
.mc-din::placeholder{color:var(--mc-ink3)}
.mc-f-photo,.mc-f-dd{margin-top:18px}

/* ── the uploader, wearing this sheet's clothes ────────────────────────────
   mountUploader() is the site's one uploader and this is a skin on it, never a
   second one: the drop zone becomes a single quiet bar and the tiles a strip,
   and the first tile is marked COVER because attachments.ord is what decides
   the cover everywhere else. Nothing here changes what it uploads or when. */
.mc-f-photo .amsup-zone{flex-direction:row;align-items:center;justify-content:center;gap:9px;
  height:70px;min-height:0;padding:0;border-radius:10px;border:1px dashed var(--mc-line2);background:none;
  color:var(--mc-ink3);font-size:13px;transition:border-color .14s,color .14s,background .14s}
.mc-f-photo .amsup.has-items .amsup-zone{height:56px;min-height:0;padding:0}
.mc-f-photo .amsup-zone:hover,.mc-f-photo .amsup-zone.drag{border-color:var(--mc-acc);border-style:dashed;
  color:var(--mc-acc-ink);background:var(--mc-acc-wash)}
.mc-f-photo .amsup-ic{width:17px;height:17px}
.mc-f-photo .amsup-cta{display:flex;align-items:baseline;gap:5px;text-align:left}
.mc-f-photo .amsup-cta b{font-size:13px;font-weight:500;color:inherit;display:inline}
.mc-f-photo .amsup-cta span{font-size:13px;color:inherit}
.mc-f-photo .amsup-grid{display:flex;flex-wrap:wrap;gap:8px}
.mc-f-photo .amsup-tile{width:88px;height:66px;aspect-ratio:auto;border-radius:8px;flex:none}
/* attachments.ord decides the cover everywhere else on the site, and the first
   upload is ord 0 — so the strip says which one that is rather than leaving it
   to be discovered on the mod's own page. */
.mc-f-photo .amsup-tile:first-child::after{content:"COVER";position:absolute;left:4px;bottom:4px;
  font-family:var(--mono);font-size:8px;letter-spacing:.1em;background:var(--mc-acc);
  color:var(--accent-on);padding:2px 5px;border-radius:4px;pointer-events:none}

/* ── the three dropdowns, 1:1 with the prototype ──────────────────────────
   A REAL <select> UNDERNEATH, ALWAYS. The button and the list below are a skin
   on it: the value lives in the <select> (one source of truth, keyboard- and
   screen-reader-reachable, and still there if this file throws), and mcDD()
   only ever reads and writes it. That is why the site's own enhanceSelect()
   could not be reused here and why this is not a second answer to "what is
   selected" — enhanceSelect draws one line per option, and the prototype's
   Status list carries a coloured dot and a second line of explanation per row
   ("Complete · Finished and on the car"), which is information the field is
   there to give. Anything with only a label still goes through enhanceSelect
   everywhere else on the site.

   The list is a CHILD OF THE FIELD and absolutely positioned, not fixed — the
   modal scrolls it away with the form rather than leaving it hanging over a
   row it no longer belongs to, and it cannot be caught out by a transformed
   ancestor the way a fixed popover can. */
.mc-dd{position:relative;width:100%}
.mc-dd select{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;
  clip:rect(0 0 0 0);overflow:hidden}
.mc-dd-btn{display:flex;align-items:center;gap:11px;width:100%;height:48px;padding:0 14px;
  border-radius:10px;border:1px solid var(--mc-line);background:var(--mc-sunken);
  font-size:14.5px;color:var(--mc-ink3);text-align:left;cursor:pointer;
  transition:border-color .16s,background .16s,color .16s}
.mc-dd-btn:hover{border-color:var(--mc-line2)}
.mc-dd-btn .lead{flex-shrink:0;opacity:.75;display:flex}
.mc-dd-btn .val{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.mc-dd-btn .cv{opacity:.55;flex-shrink:0;transition:transform .2s var(--ease)}
.mc-dd.set .mc-dd-btn{color:var(--mc-ink);font-weight:500;background:var(--mc-panel);border-color:var(--mc-line2)}
.mc-dd.set .mc-dd-btn .lead{opacity:1;color:var(--mc-acc)}
.mc-dd.on .mc-dd-btn{border-color:var(--mc-acc);background:var(--mc-panel);color:var(--mc-ink);
  box-shadow:0 0 0 3px var(--mc-acc-wash)}
.mc-dd.on .mc-dd-btn .cv{transform:rotate(180deg)}
.mc-dd-list{position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:62;display:none;padding:6px;
  border:1px solid var(--mc-line2);border-radius:12px;background:var(--mc-panel);
  box-shadow:var(--sh-lg);max-height:264px;overflow-y:auto}
.mc-dd-list.up{top:auto;bottom:calc(100% + 6px)}
.mc-dd.on .mc-dd-list{display:block;animation:mc-fdrop .15s var(--ease)}
@keyframes mc-fdrop{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
.mc-dd-opt{display:flex;align-items:center;gap:11px;width:100%;padding:11px;border-radius:8px;
  font-size:14px;color:var(--mc-ink2);text-align:left;border:0;background:none;cursor:pointer}
.mc-dd-opt:hover,.mc-dd-opt.cur{background:var(--mc-sunken);color:var(--mc-ink)}
.mc-dd-opt.sel{background:var(--mc-acc-wash);color:var(--mc-acc-ink);font-weight:600}
/* The row's own glyph (Mods::categoryIcon()). It is dimmed against the label
   it sits beside — the word is what the row is, the drawing is how it is found
   in a list of seventeen — and comes up to full on hover and on the chosen row,
   where it inherits .sel's accent ink. */
.mc-dd-opt .oic{flex-shrink:0;opacity:.72}
.mc-dd-opt:hover .oic,.mc-dd-opt.cur .oic{opacity:.85}
.mc-dd-opt.sel .oic{opacity:1}
.mc-dd-opt .tk{margin-left:auto;opacity:0;flex-shrink:0}
.mc-dd-opt.sel .tk{opacity:1}
.mc-dd-opt .sw{width:8px;height:8px;border-radius:50%;background:var(--mc-ink3);flex-shrink:0}
.mc-dd-opt .sw.live{background:var(--mc-ok)}
.mc-dd-opt .sw.wip{background:var(--mc-acc)}
.mc-dd-opt small{display:block;font-size:11.5px;color:var(--mc-ink3);font-weight:400;margin-top:1px}
.mc-dd-opt.sel small{color:var(--mc-acc-ink);opacity:.75}

/* ── the bar ───────────────────────────────────────────────────────────── */
.mc-bar{display:flex;align-items:center;gap:9px;padding:13px 16px;flex-shrink:0;flex-wrap:wrap;
  background:var(--mc-sunken);border-top:1px solid var(--mc-line);border-radius:0 0 15px 15px}
.mc-hint{font-size:12px;color:var(--mc-ink3);margin-right:auto}
.mc-dbtn{display:inline-flex;align-items:center;gap:7px;height:38px;padding:0 16px;border-radius:9px;
  border:1px solid var(--mc-line2);background:var(--mc-panel);color:var(--mc-ink2);
  font-size:14px;font-weight:600;cursor:pointer;box-shadow:var(--sh-sm);
  transition:background .14s,border-color .14s,color .14s}
.mc-dbtn:hover{background:var(--mc-sunken);color:var(--mc-ink);border-color:var(--mc-ink3)}
.mc-dbtn[disabled]{opacity:.5;cursor:default}
.mc-pwrap{position:relative;display:inline-flex}
.mc-post{display:inline-flex;align-items:center;gap:7px;height:38px;padding:0 20px;border-radius:9px;
  border:1px solid var(--mc-line2);background:var(--mc-panel);color:var(--mc-ink3);
  font-size:14px;font-weight:600;cursor:pointer;box-shadow:var(--sh-sm);
  transition:background .18s,border-color .18s,color .18s}
.mc-post:hover{border-color:var(--mc-ink3)}
.mc-post .mc-lock{display:flex}
/* The button is only the accent once the write path would actually take it. */
.mc-post.ready{background:var(--mc-acc);border-color:var(--mc-acc);color:var(--accent-on)}
.mc-post.ready:hover{background:color-mix(in srgb,var(--mc-acc) 88%,#000);border-color:color-mix(in srgb,var(--mc-acc) 88%,#000)}
.mc-post.ready .mc-lock{display:none}

/* ── the one notice ──────────────────────────────────────────────────────
   THE KIND MODIFIERS ARE NAMESPACED, and that is not tidiness. There is a bare
   global `.warn p{color:#7F1D1D}` in the stylesheet, so `.mc-pop.warn` painted
   every word of the notice's body dark red — a warning that reads as an error,
   on the one panel whose whole job is to say which of those it is. It is the
   share sheet's `.fit` lesson (a bare global `.fit` is a green PILL, so
   `.shs-w.fit` came out as a chip inside a row that already had one), and the
   answer is the same: nothing in here wears a name the rest of the site owns. */
.mc-pop{position:absolute;right:0;bottom:calc(100% + 13px);z-index:55;width:298px;
  padding:13px 14px 12px;border-radius:12px;background:var(--mc-panel);
  border:1px solid var(--mc-line);box-shadow:var(--sh-lg);text-align:left;
  animation:mcup .17s var(--ease)}
@keyframes mcup{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.mc-pop::before,.mc-pop::after{content:"";position:absolute;right:26px;width:12px;height:12px;transform:rotate(45deg)}
.mc-pop::before{bottom:-7px;background:var(--mc-line)}
.mc-pop::after{bottom:-6px;background:var(--mc-panel)}
.mc-pop-top{display:flex;align-items:center;gap:9px;margin-bottom:7px}
.mc-pop-top b{font-size:13.5px;color:var(--mc-ink)}
.mc-pop-ic{width:24px;height:24px;border-radius:7px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center}
.mc-pop--err .mc-pop-ic{background:var(--mc-err-wash);border:1px solid var(--mc-err-line);color:var(--mc-err)}
.mc-pop--warn .mc-pop-ic{background:var(--mc-warn-wash);border:1px solid var(--mc-warn-line);color:var(--mc-warn)}
.mc-pop-body{margin:0;font-size:12.5px;line-height:1.55;color:var(--mc-ink2)}
.mc-pop-body b{color:var(--mc-ink);font-weight:600}
.mc-pop-acts{display:flex;justify-content:flex-end;gap:7px;margin-top:11px;flex-wrap:wrap}
.mc-ebtn{height:30px;padding:0 12px;border-radius:8px;border:1px solid var(--mc-line2);
  background:var(--mc-panel);color:var(--mc-ink);font-size:12.5px;font-weight:600;cursor:pointer}
.mc-ebtn:hover{background:var(--mc-sunken)}
.mc-ebtn.primary{background:var(--mc-acc);border-color:var(--mc-acc);color:var(--accent-on)}

/* ── the discard cover, and the published state ────────────────────────── */
.mc-confirm{position:absolute;inset:0;z-index:80;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;padding:34px 30px;border-radius:15px;
  background:color-mix(in srgb,var(--mc-panel) 94%,transparent);backdrop-filter:blur(6px);
  animation:mcfade .18s var(--ease)}
@keyframes mcfade{from{opacity:0}to{opacity:1}}
/* A ring rather than a filled plate: the plate was the heaviest thing on a
   cover that is asking a question, and it sat directly above a headline that
   is already doing the work. */
.mc-cico{width:54px;height:54px;border-radius:16px;display:flex;align-items:center;justify-content:center;
  background:var(--mc-err-wash);border:1px solid var(--mc-err-line);color:var(--mc-err);margin-bottom:17px;
  box-shadow:0 0 0 5px color-mix(in srgb,var(--mc-err-wash) 45%,transparent)}
.mc-confirm h4{margin:0 0 7px;font-family:var(--dis);font-size:19px;font-weight:600;
  letter-spacing:-.026em;color:var(--mc-ink)}
.mc-cmsg{margin:0;font-size:13.5px;line-height:1.6;color:var(--mc-ink2);max-width:36ch}
.mc-cacts{display:flex;gap:9px;margin-top:22px;flex-wrap:wrap;justify-content:center}
.mc-cbtn{display:inline-flex;align-items:center;gap:8px;height:42px;padding:0 18px;border-radius:10px;
  border:1px solid var(--mc-line2);background:var(--mc-panel);color:var(--mc-ink);
  font-size:14px;font-weight:600;letter-spacing:-.005em;cursor:pointer;box-shadow:var(--sh-sm);
  transition:background .14s,border-color .14s,color .14s,box-shadow .14s}
/* The glyph is the quieter half of a label: full strength reads as two things
   shouting. It comes up to match on hover, so the button feels lit rather than
   merely tinted. */
.mc-cbtn .ic{opacity:.75;transition:opacity .14s}
.mc-cbtn:hover .ic,.mc-cbtn:focus-visible .ic{opacity:1}
.mc-cbtn:hover{background:var(--mc-sunken);border-color:var(--mc-ink3)}
.mc-cbtn:focus-visible{outline:2px solid var(--mc-acc);outline-offset:2px}
/* No standing halo on the primary: it is already the only filled button here,
   and a permanent ring is indistinguishable from the focus ring that lands on
   this very button when the cover opens. */
.mc-cbtn.mc-keep{background:var(--mc-acc);border-color:var(--mc-acc);color:var(--accent-on);
  box-shadow:0 1px 2px rgba(8,8,11,.18)}
.mc-cbtn.mc-keep .ic{opacity:.9}
.mc-cbtn.mc-keep:hover{background:color-mix(in srgb,var(--mc-acc) 88%,#000);
  border-color:color-mix(in srgb,var(--mc-acc) 88%,#000);color:var(--accent-on)}
/* THE DESTRUCTIVE ONE IS THE QUIETEST THING ON THE COVER. It was a bordered
   box the same size and shape as the two beside it, which made discarding look
   like an equal, ordinary choice on a panel whose whole job is to stop one.
   Reachable, named, red — and no border, so nothing draws the eye to it. */
.mc-cbtn.mc-danger{border-color:transparent;background:none;box-shadow:none;color:var(--mc-err)}
.mc-cbtn.mc-danger:hover{background:var(--mc-err-wash);border-color:var(--mc-err-line);color:var(--mc-err)}
.mc-cbtn.mc-danger:focus-visible{outline-color:var(--mc-err)}
.mc-sent{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;
  padding:56px 24px;text-align:center;flex:1}
.mc-sent .mc-tick{width:48px;height:48px;border-radius:50%;background:var(--mc-ok-wash);color:var(--mc-ok);
  display:flex;align-items:center;justify-content:center}
.mc-sent b{font-size:17px;color:var(--mc-ink)}
.mc-pmsg{margin:0;font-size:13.5px;color:var(--mc-ink3)}
/* Publishing takes the form away and leaves the receipt — the scroll pane and
   the bar are what is being replaced, so they go rather than being covered. */
.mc.done .mc-scroll,.mc.done .mc-bar,.mc.done .mc-vbar{display:none}

/* ── the phone: a bottom sheet, same component ─────────────────────────────
   Same rule as above — it comes to rest with no transform, so the dropdowns'
   popovers are still positioned against the viewport rather than against the
   sheet. */
@media(max-width:640px){
  .mc-sheet{inset:auto 0 var(--floor-modal,0px) 0;margin:0;width:100%;
    max-height:calc(92vh - var(--floor-modal,0px));
    border-radius:18px 18px 0 0;border-left:0;border-right:0;border-bottom:0}
  .mc-sheet.on{animation:mc-up .26s var(--ease)}
  @keyframes mc-up{from{transform:translateY(100%)}}
  .mc-bar,.mc-confirm{border-radius:0}
  .mc-pop{width:calc(100vw - 32px);right:-8px}
  .mc-head{padding-left:14px}
  /* On a phone the tagline is the first thing to go: the pill is a live
     instruction and the title says what the screen is, but "Tell the world
     what you did" is scene-setting, and scene-setting does not get to push a
     requirement off the edge. */
  .mc-head small{display:none}
  /* AND THEN THE PILL TAKES ITS OWN LINE. Dropping the tagline was not enough
     at 390px: "Needs a vehicle + a title + a description" beside a title and a
     close button leaves it about 150px, and the sentence is the one thing on
     this screen that says what is still missing — truncated to "Needs a
     vehicle + a titl…" it stops being an instruction. So the head wraps: the
     title and the way out on one line, the requirement whole underneath. */
  .mc-head{flex-wrap:wrap;row-gap:9px}
  /* The wrap puts the requirement on its own line, so the first line is the way
     back, the title and the way out — in that reading order. .mc-back and
     .mc-htxt keep the default order:0 and need no rule; naming them here would
     be three numbers where one is doing the work. */
  .mc-x{order:2}
  .mc-req{order:3;flex-basis:100%;height:auto;min-height:26px;padding:5px 11px;
    white-space:normal;line-height:1.35}
  .mc-req > span:last-child{white-space:normal;overflow:visible}
  .mc-hint{display:none}
  .mc-bar{gap:8px}
  .mc-dbtn,.mc-post{flex:1;justify-content:center}
  /* The uploader's own two-part label is a heading and a hint written to sit on
     two lines; in a 70px bar at this width they were laid out as two columns,
     which reads as one sentence broken in half. Let the bar grow instead. */
  .mc-f-photo .amsup-zone{height:auto;min-height:70px;padding:12px 14px}
  .mc-f-photo .amsup-cta{flex-wrap:wrap;justify-content:center;text-align:center}
}
@media(prefers-reduced-motion:reduce){
  .mc-sheet,.mc-scrim,.mc-vlist,.mc-pop,.mc-confirm{transition:none!important;animation:none!important}
  .mc-sheet{opacity:1}
}


/* ════════════════════════════════════════════════════════════════════════
   CREATE — the chooser modal.  Markup: views/app/create-modal.php
                                Tiles:  app/CreateMenu.php (also /post)
                                Behaviour: views/app/js/07h-create-modal.php

   IT DEFINES NO COLOUR THE SITE ALREADY PUBLISHES. Every --cm-* below resolves
   to a :root token, the mod composer's rule and the hover card's, for the same
   reason: the accent is operator-configurable from the Appearance screen, and a
   panel carrying #EA580C would be the one orange thing on the site that did not
   move when somebody repainted it. --tint defaults to var(--accent) so a tile's
   hover follows it too; the one tile that overrides it does so in the markup,
   because it carries its own artwork the accent would fight.

   THE HONEYCOMB TILE RESTS ON THE ACCENT, not only hovers towards it. It used
   to be two hand-mixed browns, which is the accent already veiled, computed
   once and frozen — the rule above broken by the one tile whose whole subject
   is the site's own colour. It is var(--tint) under a veil now (see the
   honeycomb block below), so it repaints with everything else.

   THE PLATE IS DARK IN BOTH THEMES, and that IS a colour of its own — the one
   here. It is the vehicle profile's slab decision: the tiles are photographs
   and textures, and a plate that inverts with the theme would mean the artwork
   was designed against two backgrounds instead of one. So --cm-plate is a
   literal, stated once, and nothing else in this file is.
   ════════════════════════════════════════════════════════════════════════ */
/* WHERE A TOKEN IS DECLARED IS PART OF WHAT IT MEANS. These were all on `.cm`,
   the inner div, and two things were wrong with that at once: `.cm-sheet` is
   OUTSIDE it and paints the panel, so its background and border resolved to
   nothing and the modal came up transparent over the page; and the TILES are
   drawn at /post as well, where there is no `.cm` above them at all, so the two
   that do not carry their own artwork had no plate under them and the drafting
   grid drew onto the page. Both render perfectly as CSS — an undeclared custom
   property is not an error, the declaration is simply dropped — which is
   exactly how views/app/css/24-image-picker.php shipped a button with no
   background for months.

   So: the panel's tokens sit on the panel, and the tile's sit on the tile,
   which is the element that travels. */
.cm-sheet{
  --cm-panel:var(--surface); --cm-line:var(--border); --cm-line2:var(--border2);
  --cm-ink:var(--text); --cm-ink2:var(--t2); --cm-ink3:var(--t3);
  --cm-sunken:var(--surface2);
}

/* ── the shell ─────────────────────────────────────────────────────────────
   It settles with NO transform, and that is structural rather than tidy: a
   transformed element becomes the containing block for every position:fixed
   descendant. The centring is `inset` + `margin:auto`, which needs none, and
   the entrance is an ANIMATION with no fill mode — it interpolates from a
   shifted state to the element's own computed style and leaves `transform:none`
   behind. A transition cannot do that; there is no way to transition TO none,
   and `translate(0,0)` still creates a containing block. Same reasoning, and
   the same z-ladder, as views/app/css/29-mod-composer.php.

   The bottom edge is --floor, never the window: the admin bar and the phone's
   tab bar stack in that corner, and 56px of a sheet behind the tab bar is where
   the one control that finishes the job ends up (CONVENTIONS §6). */
.cm-scrim{position:fixed;inset:0;z-index:1300;background:rgba(10,12,16,.5);
  backdrop-filter:blur(3px);opacity:0;transition:opacity .24s var(--ease)}
.cm-scrim.on{opacity:1}
/* IT ENDS AT --floor-modal, NOT --floor. Its scrim covers the phone's tab
   bar, so leaving room for that bar holds a band of unusable navigation
   open under the sheet — 90px of scrimmed page on an operator's phone.
   What a scrim cannot cover is #adminbar (z-1900) and the home
   indicator, and --floor-modal is exactly those two (§6). */
.cm-sheet{position:fixed;inset:0 0 var(--floor-modal,0px) 0;margin:auto;z-index:1310;
  width:min(720px,calc(100vw - 40px));
  height:fit-content;
  max-height:min(760px,calc(100vh - 72px - var(--floor-modal,0px)));
  display:flex;flex-direction:column;
  background:var(--cm-panel);border:1px solid var(--cm-line2);border-radius:16px;
  box-shadow:var(--sh-lg);overflow:hidden;
  opacity:0;transition:opacity .2s var(--ease)}
.cm-sheet.on{opacity:1;animation:cm-in .24s var(--ease)}
@keyframes cm-in{from{opacity:0;transform:translateY(10px) scale(.985)}}
.cm{position:relative;display:flex;flex-direction:column;min-height:0;flex:1}

/* ── head ─────────────────────────────────────────────────────────────── */
.cm-head{display:flex;align-items:flex-start;gap:12px;padding:16px 18px;
  border-bottom:1px solid var(--cm-line);flex:0 0 auto}
.cm-htxt{min-width:0}
.cm-head h3{margin:0;font-family:var(--dis);font-size:18px;font-weight:600;
  letter-spacing:-.015em;color:var(--cm-ink)}
.cm-head p{margin:2px 0 0;color:var(--cm-ink3);font-size:12.5px}
.cm-x{width:32px;height:32px;margin-left:auto;flex:0 0 auto;
  display:grid;place-items:center;border-radius:9px;
  border:1px solid var(--cm-line2);background:none;color:var(--cm-ink2);
  cursor:pointer;transition:background .13s var(--ease),color .13s var(--ease)}
.cm-x:hover{background:var(--cm-sunken);color:var(--cm-ink)}

.cm-body{padding:18px;overflow-y:auto;overscroll-behavior:contain;min-height:0}

/* ── the tiles ─────────────────────────────────────────────────────────────
   One rule set, two hosts: this grid inside the modal, and #cmp-chooser's own
   at /post (below). The TILE is written once — a second copy is how the two
   drawings of one list stop looking like one thing. */
.cm-tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}

.cm-tile{--tint:var(--accent);--cm-plate:#0B0B10;
  --cm-sunken:var(--surface2);--cm-line2:var(--border2);--cm-ink:var(--text);--cm-ink3:var(--t3);position:relative;overflow:hidden;isolation:isolate;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;
  aspect-ratio:5/4;padding:18px 14px;text-align:center;cursor:pointer;
  font:inherit;text-decoration:none;
  background:var(--cm-plate);border:1px solid rgba(255,255,255,.085);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-sm),inset 0 1px 0 rgba(255,255,255,.07);
  transition:background .16s var(--ease),border-color .16s var(--ease),
             box-shadow .16s var(--ease),transform .07s var(--ease)}
.cm-tile:active{transform:translateY(1px);border-color:var(--tint)}
.cm-tile:focus-visible{outline:2px solid rgba(255,255,255,.85);outline-offset:-5px}

/* The drafting grid — the plain tiles echo a blueprint. Two rulings at two
   scales, so the texture reads at any tile size. */
.cm-tile::before{content:"";position:absolute;inset:0;z-index:-2;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='23' height='23'%3E%3Cpath d='M23 0H0v23' fill='none' stroke='%23ffffff' stroke-opacity='.05' stroke-width='1'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='115' height='115'%3E%3Cpath d='M115 0H0v115' fill='none' stroke='%23ffffff' stroke-opacity='.08' stroke-width='1'/%3E%3C/svg%3E");
  background-size:23px 23px,115px 115px;
  transition:opacity .16s var(--ease)}
.cm-tile.has-img::before{display:none}

/* Film grain, on everything, so a photograph and a texture sit in one family. */
.cm-tile::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:var(--grain);background-size:150px 150px;
  opacity:.09;mix-blend-mode:overlay}

/* THE HONEYCOMB IS THE SAME TWO-LAYER RECIPE AS THE PHOTOGRAPHIC PLATE: the
   tint at full strength with a dark veil pulled over it, exactly as .cm-shade
   veils the Add-a-mod photograph. That is what makes the two textured tiles
   read as a pair rather than as two ideas — and it is why --veil is the single
   knob for depth here, the same number --shade is over there.

   IT USED TO BE TWO LITERAL BROWNS (#2D170C paper, #442C1F linework), mixed
   towards --tint only on hover. They were the accent already veiled, computed
   once by hand and then frozen — so this tile was the one thing in the modal
   that did NOT move when an operator repainted the site from the Appearance
   screen, which is the exact rule this file's header states and the reason the
   accent is never written as a literal anywhere else in it. Resting on
   var(--tint) under a veil is the same colour for the default accent and the
   right one for every other.

   --veil is REGISTERED, and that is what makes the hover a fade rather than a
   jump: a custom property is a string to the animation engine unless @property
   gives it a type, so an unregistered one steps at the end of the transition.
   Where @property is not supported the declaration below is simply ignored and
   the value written on the rule still paints — the tile is correct, and only
   the 160ms between the two depths is lost.

   The linework is painted through a MASK rather than drawn as an image, which
   is what lets it brighten on hover without a second copy of the artwork. */
@property --veil{syntax:'<number>';inherits:false;initial-value:0.785}
.cm-tile.p-hive{--veil:0.785;
  background:linear-gradient(rgb(8 9 14/var(--veil)),rgb(8 9 14/var(--veil))),var(--tint);
  transition:--veil .16s var(--ease),border-color .16s var(--ease),
             box-shadow .16s var(--ease),transform .07s var(--ease)}
.cm-tile.p-hive::before{background-image:none;background-color:rgb(255 255 255/0.109);
  -webkit-mask-image:var(--cm-hive);mask-image:var(--cm-hive);
  -webkit-mask-size:17.12px 29.66px;mask-size:17.12px 29.66px;
  -webkit-mask-repeat:repeat;mask-repeat:repeat}
/* The hover RESTATES the background, and dropping that line is not a tidy-up:
   .cm-tile:hover sets a background of its own, and without this the plainer
   rule would take the hive tile on hover and the honeycomb would vanish under
   the pointer. This selector is one class more specific, which is what wins. */
.cm-tile.p-hive:hover,.cm-tile.p-hive:focus-visible{--veil:0.703;
  background:linear-gradient(rgb(8 9 14/var(--veil)),rgb(8 9 14/var(--veil))),var(--tint)}
.cm-tile.p-hive:hover::before,.cm-tile.p-hive:focus-visible::before{opacity:1;
  background-color:rgb(255 255 255/0.164)}
.cm-tile{
  --cm-hive:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 173.205 300.0'%3E%3Cpath d='M86.6 50.0L0.0 100.0L-86.6 50.0L-86.6 -50.0L-0.0 -100.0L86.6 -50.0ZM259.8 50.0L173.2 100.0L86.6 50.0L86.6 -50.0L173.2 -100.0L259.8 -50.0ZM0.0 200.0L-86.6 250.0L-173.2 200.0L-173.2 100.0L-86.6 50.0L-0.0 100.0ZM173.2 200.0L86.6 250.0L-0.0 200.0L0.0 100.0L86.6 50.0L173.2 100.0ZM346.4 200.0L259.8 250.0L173.2 200.0L173.2 100.0L259.8 50.0L346.4 100.0ZM86.6 350.0L0.0 400.0L-86.6 350.0L-86.6 250.0L-0.0 200.0L86.6 250.0ZM259.8 350.0L173.2 400.0L86.6 350.0L86.6 250.0L173.2 200.0L259.8 250.0Z' fill='none' stroke='%23fff' stroke-width='5'/%3E%3C/svg%3E")}

/* The photograph, and the shade over it. Two layers rather than a gradient on
   one, because hover moves them independently — the picture pushes in, the
   shade takes the tint.

   THE VEIL IS THE PICTURE'S OWN NUMBER, not one number for every picture.
   --shade was the literal .751 written here, which is right for flat artwork
   and too heavy for a photograph: the Add-a-mod plate is a rendering with
   almost no highlight to lose, while a sunset over a car meet is mostly
   highlight, and pushing it 75% dark leaves a grey rectangle that could be any
   photograph at all. So the number is a default and the row that knows better
   overrides it (app/CreateMenu.php).

   --scrim IS A SECOND, SEPARATE QUESTION, and folding it into --shade is what
   the default of 0 refuses to do. Lightening the veil to keep a photograph
   readable puts light back everywhere, the bottom third included, which is
   exactly where the title and the blurb sit — so the two knobs pull against
   each other and one number cannot hold both. The scrim is a gradient that is
   transparent across the top 42% and reaches full strength at 92%: it darkens
   only the band the type sits in, so a picture can take a lighter veil without
   the caption on it going soft. A tile that does not ask for one pays nothing
   — at --scrim:0 every stop of the gradient is transparent. */
.cm-bg{position:absolute;inset:0;z-index:-2;background-size:cover;background-position:center;
  transform:scale(1.02);transition:transform .6s var(--ease),filter .3s var(--ease)}
.cm-shade{position:absolute;inset:0;z-index:-2;
  background:
    linear-gradient(to bottom,
      rgb(4 5 9/0)                              42%,
      rgb(4 5 9/calc(var(--scrim,0) * .156)) 54.5%,
      rgb(4 5 9/calc(var(--scrim,0) * .5))      67%,
      rgb(4 5 9/calc(var(--scrim,0) * .844)) 79.5%,
      rgb(4 5 9/var(--scrim,0))                 92%),
    rgb(8 9 14/var(--shade,.751));
  transition:background .2s var(--ease)}

.cm-tile:hover,.cm-tile:focus-visible{
  background:color-mix(in srgb,var(--tint) 9%,var(--cm-plate));
  border-color:color-mix(in srgb,var(--tint) 62%,transparent);
  box-shadow:0 10px 24px -16px color-mix(in srgb,var(--tint) 70%,transparent),
             inset 0 1px 0 rgba(255,255,255,.09)}
.cm-tile:hover::before,.cm-tile:focus-visible::before{opacity:.5}
.cm-tile:hover .cm-bg,.cm-tile:focus-visible .cm-bg{transform:scale(1.06)}
/* Hover lifts the veil by a fixed AMOUNT rather than to a fixed number. It was
   .66 — .751 minus .09 computed by hand, which is right only while every tile
   veils at the default: a photograph resting at .62 would have got DARKER when
   the pointer landed on it, which is the one direction a hover must never go. */
.cm-tile:hover .cm-shade,.cm-tile:focus-visible .cm-shade{
  background:linear-gradient(color-mix(in srgb,var(--tint) 13%,transparent),
                             color-mix(in srgb,var(--tint) 13%,transparent)),
             rgb(8 9 14/calc(var(--shade,.751) - .09))}

/* The glyph. A size is set HERE and not passed to the renderer for the brand
   <symbol>s, which take theirs from the stylesheet — but ams_icon() is given
   one for the registry glyphs, because a bare svg with no size falls back to
   the UA's 300x150 box (the failure that drew a 40px notepad on the vehicle
   profile's section bar). Both land on the same 38px so the family is one size. */
.cm-ico{display:grid;place-items:center;flex:0 0 auto;color:rgba(255,255,255,.90);
  transition:color .16s var(--ease),transform .16s var(--ease)}
.cm-ico svg{width:38px;height:38px;display:block}
/* The two brand marks are filled silhouettes on a 20 grid. stroke:none is
   load-bearing here for the reason 00-marks.php gives: a rule elsewhere setting
   stroke:currentColor outlines the silhouette and closes its holes. */
.cm-ico .cm-mark{fill:currentColor;stroke:none}
.cm-tile:hover .cm-ico,.cm-tile:focus-visible .cm-ico{color:var(--tint);transform:translateY(-2px)}
.cm-tile.has-img .cm-ico{filter:drop-shadow(0 1px 5px rgba(4,6,10,.8))}

.cm-txt{min-width:0}
.cm-txt strong{display:block;font-size:15px;font-weight:600;color:#fff;
  letter-spacing:-.014em;line-height:1.25}
.cm-txt small{display:block;font-size:11.5px;line-height:1.4;color:rgba(255,255,255,.52);
  margin:4px auto 0;max-width:25ch;text-wrap:balance}
.cm-tile.has-img .cm-txt strong{text-shadow:0 1px 4px rgba(4,6,10,.9)}
.cm-tile.has-img .cm-txt small{text-shadow:0 1px 3px rgba(4,6,10,.85)}

/* THE ONE TILE THAT MAKES NOTHING. It is a way BACK to work you already
   started, so it is drawn as the quieter thing it is — the site's own surface
   rather than the dark plate, no drafting grid, no grain — and it cannot be
   read as a sixth kind of thing to create. It sits in the same grid because it
   is the same decision ("what am I doing here"), and being the odd one out in
   that grid is the point rather than a compromise. */
.cm-tile.is-resume{background:var(--cm-sunken,#F5F5F7);
  border:1px dashed var(--cm-line2);box-shadow:none}
.cm-tile.is-resume::before,.cm-tile.is-resume::after{display:none}
.cm-tile.is-resume .cm-ico{color:var(--cm-ink3)}
.cm-tile.is-resume .cm-txt strong{color:var(--cm-ink);text-shadow:none}
.cm-tile.is-resume .cm-txt small{color:var(--cm-ink3);text-shadow:none}
.cm-tile.is-resume:hover,.cm-tile.is-resume:focus-visible{
  background:var(--cm-sunken,#F5F5F7);
  border-color:color-mix(in srgb,var(--accent) 62%,transparent);
  box-shadow:0 10px 24px -16px color-mix(in srgb,var(--accent) 70%,transparent)}
.cm-tile.is-resume:hover .cm-ico,.cm-tile.is-resume:focus-visible .cm-ico{color:var(--accent)}
.cm-tile.is-resume:focus-visible{outline-color:var(--cm-ink)}

/* ── the same tiles at /post ───────────────────────────────────────────────
   #cmp-chooser is the page's own host and it is wider than the modal, so the
   grid is the only thing that differs. The TILE does not: one list drawn twice
   that looked like two things would be the drift this whole file exists to
   end, one layer down. */
.cm-tiles-page{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;max-width:760px}

/* ── tablet ───────────────────────────────────────────────────────────── */
@media (max-width:820px){
  .cm-sheet{width:min(520px,calc(100vw - 32px))}
  .cm-tiles{grid-template-columns:repeat(2,1fr)}
}

/* ── phone: a bottom sheet ─────────────────────────────────────────────────
   It ends at --floor, not at the window, and it is anchored to the bottom
   rather than centred: a picker is reached for with a thumb. 100dvh is
   deliberate over 100vh, which measures past iOS's address bar. */
@media (max-width:600px){
  .cm-sheet{inset:auto 0 var(--floor-modal,0px) 0;margin:0;width:100%;
    max-height:calc(100dvh - 28px - var(--floor-modal,0px));
    border-radius:18px 18px 0 0;border-bottom:0;
    animation:none}
  .cm-sheet.on{animation:cm-sheet-in .26s var(--ease)}
  @keyframes cm-sheet-in{from{transform:translateY(100%)}}
  .cm-head{padding:15px 15px 13px}
  /* The LEFT and RIGHT insets are still added, because nothing else clears
     them; the BOTTOM one is not, because --floor already carries the home
     indicator (§6) and the sheet is resting on --floor. Adding it here counted
     it twice and lifted the tiles that far off the bottom of the sheet. */
  .cm-body{padding:13px calc(13px + env(safe-area-inset-left))
                   13px
                   calc(13px + env(safe-area-inset-right))}
  .cm-tiles{gap:9px}
  .cm-tile{aspect-ratio:6/5;padding:14px 10px;gap:13px}
  .cm-ico svg{width:34px;height:34px}
  .cm-txt strong{font-size:13.5px}
  .cm-txt small{font-size:11px;max-width:21ch}
}
@media (max-width:360px){
  .cm-tiles{grid-template-columns:1fr}
  .cm-tile{aspect-ratio:3/2}
}

@media (prefers-reduced-motion:reduce){
  .cm-scrim,.cm-sheet,.cm-sheet.on{animation:none;transition:none}
  /* .cm-tile.p-hive is listed IN ITS OWN RIGHT, not for symmetry: it carries a
     transition of its own at one class more specificity, so `.cm-tile` alone
     does not outrank it and the hive tile would have gone on animating --veil
     for a reader who asked the browser to stop. */
  .cm-tile,.cm-tile.p-hive,.cm-bg,.cm-shade,.cm-ico,.cm-tile::before{transition:none}
  .cm-tile:hover .cm-bg{transform:scale(1.02)}
  .cm-tile:hover .cm-ico{transform:none}
}

/* The page underneath must not scroll behind an open sheet. The mod composer's
   own lock class is deliberately not reused: the two can never be open at once
   (pressing the mod tile closes this one first), but sharing a class would mean
   whichever closed second unlocked the page for both. */
body.cm-locked{overflow:hidden}


/* ════════════════════════════════════════════════════════════════════════
   DRAFTS — /drafts.  Markup: views/app/page-drafts.php
                      Rows:   app/render-drafts.php
                      Data:   app/Drafts.php
                      Behaviour: views/app/js/07i-drafts.php

   IT DEFINES NO COLOUR THE SITE ALREADY PUBLISHES. Every --dr-* resolves to a
   :root token, the mod composer's rule and the hover card's: the accent is
   operator-configurable from the Appearance screen, and a page carrying
   #EA580C would be the one orange thing that did not move when somebody
   repainted the site.
   ════════════════════════════════════════════════════════════════════════ */
.dr{
  --dr-panel:var(--surface); --dr-sunken:var(--surface2);
  --dr-line:var(--border); --dr-line2:var(--border2);
  --dr-ink:var(--text); --dr-ink2:var(--t2); --dr-ink3:var(--t3);
}

.dr{padding-top:var(--pad-top,26px);padding-bottom:36px}

.dr-head{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap;margin-bottom:22px}
.dr-head h1{margin:0;font-family:var(--dis);font-size:26px;font-weight:600;letter-spacing:-.02em}
.dr-head p{margin:4px 0 0;color:var(--dr-ink3);font-size:13.5px}
.dr-new{margin-left:auto;height:var(--btn-h-lg,44px);padding:0 16px}

.dr-sec{margin-bottom:30px}
.dr-sh{margin-bottom:11px}
.dr-sh h2{margin:0;font-family:var(--dis);font-size:15px;font-weight:600;letter-spacing:-.012em;
  text-transform:uppercase;letter-spacing:.06em;color:var(--dr-ink2);font-size:11.5px}
.dr-sh p{margin:5px 0 0;color:var(--dr-ink3);font-size:13px}

/* ── the list ──────────────────────────────────────────────────────────────
   One row shape for a mod, a listing and an unfinished form, because they are
   one sentence: a picture, what it is called, what it is about, one way to
   finish it. Rows share a container border rather than each carrying their own,
   so a column of six does not read as six separate cards. */
.dr-list{border:1px solid var(--dr-line);border-radius:var(--r-lg);
  background:var(--dr-panel);overflow:hidden}
.dr-row{display:flex;align-items:center;gap:13px;width:100%;
  padding:11px 13px;text-align:left;font:inherit;color:inherit;
  background:none;border:0;border-top:1px solid var(--dr-line);cursor:pointer;
  text-decoration:none;transition:background .13s var(--ease)}
.dr-row:first-child{border-top:0}
.dr-row:hover{background:var(--dr-sunken)}
.dr-row:focus-visible{outline:2px solid var(--dr-ink);outline-offset:-2px}

.dr-pic{flex:0 0 auto;width:64px;height:48px;border-radius:8px;overflow:hidden;
  background:var(--dr-sunken);display:grid;place-items:center}
.dr-pic img{width:100%;height:100%;object-fit:cover;display:block}
.dr-ph{color:var(--dr-ink3);display:grid;place-items:center}

.dr-m{min-width:0;flex:1 1 auto}
.dr-t{display:block;font-weight:600;font-size:14.5px;letter-spacing:-.008em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dr-l{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:3px;
  font-size:12.5px;color:var(--dr-ink3)}
.dr-cat{display:inline-flex;align-items:center;gap:5px}
/* No width here. `.ic.cat-ic` is the ONE rule that sizes a category mark
   (test/category-glyph-size.php) and a local width would outrank it silently. */
.dr-car{color:var(--dr-ink3)}
.dr-price{color:var(--dr-ink2);font-weight:600}
.dr-none{color:var(--dr-ink3);font-style:italic}

.dr-go{flex:0 0 auto;display:inline-flex;align-items:center;gap:9px;color:var(--dr-ink3)}
/* The verb, not a status. Every row on this page is a draft, so a badge reading
   "Draft" on all of them would be the page's own title repeated once per line;
   what differs between rows is nothing, and what the reader wants is the way in. */
.dr-tag{font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  padding:3px 8px;border-radius:999px;
  background:var(--accent-soft);color:var(--accent-fg);
  border:1px solid var(--accent-line)}
.dr-row:hover .dr-go{color:var(--dr-ink2)}

.dr-empty{margin:0;padding:20px 16px;border:1px dashed var(--dr-line2);
  border-radius:var(--r-lg);color:var(--dr-ink3);font-size:13.5px}

@media (max-width:600px){
  .dr-head{gap:12px}
  .dr-new{margin-left:0;width:100%;justify-content:center}
  .dr-row{padding:10px 11px;gap:11px}
  .dr-pic{width:54px;height:42px}
  .dr-t{font-size:14px}
  /* The chevron carries no information a whole row that is obviously pressable
     does not already carry, and 44px of thumb target is worth more than it. */
  .dr-go .ic{display:none}
}


/* ════════════════════════════════════════════════════════════════════════
   CONTROLS — the fields the mod sheet never needed.

   A mod is a title, a description and three dropdowns. A vehicle is a record:
   an identity row, half a dozen optional fields, a story. An event is a when
   and a where with two switches on it. So this file is text inputs, rows,
   section rules, toggles and the two things that turn .mc-dd from a list of
   five into a list of a hundred — a search box and a way to enter what the
   list does not have.
   ════════════════════════════════════════════════════════════════════════ */

/* ── section rules ─────────────────────────────────────────────────────────
   REQUIRED and OPTIONAL, as a labelled rule. Three fields gate publishing and
   nine do not, and a form that does not say which is which is a form people
   fill in entirely before discovering that most of it was voluntary. The chip
   in the head counts what is missing; this says where the missing things are. */
.mc-grp + .mc-grp{margin-top:28px}
.mc-sec{display:flex;align-items:center;gap:11px;margin-bottom:13px}
.mc-sec-t{font-family:var(--mono);font-size:10.5px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--mc-ink);white-space:nowrap}
.mc-sec-r{flex:1 1 0%;height:1px;background:var(--mc-line)}

/* ── rows ──────────────────────────────────────────────────────────────────
   .mc-row is the plain two-up; .mc-idrow is the identity row, which gets more
   height and a larger type size because it is the record — the year, make and
   model ARE the car, and everything under them is decoration by comparison.
   Its first column is fixed: a year is four characters and giving it a third
   of the width makes the two fields that carry real words narrower for it. */
.mc-row{display:grid;gap:11px;margin-top:18px}
.mc-row.c2{grid-template-columns:1fr 1fr}
.mc-row.c3{grid-template-columns:104px 1fr 1fr}
.mc-sub{min-width:0}
.mc-idrow{display:grid;grid-template-columns:106px 1fr 1fr;gap:11px}
.mc-idrow .mc-in,.mc-idrow .mc-dd-btn{height:54px;font-size:16px}
.mc-idrow .mc-in::placeholder{font-size:15px}

/* ── text input ────────────────────────────────────────────────────────────
   Matched to .mc-dd-btn's height, padding and radius on purpose: an input and
   a dropdown sit side by side in nearly every row here, and two controls that
   are one pixel different in height is the thing you cannot stop seeing. */
.mc-in{width:100%;height:48px;padding:0 14px;border:1px solid var(--mc-line);border-radius:10px;
  background:var(--mc-sunken);font-family:var(--ui);font-size:14.5px;font-weight:500;
  color:var(--mc-ink);outline:none;transition:border-color .16s,background .16s,box-shadow .16s}
.mc-in::placeholder{color:var(--mc-ink3);font-weight:400}
.mc-in:hover{border-color:var(--mc-line2)}
.mc-in:focus{border-color:var(--mc-acc);background:var(--mc-panel);box-shadow:0 0 0 3px var(--mc-acc-wash)}
.mc-in.bad{border-color:var(--mc-err)}
.mc-in.bad:focus{box-shadow:0 0 0 3px var(--mc-err-wash)}

/* an input with a glyph in it. The icon is pointer-events:none or it eats the
   click that focuses the field it is sitting inside. */
.mc-inw{position:relative;display:block}
.mc-inw .mc-inw-i{position:absolute;left:14px;top:50%;transform:translateY(-50%);
  color:var(--mc-ink3);pointer-events:none;display:flex;transition:color .16s}
.mc-inw .mc-in{padding-left:40px}
.mc-inw:focus-within .mc-inw-i{color:var(--mc-acc)}

/* ── what a refusal looks like ─────────────────────────────────────────────
   THE EYEBROW AND THE CONTROL, NEVER A SENTENCE. The chip in the head already
   says what is missing, in one line, counting down; a second copy of that
   under each field would be the same words three times on one screen, and the
   two would then have to be kept saying the same thing. Marking is also only
   ever applied after somebody has PRESSED the button (the engine's `forced`
   flag) — a form that turns red while you are still filling it in is telling
   you off for not having finished yet. */
.mc-f.bad .mc-eyebrow,.mc-sub.bad .mc-eyebrow{color:var(--mc-err)}
.mc-f.bad .mc-dd-btn,.mc-sub.bad .mc-dd-btn,
.mc-f.bad .mc-in,.mc-sub.bad .mc-in{border-color:var(--mc-err)}
.mc-f.bad .mc-photofield{border-color:var(--mc-err);background:var(--mc-err-wash)}

/* ── the dropdown, for a list nobody can read at a glance ──────────────────
   .mc-dd itself is 29-mod-composer.php's. What is added here is what a list of
   a hundred makes needs and a list of five statuses does not: a filter box
   that sticks to the top of the list while the options scroll under it, an
   empty state that says which list came back empty, and the row that offers to
   use what was typed. The mod sheet's three dropdowns never draw any of it —
   the engine only emits the search box past its own threshold. */
.mc-dd-opts{max-height:236px;overflow-y:auto;overscroll-behavior:contain}
.mc-dd-search{display:flex;align-items:center;gap:8px;padding:7px 9px;margin:-2px -2px 5px;
  border-bottom:1px solid var(--mc-line);color:var(--mc-ink3);
  position:sticky;top:0;background:var(--mc-panel);z-index:2}
.mc-dd-search input{flex:1;min-width:0;border:0;background:none;outline:none;
  font-family:var(--ui);font-size:14px;color:var(--mc-ink)}
.mc-dd-search input::placeholder{color:var(--mc-ink3)}
.mc-dd-empty{margin:0;padding:14px 11px;font-size:13px;color:var(--mc-ink3);text-align:center}
/* the second line under an option — Status reads "Daily · You drive it now."
   rather than one word, which is the information the field exists to give */
.mc-dd-opt small{display:block;font-size:11.5px;color:var(--mc-ink3);font-weight:400;margin-top:1px}
.mc-dd-opt.sel small{color:var(--mc-acc-ink);opacity:.75}
/* "Use 'Skyline'" — see the engine on why only some lists offer it */
.mc-dd-opt.custom{color:var(--mc-acc-ink);font-weight:600}
.mc-dd-opt.custom .oic{opacity:1}
/* a chosen value the list does not contain. The lead glyph goes quiet because
   the one it would show belongs to the FIELD rather than to this answer, and a
   confident icon beside a value nothing recognises overstates it. */
.mc-dd.is-custom .mc-dd-btn .lead{color:var(--mc-ink3)}

/* ── toggles ───────────────────────────────────────────────────────────────
   Squared off deliberately: a fully rounded track is the one shape this design
   system does not use anywhere else, and a switch borrowed from another system
   is the control that reads as somebody else's. The <input> is the state —
   visually hidden rather than display:none, so it keeps its focus ring
   (:focus-visible ~ .mc-sw) and its keyboard. */
.mc-togs{border:1px solid var(--mc-line);border-radius:11px;background:var(--mc-panel);padding:0 13px}
.mc-tog{display:flex;align-items:flex-start;gap:14px;padding:12px 0;cursor:pointer;user-select:none}
.mc-tog + .mc-tog,.mc-tog-more + .mc-tog{border-top:1px solid var(--mc-line)}
.mc-tog input{position:absolute;opacity:0;width:0;height:0}
.mc-tog-txt{flex:1 1 0%;min-width:0}
.mc-tog-txt b{display:block;font-size:14px;font-weight:600;letter-spacing:-.012em;color:var(--mc-ink)}
.mc-tog-txt small{display:block;font-size:12px;line-height:1.45;color:var(--mc-ink3);margin-top:1px}
.mc-sw{flex-shrink:0;width:38px;height:22px;border-radius:7px;background:var(--mc-line2);
  padding:3px;display:flex;margin-top:1px;transition:background .16s}
.mc-sw i{width:16px;height:16px;border-radius:5px;background:var(--mc-panel);
  box-shadow:var(--sh-sm);transition:transform .18s var(--ease)}
.mc-tog input:checked ~ .mc-sw{background:var(--mc-acc)}
.mc-tog input:checked ~ .mc-sw i{transform:translateX(16px)}
.mc-tog input:focus-visible ~ .mc-sw{box-shadow:0 0 0 3px var(--mc-acc-wash)}
/* the field a switch reveals. It sits INSIDE the group and under the row that
   turned it on, so "Repeats → how often" reads as one question rather than as
   a field that appeared somewhere else on the form. */
.mc-tog-more{padding:0 0 13px;display:grid;gap:7px}
.mc-tog-more[hidden]{display:none}
.mc-tog-more .mc-in,.mc-tog-more .mc-dd-btn{height:42px;background:var(--mc-sunken)}

.mc-vingo:focus-visible,.lst-addbtn:focus-visible{outline:2px solid var(--mc-acc);outline-offset:2px}


/* ════════════════════════════════════════════════════════════════════════
   THE COVER — one object, three sizes.

   A vehicle sheet opens on the car, an event has a cover field down in
   Optional, and a listing's photo is the left half of its price tag. Those are
   the SAME control at three sizes and it is written once: empty it is an
   invitation, filled it is the picture with a rail of thumbnails along the
   bottom and a Remove in the corner. `.has` is the only state, set by the
   engine when a photo lands.

   IT IS NOT mountPhotoEditor() AND NOT THE amsup TRAY. The tray draws a grid
   of equal tiles, which is right where every photo is a photo of the same
   thing; here the FIRST one is the cover and the rest are candidates for it, so
   the first is the whole frame and the others are 42px along the bottom. The
   editor crops a background-image on a div and this is a real <img>, which is
   what alt text hangs on — the same reason the vehicle profile's own cover is
   an <img> (views/app/css/07b-vehicle-profile/).
   ════════════════════════════════════════════════════════════════════════ */

.veh-cover{position:relative;z-index:1;flex:3 1 0%;min-width:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:9px;padding:0 18px;overflow:hidden;cursor:pointer;
  transition:background-color .18s}
.veh-cover:hover,.veh-cover.drag{background-color:rgba(255,255,255,.07)}
.veh-cover:focus-visible{outline:2px solid #fff;outline-offset:-4px}

.veh-cover-cta{display:flex;flex-direction:column;align-items:center;gap:2px;text-align:center;
  pointer-events:none}
.veh-cover-cta b{font-family:var(--dis);font-size:14px;font-weight:600;letter-spacing:-.018em;
  color:rgba(255,255,255,.94)}
.veh-cover-cta span{font-size:12px;color:rgba(255,255,255,.58)}

/* filled. The invitation goes rather than being dimmed — a "drag one in" under
   a photograph is an instruction for a job already done. */
.veh-cover.has{background-image:none;background-color:#15151A;cursor:default}
.veh-cover.has .veh-carline,.veh-cover.has .veh-cover-cta{display:none}
.veh-cover-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:none}
.veh-cover.has .veh-cover-img{display:block}
/* the rail and the Remove sit ON the photograph, and a photograph of a silver
   car in daylight is white where they are. The gradient is what keeps them
   readable without dimming the whole picture. */
.veh-cover.has::after{content:"";position:absolute;left:0;right:0;bottom:0;height:74px;
  background:linear-gradient(to top,rgba(8,8,11,.72),transparent);pointer-events:none}

/* ── the rail ──────────────────────────────────────────────────────────────
   Every photo taken, cover first. Pressing one MAKES it the cover — which is
   the opposite of the vehicle profile's filmstrip, where pressing a thumbnail
   is a browse and saves nothing. The difference is that nothing here is saved
   yet at all: there is no record to change, only an order to set, and
   attachments.ord is what decides the cover everywhere else on the site. */
.veh-rail{position:absolute;left:12px;bottom:12px;z-index:2;display:none;gap:6px;align-items:center}
.veh-cover.has .veh-rail{display:flex}
.veh-thumb{position:relative;width:42px;height:32px;border-radius:7px;overflow:hidden;flex-shrink:0;
  border:1px solid rgba(255,255,255,.28);background:#26262C;padding:0;cursor:pointer}
.veh-thumb img{width:100%;height:100%;object-fit:cover;display:block}
.veh-thumb.on{border-color:#fff;box-shadow:0 0 0 2px rgba(255,255,255,.3)}
.veh-add{width:42px;height:32px;border-radius:7px;flex-shrink:0;border:1px dashed rgba(255,255,255,.42);
  background:rgba(255,255,255,.09);color:#fff;display:grid;place-items:center;cursor:pointer;padding:0}
.veh-add:hover{background:rgba(255,255,255,.18)}

.veh-cover-x{position:absolute;right:12px;bottom:12px;z-index:2;display:none;height:32px;padding:0 12px;
  border-radius:8px;border:1px solid rgba(255,255,255,.24);background:rgba(8,8,11,.5);color:#fff;
  font-family:var(--ui);font-size:12.5px;font-weight:600;cursor:pointer;backdrop-filter:blur(4px)}
.veh-cover.has .veh-cover-x{display:block}
.veh-cover-x:hover{background:rgba(8,8,11,.75)}
.veh-cover-cap{position:absolute;left:12px;top:12px;z-index:2;display:none;font-family:var(--mono);
  font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;color:rgba(255,255,255,.72)}
.veh-cover.has .veh-cover-cap{display:block}

/* THE UPLOAD'S OWN PROGRESS, ON THE PHOTOGRAPH IT BELONGS TO. Every caller of
   uploadMedia() passes onProgress and the check fails on one that does not —
   an upload with no feedback throws nothing and resolves fine, which is exactly
   why it survived on five surfaces. Here the bar rides the tile: a phone on a
   phone connection is where this matters, and a spinner in the corner of the
   sheet would not say WHICH of four photos is still going. */
.veh-thumb.up::after{content:"";position:absolute;left:0;bottom:0;height:3px;
  width:calc(var(--up-pct,0) * 1%);background:var(--mc-acc);transition:width .18s linear}
.veh-thumb.up{opacity:.72}
.veh-thumb.failed{border-color:var(--mc-err);opacity:1}
.veh-thumb.failed::after{content:"!";position:absolute;inset:0;display:grid;place-items:center;
  background:rgba(180,52,44,.62);color:#fff;font-size:13px;font-weight:700}

/* ── a cover that sits in the form rather than leading the sheet ───────────
   The event's. Dashed until it holds something, because in the middle of a
   form an empty solid box reads as a field that failed to load. */
.veh-cover.mc-photofield{height:104px;flex:none;border:1px dashed var(--mc-line2);border-radius:10px;
  background:var(--mc-sunken);gap:7px;padding:0 14px}
.veh-cover.mc-photofield:hover{background:var(--mc-acc-wash);border-color:var(--mc-acc)}
.veh-cover.mc-photofield .veh-cover-cta b{font-size:13.5px;color:var(--mc-acc-ink)}
.veh-cover.mc-photofield .veh-cover-cta span{font-size:12px;color:var(--mc-ink3)}
.veh-cover.mc-photofield .cs-upic{color:var(--mc-acc);opacity:.85}
.veh-cover.mc-photofield.has{border-style:solid;border-color:var(--mc-line)}
.veh-cover.mc-photofield.has .cs-upic{display:none}


/* ════════════════════════════════════════════════════════════════════════
   THE VEHICLE HERO — the two ways to start a car record.

   A mod is a written record, so its sheet opens on a text field. A vehicle is
   a physical object you know by LOOKING at it, so this one opens on the car:
   empty it is a full-bleed invitation the shape of the garage card you are
   about to make, filled it is your car sitting at the top of the sheet the
   whole time you work.

   IT SITS OUTSIDE .mc-scroll DELIBERATELY. It does not scroll away — the
   photograph is what you are checking the fields against, and a form where the
   subject leaves the screen as you fill it in is a form you fill in from
   memory.

   THE VIN TAKES A QUARTER OF IT, and that is the judgement in this file. A VIN
   fills three of the four required fields in one press, so it is not an
   optional extra buried under a section rule — it is the OTHER way to start
   the record, and it belongs beside the first one. Most people will not have
   one to hand, which is why it is a quarter and not a half, and why what it
   opens — the scanner, 02b-vin-scanner.php — is a window of its own rather
   than a row of the form.
   ════════════════════════════════════════════════════════════════════════ */

.veh-hero{position:relative;flex-shrink:0;display:flex;height:144px;overflow:hidden;background:#15151A}

/* EVERY BRANDED COLOUR IN THE HERO IS ON THIS ONE LAYER — ground, hex pattern
   and the scrim under the caption. Nothing else sits on it, so the saturate()
   below cannot reach a photograph: a filter applies to an element and all its
   descendants, and with this on .veh-hero itself every car anybody uploaded
   would come up washed out, which is the kind of thing that reads as a bad
   camera rather than as a bug.
 
   THE BLUE IS THE ONE COLOUR HERE THAT IS NOT A TOKEN. It is the hero's own
   ground and it is deliberately not the accent: the accent is
   operator-configurable, the VIN pane beside this one IS the accent, and two
   panes in one object both moving to the same repaint would collapse the
   hero into a single flat block. The hex is the site's mark, at the tint the
   pattern reads at over this ground. */
.veh-hero-paint{position:absolute;inset:0;z-index:0;pointer-events:none;
  background-color:#154378;
  background-image:
    radial-gradient(ellipse 46% 76% at 37% 46%,rgba(21,67,120,.9) 0%,rgba(21,67,120,.5) 54%,rgba(21,67,120,0) 100%),
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='138' height='239.02' viewBox='0 0 138 239.02'><g fill='none' stroke='%235B8CBC' stroke-width='9.6' stroke-opacity='.62'><path d='M69 0 L138 39.84 L138 119.51 L69 159.35 L0 119.51 L0 39.84 Z'/><path d='M69 159.35 L69 239.02'/></g></svg>");
  background-size:auto,10px 17.32px;
  /* the hero is a big block of colour sitting above the form the whole time
     you work, so it runs muted. The accent stays at full strength — it only
     ever appears in small marks that have to carry weight. */
  filter:saturate(.6)}

.veh-carline{width:88px;height:auto;color:#fff;opacity:.82;pointer-events:none;
  transition:opacity .18s,transform .2s var(--ease)}
.veh-cover:hover .veh-carline{transform:translateY(-2px)}

/* ── the VIN pane ──────────────────────────────────────────────────────────
   A <button> rather than a div with a role, because it is one: it opens the
   scanner. It carries the accent at full strength against the muted hero,
   which is what makes a quarter of the width read as an equal offer. */
.veh-vin-pane{position:relative;z-index:1;flex:1 1 0%;min-width:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:5px;padding:0 10px;cursor:pointer;
  border:0;color:#fff;font-family:var(--ui);text-align:center;
  background-color:var(--mc-acc);
  background-image:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='138' height='239.02' viewBox='0 0 138 239.02'><g fill='none' stroke='%23FFFFFF' stroke-width='9.6' stroke-opacity='.20'><path d='M69 0 L138 39.84 L138 119.51 L69 159.35 L0 119.51 L0 39.84 Z'/><path d='M69 159.35 L69 239.02'/></g></svg>");
  background-size:10px 17.32px;
  transition:background-color .16s}
.veh-vin-pane:hover{background-color:color-mix(in srgb,var(--mc-acc) 88%,#000)}
.veh-vin-pane.on{background-color:color-mix(in srgb,var(--mc-acc) 76%,#000)}
.veh-vin-pane:focus-visible{outline:2px solid #fff;outline-offset:-4px}
.veh-vin-pane .ic{opacity:.9;margin-bottom:1px}
.veh-vin-pane b{font-size:12.5px;font-weight:600;letter-spacing:-.01em;color:#fff;line-height:1.25}
.veh-vin-pane span{font-size:11px;line-height:1.35;color:rgba(255,255,255,.78);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.veh-vin-pane.done .ic{color:#fff}



/* ════════════════════════════════════════════════════════════════════════
   THE VIN SCANNER — the window the vehicle sheet's VIN pane opens.

   ITS OWN WINDOW RATHER THAN A STRIP IN THE FORM. You are holding a phone up
   to a door jamb with one hand; the viewfinder wants the whole screen, not
   150px of it. Typing sits underneath, for the desk and for a camera that was
   refused. Markup: the foot of views/app/sheet-vehicle.php. Behaviour:
   views/app/js/07j-create-sheet/03b-vin-scanner.php.

   IT IS A CHILD OF <body> AND A SCRIMMED OVERLAY, so it ends at --floor-modal
   like the sheet under it (29-mod-composer.php's rule, test/floor-insets.php)
   and sits ABOVE .mc-sheet (z-1310) and below #adminbar (z-1900).

   ITS STATES ARE `is-live`, `is-nocam` AND `is-hit`, NAMESPACED FOR A REASON
   THAT HAS ALREADY COST THIS SITE ONCE: there is a bare global `.live` in
   00-tokens-and-buttons.php — the seven-pixel green dot of the live pulse —
   and with the viewfinder wearing `.live` it became exactly that, 7×7 and
   round, with nothing thrown. The share sheet met the same thing in `.fit`.

   IT DEFINES NO COLOUR OF ITS OWN. The panel, the head and every line of text
   are the --mc-* tokens the inner .mc declares, so the scanner repaints with
   the accent. The two fixed darks — the viewfinder's ground and the hit
   wash — are the one place that is right: a camera feed is dark whatever the
   theme, and the brackets over it are white for the same reason.
   ════════════════════════════════════════════════════════════════════════ */

.vin-scrim{position:fixed;inset:0;z-index:1500;background:rgba(10,12,16,.5);
  opacity:0;transition:opacity .2s var(--ease)}
.vin-scrim.on{opacity:1}
.vin-scrim:not(.on),.vin-modal:not(.on){pointer-events:none}
.vin-scrim[hidden],.vin-modal[hidden]{display:none !important}

.vin-modal{position:fixed;inset:0 0 var(--floor-modal,0px) 0;margin:auto;z-index:1510;
  width:min(462px,calc(100vw - 32px));height:fit-content;
  max-height:min(760px,calc(100vh - 56px - var(--floor-modal,0px)));
  display:flex;flex-direction:column;overflow:hidden;
  background:var(--surface);border:1px solid var(--border);border-radius:16px;
  box-shadow:var(--sh-lg);opacity:0;transition:opacity .2s var(--ease)}
.vin-modal.on{opacity:1;animation:mc-in .24s var(--ease)}
.vin-modal:focus{outline:none}
.vin-head{background:var(--mc-sunken)}
/* the sub-line is an instruction — where the sticker IS — so it wraps rather
   than trimming to "The barcode on the door…" */
.vin-head small{white-space:normal;line-height:1.35}
.vin-kind{width:34px;height:34px;border-radius:10px;flex-shrink:0;display:flex;align-items:center;
  justify-content:center;background:var(--mc-acc-wash);color:var(--mc-acc)}
.vin-bd{padding:14px 16px 16px;overflow-y:auto;min-height:0}

/* ── the viewfinder ──────────────────────────────────────────────────────── */
.vin-cam{position:relative;aspect-ratio:4 / 3;max-height:46vh;border-radius:12px;overflow:hidden;
  background:#0B0D11;display:grid;place-items:center}
.vin-cam video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:none}
.vin-cam.is-live video{display:block}
.vin-idle{display:flex;flex-direction:column;align-items:center;gap:10px;padding:0 28px;
  color:rgba(255,255,255,.66);font-size:13px;line-height:1.5;text-align:center}
.vin-cam.is-live .vin-idle{display:none}
/* "Use a photo" is offered only where the camera could not be opened. Drawn
   with a live feed it is a second way to do what the feed is already doing;
   drawn where nothing can read a barcode it is a button onto a refusal. */
.vin-photo{display:none;align-items:center;gap:6px;height:34px;padding:0 14px;margin-top:2px;
  border:1px solid rgba(255,255,255,.28);border-radius:9px;background:rgba(255,255,255,.1);
  color:#fff;font-family:var(--ui);font-size:12.5px;font-weight:600;cursor:pointer}
.vin-photo:hover{background:rgba(255,255,255,.17)}
.vin-cam.is-nocam .vin-photo{display:inline-flex}

/* corner brackets rather than a box — a full border reads as a crop tool,
   brackets read as a scanner. Sized to a VIN barcode, long and shallow, so
   it tells you how to hold the phone. */
.vin-frame{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:none;
  width:84%;height:64px;box-shadow:0 0 0 999px rgba(8,10,14,.52)}
.vin-cam.is-live .vin-frame{display:block}
.vin-frame i{position:absolute;width:26px;height:26px;border:2.5px solid #fff}
.vin-frame i.tl{left:-1px;top:-1px;border-right:0;border-bottom:0;border-radius:10px 0 0 0}
.vin-frame i.tr{right:-1px;top:-1px;border-left:0;border-bottom:0;border-radius:0 10px 0 0}
.vin-frame i.bl{left:-1px;bottom:-1px;border-right:0;border-top:0;border-radius:0 0 0 10px}
.vin-frame i.br{right:-1px;bottom:-1px;border-left:0;border-top:0;border-radius:0 0 10px 0}
.vin-line{position:absolute;left:6px;right:6px;height:2px;background:var(--mc-acc);
  box-shadow:0 0 10px var(--mc-acc);animation:vinscan 2s ease-in-out infinite}
@keyframes vinscan{0%,100%{top:4px}50%{top:calc(100% - 6px)}}

/* the helper line sits over the feed so the panel below it carries status
   alone */
.vin-bar{position:absolute;left:0;right:0;bottom:0;z-index:3;display:none;padding:26px 12px 11px;
  background:linear-gradient(to top,rgba(8,10,14,.86),transparent)}
.vin-cam.is-live .vin-bar{display:flex}
.vin-bar span{color:rgba(255,255,255,.88);font-size:12.5px;line-height:1.4}

/* the payoff — worth a beat before the window closes. The lens is already
   released by the time this is drawn; the wash covers a feed that has gone
   black. */
.vin-hit{position:absolute;inset:0;z-index:5;display:none;flex-direction:column;align-items:center;
  justify-content:center;gap:12px;background:rgba(9,30,19,.86);animation:mcfade .18s var(--ease)}
.vin-cam.is-hit .vin-hit{display:flex}
.vin-tick{width:46px;height:46px;border-radius:14px;display:grid;place-items:center;
  background:var(--mc-ok);color:#08130C}
.vin-hit b{font-family:var(--mono);font-size:13px;letter-spacing:.1em;color:#fff}

/* :empty rather than a hidden attribute the JS has to remember to set — a
   status line that stays in the layout as a blank strip is a gap nobody can
   explain, and one that has to be un-hidden is one that eventually is not. */
.vin-camnote{margin:11px 2px 0;font-size:12.5px;line-height:1.5;color:var(--mc-ink3)}
.vin-camnote:empty{display:none}
.vin-camnote.err{color:var(--mc-err)}
.vin-camnote.ok{color:var(--mc-ok)}
.vin-or{display:flex;align-items:center;gap:11px;margin:15px 0 12px;font-family:var(--mono);
  font-size:9.5px;font-weight:500;letter-spacing:.18em;text-transform:uppercase;color:var(--mc-ink3)}
.vin-or::before,.vin-or::after{content:'';flex:1 1 0%;height:1px;background:var(--mc-line)}

/* ── typing it ───────────────────────────────────────────────────────────
   The input is mono and letter-spaced because a VIN is checked character by
   character against a plate — but its PLACEHOLDER is not, because a sentence
   set in mono with .09em of tracking is a sentence nobody reads. */
.mc-vinrow{display:flex;gap:8px}
.mc-vinrow .mc-in{flex:1;min-width:0;height:42px;font-family:var(--mono);font-size:13px;
  letter-spacing:.09em;text-transform:uppercase;background:var(--mc-panel)}
.mc-vinrow .mc-in::placeholder{font-family:var(--ui);font-size:13.5px;letter-spacing:0;text-transform:none}
.mc-vingo{height:42px;padding:0 16px;flex-shrink:0;display:inline-flex;align-items:center;gap:6px;
  border:1px solid var(--mc-acc);border-radius:10px;background:var(--mc-acc);color:var(--accent-on);
  font-family:var(--ui);font-size:13.5px;font-weight:600;cursor:pointer;transition:opacity .16s}
.mc-vingo[disabled]{opacity:.4;cursor:default}
.mc-vinmsg{margin:9px 2px 0;font-size:12px;line-height:1.45;color:var(--mc-ink3)}
.mc-vinmsg:empty{display:none}
.mc-vinmsg.err{color:var(--mc-err)}
.mc-vinmsg.ok{color:var(--mc-ok)}
.vin-photo:focus-visible,.vin-modal .mc-x:focus-visible{outline:2px solid var(--mc-acc);outline-offset:2px}


/* ════════════════════════════════════════════════════════════════════════
   THE EVENT'S WHEN — because an event is a moment before it is anything else.

   It takes the band the vehicle's photograph takes, and for the same reason:
   it is the thing the rest of the form is about, and it must not scroll away
   while you fill the rest in. It is a band and not a calendar — a whole month
   of squares to pick one day from is a component, and the thing it replaces is
   two native inputs that already work, already open the phone's own picker and
   already know what today is.

   A START AND AN END, EACH WITH ITS OWN DATE AND TIME. That shape is why there
   is no "runs over several days" switch: an event that spans days is a later
   end date, and a switch that reveals a field which was going to be there
   anyway is a question asked twice.
   ════════════════════════════════════════════════════════════════════════ */

.evt-when{flex-shrink:0;padding:13px 16px 15px;background:var(--mc-sunken);
  border-bottom:1px solid var(--mc-line);transition:background .18s}
.evt-when-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.evt-half{min-width:0}
.evt-pair{display:grid;grid-template-columns:1.22fr 1fr;gap:7px}
/* A GRID ITEM'S min-width IS auto, AND A NATIVE DATE INPUT'S min-content IS
   WIDE — wide enough that without this the time field beside it runs off the
   edge of the sheet. It is the same trap .evt-when-grid's own children are in,
   and the reason every grid in this stylesheet states it. */
.evt-pair > *{min-width:0}
.evt-when .mc-in{height:42px;padding:0 11px;background:var(--mc-panel);
  font-variant-numeric:tabular-nums}

/* THE WEEKDAY, WHICH IS THE ONE THING A NATIVE DATE INPUT HIDES. It shows
   09/05/2026; what decides whether anybody comes to a car meet is that it is a
   Saturday. It rides in the label rather than beside the field, so it reads as
   part of "Starts" instead of as a value somebody typed. */
.evt-when .mc-lab i{font-variant-numeric:normal}

/* All-day is set down in Optional, so the times have to visibly stop applying
   rather than quietly keeping a value nobody will use. pointer-events with the
   opacity, or they are still focusable by tab into a field that means nothing. */
.evt-when.allday .evt-t{opacity:.35;pointer-events:none}

/* THE REPEAT SENTENCE, UNDER THE BAND. Recur::sentence() writes it and
   AMSR.recurSentence() writes it here — the pair is diff-tested, because the
   sheet has to label the picker as the date is chosen, before the server has
   ever seen it. It is quiet type: it is a consequence of two answers rather
   than a third answer. */
.evt-rep{margin:9px 2px 0;font-size:12px;line-height:1.45;color:var(--mc-acc-ink);
  display:flex;align-items:center;gap:6px}
.evt-rep:empty{display:none}


/* ════════════════════════════════════════════════════════════════════════
   THE LISTING'S TAG, AND ITS FITMENT.

   A vehicle sheet opens on a photograph, an event on a date. A listing opens
   on a price tag: the picture on the left, what it is and what it costs on the
   right, in one object. Those three are also exactly what a listing cannot go
   up without — so the tag IS the required section, and there is nothing above
   the Optional rule but this.

   THE SILHOUETTE IS A SWING TAG AND IT IS CUT, NOT BORDERED. clip-path draws
   the pointed end, the punched hole and the clipped corners, which means the
   object can have no border — a tag is a solid piece of card, not an outlined
   box. That in turn is why the shadow lives on a WRAPPER: box-shadow follows
   the border box and would draw a rectangle behind a shape that is not one, so
   it is two drop-shadow() filters on .lst-tagwrap, which follow the cut edge.
   ════════════════════════════════════════════════════════════════════════ */

.lst-tagwrap{filter:drop-shadow(0 1px 1px rgba(12,12,16,.06)) drop-shadow(0 7px 16px rgba(12,12,16,.11))}
body.dark .lst-tagwrap{filter:drop-shadow(0 1px 1px rgba(0,0,0,.4)) drop-shadow(0 7px 16px rgba(0,0,0,.55))}

.lst-tag-block{position:relative;display:flex;padding-left:32px;overflow:hidden;
  background:var(--mc-panel);transition:background .18s;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.75);
  clip-path:polygon(32px 0,calc(100% - 8px) 0,calc(100% - 2.3px) 2.3px,100% 8px,100% calc(100% - 8px),calc(100% - 2.3px) calc(100% - 2.3px),calc(100% - 8px) 100%,32px 100%,0 calc(50% + 2px),0 calc(50% - 2px))}
body.dark .lst-tag-block{box-shadow:inset 0 1px 0 rgba(255,255,255,.06)}
.lst-tag-block.bad{background:var(--mc-err-wash)}

/* the eyelet: a reinforcing ring with the hole punched through it, the hole
   filled with the SHEET's own surface rather than with transparent, because
   clip-path has already cut the card away there and a real hole would show the
   scrim behind the sheet through it. */
.lst-tag-block::after{content:'';position:absolute;left:7px;top:50%;width:17px;height:17px;
  margin-top:-8.5px;border-radius:50%;background:var(--mc-sunken);
  box-shadow:inset 0 0 0 1px var(--mc-line);pointer-events:none;z-index:1}
.lst-tag-block::before{content:'';position:absolute;left:11px;top:50%;width:9px;height:9px;
  margin-top:-4.5px;border-radius:50%;background:var(--surface);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.26);pointer-events:none;z-index:2}

.veh-cover.lst-shotpane{flex:0 0 134px;min-height:128px;padding:0 8px;gap:4px;
  border:0;border-radius:0;background:var(--mc-sunken)}
.veh-cover.lst-shotpane:hover{background:var(--mc-acc-wash)}
.veh-cover.lst-shotpane .veh-cover-cta b{font-size:12.5px;color:var(--mc-acc-ink)}
.veh-cover.lst-shotpane .veh-cover-cta span{font-size:11px;color:var(--mc-ink3)}
.veh-cover.lst-shotpane .cs-upic{color:var(--mc-acc);opacity:.85}
.veh-cover.lst-shotpane.has .cs-upic{display:none}
.veh-cover.lst-shotpane .veh-cover-cap{display:none}
.lst-shotpane .veh-rail{left:7px;bottom:7px;gap:4px}
.lst-shotpane .veh-thumb,.lst-shotpane .veh-add{width:26px;height:20px;border-radius:5px}
.lst-shotpane .veh-cover-x{right:7px;top:7px;bottom:auto;height:23px;padding:0 8px;font-size:11px}

.lst-tag-bd{position:relative;flex:1 1 0%;min-width:0;padding:12px 15px 13px;display:grid;
  align-content:center;gap:9px}
/* the perforation between the picture and the words, and again between the
   name and the price — the two lines a real tag is scored along */
.lst-tag-bd::before{content:'';position:absolute;left:0;top:0;bottom:0;width:1px;
  background:repeating-linear-gradient(180deg,var(--mc-line2) 0 4px,transparent 4px 8px)}
.lst-tag-bd .mc-f-title{padding:0;margin:0;border:0}
.lst-tag-bd .mc-tin{font-size:15.5px;line-height:1.35}
.lst-tag-bd .mc-f-title.bad{border:0;padding:0}
.lst-tag-perf{height:1px;background:repeating-linear-gradient(90deg,
  var(--mc-line2) 0 4px,transparent 4px 8px)}
.lst-tag-row{display:grid;grid-template-columns:1.12fr 1fr;gap:8px}
.lst-tag-row > *{min-width:0}
.lst-cur{font-family:var(--dis);font-size:16px;font-weight:600;color:var(--mc-ink3)}
.lst-tag-row .mc-in,.lst-tag-row .mc-dd-btn{height:40px}
/* the price is the biggest thing on the tag, and it is DISPLAY type rather
   than mono: mono on this site means a measured figure (§ the feed card), and
   an asking price is a decision somebody made, not a measurement. */
.lst-tag-row .lst-price{font-family:var(--dis);font-size:19px;font-weight:600;
  letter-spacing:-.022em;padding-left:32px}
.lst-tag-row .mc-inw-i{left:11px}
/* terms with no number to type — Free, and Contact for price. The box is
   disabled rather than removed: a control that disappears takes the layout
   with it, and the row would reflow under the hand that just changed it. */
.lst-tag-row.noprice .mc-sub:first-child{opacity:.4}

/* ── fitment ───────────────────────────────────────────────────────────────
   THE ONE QUESTION EVERY PARTS BUYER ASKS FIRST. It reads the same catalogue
   the vehicle sheet does, so what comes out is a generation the site can match
   against a reader's garage — which is what makes the green fitment line on a
   parts card mean anything (app/Api/ApiFeedFit.php). Typed free text would
   look identical on this screen and match nothing for ever. */
.lst-fits{border:1px solid var(--mc-line);border-radius:11px;background:var(--mc-panel);
  padding:12px 13px;display:grid;gap:10px}
.lst-fits-add{display:grid;grid-template-columns:1fr 1fr auto;gap:8px}
.lst-fits-add > *{min-width:0}
.lst-fits-add .mc-dd-btn,.lst-addbtn{height:42px}
.lst-addbtn{padding:0 16px;flex-shrink:0;border:1px solid var(--mc-acc);border-radius:10px;
  background:var(--mc-acc);color:var(--accent-on);font-family:var(--ui);font-size:13.5px;
  font-weight:600;cursor:pointer;transition:opacity .16s}
.lst-addbtn[disabled]{opacity:.38;cursor:default}
.lst-list{display:grid;gap:6px}
.lst-list:empty{display:none}
.lst-fit{display:flex;align-items:center;gap:10px;padding:9px 10px 9px 12px;
  border:1px solid var(--mc-line);border-radius:9px;background:var(--mc-sunken)}
.lst-fit b{flex:1 1 0%;min-width:0;font-size:13.5px;font-weight:600;color:var(--mc-ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* the year span IS a measured figure, so this one is mono */
.lst-fit small{font-family:var(--mono);font-size:10.5px;color:var(--mc-ink3);flex-shrink:0}
.lst-fit-x{width:24px;height:24px;flex-shrink:0;display:grid;place-items:center;border:0;
  border-radius:6px;background:none;color:var(--mc-ink3);cursor:pointer;
  transition:background .14s,color .14s}
.lst-fit-x:hover{background:var(--mc-panel);color:var(--mc-err)}
.lst-none{margin:0;font-size:12px;line-height:1.5;color:var(--mc-ink3)}
.lst-tagwrap + .mc-grp{margin-top:22px}


/* ════════════════════════════════════════════════════════════════════════
   THE PHONE.

   .mc-sheet's own phone rules — the bottom sheet, the slide up, the
   --floor-modal it ends at — are 29-mod-composer.php's and are not restated
   here. What is below is only what these three sheets ADD to that shape.
   ════════════════════════════════════════════════════════════════════════ */

@media (max-width:640px){
  /* THE HERO SHRINKS RATHER THAN GOING, and the pattern shrinks with it. At
     118px a photograph is still a photograph; dropping it would take the one
     thing on the vehicle sheet that says what you are making. */
  .veh-hero{height:118px}
  .veh-cover{flex:2.3 1 0%;gap:6px;padding:0 12px}
  .veh-carline{width:66px}
  /* THE VIN PANE KEEPS ITS LABEL AND LOSES ITS SUBTITLE. "year · make · model"
     is what the shortcut is worth; "Decode a VIN" is what it IS, and a pane
     with no words on it is a coloured rectangle. */
  .veh-vin-pane{gap:4px;padding:0 8px}
  .veh-vin-pane b{font-size:11.5px;white-space:normal}
  .veh-vin-pane span{display:none}
  /* the decode button goes full width under its field rather than squeezing
     the 17 characters it sits beside into nothing */
  .mc-vinrow{flex-wrap:wrap}
  .mc-vingo{width:100%}
  /* THE SCANNER TAKES THE SCREEN. It is what you are holding up to the car,
     and a viewfinder with a margin round it is a smaller viewfinder. */
  .vin-modal{width:calc(100vw - 16px);max-height:calc(100vh - 24px - var(--floor-modal,0px))}
  .vin-cam{max-height:52vh}
}

@media (max-width:640px){
  /* one column, and the gap grows: side by side these read as a pair, stacked
     they need the space to stop reading as one long list */
  .evt-when-grid{grid-template-columns:1fr;gap:13px}
}
@media (max-width:400px){
  .evt-pair{grid-template-columns:1fr;gap:8px}
}

@media (max-width:560px){
  .mc-row.c2,.mc-row.c3{grid-template-columns:1fr;gap:14px}
  /* THE IDENTITY ROW STACKS TOO, AND THAT IS NOT A DEFEAT. Year, make and
     model in a 358px column are three fields of 110px, and a make is
     "Volkswagen". The row exists to make the record read as one thing on a
     desktop; on a phone the thing that matters is being able to read what you
     picked. */
  .mc-idrow{grid-template-columns:1fr;gap:14px}
  .lst-fits-add{grid-template-columns:1fr}
}

@media (max-width:600px){
  /* THE TAG TURNS, KEEPING ITS POINT AND ITS HOLE. The clip-path is restated
     rather than inherited because its first and eighth points are the padding
     that makes room for the eyelet, and that padding is 2px narrower here —
     a clip-path is one value, so it cannot be half-overridden. */
  .lst-tag-block{flex-direction:column;padding-left:30px;
    clip-path:polygon(30px 0,calc(100% - 8px) 0,calc(100% - 2.3px) 2.3px,100% 8px,
      100% calc(100% - 8px),calc(100% - 2.3px) calc(100% - 2.3px),calc(100% - 8px) 100%,
      30px 100%,0 calc(50% + 2px),0 calc(50% - 2px))}
  .lst-tag-block::after{left:6px}
  .lst-tag-block::before{left:10px}
  .veh-cover.lst-shotpane{flex:0 0 auto;min-height:104px}
  /* the perforation turns with the card: it was the vertical score between
     picture and words, and stacked it is the horizontal one above them */
  .lst-tag-bd::before{left:0;right:0;top:0;bottom:auto;width:auto;height:1px;
    background:repeating-linear-gradient(90deg,var(--mc-line2) 0 4px,transparent 4px 8px)}
}
@media (max-width:440px){.lst-tag-row{grid-template-columns:1fr}}

@media (prefers-reduced-motion:reduce){
  .veh-carline,.mc-sw i,.mc-dd-list,.vin-modal,.vin-scrim,.vin-line,.vin-hit{transition:none !important;animation:none !important}
  .vin-modal.on{opacity:1}
}


/* ════════════════════════════════════════════════════════════════════════
   PHOTO TITLES — the tool.  Markup: views/app/photo-notes.php
                             Behaviour: views/app/js/07l-photo-notes.php

   THE CHROME IS DARK IN BOTH THEMES, and it is the one colour of its own on
   this sheet. A photograph is titled against a darkroom grey so the picture
   is judged on its own rather than against whatever the page is — the Create
   chooser's plate rule. Every --pn-* below that names a colour the site
   already publishes resolves to the :root token (the accent on a pin, the
   card's surface and ink, the green tick), for the hover card's reason: the
   accent is operator-configurable and a tool carrying #EA580C would be the
   one orange thing that did not move when somebody repainted the site.

   --pn-steel IS THE TOOL'S OWN COLOUR FOR A MARKER COUNT — on the filmstrip,
   on a spot row's number, and on the gallery tile's "2 spots" pin outside
   this file — and it is declared on :root so that pin can read it. It is
   deliberately not the accent: the accent is a pin ON the picture, and a
   count of pins should not look like one of them.
   ════════════════════════════════════════════════════════════════════════ */
:root{ --pn-steel:#59A9E8; --pn-steel-ink:#06192B; --pn-steel-soft:rgba(89,169,232,.2) }
.pn-dlg{
  --pn-bg:#131619; --pn-chrome:#1A1E22; --pn-panel:#1F242A; --pn-sunk:#0E1113; --pn-raise:#272D34;
  --pn-hair:rgba(255,255,255,.08); --pn-hair2:rgba(255,255,255,.15);
  --pn-fg:#DFE4E9; --pn-fg2:#8B959F; --pn-fg3:#5C666F;
  --pn-ok:var(--green); --pn-warn:var(--warn,#E8B45A);
}

/* ── the shell ─────────────────────────────────────────────────────────────
   Centred with inset + margin:auto, NO transform: the entrance is an
   animation with no fill mode, so once it ends the computed transform is
   `none` again and nothing fixed inside it is re-parented (the mod sheet's
   note has the long form). The ladder is the marketplace's: scrim 1300,
   dialog 1310 — above the chat dock, below the admin bar.

   IT ENDS AT --floor-modal, NOT --floor. Its scrim covers the phone's tab
   bar, so leaving room for that bar holds a band of unusable navigation
   open under the tool. What a scrim cannot cover is #adminbar and the home
   indicator, and --floor-modal is exactly those two (§6). */
.pn-scrim{position:fixed;inset:0 0 var(--floor-modal,0px) 0;z-index:1300;background:rgba(8,10,12,.68);
  backdrop-filter:blur(4px);animation:pn-fade .18s var(--ease)}
.pn-scrim[hidden]{display:none}
@keyframes pn-fade{from{opacity:0}}
@keyframes pn-rise{from{opacity:0;transform:translateY(10px) scale(.99)}}
.pn-dlg{position:fixed;inset:0 0 var(--floor-modal,0px) 0;margin:auto;z-index:1310;
  width:min(1400px,calc(100vw - 40px));height:min(846px,calc(100vh - 40px - var(--floor-modal,0px)));
  background:var(--pn-bg);color:var(--pn-fg);border-radius:12px;overflow:hidden;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 0 0 1px rgba(0,0,0,.6),0 34px 90px -24px rgba(0,0,0,.75);
  display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:46px minmax(0,1fr) 28px;
  animation:pn-rise .24s var(--ease);
  font:450 13px/1.5 var(--ui);letter-spacing:-.008em}
.pn-dlg[hidden]{display:none}
body.pn-locked{overflow:hidden}
.pn-dlg button{font:inherit;color:inherit}
.pn-dlg :focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:3px}
.pn-sp{flex:1}

/* ── the bar ─────────────────────────────────────────────────────────── */
.pn-tbar{display:flex;align-items:center;gap:14px;padding:0 10px 0 16px;
  background:var(--pn-chrome);border-bottom:1px solid var(--pn-hair);min-width:0}
.pn-mark{font:600 12.5px/1 var(--dis);letter-spacing:-.012em;color:var(--pn-fg);flex:none}
.pn-path{font:400 11px/1 var(--mono);color:var(--pn-fg3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pn-path b{color:var(--pn-fg2);font-weight:400}
.pn-gauge{display:flex;align-items:center;gap:8px;flex:none}
.pn-gauge__bar{display:flex;gap:2px}
.pn-gauge__t{width:14px;height:4px;background:var(--pn-hair2)}
.pn-gauge__t.on{background:var(--pn-ok)}
.pn-gauge__n{font:500 11px/1 var(--mono);color:var(--pn-fg2)}
/* A tool button: glyph then label (§15), on the tool's own plate rather than
   .btn's, because .btn is the site's light-surface button and this bar is a
   darkroom. The glyph's size is stated here, once, the way .btn states its. */
.pn-tbtn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 12px;border:1px solid var(--pn-hair2);
  background:var(--pn-panel);color:var(--pn-fg2);font:450 11.5px/1 var(--ui);cursor:pointer;border-radius:4px;flex:none;
  transition:background .15s var(--ease),color .15s var(--ease)}
.pn-tbtn svg,.pn-tbtn>.ic{width:13px;height:13px}
.pn-tbtn:hover{background:var(--pn-raise);color:var(--pn-fg)}
.pn-tbtn--go{background:var(--pn-steel);border-color:var(--pn-steel);color:var(--pn-steel-ink);font-weight:500}
.pn-tbtn--go:hover{background:#6FB6EC;color:var(--pn-steel-ink)}
.pn-tbtn--go.done{background:var(--pn-ok);border-color:var(--pn-ok);color:#06210F}
.pn-tbtn[disabled]{opacity:.55;cursor:default}
.pn-xb{width:30px;height:30px;border-radius:4px;border:1px solid transparent;background:none;
  color:var(--pn-fg3);cursor:pointer;display:grid;place-items:center;flex:none;padding:0}
.pn-xb:hover{background:var(--pn-raise);color:var(--pn-fg)}

.pn-body{display:grid;grid-template-columns:98px minmax(0,1fr) 324px;min-height:0;min-width:0}

/* ── the filmstrip ───────────────────────────────────────────────────── */
.pn-strip{background:var(--pn-chrome);border-right:1px solid var(--pn-hair);
  overflow-y:auto;padding:8px;display:flex;flex-direction:column;gap:6px}
.pn-sh{position:relative;padding:0;border:1px solid var(--pn-hair);background:var(--pn-sunk);
  cursor:pointer;aspect-ratio:4/3;overflow:hidden;border-radius:3px;flex:none;
  transition:border-color .14s var(--ease)}
.pn-sh img{width:100%;height:100%;object-fit:cover;display:block;opacity:.6;transition:opacity .14s var(--ease)}
.pn-sh:hover img{opacity:.85}
.pn-sh.here{border-color:var(--pn-steel);box-shadow:0 0 0 1px var(--pn-steel)}
.pn-sh.here img{opacity:1}
.pn-sh__i{position:absolute;left:3px;top:3px;font:500 9px/1 var(--mono);color:var(--pn-fg);
  background:rgba(6,8,10,.82);padding:2px 4px;border-radius:2px}
.pn-sh__f{position:absolute;right:3px;bottom:3px;width:12px;height:12px;border-radius:2px;
  background:var(--pn-ok);color:#06210F;display:grid;place-items:center}
.pn-sh__f svg{width:8px;height:8px}
.pn-sh__f[hidden]{display:none}
.pn-sh__p{position:absolute;right:3px;top:3px;font:500 9px/1 var(--mono);
  color:var(--pn-steel-ink);background:var(--pn-steel);padding:2px 4px;border-radius:2px}
.pn-sh__p[hidden]{display:none}

/* ── the canvas, and the card on it ───────────────────────────────────── */
.pn-cv{position:relative;min-width:0;min-height:0;background:var(--pn-sunk);
  display:flex;align-items:center;justify-content:center;padding:26px}
/* THE CARD IS WHAT A VISITOR SEES: the site's own surface and ink, so a title
   typed here is previewed on the plate a reader on this theme will get. */
.pn-card{margin:auto;background:var(--surface);border-radius:7px;overflow:hidden;
  box-shadow:0 0 0 1px rgba(255,255,255,.13),0 30px 70px -28px #000;display:flex;flex-direction:column}
.pn-frame{position:relative;line-height:0;cursor:crosshair;flex:none}
.pn-frame img{display:block;width:100%;height:100%;object-fit:contain}
.pn-card__cap{padding:15px 18px 18px;background:var(--surface);flex:none}
.pn-card__t{margin:0;font:450 15px/1.5 var(--ui);letter-spacing:-.01em;color:var(--text)}
.pn-card__t.none{color:var(--t3);font-style:italic}
.pn-card__m{margin:8px 0 0;font:400 11px/1 var(--mono);color:var(--t3)}
.pn-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:3;width:28px;height:46px;
  padding:0;background:rgba(20,24,28,.88);border:1px solid var(--pn-hair2);color:var(--pn-fg2);
  display:grid;place-items:center;cursor:pointer;border-radius:4px}
.pn-nav:hover{color:var(--pn-fg);background:var(--pn-raise)}
.pn-nav:disabled{opacity:.22;cursor:default}
.pn-nav--p{left:9px}.pn-nav--n{right:9px}

/* A marker on the picture. The accent, because it is the site's mark for
   "here" and the same colour the lightbox draws the saved ones in; hollow
   while its line is still unwritten, black while its row has the focus. */
.pn-pin{position:absolute;transform:translate(-50%,-50%);width:21px;height:21px;border-radius:4px;
  padding:0;background:var(--accent);color:#fff;border:1.5px solid rgba(255,255,255,.92);
  font:500 10px/1 var(--mono);display:grid;place-items:center;cursor:grab;touch-action:none;
  overflow:visible;box-shadow:0 2px 9px rgba(0,0,0,.5);transition:box-shadow .14s var(--ease)}
.pn-pin:hover{box-shadow:0 0 0 3px var(--accent-line),0 2px 9px rgba(0,0,0,.5);z-index:5}
.pn-pin.on{background:#111;color:#fff;z-index:5}
.pn-pin.empty{background:#fff;color:var(--accent);border-color:var(--accent)}
.pn-pin.drag{cursor:grabbing;transition:none}
.pn-pin__l{position:absolute;left:50%;top:calc(100% + 7px);transform:translateX(-50%);
  max-width:230px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  background:rgba(8,11,13,.96);border:1px solid var(--pn-hair2);color:var(--pn-fg);
  font:450 11px/1.3 var(--ui);padding:5px 7px;border-radius:4px;pointer-events:none;
  opacity:0;transition:opacity .13s var(--ease)}
.pn-pin.flip .pn-pin__l{top:auto;bottom:calc(100% + 7px)}
.pn-pin:hover .pn-pin__l,.pn-pin.on .pn-pin__l{opacity:1}
.pn-pin__l:empty{display:none}

/* ── the inspector ───────────────────────────────────────────────────── */
.pn-insp{background:var(--pn-panel);border-left:1px solid var(--pn-hair);overflow-y:auto;min-height:0}
.pn-sect{border-bottom:1px solid var(--pn-hair);padding:13px 14px}
.pn-sect__h{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:10px}
.pn-sect__h>span:first-child{font:500 10.5px/1 var(--mono);color:var(--pn-fg3);letter-spacing:.06em}
.pn-v{font:500 10.5px/1 var(--mono);color:var(--pn-fg2)}
.pn-v.near{color:var(--pn-warn)}
.pn-tin{width:100%;height:38px;padding:0 10px;border:1px solid var(--pn-hair2);border-radius:4px;
  background:var(--pn-sunk);color:var(--pn-fg);font:450 14px/1 var(--ui);letter-spacing:-.01em;
  transition:border-color .14s var(--ease),box-shadow .14s var(--ease)}
.pn-tin::placeholder{color:var(--pn-fg3)}
.pn-tin:focus{outline:none;border-color:var(--pn-steel);box-shadow:0 0 0 3px var(--pn-steel-soft)}
.pn-sub{margin:8px 0 0;font-size:11.5px;line-height:1.5;color:var(--pn-fg3)}
.pn-srow{display:flex;gap:7px;align-items:center;margin-bottom:6px}
.pn-srow__n{flex:none;width:21px;height:21px;border-radius:4px;background:var(--pn-steel);color:var(--pn-steel-ink);
  font:500 10px/1 var(--mono);display:grid;place-items:center}
.pn-srow.empty .pn-srow__n{background:transparent;color:var(--pn-steel);box-shadow:inset 0 0 0 1.5px var(--pn-steel)}
.pn-srow input{flex:1;min-width:0;height:29px;padding:0 9px;border:1px solid var(--pn-hair2);
  border-radius:4px;background:var(--pn-sunk);color:var(--pn-fg);font-size:12px}
.pn-srow input:focus{outline:none;border-color:var(--pn-steel);box-shadow:0 0 0 2px var(--pn-steel-soft)}
.pn-srow__x{flex:none;width:25px;height:25px;border:1px solid transparent;background:none;padding:0;
  color:var(--pn-fg3);cursor:pointer;display:grid;place-items:center;border-radius:4px}
.pn-srow__x svg{width:12px;height:12px}
.pn-srow__x:hover{background:var(--pn-raise);color:#F08080}
.pn-enote{margin:0;font-size:11.5px;line-height:1.5;color:var(--pn-fg3)}
.pn-enote[hidden]{display:none}
.pn-kv{display:grid;grid-template-columns:auto 1fr;gap:5px 14px;font:400 11px/1.5 var(--mono);margin:0}
.pn-kv dt{color:var(--pn-fg3)}
.pn-kv dd{margin:0;color:var(--pn-fg2);text-align:right}

/* ── the status bar ──────────────────────────────────────────────────── */
.pn-sbar{display:flex;align-items:center;gap:15px;padding:0 12px;background:var(--pn-chrome);
  border-top:1px solid var(--pn-hair);font:400 10.5px/1 var(--mono);color:var(--pn-fg3);min-width:0}
.pn-sbar kbd{font:500 10px/1 var(--mono);border:1px solid var(--pn-hair2);border-radius:3px;padding:2px 4px;color:var(--pn-fg2)}
.pn-live{color:var(--pn-fg2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pn-live.ok{color:var(--pn-ok)}
.pn-live.err{color:#F08080}

/* ── narrower ────────────────────────────────────────────────────────── */
@media (max-width:1180px){ .pn-body{grid-template-columns:84px minmax(0,1fr) 292px} }
/* drop the filmstrip before sacrificing the canvas; the arrows still walk the set */
@media (max-width:900px){
  .pn-body{grid-template-columns:minmax(0,1fr) 280px}
  .pn-strip{display:none}
  .pn-path{display:none}
}
@media (max-width:640px){
  .pn-body{grid-template-columns:1fr;grid-template-rows:minmax(160px,47%) auto}
  .pn-insp{border-left:none;border-top:1px solid var(--pn-hair)}
  .pn-sbar{display:none}
  .pn-dlg{grid-template-rows:46px minmax(0,1fr)}
  .pn-cv{padding:12px}
  /* the two verbs keep their words: an icon-only Save all on the one screen
     where the bar is tightest is the wrong place to economise */
  .pn-tbtn{padding:0 9px}
}
@media (max-width:560px){
  /* the whole screen, still ending at --floor-modal: the scrimmed tab bar
     under it is not navigation anybody can press */
  .pn-dlg{inset:auto 0 var(--floor-modal,0px) 0;margin:0;width:100%;border-radius:0;
    height:calc(100vh - var(--floor-modal,0px))}
  .pn-gauge__bar{display:none}
  /* 390px: the mark, the fraction, two verbs and the way out do not all fit
     with their words. Clear title is the one that folds to its glyph — it
     carries an aria-label for exactly this — so Save all, the verb the
     whole bar is for, keeps its name and the × stays on screen. */
  .pn-tbar{gap:8px;padding:0 8px 0 12px}
  #pn-clear [data-blabel]{display:none}
  #pn-clear{padding:0 8px}
}
@media (prefers-reduced-motion:reduce){ .pn-scrim,.pn-dlg{animation:none} }