/* ==========================================================================
   CAREERS  -  full page rebuild
   Section architecture follows the reference the client supplied
   (credenceinnovations.org/careers): a three-card "what the job includes" band
   on a drawn route, a numbered benefits ledger with a sticky rail and a
   progress meter, an open-roles grid, a clips row, and an FAQ.

   THE HERO IS NO LONGER PART OF THAT ARCHITECTURE. The reference's stamped
   badge hero was replaced, by request, with the `.clk` chronograph from
   team.html's Leadership section - see section 1 below, and the block comment
   on the section in careers.html.

   MOBILE FIRST throughout. The client's site is opened on a phone far more
   than on a desktop, so the default rules below ARE the phone layout and the
   min-width queries add the desktop composition on top. Nothing here is a
   desktop layout patched down.

   IMAGES ARE PLACEHOLDERS ON PURPOSE. Every .ph block is a labelled, ratio-
   locked box with no <img> behind it - requested, and it also means the page
   cannot ship a stock photograph by accident. Dropping a real image in is one
   <img> inside the .ph; the box already owns the ratio, the radius and the
   border.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. HERO  -  the instrument, as a hero

   The hero IS the `.clk` component from css/editorial-1b.css (team.html,
   Leadership), by request. Everything that composes it - the grid, the two
   drifting plates, the case, the dial, the tell - lives there and is shared,
   so a change made for one page lands on both and there is no second
   chronograph to keep in step.

   THE OLD `.chero` AND `.stamp` RULES ARE GONE, not commented out. `.stamp`
   existed only for this hero's rotating NOW HIRING badge and nothing else on
   the site used it (index.html's `.ledger__stamp` / `.panes__stamp` are
   different blocks); `.chero*` had no other consumer either. Leaving ~90 dead
   selectors in a hand-maintained sheet is how the next person ends up styling
   a hero that is not on the page.

   WHAT IS LEFT IS THE ONE THING A HERO NEEDS AND A MID-PAGE SECTION DOES NOT.
   On team.html `.clk` is a `.section`, so its vertical rhythm comes from
   `--section`. Here it is the first thing under a fixed header, so it owns its
   own top padding and has to clear the nav. Both numbers below are the ones
   `.chero` used, so the page's opening measure is unchanged.

   Nothing else is overridden. No type sizes, no colours, no stage geometry -
   the responsive collapse at 1080px / 640px, the reduced-motion rules and the
   hover states all come from `.clk` as written.
   -------------------------------------------------------------------------- */
.clk--hero {
  padding-top: clamp(6.5rem, 5rem + 8vw, 9.5rem);
  padding-bottom: clamp(2.5rem, 2rem + 3vw, 4.5rem);
}

/* The h1 is `.clk__h`, which is set for an h2 slot and carries a top margin
   to sit under an eyebrow mid-page. In a hero the eyebrow is the first line
   on the page, so that gap doubles up against the section padding. Trimming
   the margin rather than the padding keeps the eyebrow-to-headline distance
   identical to team.html. */
.clk--hero .clk__h { margin-top: clamp(0.75rem, 0.65rem + 0.4vw, 1.1rem); }

/* `.clk__act` holds a `.link-line` on team.html and the page's existing gold
   CTA here: a hero's primary action stays a button. The button brings its own
   optical top space, so the ruled signature above it needs a little less. */
.clk--hero .clk__act { margin-top: var(--space-4); }

/* --------------------------------------------------------------------------
   .cpill  -  the shared section label

   IT WAS CALLED `.route__pill` AND IT WAS NEVER `.route`'s. Three other
   sections on this page use it - "The upside", "Open roles" and the FAQ - so
   when the route component was deleted this went with it and took three
   eyebrows down that had nothing to do with the section being replaced. It
   is renamed rather than restored under the old name, because a `route__`
   prefix pointing at a component that no longer exists is the same trap set
   again for whoever deletes the next section.

   The styling is unchanged, deliberately. Three sections that were not part
   of this brief render exactly as they did.
   -------------------------------------------------------------------------- */
.cpill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0.8rem;
  border: 1px solid var(--border-gold);
  border-radius: 999px;
  background: rgba(156, 120, 72, 0.08);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-light);
}

/* --------------------------------------------------------------------------
   2. WHAT THE JOB INCLUDES  (three cards on a drawn route)

   RESTORED BY REQUEST. This was replaced by `.ord`, a bank of three
   full-width registers with one open. The reader preferred this one, so it
   is back exactly as it was, with one deliberate difference: the label uses
   `.cpill` rather than `.route__pill`. That class was never this section's -
   "The upside", "Open roles" and the FAQ all use it too - and it now lives
   as a shared component near the top of this file so that deleting any one
   section cannot take three other eyebrows down with it.
   -------------------------------------------------------------------------- */
.route { padding-block: clamp(2.5rem, 2rem + 3vw, 4.5rem); }
.route__head { max-width: 46rem; margin-inline: auto; text-align: center; }
.route__h {
  margin-top: clamp(0.9rem, 0.8rem + 0.5vw, 1.3rem);
  font-size: clamp(1.75rem, 1.3rem + 2.2vw, 3rem);
  font-weight: 600;
  letter-spacing: -0.032em;
  line-height: 1.08;
  color: var(--white);
  text-wrap: balance;
}
.route__h em { font-style: italic; color: var(--gold-light); }
.route__sub {
  margin-top: 0.9rem;
  color: var(--vein);
  line-height: 1.65;
  text-wrap: pretty;
}
.route__stats {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem 1.5rem;
  margin-top: clamp(1.1rem, 0.95rem + 0.6vw, 1.5rem);
}
.route__stats li {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--text-sm);
  color: var(--ink);
}
.route__stats li::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--gold);
  flex: none;
}

.route__wrap { position: relative; margin-top: clamp(2rem, 1.6rem + 2vw, 3.25rem); }
/* the dotted arc the cards sit on. Desktop only: at phone width the cards
   stack and a curve drawn behind a single column is just noise. */
.route__path { display: none; }
.route__cards {
  list-style: none;
  display: grid;
  gap: clamp(2.25rem, 2rem + 2vw, 3rem);
}
.rcard { position: relative; }
.rcard__pin {
  position: absolute;
  top: -14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--obsidian);
  border: 1px solid var(--border-gold-strong);
  color: var(--gold-light);
}
.rcard__pin svg { width: 14px; height: 14px; }
.rcard__shot { --ph-ar: 4 / 5; position: relative; }
.rcard__freq {
  position: absolute;
  top: 0.7rem;
  left: 0.7rem;
  z-index: 2;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background: rgba(6, 6, 8, 0.72);
  border: 1px solid var(--border-gold);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-light);
}
/* the label card overlaps the bottom edge of the plate, as in the reference */
.rcard__label {
  position: relative;
  z-index: 2;
  margin: -2rem 0.85rem 0;
  padding: clamp(0.9rem, 0.8rem + 0.5vw, 1.25rem);
  border: 1px solid var(--border-gold);
  border-radius: var(--radius-md);
  background: rgba(12, 12, 17, 0.92);
  backdrop-filter: blur(12px);
}
.rcard__place {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}
.rcard__name {
  margin-top: 0.25rem;
  font-size: clamp(1.05rem, 0.98rem + 0.35vw, 1.25rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--white);
}
.rcard__note { margin-top: 0.4rem; font-size: var(--text-sm); line-height: 1.55; color: var(--vein); }

@media (min-width: 860px) {
  .route__cards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1rem, 0.85rem + 1vw, 1.75rem); }
  .route__path {
    display: block;
    position: absolute;
    inset: 0 0 auto;
    width: 100%;
    height: 260px;
    pointer-events: none;
    color: var(--border-gold-strong);
  }
  .route__path path { stroke-dasharray: 1 10; stroke-linecap: round; }
  /* the middle card rides up onto the arc */
  .rcard--mid { margin-top: clamp(-2.75rem, -2.5vw, -1.25rem); }
}

/* --------------------------------------------------------------------------
   3. THE UPSIDE  (sticky rail + numbered ledger)
   -------------------------------------------------------------------------- */
.gain { padding-block: clamp(2.5rem, 2rem + 3vw, 4.5rem); }
.gain__grid { display: grid; gap: clamp(1.75rem, 1.4rem + 2vw, 3rem); }
.gain__h {
  font-size: clamp(1.75rem, 1.3rem + 2.2vw, 2.9rem);
  font-weight: 600;
  letter-spacing: -0.032em;
  line-height: 1.06;
  color: var(--white);
}
.gain__h em { display: block; font-style: italic; color: var(--gold-light); }
.gain__sub { margin-top: 1rem; color: var(--vein); line-height: 1.65; max-width: 34rem; text-wrap: pretty; }
.gain__meter { display: none; }

.gain__list { list-style: none; display: grid; }

/* THE ROW REVEAL NEVER HIDES THE ROW.
   An earlier version used clip-path: inset(0 0 100% 0) as the from-state.
   That deadlocks: Chromium counts the target's own clip in intersectionRatio,
   so a fully-clipped row reports 0 and the site observer (threshold 0.12)
   can never fire the class that would un-clip it. The section rendered empty.

   So the row itself is always fully painted and readable. What animates is
   the RULE above it - a gold line that draws left-to-right as the row
   arrives - and a small settle on the text. If the observer never fires,
   the reader loses a line animation and loses no content. */
.gain__row {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.85rem 1rem;
  align-items: start;
  padding: clamp(1.1rem, 0.95rem + 0.7vw, 1.6rem) clamp(0.5rem, 0.4rem + 0.5vw, 1rem);
  border-top: 1px solid var(--border-neutral);
  border-radius: var(--radius-md);
  transition: background var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
/* the drawing rule, over the top border */
.gain__row::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  height: 1px;
  width: 100%;
  background: var(--acc, var(--gold));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.7s var(--ease-out);
}
.gain__row.is-visible::before { transform: scaleX(1); }
.gain__row.reveal { opacity: 1; transform: none; }
.gain__row .gain__body,
.gain__row .gain__n { transition: opacity 0.55s var(--ease-out), transform 0.55s var(--ease-out); }
.gain__row.reveal:not(.is-visible) .gain__body,
.gain__row.reveal:not(.is-visible) .gain__n { opacity: 0.999; transform: translateY(6px); }
.gain__row.is-visible .gain__body,
.gain__row.is-visible .gain__n { transform: none; }
.gain__list .gain__row:last-child { border-bottom: 1px solid var(--border-neutral); }

/* pointing at a row lifts it and lights its own accent colour */
.gain__row:hover {
  background: var(--gold-wash);
  transform: translateX(4px);
}
.gain__n {
  font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.2rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  color: transparent;
  -webkit-text-stroke: 1px var(--acc, var(--border-gold-strong));
  font-variant-numeric: tabular-nums;
  transition: color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.gain__row:hover .gain__n { color: var(--acc, var(--gold)); transform: translateY(-2px); }
.gain__body { min-width: 0; }
.gain__tag {
  display: inline-block;
  margin-bottom: 0.3rem;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--acc, var(--gold));
}
.gain__title {
  font-size: clamp(1.05rem, 0.98rem + 0.35vw, 1.25rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--white);
  text-wrap: balance;
}
.gain__desc { margin-top: 0.4rem; color: var(--vein); font-size: var(--text-sm); line-height: 1.6; text-wrap: pretty; }

/* the circular arrow: hidden on a phone where there is no hover to reward */
.gain__go { display: none; }

@media (min-width: 980px) {
  .gain__grid { grid-template-columns: 0.82fr 1.18fr; gap: clamp(2.5rem, 2rem + 3vw, 4.5rem); }
  .gain__row { grid-template-columns: auto 1fr auto; align-items: center; }
  .gain__go {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid var(--border-gold);
    color: var(--gold-light);
    opacity: 0;
    transform: translateX(-6px);
    transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out),
      background var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
  }
  .gain__go svg { width: 15px; height: 15px; }
  .gain__row:hover .gain__go {
    opacity: 1;
    transform: none;
    background: var(--gold);
    color: var(--obsidian);
  }
  .gain__rail { position: sticky; top: clamp(6rem, 12vh, 9rem); align-self: start; }
  .gain__meter {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-top: clamp(1.5rem, 1.2rem + 1vw, 2.25rem);
  }
  .gain__track { position: relative; width: 2px; height: 5.5rem; background: var(--border-neutral); }
  .gain__fill {
    transition: transform 0.6s var(--ease-out);
    position: absolute;
    inset: 0 0 auto;
    width: 100%;
    height: 100%;
    background: var(--gold);
    transform-origin: top;
    transform: scaleY(var(--gain-p, 0));
  }
  .gain__count { font-size: 2.4rem; font-weight: 700; letter-spacing: -0.03em; color: var(--white); line-height: 1; }
  .gain__countlbl { font-size: var(--text-xs); letter-spacing: 0.14em; text-transform: uppercase; color: var(--vein); line-height: 1.6; }
}

/* --------------------------------------------------------------------------
   4. OPEN ROLES
   -------------------------------------------------------------------------- */
.roles { padding-block: clamp(2.5rem, 2rem + 3vw, 4.5rem); scroll-margin-top: 5rem; }
.roles__head {
  display: grid;
  gap: 0.9rem;
  margin-bottom: clamp(1rem, 0.8rem + 0.9vw, 1.6rem);
}
.roles__h {
  font-size: clamp(1.75rem, 1.3rem + 2.2vw, 2.9rem);
  font-weight: 600;
  letter-spacing: -0.032em;
  line-height: 1.06;
  color: var(--white);
}
/* the mask the headline lifts out of. It is a span-and-i and not a single
   element because the overflow has to belong to a box the transform does not
   move - the i travels, the span stays and clips it. */
.roles__h span { display: block; overflow: hidden; padding-bottom: 0.06em; }
.roles__h i { display: block; font-style: normal; }
.roles__h em { font-style: italic; color: var(--gold-light); }

/* --------------------------------------------------------------------------
   .roles--index  -  THE BAND ON THE HOME PAGE WEARS THAT PAGE'S TITLE.

   index.html runs nine numbered sections, each headed the same way: a gold
   `.eyebrow` with a leading rule and a "/ nn", then an h2 carrying an <em>
   accent. Dropped in with this page's own head — a rounded `.cpill` reading
   "Open roles" over a mask-revealed headline — the careers band was the one
   section in that run with no number and a different kind of label, and it
   read as a piece of a different site pasted mid-scroll.

   So the home page's copy takes the house head: eyebrow, number, h2.

   AND THAT IS VERY NEARLY ALL IT NEEDS. `.roles__h` was already in family —
   46.4px at weight 600 against § 08's 46.4px at 600 — and `h1, h2, h3, h4`
   in css/main.css already sets --white, weight 600 and text-wrap: balance
   on every heading in the site, this one included. A first cut of this rule
   forced `color: var(--ink)` on the theory that the other section headings
   inherited body colour; they do not, they are white like this one, and the
   override would have made this the only off-white h2 in a run of nine.
   Measured before it shipped. What is left is the one thing genuinely
   missing: a measure, so the line breaks where its neighbours break.

   THE CAREERS PAGE IS UNTOUCHED. It carries no `.roles--index`, so its pill
   and its mask are exactly as they were. Everything below the head — the
   rule, the three cards, every measurement in them — is shared by both pages
   and is not modified here.
   -------------------------------------------------------------------------- */
.roles--index .roles__h { max-width: 16ch; }
.roles__count { display: flex; align-items: baseline; gap: 0.6rem; }
.roles__countn {
  font-size: 2rem;
  font-weight: 700;
  color: var(--gold-light);
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.roles__countlbl { font-size: var(--text-xs); letter-spacing: 0.14em; text-transform: uppercase; color: var(--vein); }

/* the spine. The three cards hang off one rule that spans the container, so
   they read as one bank rather than three objects that happen to be adjacent.
   Left DRAWN by the stylesheet: with motion.js absent the rule is simply
   there, which is the contract every section on this site is built on. */
.roles__rule {
  display: block;
  height: 1px;
  margin-bottom: clamp(1.1rem, 0.9rem + 0.9vw, 1.75rem);
  background: linear-gradient(90deg, var(--gold), rgba(184, 145, 88, 0.28) 74%, transparent);
  transform-origin: left center;
}

/* --------------------------------------------------------------------------
   .jr  -  the three open roles, as photographic cards

   WHAT THIS REPLACED, MEASURED. `.rrole` was three full-width bars stacked
   down the page: 1190px wide, ~250px tall each, text left and an Apply button
   parked on the right. In a 1270px container each description was capped at
   736px, so 454px of every row was empty. 1029px of page, no photograph
   anywhere on it, 3px rounded corners and 999px pill tags - a job board list,
   which is what a candidate has already scrolled past on four other sites
   before landing here.

   THEY ARE CARDS NOW BECAUSE THEY ARE BEING SHOWN, NOT LISTED. Three roles
   side by side can be COMPARED - which is the actual job of this section, and
   the thing a vertical list of wide bars makes impossible because no two of
   them are ever on screen together at a readable size.

   EACH CARD LEADS WITH ITS OWN PHOTOGRAPH, and that is what stops three
   cards from reading as three boxes: the plate is the role, the numeral is
   cut into it at display scale, and the type below is a spec sheet under a
   picture rather than a paragraph in a container.

   THE WHOLE CARD IS THE TARGET. `.jr__go::after` is stretched over the card,
   so the hit area is 380x560 instead of a 96px button, and the foot bar is
   still a real anchor carrying the real word. One link per card, no nested
   interactives, nothing for a screen reader to announce twice.

   NO PILLS AND NO ROUNDED BOXES. The tags were 999px capsules and the card
   was 3px; both are the house tell of a component nobody chose. Everything
   here is cut square to --radius-sm, which is what the rest of this site
   uses, and the tags are hairline chips that read as a datasheet.
   -------------------------------------------------------------------------- */

.roles__list {
  list-style: none;
  display: grid;
  gap: clamp(0.9rem, 0.7rem + 0.9vw, 1.5rem);
}

.jr { display: flex; }

/* the card is a column so the foot bar can be pushed to the bottom by the
   body's `margin-top: auto` - three roles have three different description
   lengths and a row of cards whose buttons do not line up is the first thing
   that reads as unfinished */
.jr__card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  overflow: hidden;
  border: 1px solid var(--border-neutral);
  border-radius: var(--radius-sm);
  background: linear-gradient(180deg, rgba(184, 145, 88, 0.05), transparent 46%), var(--surface);
  transition:
    border-color 0.5s var(--ease-out),
    transform 0.5s var(--ease-out),
    box-shadow 0.5s var(--ease-out);
}

/* the sheen. A pointer-tracked pool, written by motion.js as two lengths, and
   ADDITIVE ONLY - at rest it is invisible, so a card with no JS is simply a
   card rather than one with a stuck highlight on it. */
.jr__card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(16rem 16rem at var(--mx, 50%) var(--my, 0%),
    rgba(214, 182, 126, 0.09), transparent 70%);
  transition: opacity 0.45s var(--ease-out);
}

/* ---- the plate ---------------------------------------------------------- */

.jr__plate {
  position: relative;
  /* the FLOOR is what matters here, not the ceiling. At 9rem the clamp's
     minimum was doing the work on a phone and each of the three cards was
     carrying 144px of photograph in a single column - 72px of scroll across
     the section, bought back by cutting the floor to 7.5rem. The desktop
     height is unchanged either way. */
  height: clamp(7.5rem, 5rem + 9vw, 13rem);
  overflow: hidden;
  flex: none;
  /* the arrival wipe, composed from one number so GSAP never writes
     `clip-path` and can never collide with the window's transform */
  clip-path: inset(0 0 calc(var(--open, 0) * 100%) 0);
}

/* --py is the scroll parallax and --zin is the arrival and the hover push.
   ONE transform, composed here: a tween writing `transform` for either would
   erase the other on its first tick. */
.jr__win {
  position: absolute;
  inset: -8% 0;
  display: block;
  transform: translateY(calc(var(--py, 0) * 1px)) scale(var(--zin, 1));
  transition: transform 0.7s var(--ease-out);
}
.jr__win img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.62) saturate(0.78) contrast(1.06);
  transition: filter 0.6s var(--ease-out);
}
.jr__plate::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(23, 21, 15, 0.55) 0%, transparent 34%, rgba(23, 21, 15, 0.9) 100%),
    radial-gradient(110% 80% at 14% 0%, rgba(184, 145, 88, 0.14), transparent 62%);
}

.jr__top {
  position: absolute;
  z-index: 2;
  left: clamp(0.9rem, 0.7rem + 0.8vw, 1.35rem);
  top: clamp(0.8rem, 0.6rem + 0.7vw, 1.15rem);
}
.jr__status {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold-light);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.9);
}
/* the dot is the only round thing left on this card, and it earns it: it is
   a status light, and status lights are round */
.jr__status::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold-light);
  box-shadow: 0 0 8px rgba(192, 156, 96, 0.9);
  animation: jr-live 2.4s ease-in-out infinite;
}
@keyframes jr-live {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

/* the index, cut into the corner of its own photograph at display scale.
   Outlined rather than filled so it stays part of the picture, and it fills
   when the card is taken. */
.jr__n {
  position: absolute;
  z-index: 2;
  right: clamp(0.75rem, 0.5rem + 0.9vw, 1.2rem);
  bottom: clamp(0.1rem, -0.1rem + 0.6vw, 0.45rem);
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 1.9rem + 2.8vw, 4.25rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
  color: transparent;
  -webkit-text-stroke: 1px rgba(214, 182, 126, 0.6);
  transition: color 0.5s var(--ease-out), -webkit-text-stroke-color 0.5s var(--ease-out);
}

/* ---- the body ----------------------------------------------------------- */

.jr__body {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  flex: 1 1 auto;
  padding: clamp(1.1rem, 0.9rem + 0.9vw, 1.6rem) clamp(1.1rem, 0.9rem + 0.9vw, 1.6rem) 0;
}

.jr__name {
  font-size: clamp(1.15rem, 1.05rem + 0.5vw, 1.42rem);
  font-weight: 600;
  letter-spacing: -0.026em;
  line-height: 1.2;
  color: var(--white);
  text-wrap: balance;
}
.jr__meta {
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold);
  line-height: 1.7;
}
.jr__desc {
  color: var(--vein);
  font-size: var(--text-sm);
  line-height: 1.65;
  text-wrap: pretty;
}

.jr__tags {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  /* pushes the foot bar down, so three cards of three different lengths still
     line their buttons up on one row */
  margin-top: auto;
  padding-top: 0.35rem;
}
.jr__tags li {
  padding: 0.24rem 0.6rem;
  border: 1px solid var(--border-gold);
  border-radius: var(--radius-sm);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--ink);
  transition: border-color 0.5s var(--ease-out);
}
/* phones and tablets: 10.9px is under the sitewide legibility floor */
@media (max-width: 1020px) {
  .jr__tags li { font-size: 0.72rem; }
}

/* ---- the foot ----------------------------------------------------------- */

.jr__act { margin-top: clamp(1rem, 0.85rem + 0.6vw, 1.35rem); }

/* Not `.btn`. A filled gold pill parked inside a card whose whole surface is
   already the link reads as a second, smaller target sitting on the first. A
   bar cut across the foot on a gold hairline is one edge of the card doing
   the job, and it fills on hover so there is never a doubt it is pressable. */
/* NOT `position: relative`, AND THAT IS THE WHOLE TRICK. The stretch below is
   `inset: 0` against the nearest POSITIONED ancestor. Give this bar a
   position of its own and the pseudo resolves against the bar instead of the
   card, and the "whole card is clickable" claim silently becomes "the 46px
   foot bar is clickable" - which is what it did on the first pass, measured:
   plate, name, description and tags all missed. `.jr__card` is the only
   positioned ancestor in the chain, so the overlay lands on the card. */
.jr__go {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 46px;
  padding: 0 clamp(1.1rem, 0.9rem + 0.9vw, 1.6rem);
  border-top: 1px solid var(--border-gold-strong);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold-light);
  background: linear-gradient(90deg, rgba(184, 145, 88, 0.12), transparent 70%);
  transition: color 0.45s var(--ease-out), background 0.45s var(--ease-out);
}
/* THE WHOLE CARD IS THE HIT AREA. Stretched from the one real anchor, so
   there is still exactly one link per card and nothing to announce twice. */
.jr__go::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
}

.jr__go .btn__arrow,
.jr__go svg {
  flex: none;
  width: 16px;
  height: 16px;
  transition: transform 0.45s var(--ease-out);
}

.jr__go:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: -3px;
}

/* ---- taken ---------------------------------------------------------------
   Hover and keyboard focus land on the SAME state, deliberately: a card that
   only lights for a mouse is a card half the people who use it never see. */
@media (hover: hover) {
  .jr__card:hover { transform: translateY(-4px); }
}
.jr__card:hover,
.jr__card:focus-within {
  border-color: var(--border-gold-strong);
  box-shadow: 0 30px 56px -38px rgba(0, 0, 0, 0.95);
}
.jr__card:hover::after,
.jr__card:focus-within::after { opacity: 1; }
.jr__card:hover .jr__win,
.jr__card:focus-within .jr__win { --zin: 1.07; }
.jr__card:hover .jr__win img,
.jr__card:focus-within .jr__win img { filter: brightness(0.82) saturate(0.9) contrast(1.04); }
.jr__card:hover .jr__n,
.jr__card:focus-within .jr__n {
  color: rgba(214, 182, 126, 0.22);
  -webkit-text-stroke-color: var(--gold-light);
}
.jr__card:hover .jr__tags li,
.jr__card:focus-within .jr__tags li { border-color: var(--border-gold-strong); }
.jr__card:hover .jr__go,
.jr__card:focus-within .jr__go {
  color: var(--obsidian);
  background: linear-gradient(90deg, var(--gold-light), var(--gold) 78%);
}
.jr__card:hover .jr__go svg,
.jr__card:focus-within .jr__go svg { transform: translateX(5px); }

/* ---- wider -------------------------------------------------------------- */

@media (min-width: 720px) {
  .roles__head { grid-template-columns: 1fr auto; align-items: end; }
  .roles__count { justify-content: flex-end; }
  .roles__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* THREE CARDS IN TWO COLUMNS LEAVES ONE STANDING ALONE beside an empty cell,
   which is the dead channel this site has been called out for twice. The odd
   one takes the whole row instead: its plate becomes a letterbox rather than
   a portrait, the row is full, and nothing has to be hidden or duplicated to
   make the count come out even. */
@media (min-width: 720px) and (max-width: 999px) {
  .roles__list > .jr:last-child { grid-column: 1 / -1; }
}

@media (min-width: 1000px) {
  .roles__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (prefers-reduced-motion: reduce) {
  .jr__card,
  .jr__card::after,
  .jr__win,
  .jr__win img,
  .jr__n,
  .jr__go,
  .jr__go svg,
  .jr__tags li { transition: none; }
  .jr__status::before { animation: none; }
  .jr__card:hover { transform: none; }
}

/* --------------------------------------------------------------------------
   Shared: section head used by the FAQ
   -------------------------------------------------------------------------- */
.cfaq { padding-block: clamp(2.5rem, 2rem + 3vw, 4.5rem); }
.cfaq__head { max-width: 46rem; margin-bottom: clamp(1.5rem, 1.2rem + 1.5vw, 2.25rem); }
.cfaq__h {
  font-size: clamp(1.75rem, 1.3rem + 2.2vw, 2.9rem);
  font-weight: 600;
  letter-spacing: -0.032em;
  color: var(--white);
}
.cfaq__sub { margin-top: 0.9rem; color: var(--vein); line-height: 1.65; text-wrap: pretty; }

/* ==========================================================================
   .vox  -  "What it is actually like" (careers, above the FAQ)

   WHAT THIS REPLACED, MEASURED. `.says` was three identical 383x374 cards in
   a row, each opening with a 52px curly quote glyph and closing with a
   circular monogram - the single most templated component on the web, and
   the one a candidate has already scrolled past on every careers page they
   have ever opened. Its head was capped at 42rem inside a 1270px container,
   which left 598px of dead page beside it, and the quotes were set at 17px:
   the same size as body copy, in equal boxes, three at once. Three quotes
   shown together are three quotes nobody reads.

   (The old card also carried `border-radius: var(--radius-lg)`, a token this
   site has never defined - it resolved to nothing and the cards were square
   by accident. They are square on purpose now.)

   THE SECTION SHOWS ONE VOICE AT A TIME, AT DISPLAY SCALE. A quote you can
   actually read beats three you skim, and it is the only way to give this
   section a real typographic event: 28px against the 17px it was.

   IT IS A DECK, AND IT DEALS ITSELF. Three plates stacked with the two
   behind peeking above the live one, and on every advance the live plate
   FALLS FORWARD AND AWAY while the next rises into its place. That gesture
   is this section's alone - it is not the ruled register the team page uses,
   and it is not a fade. A fade says "different text now"; a card coming off
   the top says "next person".

   THE PLATE IS THE FULL CONTAINER AND THE SPEAKER FILLS THE RIGHT OF IT, so
   nothing is capped and there is no channel down the middle - the failure
   the old head had.

   NO FACES, STILL. There is no photograph of these people and a stock
   portrait beside a real name is a worse lie than a monogram. The initials
   stay; the circle around them does not, because nothing else on this site
   is round except a status light.

   THE ADVANCE IS ANNOUNCED BY THE CONTROL THAT WILL DO IT. Three hairline
   segments under the deck, one per speaker, and the live one FILLS over the
   length of the hold. A deck that moves with no warning reads as a fault.
   It is dropped the moment the reader takes the control, because from then
   on nothing moves unasked.

   STATE IS main.js's. This markup ships with the first plate live, so with
   no JavaScript the section is one complete, readable quote.
   ========================================================================== */

/* --vdwell IS NOT @property-REGISTERED, AND DOES NOT NEED TO BE. The dwell
   transitions `transform`, not the custom property: the computed transform
   goes scaleX(0) -> scaleX(1) as the number is rewritten, and a transform
   transition interpolates that on the compositor. Registering it and
   transitioning the property instead would put a style recalc on every frame
   of a six-second fill to buy exactly nothing. (`.post` on the team page DOES
   register its equivalent, because that one transitions the property.) */

.vox { padding-block: var(--section); position: relative; }

/* ---- the rail ----------------------------------------------------------- */

.vox__rail {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem 2rem;
  flex-wrap: wrap;
}
.vox__rail .eyebrow { margin-bottom: 0; }
.vox__idx {
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  font-variant-numeric: tabular-nums;
  color: var(--vein);
}
.vox__idx b { color: var(--gold-light); font-weight: 700; }

.vox__rule {
  display: block;
  height: 1px;
  margin: clamp(0.9rem, 0.7rem + 0.8vw, 1.35rem) 0 clamp(1.2rem, 0.9rem + 1.2vw, 2rem);
  background: linear-gradient(90deg, var(--gold), rgba(184, 145, 88, 0.28) 74%, transparent);
  transform-origin: left center;
}

/* ---- the head ------------------------------------------------------------
   Heading and sub BESIDE each other. Stacked and capped at 42rem they cost
   160px of height and left 598px of the container empty. */

.vox__head {
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(0, 1fr);
  column-gap: clamp(1.5rem, 1rem + 2.6vw, 3.5rem);
  row-gap: 0.9rem;
  align-items: end;
  margin-bottom: clamp(1.5rem, 1.2rem + 1.6vw, 2.5rem);
}
.vox__h {
  font-size: var(--text-h2);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.08;
  color: var(--white);
  text-wrap: balance;
}
.vox__h span { display: block; overflow: hidden; padding-bottom: 0.06em; }
.vox__h i { display: block; font-style: normal; }
.vox__sub {
  position: relative;
  padding-left: clamp(0.9rem, 0.6rem + 1vw, 1.5rem);
  color: var(--ink);
  font-size: var(--text-lg);
  line-height: 1.6;
  text-wrap: pretty;
}
.vox__sub::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.35em;
  bottom: 0.35em;
  width: 1px;
  background: linear-gradient(180deg, var(--gold), rgba(184, 145, 88, 0.08));
}

/* ---- the deck ------------------------------------------------------------
   All three plates occupy ONE grid cell, so the deck is as tall as its
   longest quote and dealing can never shift the page under the reader. The
   padding is the room the two plates behind peek into. */

.vox__deck {
  position: relative;
  display: grid;
  grid-template-areas: "plate";
  padding-top: 34px;
}

.vox__plate {
  grid-area: plate;
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(1.5rem, 1rem + 2.4vw, 3.25rem);
  align-items: start;
  padding: clamp(1.5rem, 1.2rem + 1.4vw, 2.4rem);
  border: 1px solid var(--border-neutral);
  border-radius: var(--radius-sm);
  background: linear-gradient(158deg, var(--surface), var(--obsidian-raised) 72%);
  /* --d is the depth in the stack: 0 is live, 1 and 2 are behind it. One
     number drives the lift, the shrink, the dimming and the layer, so a
     plate can never be at one depth for its position and another for its
     tone.

     --ay AND --ao ARE THE ARRIVAL, AND THEY EXIST BECAUSE GSAP CANNOT HAVE
     `transform` OR `opacity` HERE. A tween on either writes the whole
     property inline, which erases the depth composition on its first tick -
     every plate would square up to depth 0 and the deck would flatten into
     one card. Both are composed here and motion.js tweens only the numbers.
     --ao MULTIPLIES the depth dimming rather than replacing it, so the
     plates behind stay dimmed after the arrival finishes. */
  transform:
    translateY(calc(var(--d, 0) * -15px + var(--ay, 0) * 1px))
    scale(calc(1 - var(--d, 0) * 0.038));
  opacity: calc((1 - var(--d, 0) * 0.28) * var(--ao, 1));
  z-index: calc(10 - var(--d, 0));
  transition:
    transform 0.62s var(--ease-out),
    opacity 0.62s var(--ease-out),
    border-color 0.5s var(--ease-out),
    box-shadow 0.62s var(--ease-out);
}
.vox__plate.is-live {
  border-color: var(--border-gold-strong);
  box-shadow: 0 34px 60px -40px rgba(0, 0, 0, 0.95);
}

/* THE PLATES BEHIND ARE CHROME, NOT GHOST TEXT. Their contents are hidden
   rather than dimmed: three quotes bleeding through each other at 20%
   opacity is mush, and `visibility` also takes them out of the accessibility
   tree, so the deck announces one quote instead of three. */
.vox__plate:not(.is-live) > * { visibility: hidden; }

/* the deal-off: forward and down, in front of the stack it is leaving */
.vox__plate.is-leaving {
  transform: translateY(40px) scale(0.965);
  opacity: 0;
  z-index: 12;
}

/* ---- the quote ---------------------------------------------------------- */

.vox__said { position: relative; }

/* A HANGING MARK, WHICH IS WHAT AN OPENING QUOTE IS FOR. It used to sit
   above the text as a 52px blob doing no typographic work. Pulled into the
   margin it aligns the first line of every quote to the same left edge as
   everything else in the section, which is the whole reason the convention
   exists. */
.vox__mark {
  position: absolute;
  left: -0.52em;
  top: -0.18em;
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 1.8rem + 2.4vw, 3.75rem);
  line-height: 1;
  font-weight: 700;
  color: transparent;
  -webkit-text-stroke: 1px rgba(214, 182, 126, 0.55);
  pointer-events: none;
}

.vox__quote p {
  color: var(--ink);
  font-size: clamp(1.15rem, 0.95rem + 1.05vw, 1.75rem);
  line-height: 1.5;
  letter-spacing: -0.015em;
  text-wrap: pretty;
  /* uncovered left to right, in reading order - the direction every rule on
     this page draws in. Default 1: with motion.js absent it is simply there. */
  -webkit-mask-image: linear-gradient(90deg, #000 0 calc(var(--wipe, 1) * 100%), transparent 0);
          mask-image: linear-gradient(90deg, #000 0 calc(var(--wipe, 1) * 100%), transparent 0);
}

/* ---- the speaker --------------------------------------------------------- */

.vox__by {
  display: grid;
  gap: 0.75rem;
  justify-items: start;
  min-width: clamp(9rem, 7rem + 6vw, 13rem);
  padding-left: clamp(1.25rem, 0.9rem + 1.6vw, 2.25rem);
  border-left: 1px solid var(--border-gold);
}

/* initials rather than a face: there is no photograph of these people, and a
   stock portrait beside a real name is a worse lie than a monogram. Cut
   square, because nothing on this site is round except a status light. */
.vox__mono {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border: 1px solid var(--border-gold-strong);
  border-radius: var(--radius-sm);
  background: var(--gold-wash);
  color: var(--gold-light);
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}
.vox__name {
  color: var(--white);
  font-family: var(--font-display);
  font-size: clamp(1rem, 0.94rem + 0.3vw, 1.2rem);
  font-weight: 600;
  letter-spacing: -0.018em;
  line-height: 1.2;
}
.vox__role {
  margin-top: 0.3rem;
  color: var(--gold);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.5;
}

/* ---- the control ---------------------------------------------------------
   Three hairline segments, one per speaker, and the live one fills over the
   length of the hold. The control that is going to move the deck is the same
   element that says when. */

.vox__ctl {
  display: flex;
  align-items: center;
  gap: clamp(0.6rem, 0.4rem + 0.8vw, 1rem);
  margin-top: clamp(1.1rem, 0.9rem + 0.9vw, 1.75rem);
}

.vox__seg {
  position: relative;
  flex: 1 1 0;
  min-height: 44px;      /* the target, not the mark */
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: flex;
  align-items: center;
}
.vox__seg::before {
  content: "";
  flex: 1;
  height: 2px;
  background: var(--border-neutral);
  transition: background 0.45s var(--ease-out);
}
.vox__seg:hover::before { background: var(--border-gold-strong); }
.vox__seg:focus-visible { outline: 1px solid var(--gold); outline-offset: 2px; }

.vox__seg i {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--gold-light), var(--gold));
  transform: scaleX(var(--vdwell, 0));
  transform-origin: left center;
  box-shadow: 0 0 10px rgba(192, 156, 96, 0.5);
}
/* once a segment has been played it stays lit behind, so the row reads as a
   position in three rather than as one lamp wandering along a rail */
.vox__seg.is-done i { transform: scaleX(1); opacity: 0.4; }
.vox.is-held .vox__seg.is-live i { transform: scaleX(1); }

/* ---- narrower ------------------------------------------------------------ */

@media (max-width: 860px) {
  .vox__head { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .vox__plate {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(1.2rem, 1rem + 1vw, 1.75rem);
  }
  /* the speaker goes under the quote, so the rule that separated them turns
     with it rather than hanging off the side of nothing */
  .vox__by {
    padding-left: 0;
    padding-top: clamp(1.1rem, 0.9rem + 0.8vw, 1.5rem);
    border-left: 0;
    border-top: 1px solid var(--border-gold);
    min-width: 0;
    width: 100%;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 0.9rem;
  }
  .vox__mark { left: -0.34em; }
}

@media (max-width: 560px) {
  .vox__deck { padding-top: 24px; }
  /* the same composition, shallower - --ay has to stay in it or the arrival
     silently stops moving on a phone */
  .vox__plate {
    transform:
      translateY(calc(var(--d, 0) * -11px + var(--ay, 0) * 1px))
      scale(calc(1 - var(--d, 0) * 0.03));
  }
  .vox__mono { width: 40px; height: 40px; }
}

@media (prefers-reduced-motion: reduce) {
  .vox__plate,
  .vox__seg::before { transition: none; }
  .vox__seg i { transform: scaleX(1); opacity: 0.4; }
  .vox__seg.is-live i { opacity: 1; }
}
