/* ==========================================================================
   07 JOBS — horizontal scroll rail of documented jobs on the deepest surface.
   This is a GALLERY, not a comparison: matched before/after pairs do not exist
   yet and cropping two different photographs into a slider would lie about the
   one thing this business sells. See src/assets/photos/README.md. 6 images.
   ========================================================================== */

.jobs { background: var(--surface-sunken); overflow: hidden; }

.jobs__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-md);
  margin-block-end: var(--space-stack);
}

.jobs__hint {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}

.jobs__rail {
  display: flex;
  gap: var(--grid-gap);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-block-end: var(--space-sm);
  scrollbar-width: thin;
}
.jobs__rail::-webkit-scrollbar { height: var(--space-3xs); }
.jobs__rail::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--radius-pill); }

.job {
  flex: 0 0 auto;
  width: var(--card-min-wide);
  max-width: 82vw;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  background: var(--surface-raised);
  border: var(--border-width-hair) solid var(--border-hairline);
  border-radius: var(--radius-card);
  clip-path: var(--chamfer-clip);
  overflow: hidden;
  transition: border-color var(--dur-fast) var(--ease-state), transform var(--dur-fast) var(--ease-lift);
}
.job:hover { border-color: var(--border-accent-soft); transform: translate3d(0, var(--lift-tile), 0); }
.job:hover .media img { transform: scale3d(var(--scale-media-hover), var(--scale-media-hover), 1); }
.job:hover .media::before { transform: skewX(var(--sheen-skew)) translate3d(1200%, 0, 0); }

.job__media { aspect-ratio: var(--ratio-tall); }
.job__media::after { background: var(--chamfer-edge), var(--overlay-media); }

.job__index {
  position: absolute;
  z-index: var(--z-content);
  /* top-LEFT: the chamfer cuts the top-right corner and would clip it */
  inset-block-start: var(--space-2xs);
  inset-inline-start: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--text-h4);
  font-weight: var(--weight-bold);
  color: var(--text-accent);
}

.job__body { display: flex; flex-direction: column; gap: var(--job-body-gap); padding: var(--card-pad); flex: 1; }
.job__title { font-size: var(--text-h4); color: var(--text-primary); }
.job__paint {
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  line-height: var(--leading-micro);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-secondary);
}
/* Not every frame in the rail is a vehicle, so not every card carries a paint
   name — and the ones that did not sat their title a whole eyebrow line above
   their neighbours. The line is reserved instead of the copy being invented. */
/* Reserved with :first-child rather than :not(:has()) — .job__paint is always
   the record's opening line when it exists, so the title being first IS the
   absence, and a selector every engine has read since 2011 says so. Firefox
   before 121, which includes the 115 ESR still shipping on managed desktops,
   drops any rule containing :has(), and there the reserved line disappeared
   and one card in the rail sat a line proud of its neighbours.
   The offset is the missing line PLUS the flex gap the missing element would
   have brought with it — the gap is read from the same custom property the
   container sets it from, so the two cannot drift. */
.job__body { --job-body-gap: var(--space-2xs); }
.job__body > .job__title:first-child {
  margin-block-start: calc(var(--text-micro) * var(--leading-micro) + var(--job-body-gap));
}
.job__desc { font-size: var(--text-body-sm); line-height: var(--leading-body); color: var(--text-muted); }

.job__foot {
  display: flex;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-block-start: auto;
  padding-block-start: var(--space-sm);
  background: var(--tick-rule-fine);
  font-family: var(--font-mono);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
}
.job__foot b { color: var(--text-secondary); font-weight: var(--weight-medium); }

/* the honest note card that closes the rail */
.job--note .job__body { justify-content: center; }
.job--note .media::after { background: var(--overlay-media-heavy); }
.job--note .job__note {
  font-size: var(--text-body-sm);
  line-height: var(--leading-body);
  color: var(--text-secondary);
}

/* --- the expanded record -------------------------------------------------
   A city page carries ONE job, not a rail, and a .job outside .jobs__rail
   renders at --card-min-wide and floats as a stray card. Expanded, the frame
   keeps the narrow track and the record takes the rest.
   The row wraps, and the body carries a real basis rather than 0, so that
   between --bp-md and --bp-lg — and on the record that carries two frames —
   the record drops under the frames instead of being crushed to a column of
   single words. specs/021-city-pages.md block 06. */
.job--expanded { width: auto; max-width: none; }

@media (min-width: 900px) {
  .job--expanded { flex-direction: row; flex-wrap: wrap; }
  /* NO ratio override. The two job frames are 4:5 and 3:4 portraits, and
     --ratio-card cut a 380x285 letterbox out of the middle of them: on the
     first record that removed the polisher and left a dark red smear. The
     rail's own --ratio-tall is the ratio the files were shot at. */
  .job--expanded .job__media { flex: 0 0 var(--card-min-wide); }
  /* Centring a full-height body put the closing rule at the foot of a 500px
     track with three lines of prose above it and ~90px of nothing between.
     The body is only as tall as the record, centred against the frame, so the
     DURATION rule closes the prose instead of floating below it. An expanded
     record also sets one step larger than a rail card — it is the page's one
     job, not one of six. */
  .job--expanded .job__body {
    flex: 1 1 var(--width-prose);
    align-self: center;
    padding: var(--card-pad-lg);
    --job-body-gap: var(--space-xs);
  }
  .job--expanded .job__title { font-size: var(--text-h3); }
  .job--expanded .job__desc { font-size: var(--text-lead); max-width: var(--width-measure); }

  /* TWO frames beside one record. At --card-min-wide the pair set the card
     509px tall around a 284px record and opened 225px of it as bare ground.
     The narrower track brings the frames' block size within reach of the
     record's and hands the width back to the record, which is what stops the
     expanded card reading as a 500px box with a paragraph floating in it. */
  /* Stated on the article as .job--pair, not detected with :has(): Firefox
     115 ESR has no :has() and would drop this rule, putting both frames back
     on --card-min-wide and reopening the 225px of bare ground under the
     record that the narrower track exists to close. */
  .job--pair .job__media { flex-basis: var(--card-min); }
}

@media (min-width: 1024px) {
  .jobs__rail { margin-inline-end: calc(50% - 50vw); padding-inline-end: var(--rail-peek); }
}

/* --------------------------------------------------------------------------
   THE PHOTOGRAPHY POLICY STANDFIRST. Every record in this rail names a car and
   a colour over a frame that is neither. The resolution is not faked matching
   photography: it is stating what the frames are, once, at the head of the
   rail, and letting every card inherit it. docs/content.md §Photography policy
   — the jobs rail. Chrome, not page copy: .jobs__policy is the exempt hook for
   the no-shared-sentence check, specs/021-city-pages.md criteria 47-50.
   -------------------------------------------------------------------------- */
.jobs__policy b {
  color: var(--text-secondary);
  font-weight: var(--weight-semibold);
}
