/* ================================================================
   Work at Keytos — page styles (.kwork-* hero/values/perks, .kjob-* openings)
   Figma "Careers page": desktop 7:2826, mobile 43:478.

   Everything else under css/ is vendored verbatim from the
   KeytosLandingPage design system — see VENDORED.md. This file is the
   only page-specific stylesheet, and it loads last so its
   same-specificity overrides win on source order.

   Section fills, taken from the design:
     band (hero + values)  ebf5ff -> ffffff gradient
     quote strip           ebf5ff   (.kwork-tint)
     team benefits         ffffff   (.kcap-section's own fill)
     openings              ebf5ff   (.kwork-tint)
     CTA band              blue gradient (.kpcta-section's own fill)
     FAQ                   ffffff   (.kfaq-section's own fill)
   ================================================================ */

/* ---- Gradient band --------------------------------------------
   Deliberately NOT named "*-gradient-band". On the marketing site that
   suffix opts a page into hero.css's alternating canvas/card backgrounds
   for every section after the band. This page names all six of its fills
   itself, so it stays out of that machinery entirely — which also means
   vendored hero.css needs no local edits. The two rules the suffix
   selector would have supplied are restated below.

   The band spans the hero AND the values grid, so the fade runs the full
   height rather than hero.css's hero-plus-stats-strip 50%. */
.kwork-band {
  background: linear-gradient(180deg, var(--color-info-background) 1%, var(--color-surface-card) 99%);
}
.kwork-band .khero { background: transparent; }
.kwork-band .kcap-section { background: transparent; }

/* Light blue section fill. The second selector outranks .kstat's own
   canvas background rather than relying on file order alone. */
.kwork-tint,
.kstat.kwork-tint { background: var(--color-info-background); }

/* ---- Shared section heading -----------------------------------
   Same shape as .kcap-title / .kfaq-title: H2, brand blue, centred on
   desktop and left-aligned once the section left-aligns at 767px. */
.kwork-title {
  margin: 0;
  max-width: var(--content-max);
  text-align: center;
  font-family: var(--font-family-primary);
  font-weight: 700;
  font-size: var(--font-size-h2);
  line-height: var(--line-height-h2);
  color: var(--color-text-brand);
}

/* ================================================================
   Hero (.khero--work) — media left, copy right, 50/50
   The clip is a transparent VP9 WebM of the "DON'T" graffiti painting
   itself over a static WORK AT KEYTOS wordmark, so the two layers sit in
   one 16:9 box and the hero gradient shows through both.
   ================================================================ */
.khero--work .khero-inner { align-items: center; }
.khero--work .khero-content { flex: 1 1 0; }
.khero--work .khero-media {
  flex: 1 1 0;
  align-self: center;
  aspect-ratio: 16 / 9;
  min-height: 0;
}

/* Transparent clip rather than a photo: drop the placeholder gradient and
   the rounded clipping a framed image needs. */
.khero-media--clip {
  background: none;
  border-radius: 0;
  overflow: visible;
}

/* All three layers are authored on the same 16:9 canvas, so they register
   with no positioning maths. */
.kwork-hero-art { position: relative; width: 100%; height: 100%; }
.kwork-hero-art img,
.kwork-hero-art video {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* The graffiti paints over the wordmark: together they read
   "Don't work at Keytos". The still and the clip share the upper layer —
   only ever one of them is visible. */
.kwork-hero-wordmark { z-index: 0; }
.kwork-hero-still,
.kwork-hero-clip { z-index: 1; }

/* The still is the default and everything else is hidden, so any path that
   cannot be proved good — no JS, reduced motion, a clip that will not start —
   keeps a hero that reads correctly. careers.js then promotes one of two clip
   states, and which one decides how the wordmark is handled:

     .is-clip-alpha   the transparent WebM. Carries the graffiti alone, so it
                      needs the wordmark layer beneath it.
     .is-clip-flat    the opaque MP4. The wordmark is baked into the encode,
                      so the wordmark layer must stay DOWN or the same letters
                      are drawn twice — and being opaque it would cover them
                      anyway.

   The still is the same shape as the MP4 (both are full composites), which is
   why neither of them wants the wordmark layer.

   visibility rather than display, so every layer keeps its box and no swap
   can shift the artwork. */
.kwork-hero-wordmark,
.kwork-hero-clip { visibility: hidden; }
.is-clip-alpha .kwork-hero-wordmark,
.is-clip-alpha .kwork-hero-clip,
.is-clip-flat .kwork-hero-clip { visibility: visible; }
.is-clip-alpha .kwork-hero-still,
.is-clip-flat .kwork-hero-still { visibility: hidden; }

/* ---- Hero facts -----------------------------------------------
   Three facts separated by hairlines. The row count is driven by the
   width of the column the grid sits in, not the viewport: beside the
   media that column is ~616px, but once the hero stacks the same grid
   gets the full section width back, so a viewport media query would give
   the wrong answer in one of the two modes. .kwork-stats is therefore a
   size container and the grid inside queries it.

   Columns are content-sized rather than even fractions, which is what
   Figma draws — the rules hug the text with 24px either side instead of
   sitting at even thirds. That also means one row fits in far less width
   than three equal columns would need. */
.kwork-stats { container-type: inline-size; width: 100%; }

/* Narrowest first: one fact per row, hairlines horizontal between them.
   The five children are item, rule, item, rule, item in every state; the
   container queries below only re-place them. */
.kwork-stats-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--space-12);
}
.kwork-stat-rule { height: 1px; background: var(--color-border-default); }

/* Two rows, 2 + 1 -- the layout the design itself uses at desktop, now that
   "Boston & Mexico City" is too wide for three across a 616px hero column.
   Thresholds are measured, not guessed. The requirement moves with the type
   scale, so both gates take the widest case (a 1440 viewport, --font-size-h4
   at 24px), which is the only way one gate can hold at every width:

     viewport   h4     one row   two rows
     1440       24px     731        487     <- gates are set from this row
     900        22px     678        451
     <=767      20px     626        414

   The cost is a narrow band around a 768-810 viewport that shows two rows
   where one would just fit. Nothing is squeezed there, and two rows is what
   the design uses at desktop anyway. Re-measure when the fact text changes
   -- adding the word "City" alone moved the one-row figure up by 52px. */
@container (min-width: 500px) {
  .kwork-stats-grid {
    grid-template-columns: auto 1px auto;
    justify-content: start;
    column-gap: var(--space-24);
  }
  /* First rule turns vertical; the second stays a horizontal divider
     between the two rows. */
  .kwork-stats-grid > :nth-child(2) { height: auto; }
  .kwork-stats-grid > :nth-child(4),
  .kwork-stats-grid > :nth-child(5) { grid-column: 1 / -1; }
}

/* One row, once all three facts and both rules fit. At 1280+ the hero column
   is only 616px, so this state belongs to the stacked hero, where the facts
   get the full section width back. */
@container (min-width: 745px) {
  .kwork-stats-grid { grid-template-columns: auto 1px auto 1px auto; }
  .kwork-stats-grid > :nth-child(4) { grid-column: auto; height: auto; }
  .kwork-stats-grid > :nth-child(5) { grid-column: auto; }
}

.kwork-stat { display: flex; flex-direction: column; gap: var(--space-4); }
.kwork-stat-value {
  margin: 0;
  font-family: var(--font-family-primary);
  font-weight: 700;
  font-size: var(--font-size-h4);
  line-height: var(--line-height-h4);
  color: var(--color-info-default);
}
.kwork-stat-label {
  margin: 0;
  font-family: var(--font-family-secondary);
  font-weight: 400;
  font-size: var(--font-size-b2);
  line-height: var(--line-height-b2);
  color: var(--color-text-secondary);
}

/* ================================================================
   Values grid (.kwork-fit)
   Four cards, each pairing the signals we hire against with the ones we
   do not. Reuses .kcap-section / .kcap-grid / .kcap-item / .kcap-icon /
   .kcap-item-title; the card chrome and the two signal groups below are
   the page-specific part.
   ================================================================ */
.kwork-fit { row-gap: var(--space-32); column-gap: var(--space-32); }
.kwork-fit .kcap-item {
  gap: var(--space-16);
  padding: var(--space-32) var(--space-24);
  background: var(--color-surface-card);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-2xl);
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
}
.kwork-fit .kcap-icon { color: var(--color-text-brand); }

/* Title and description sit 8px apart inside a card whose other blocks are
   16px apart, so they need their own wrapper (Figma 86:1708). */
.kwork-fit-head { display: flex; flex-direction: column; gap: var(--space-8); }
/* product.css sets .kcap-item-desc to primary; on these cards it is the
   quieter grey. */
.kwork-fit .kcap-item-desc { color: var(--color-text-secondary); }

/* The card body. Figma replaced the two bullet lists with a single
   paragraph per value (86:1593 and siblings), so the label glyphs, the
   divider and the bullet column are all gone. */
.kwork-fit-body {
  margin: 0;
  font-family: var(--font-family-secondary);
  font-weight: 400;
  font-size: var(--font-size-b1);
  line-height: var(--line-height-b1);
  color: var(--color-text-primary);
}

/* ================================================================
   "What our team loves" strip
   Centred heading over a two-column row: quote, attribution and podcast
   button on the left, the team photo on the right. The fr pair is
   Figma's 736 / 512 of the 1280 content width, kept proportional so the
   quote never gets squeezed into an unreadable measure between
   breakpoints.
   ================================================================ */
.kwork-love {
  width: 100%;
  max-width: var(--content-max);
  display: grid;
  grid-template-columns: minmax(0, 736fr) minmax(0, 512fr);
  gap: var(--space-32);
  align-items: center;
}
/* .kstat-quote is a flex column already. It is a <figure>, whose default
   margin would knock it off the grid column, and the previous
   single-column layout centred its text. */
.kwork-love-quote {
  margin: 0;
  max-width: none;
  align-items: flex-start;
}
.kwork-love-quote .kstat-quote-text,
.kwork-love-quote .kstat-quote-attr { text-align: left; }
/* On top of the figure's own 16px gap, for the 32px Figma puts between
   the attribution and the button. */
.kwork-love-cta { margin-top: var(--space-16); }
.kwork-love-media {
  aspect-ratio: 3 / 2;
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.kwork-love-media img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* ================================================================
   Team benefits (.kwork-perk-*) — one full-width card per benefit
   The photo that used to sit beside this list now lives in the quote
   strip above, so the cards run the full content width.
   ================================================================ */
.kwork-perks {
  width: 100%;
  max-width: var(--content-max);
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
}
/* Section and card are both white, so the 1px border and the shared card
   shadow are what separate them. min-height rather than Figma's fixed
   88px: it holds the uniform height the design gives the stack while
   still letting longer copy grow instead of overflowing. */
.kwork-perk {
  display: flex;
  align-items: center;
  gap: var(--space-24);
  min-height: 88px;
  padding: var(--space-16) var(--space-24);
  background: var(--color-surface-card);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-xl);
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
}
.kwork-perk-icon {
  flex: 0 0 24px;
  width: 24px;
  height: 24px;
  color: var(--color-text-brand);
}
.kwork-perk-icon svg { display: block; width: 100%; height: 100%; }
.kwork-perk-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.kwork-perk-title {
  margin: 0;
  font-family: var(--font-family-primary);
  font-weight: 500;
  font-size: var(--font-size-h5);
  line-height: var(--line-height-h5);
  color: var(--color-text-brand);
}
.kwork-perk-desc {
  margin: 0;
  font-family: var(--font-family-secondary);
  font-weight: 400;
  font-size: var(--font-size-b2);
  line-height: var(--line-height-b2);
  color: var(--color-text-secondary);
}

/* ================================================================
   Openings accordion (.kjob-*)
   Same grid-row height animation as .kacc-* / .kfaq-*, but the trigger
   carries a four-column row (title, employment type, location, chevron)
   and the open item lifts onto a white card.
   ================================================================ */
.kjob-section {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-32);
  padding-block: var(--section-pad-y);
  padding-inline: var(--section-pad-x);
  /* Target of the hero's "See openings" button. */
  scroll-margin-top: var(--anchor-offset);
}

.kjob-list {
  width: 100%;
  max-width: var(--content-max);
  display: flex;
  flex-direction: column;
}

.kjob-item { border-bottom: 1px solid var(--color-border-default); }
/* The section is tinted, so the open item lifts by going white. Collapsed
   rows preview the same lift on hover; .kjob-trigger transitions its
   background so that fades rather than snaps. */
.kjob-item.is-open { background: var(--color-surface-card); }
/* Only where a pointer can actually hover. On a touch screen :hover latches
   after a tap, so the row a visitor last touched stayed white — reading as a
   second open row, next to the one that really is open. */
@media (hover: hover) {
  .kjob-item:not(.is-open) > .kjob-trigger:hover { background: var(--color-surface-card); }
}

/* Buttons latch the same way: tap Apply now, See openings or Contact us on a
   phone and it keeps its hover colours until the page is left. Each of these
   :hover rules lives in a vendored file (hero.css, product.css, navbar.css),
   so rather than edit those they are neutralised here by restating the
   button's own resting values — see VENDORED.md. careers.css loads last, so
   matching the vendored selectors exactly is enough to win the cascade.

   Keep each block's declarations in step with the base rule it restores; a
   token renamed upstream has to be mirrored here. */
@media (hover: none) {
  .kbtn-primary:hover {
    background: var(--color-btn-primary-default);
    color: var(--color-text-button-fill);
  }
  .kbtn-secondary:hover {
    color: var(--color-text-primary);
    border-color: var(--color-btn-secondary-border-default);
  }
  .kpcta-btn-fill:hover {
    background: #ffffff;
    color: var(--color-text-brand);
    border-color: #ffffff;
  }
  .knav-contact:hover {
    background: var(--color-btn-primary-default);
    color: var(--color-text-button-fill);
  }
}

/* Title column is roughly half the row and the two meta columns split the
   rest, which is where Figma puts them (597 / 297 / 310 / 28 of 1232).
   The two wrappers are transparent here so the grid sees four items; they
   become real boxes in the stacked layout below. */
.kjob-trigger {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.5fr) minmax(0, 0.5fr) 28px;
  align-items: center;
  column-gap: var(--space-24);
  width: 100%;
  padding: var(--space-24);
  border: none;
  background: none;
  cursor: pointer;
  text-align: left;
  transition: background 0.2s ease;
}
.kjob-trigger-main,
.kjob-metas { display: contents; }

.kjob-name {
  font-family: var(--font-family-primary);
  font-weight: 500;
  font-size: var(--font-size-h5);
  line-height: var(--line-height-h5);
  color: var(--color-info-default);
}

.kjob-meta {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  font-family: var(--font-family-secondary);
  font-weight: 400;
  font-size: var(--font-size-b2);
  line-height: var(--line-height-b2);
  color: var(--color-text-secondary);
}
.kjob-meta svg { flex-shrink: 0; display: block; width: 20px; height: 20px; }

.kjob-chevron {
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  color: var(--color-text-primary);
  transition: transform 0.2s ease;
}
.kjob-chevron svg { display: block; width: 100%; height: 100%; }
.kjob-item.is-open .kjob-chevron { transform: rotate(180deg); }

.kjob-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.3s ease;
}
.kjob-item.is-open .kjob-body { grid-template-rows: 1fr; }
.kjob-body-inner { overflow: hidden; }

.kjob-rule {
  height: 1px;
  background: var(--color-border-default);
  margin-inline: var(--space-24);
}

.kjob-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
  padding: var(--space-24) var(--space-48);
}

/* Label left, prose in an 800px measure on the right. space-between hands
   the leftover width to the gap, which reproduces Figma's 152px trench at
   full size and collapses to the 32px minimum as the card narrows. */
.kjob-row {
  display: grid;
  grid-template-columns: 240px minmax(0, 800px);
  justify-content: space-between;
  column-gap: var(--space-32);
}
.kjob-label {
  margin: 0;
  font-family: var(--font-family-secondary);
  font-weight: 500;
  font-size: var(--font-size-b1);
  line-height: var(--line-height-b1);
  color: var(--color-text-primary);
}
.kjob-value {
  margin: 0;
  font-family: var(--font-family-secondary);
  font-weight: 400;
  font-size: var(--font-size-b2);
  line-height: var(--line-height-b2);
  color: var(--color-text-primary);
}
.kjob-value + .kjob-value { margin-top: var(--space-16); }
/* Inline prose links, matching .kacc-desc a and .kfaq-answer a. */
.kjob-value a {
  color: var(--color-text-brand);
  text-decoration: underline;
  text-underline-offset: 2px;
}
/* Guarded for the same reason as the row and button hovers above: on touch,
   a tapped link stayed stripped of its underline for as long as the page was
   open. */
@media (hover: hover) {
  .kjob-value a:hover { text-decoration: none; }
}

.kjob-bullets {
  margin: 0;
  padding-left: var(--space-20);
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}
.kjob-bullets li {
  font-family: var(--font-family-secondary);
  font-weight: 400;
  font-size: var(--font-size-b2);
  line-height: var(--line-height-b2);
  color: var(--color-text-primary);
}

/* Apply button sits in the prose column so it lines up with the answers. */
.kjob-apply { grid-column: 2; width: 100%; }

/* ================================================================
   Tablet
   ================================================================ */
@media (max-width: 1072px) {
  .kjob-section { padding-block: var(--space-48); padding-inline: var(--space-32); }
  .kjob-content { padding-inline: var(--space-32); }
}

/* 900px is this page's single stacking breakpoint: the hero goes to one
   column with the media on top (the mobile design order), the quote strip goes
   to one column, and an opening title stacks over its meta pair instead of
   sharing a four-column row. */
@media (max-width: 900px) {
  .khero--work .khero-inner { flex-direction: column; align-items: stretch; gap: var(--space-32); }
  .khero--work .khero-content { display: contents; }
  /* The generic .khero rules at this width put the media last (order: 6) with a
     280px floor, so both are restated. flex must also go back to 0 0 auto: the
     inner is a column now, so flex-basis governs HEIGHT, and a basis of 0 beats
     aspect-ratio on the main axis and collapses the artwork to nothing. */
  .khero--work .khero-media { order: 1; align-self: stretch; flex: 0 0 auto; min-height: 0; }
  .khero--work .khero-title { order: 2; }
  .khero--work .kwork-stats { order: 3; }
  .khero--work .khero-actions { order: 4; }

  /* Quote and photo stack; the photo follows the quote so the heading stays
     next to the words it introduces. */
  .kwork-love { grid-template-columns: minmax(0, 1fr); }

  .kjob-trigger { display: flex; align-items: flex-start; gap: var(--space-16); }
  .kjob-trigger-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
  }
  .kjob-metas { display: flex; flex-wrap: wrap; gap: var(--space-8) var(--space-12); }
  .kjob-chevron { align-self: center; }

  /* Once the hero is stacked, nothing on the page is centred any more —
     headings, paragraphs and loose buttons all go left, the way they do on a
     phone. The vendored sheets only do this at 767; careers.css loads last, so
     restating the same set here moves it up to 900. Buttons only go
     full-width at 767, in the block below. */
  .kwork-title,
  .kcap-title,
  .kfaq-title { text-align: left; }
  .kcap-section,
  .kfaq-section,
  .kjob-section,
  .kstat.kwork-tint { align-items: flex-start; }
  .kcap-cta { align-self: flex-start; }
  .kpcta-inner,
  .kpcta-head { align-items: flex-start; }
  .kpcta-heading,
  .kpcta-desc { text-align: left; }
}

/* ================================================================
   Mobile
   ================================================================ */
@media (max-width: 767px) {
  .kjob-section { padding-block: var(--space-32); padding-inline: var(--space-16); }
  .kjob-trigger { padding: var(--space-12); }
  .kjob-rule { margin-inline: var(--space-12); }
  .kjob-content { padding: var(--space-16) var(--space-12) var(--space-20); gap: var(--space-24); }

  /* The design gives the card stack a uniform 88px height; on one narrow
     column the copy wraps more and a one-line card would just be padding.
     The icon stays vertically centred against the wrapped copy. */
  .kwork-perk { min-height: auto; }

  /* Label above its prose. */
  .kjob-row { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-8); }
  .kjob-apply { grid-column: 1; }

  /* The CTA fills the row here like every other button at this width. */
  .kwork-love-cta { width: 100%; white-space: normal; text-align: center; }

  /* Section CTAs fill the row like every other button at this width
     (.khero-actions .kbtn and .kwork-love-cta both do). .kcap-cta is
     centred by product.css, so the stretch has to be undone explicitly. */
  .kcap-cta { align-self: stretch; width: 100%; text-align: center; }
}
