/* ============================================================================
   MTL STUDENTS · Direction B « Soleil » · page Emplois
   ----------------------------------------------------------------------------
   Loaded after soleil.css. Nothing in soleil.css is touched: every rule here is
   either a new page-scoped component or a narrow, declared override, and the
   overrides are listed in the handback so they can be promoted later.

   THE PROBLEM. There is exactly one real listing, and the live /jobs-2 still
   ships Wix's demo taxonomy ("Vanilla · Chocolate · Strawberry · Rocky Road")
   above it. So the design question is not "how do we lay out a list", it is
   "how does a board with one row look finished".

   DIRECTION A'S ANSWER, which this page deliberately does not repeat: give the
   single offer the weight of a record, admit the sparseness in an italic pull
   quote, and offer two ways out.

   DIRECTION B'S ANSWER, built out of this direction's own grammar (paper
   ground, colour blocks as structure, 3px ink borders, hard unblurred offset
   shadows, chunky uppercase Gabarito):

   1. The count becomes the largest object on the page instead of a caption.
      On a board with one row, the number IS the news, so it is a pink block
      with a display-scale numeral that is wired to the filters and flips to
      ink when it reaches zero. Their own line, with the grammar corrected.
   2. The offer is a pinned notice, not a database row: an ink header band
      carrying the employer, a poster-scale title, and the facts as the same
      chips the home page uses for the event.
   3. The emptiness is drawn rather than confessed. Under the one real offer
      sits the next position on the board, dashed and unfilled, saying why it
      is empty and handing the space to an employer. A's page says "une liste
      courte et vraie" in prose; this one shows the vacancy and makes it the
      call to action.

   Section rhythm, which is Direction B's actual layout system:
   paper (hero) → sand (board) → oxblood (employers) → gold (newsletter) → ink.
   ========================================================================== */

/* The filter script hides things with the `hidden` attribute, and most blocks
   below set an explicit display. Without this the attribute loses the
   specificity tie against its own class and quietly does nothing. */
[hidden] { display: none !important; }

/* Checked, because it bites on the Direction A version of this page: there,
   .btn never declares a background, so a <button class="btn btn--ghost">
   paints itself with the UA's `buttonface`. soleil.css does NOT have that bug
   (.btn declares `background: var(--paper)` and .btn--ghost declares
   `transparent`), so no override is needed and none is written. The gap that
   does remain is the bare reset: `button { font: inherit; color: inherit }`
   sets no background, so any future <button> on this direction that is not a
   .btn will paint buttonface. Every button on this page is a .btn. */

/* ----------------------------------------------------------------- hero -- */

/* The board starts immediately under the title, so the hero gives back part of
   its bottom padding. */
.job-hero { padding-bottom: clamp(1.25rem, 3vw, 2.5rem); }
.job-hero .hero__grid {
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  align-items: end;
}
/* Measured, not guessed. Gabarito's caps run about .66em per character, so
   "D'EMPLOIS" is 5.9em wide. soleil.css's 2.9rem floor would put it at 274px
   inside the 280px a 320px viewport has left after the gutters: true, but with
   6px to spare and no allowance for the fallback face, which is wider. The
   floor drops to 2.35rem here, which lands it at 222px. */
.job-hero .hero__title { font-size: clamp(2.35rem, .6rem + 6.2vw, 6rem); }
.job-hero .hero__dek { margin-bottom: .35rem; }

/* ---------------------------------------------------------------- board -- */
/* Sand, with the logo's arc on its top edge. Two domes on this page: here and
   the newsletter, the same ration the home page uses. */

.board { background: var(--paper-2); }
.board__h { margin-top: 1rem; max-width: 20ch; }

/* -------------------------------------------------------------- console -- */
/* The count and the controls, side by side, as two stickers rather than as a
   toolbar above a hairline.

   The tally is flex: 1 1 13rem and the filters are flex: 999 1 20rem, so
   nearly all the spare width goes to the controls while both are on screen,
   and the tally takes the whole row on its own when the controls are absent.
   That matters because the controls ship `hidden` and only appear once the
   script has wired them: with a grid, their absence would leave a hole. */

.console {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: clamp(.85rem, 2vw, 1.25rem);
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
}

.tally {
  flex: 1 1 13rem;
  display: grid;
  align-content: center;
  gap: .15rem;
  padding: clamp(1rem, 2.5vw, 1.6rem) clamp(1.1rem, 2.5vw, 1.75rem);
  background: var(--pink);
  border: var(--rule) solid var(--ink);
  border-radius: 4px;
  box-shadow: 6px 6px 0 var(--ink);
  transition: background .3s var(--ease), color .3s var(--ease);
}
/* Their live page prints a static "1" under a dropdown of ice-cream flavours.
   This one is the same sentence with the plural fixed, and the number is the
   filter's actual output. */
.tally b {
  font-family: var(--display);
  font-weight: 900;
  font-size: clamp(3rem, 2rem + 4vw, 5.5rem);
  line-height: .85;
  letter-spacing: -.04em;
}
.tally span {
  font-family: var(--display);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.3;
}
/* Zero results. Flipping the block is calmer than animating the numeral and it
   reads from the back of a meeting room. */
.tally[data-zero] { background: var(--ink); color: var(--gold); }

/* -------------------------------------------------------------- filters -- */

.filters {
  flex: 999 1 20rem;
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: 1rem clamp(.75rem, 2vw, 1.25rem);
  align-items: end;
  padding: clamp(1rem, 2.5vw, 1.6rem) clamp(1.1rem, 2.5vw, 1.75rem);
  background: var(--paper);
  border: var(--rule) solid var(--ink);
  border-radius: 4px;
  box-shadow: 6px 6px 0 var(--ink);
}

.field { display: grid; gap: .4rem; min-width: 0; }
.field label {
  font-family: var(--display);
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-72);
}

/* Pills with a hard border, the same object language as .chip and .btn. The
   newsletter input in soleil.css is the same component; these are its siblings
   rather than a second, quieter form language. 44px tall at every size, which
   clears the 32px target floor with room for a thumb. */
.field input,
.field select {
  width: 100%;
  min-width: 0;
  min-height: 44px;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 999px;
  color: var(--ink);
  font: inherit;
  font-size: 1rem;
  padding: .55rem 1rem;
  transition: box-shadow .25s var(--pop), background .25s var(--ease);
}
.field input::placeholder { color: var(--ink-50); }
.field input:hover,
.field select:hover { box-shadow: 3px 3px 0 var(--ink); }
.field input:focus,
.field select:focus { outline: 3px solid var(--focus); outline-offset: 2px; }

/* The native arrow is a system object on a page that has no other system
   objects on it, so it is replaced with the same chevron the Détails summary
   uses, in ink. */
.field select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.4rem;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23240408' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
}
/* Safari will not inherit page colours into the option list. */
.field option { background: var(--paper); color: var(--ink); }

.filters__reset {
  grid-column: 1 / -1;
  justify-self: start;
  padding-block: .7em;
  white-space: nowrap;
}

/* The scaffolding disclosure. It lives inside the form on purpose: no
   controls, no note about the controls. */
.filters__note {
  grid-column: 1 / -1;
  margin: 0;
  padding-left: .85rem;
  border-left: var(--rule) solid var(--orange);
  font-size: .75rem;
  line-height: 1.55;
  color: var(--ink-72);
  max-width: 68ch;
}

/* --------------------------------------------------------------- listing -- */

.list { display: grid; gap: clamp(.85rem, 2vw, 1.25rem); margin-top: clamp(1.5rem, 3.5vw, 2.25rem); }

/* One offer, so it is a notice pinned to a board rather than a row in a table.
   Direction A gives the same record a numeral rail and a gradient; this is the
   sticker device instead, which is what every other card in this direction
   does. */
.job {
  background: var(--paper);
  border: var(--rule) solid var(--ink);
  border-radius: 5px;
  box-shadow: 10px 10px 0 var(--pink);
  rotate: -.5deg;
  transition: rotate .5s var(--pop), box-shadow .5s var(--pop);
}
.job:hover { rotate: 0deg; box-shadow: 14px 14px 0 var(--pink); }

/* The header band. Employer in gold on ink, the way a notice is headed, and
   the sequence number stated plainly: this is offer 01 of a board of one. */
.job__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .35rem 1rem;
  padding: .7rem clamp(1.1rem, 3vw, 2rem);
  background: var(--ink);
  color: var(--gold);
  border-radius: 2px 2px 0 0;
  font-family: var(--display);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.job__seq { color: var(--pink); }
.job__org { color: var(--gold); }

.job__body { padding: clamp(1.25rem, 3vw, 2rem); }

/* Poster scale, because there is one of them. Measured the same way as the
   headings: "AMBASSADRICE" is the longest word at 12 characters, so 7.9em, and
   the 1.6rem floor puts it at 203px inside the 240px the card's own padding
   leaves at a 320px viewport. */
.job__title {
  font-family: var(--display);
  font-weight: 900;
  font-size: clamp(1.6rem, 1rem + 2.6vw, 3.2rem);
  line-height: .96;
  letter-spacing: -.02em;
  text-transform: uppercase;
  overflow-wrap: break-word;
  text-wrap: balance;
}

/* The live listing states no job type anywhere, so none is invented. The gap
   is shown: an unfilled chip with a dashed edge next to two filled ones. It is
   also load-bearing information, since selecting any specific type in the
   filter above will correctly empty the board. */
.chip--todo {
  background: none;
  border-style: dashed;
}
.chip--todo dd { color: var(--ink-72); }

/* --------------------------------------------------------------- détails -- */
/* Their action is labelled "Détails" and native <details> keeps it working
   with scripting off, which is this page's whole rule in miniature. */

.det { margin-top: .35rem; }
.det summary {
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.det summary::-webkit-details-marker { display: none; }
.det summary::marker { content: ''; }
/* soleil.css styles :focus-visible for a, button and input, but not summary. */
.det summary:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}
.det summary svg { transition: rotate .3s var(--ease); }
.det[open] summary svg { rotate: 180deg; }

.det__in {
  margin-top: 1.4rem;
  padding-top: 1.4rem;
  border-top: 2px solid var(--ink-16);
}
.det__dl {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: 1.15rem;
  margin: 0 0 1.5rem;
}
.det__dl dt {
  font-family: var(--display);
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-72);
}
.det__dl dd {
  margin: .3rem 0 0;
  font-weight: 700;
  font-size: .9375rem;
  overflow-wrap: break-word;
}
.det__todo { color: var(--ink-72); font-weight: 500; }

.det__ph {
  max-width: 60ch;
  margin-bottom: 1.5rem;
  font-size: .9375rem;
  color: var(--ink-72);
}
.det__ph b { color: var(--ink); }

/* ------------------------------------------------------------ free slot -- */
/* The next position on the board, drawn as what it is. Not a listing: no .job
   class, so the filter cannot see it and the count cannot include it. Dashed
   and unfilled against the two solid objects above it, so it cannot be
   misread as an offer. */

.slot {
  padding: clamp(1.75rem, 5vw, 3rem) clamp(1.25rem, 4vw, 2.5rem);
  border: var(--rule) dashed var(--ink-50);
  border-radius: 5px;
  text-align: center;
}
.slot__t {
  font-family: var(--display);
  font-weight: 900;
  font-size: clamp(1.25rem, .9rem + 1.8vw, 2rem);
  line-height: 1;
  letter-spacing: -.02em;
  text-transform: uppercase;
}
.slot__d {
  margin: .75rem auto 1.5rem;
  max-width: 52ch;
  font-size: .9375rem;
  color: var(--ink-72);
}

/* ---------------------------------------------------------- empty state -- */
/* A one-row board empties on almost any filter, so this is a designed screen
   and not an afterthought: it says what happened, why this board in particular
   empties so easily, and gives back both a way out and a way to hear about the
   next offer. */

.empty {
  margin-top: clamp(1.5rem, 3.5vw, 2.25rem);
  padding: clamp(2rem, 6vw, 3.25rem) clamp(1.25rem, 4vw, 2.5rem);
  background: var(--paper);
  border: var(--rule) solid var(--ink);
  border-radius: 5px;
  box-shadow: 8px 8px 0 var(--gold);
  text-align: center;
}
.empty__t {
  font-family: var(--display);
  font-weight: 900;
  font-size: clamp(1.35rem, 1rem + 1.5vw, 2rem);
  line-height: 1.05;
  letter-spacing: -.02em;
  text-transform: uppercase;
  text-wrap: balance;
}
.empty__d {
  margin: .8rem auto 1.5rem;
  max-width: 50ch;
  font-size: .9375rem;
  color: var(--ink-72);
}

/* ------------------------------------------------------------ employeurs -- */
/* The dark beat, and the destination the free slot points at. */

.hire { background: var(--oxblood); color: var(--paper); --focus: var(--gold); }
/* line-height, because this is the only .h2 in the demo that wraps onto a
   second line whose first word carries an accent. At soleil.css's .95 the acute
   on "ÉTUDIANTS" lands on the S of "VOUS" above it and the word reads as
   "VOUŞ". Same lesson the hero title already learned in soleil.css: a French
   headline needs somewhere for the accent to sit. Promotion candidate: .h2
   could carry 1.02 for everyone at no visible cost to single-line headings. */
.hire .h2 { color: var(--paper); margin-top: 1rem; max-width: 14ch; line-height: 1.02; }
/* The default ink-filled kicker is nearly the same value as oxblood and goes
   muddy on it, so the chip inverts here, exactly as it does in the Ressources
   block on the home page. */
.hire .kicker { background: var(--gold); color: var(--ink); }
.hire .lede { color: var(--paper-72); max-width: 52ch; }
/* .btn--ghost draws an ink border, which is invisible on oxblood. The home
   page never puts a ghost button on a dark ground, so this is new. Promotion
   candidate for soleil.css: a dark-ground modifier for .btn--ghost. */
.hire .btn--ghost { border-color: var(--paper); color: var(--paper); }
.hire .btn--ghost:hover { background: var(--paper); color: var(--ink); }
.hire__note { margin-top: 1.1rem; font-size: .8125rem; color: var(--paper-48); max-width: 46ch; }

.hire__grid {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: clamp(1.75rem, 5vw, 4rem);
  align-items: start;
}

/* ------------------------------------------------------------ responsive -- */

@media (max-width: 900px) {
  .job-hero .hero__grid { grid-template-columns: minmax(0, 1fr); }
  .hire__grid { grid-template-columns: minmax(0, 1fr); }
  .hire .h2 { max-width: none; }
  .filters { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .field--q { grid-column: 1 / -1; }
}

/* Every rotation in this direction is switched off below 700px, and the hard
   shadows come in: a tilted card inside a 350px column pushes its own bounding
   box past the gutter, and the budget for horizontal overflow is zero. */
@media (max-width: 700px) {
  .job { rotate: 0deg; box-shadow: 6px 6px 0 var(--pink); }
  .job:hover { box-shadow: 6px 6px 0 var(--pink); }
  .tally, .filters { box-shadow: 5px 5px 0 var(--ink); }
  .empty { box-shadow: 5px 5px 0 var(--gold); }
}

@media (max-width: 560px) {
  .filters { grid-template-columns: minmax(0, 1fr); }
  /* A full-width Détails button reads as the primary action of the card on a
     phone, which it is. */
  .det summary { width: 100%; justify-content: center; }
}

.news.block--dome { --dome-from: var(--oxblood); }

/* Backfill for the dome below: the section above paints a strip exactly one
   dome-radius tall, which the dome covers everywhere except its cut-away
   corners. Verified by pixel-sampling the corner. */
.hire { position: relative; }
.hire::after {
  content: '';
  position: absolute;
  left: 0; right: 0;
  bottom: calc(-1 * clamp(1.5rem, 5vw, 5rem));
  height: clamp(1.5rem, 5vw, 5rem);
  background: var(--oxblood);
}
