/* Synthesys Solutions — careers portal
   Layout system ported from portals/brilliqs-sales-jd, which took it from
   brands/emberlan/challenge-portal: hard 2px rules, offset shadows, numbered
   badges, alternating mist sections, marquee ribbon, four-node timeline.

   Re-skinned to the Synthesys identity — charcoal ink with the logo's two
   crescent colours. The accent law, because two accents go wrong fast:

     YELLOW  #FFED00  is a FILL, never text. Offset shadows, the highlight
                      sweep, badge grounds, the callout band, ribbon rules.
     LIME    #B0CB1F  is the MARKER. Ticks, section rules, list bullets,
                      timeline fill, dots. Shapes, not runs of text.
     OLIVE   #5E7000  is the only accent that carries TEXT — a darkened lime,
                      5.6:1 on white where raw lime is 1.9:1. Links, eyebrows,
                      labels, .accent spans.

   This is the deliberate divergence from the Brilliqs portal, which runs one
   accent because Brilliqs has no secondary. The Synthesys logo has two, so the
   portal has two, and the law above is what keeps them from muddling. */

/* ---------- fonts (self-hosted; the PDF export must not need a network) ---------- */

@font-face {
  font-family: 'Source Serif 4 Variable';
  font-style: normal;
  font-display: block;
  font-weight: 200 900;
  src: url(fonts/source-serif-4-latin-opsz-normal.woff2?v=f2ea9c12d2) format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Source Serif 4 Variable';
  font-style: normal;
  font-display: block;
  font-weight: 200 900;
  src: url(fonts/source-serif-4-latin-ext-opsz-normal.woff2?v=155f6e7010) format('woff2-variations');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Source Serif 4 Variable';
  font-style: italic;
  font-display: block;
  font-weight: 200 900;
  src: url(fonts/source-serif-4-latin-opsz-italic.woff2?v=96e6393209) format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter Variable';
  font-style: normal;
  font-display: block;
  font-weight: 100 900;
  src: url(fonts/inter-latin-wght-normal.woff2?v=3100e775e8) format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter Variable';
  font-style: normal;
  font-display: block;
  font-weight: 100 900;
  src: url(fonts/inter-latin-ext-wght-normal.woff2?v=34b9c504ca) format('woff2-variations');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter Variable';
  font-style: italic;
  font-display: block;
  font-weight: 100 900;
  src: url(fonts/inter-latin-wght-italic.woff2?v=7291b5970d) format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono Variable';
  font-style: normal;
  font-display: block;
  font-weight: 100 800;
  src: url(fonts/jetbrains-mono-latin-wght-normal.woff2?v=18be452724) format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- tokens ---------- */

:root {
  /* charcoal, lifted verbatim from the logo's .fil0 */
  --ink: #2B2A29;
  --ink-soft: #4A4946;
  --slate: #77766F;
  --slate-light: #9B998F;

  --yellow: #FFED00;        /* logo .fil1 — fills only */
  --yellow-tint: #FFF7A8;
  --yellow-wash: #FFFCE4;
  --lime: #B0CB1F;          /* logo .fil2 — markers only */
  --lime-deep: #5E7000;     /* derived: the accent that may carry text */
  --lime-wash: #F5F9E4;

  --paper: #FFFFFF;
  --mist: #F7F7F2;
  --line: #E2E1D9;
  --line-strong: #C9C7BC;

  /* Surfaces that stay a contrasting slab in BOTH themes: the ribbon, the
     footer, the Synthesys node in the org diagram. A plain token flip would
     turn these into full-width white bands on a dark page. */
  --head-bg: rgba(255, 255, 255, 0.94);
  --slab: #2B2A29;
  --slab-fg: #FFFFFF;
  --slab-muted: #A5A399;
  --slab-tag: #E8EFC4;
  --mark-opacity: 0.13;

  /* The dark palette lives here once. The two blocks below only RE-MAP these
     onto the tokens above, so a value can never drift between the OS media
     query and the toggle's manual override. Verified AA on --d-paper: body
     15.8:1, soft 8.9:1, slate 4.9:1, accent 12.6:1. Yellow and lime are left
     at their brand values — both already clear AA as fills on charcoal. */
  --d-ink: #EDECE7;
  --d-ink-soft: #B6B4AD;
  --d-slate: #85837C;
  --d-lime-deep: #C7E04A;
  --d-yellow-tint: #4F4700;
  --d-yellow-wash: #26230A;
  --d-lime-wash: #1E2409;
  --d-paper: #141310;
  --d-mist: #1C1B18;
  --d-line: #2E2C28;
  --d-line-strong: #45423C;
  --d-head-bg: rgba(20, 19, 16, 0.92);
  --d-slab: #201F1C;

  --radius: 4px;
  --serif: 'Source Serif 4 Variable', Georgia, serif;
  --sans: 'Inter Variable', -apple-system, 'Segoe UI', system-ui, sans-serif;
  --mono: 'JetBrains Mono Variable', ui-monospace, 'SF Mono', Menlo, monospace;

  --shell: 940px;
}

/* ---------- dark theme ----------
   Two entry points, one mapping. `:root:not([data-theme="light"])` means the OS
   preference applies UNLESS the toggle has explicitly pinned light: a person who
   chose light on a dark-mode machine keeps light. */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  --ink: var(--d-ink);
  --ink-soft: var(--d-ink-soft);
  --slate: var(--d-slate);
  --slate-light: var(--d-slate);
  --lime-deep: var(--d-lime-deep);
  --yellow-tint: var(--d-yellow-tint);
  --yellow-wash: var(--d-yellow-wash);
  --lime-wash: var(--d-lime-wash);
  --paper: var(--d-paper);
  --mist: var(--d-mist);
  --line: var(--d-line);
  --line-strong: var(--d-line-strong);
  --head-bg: var(--d-head-bg);
  --slab: var(--d-slab);
  --slab-fg: var(--d-ink);
  --slab-muted: var(--d-slate);
  --slab-tag: var(--d-lime-deep);
  --mark-opacity: 0.20;
  }
}

:root[data-theme="dark"] {
  --ink: var(--d-ink);
  --ink-soft: var(--d-ink-soft);
  --slate: var(--d-slate);
  --slate-light: var(--d-slate);
  --lime-deep: var(--d-lime-deep);
  --yellow-tint: var(--d-yellow-tint);
  --yellow-wash: var(--d-yellow-wash);
  --lime-wash: var(--d-lime-wash);
  --paper: var(--d-paper);
  --mist: var(--d-mist);
  --line: var(--d-line);
  --line-strong: var(--d-line-strong);
  --head-bg: var(--d-head-bg);
  --slab: var(--d-slab);
  --slab-fg: var(--d-ink);
  --slab-muted: var(--d-slate);
  --slab-tag: var(--d-lime-deep);
  --mark-opacity: 0.20;
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
html { scroll-behavior: smooth; }
html, body { overflow-x: clip; }

body {
  font-family: var(--sans);
  color: var(--ink);
  background: var(--paper);
  font-size: 17px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: 'kern' 1;
}

h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.14;
  font-optical-sizing: auto;
}

strong { font-weight: 650; color: var(--ink); }
em { font-style: italic; }
/* the one place raw yellow touches text — and it is charcoal ON yellow, 11.9:1 */
::selection { background: var(--yellow); color: #2B2A29; }

/* Prose links. Scoped to the copy containers rather than set on a bare `a`,
   because most anchors on this page are not prose: .btn, .opening cards, the
   header logo and the nav strip all carry their own treatment and a global
   rule would have to be undone four times. Anything that IS running text goes
   through here, so a new link can never fall back to browser-default blue. */
.lead-copy a,
.callout-body a,
.open-app p a,
.sec-lede a,
.tl-note a,
.fact-list a,
.nn-list a,
.rule-list a {
  color: var(--lime-deep);
  text-decoration: none;
  border-bottom: 1px solid var(--lime);
}
.lead-copy a:hover,
.callout-body a:hover,
.open-app p a:hover,
.sec-lede a:hover,
.tl-note a:hover,
.fact-list a:hover,
.nn-list a:hover,
.rule-list a:hover { border-bottom-color: var(--lime-deep); }

/* the label primitive — mono, uppercase, wide-tracked */
.label {
  font-family: var(--mono);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--lime-deep);
}

/* ---------- header ---------- */

.site-head {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 13px 28px;
  background: var(--head-bg);
  backdrop-filter: blur(8px);
  border-bottom: 2px solid var(--ink);
}
.head-logo { display: flex; align-items: center; color: var(--ink); }
.head-logo svg { height: 24px; width: auto; display: block; }
.head-right { display: flex; align-items: center; gap: 18px; }
.head-role {
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--slate);
  white-space: nowrap;
}
.head-back {
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lime-deep);
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 1px solid transparent;
}
.head-back::before { content: "\2039"; margin-right: 6px; }
.head-back:hover { border-bottom-color: var(--lime-deep); }

/* ---------- buttons ---------- */

/* The wipe is yellow and the label goes charcoal on it — the inverse of the
   Brilliqs button, where the wipe was blue and the label stayed paper. Yellow
   is a fill, so anything sitting on it must be ink. */
.btn {
  display: inline-block;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.005em;
  text-decoration: none;
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  padding: 12px 26px;
  cursor: pointer;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  transition: color 0.25s ease, background-color 0.25s ease, transform 0.15s ease;
}
.btn:active { transform: translateY(1px); }
.btn-ink { background: var(--ink); color: var(--paper); }
.btn-ink::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: var(--yellow);
  transform: translateX(-101%);
  transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1);
}
.btn-ink:hover::after { transform: translateX(0); }
/* literal #2B2A29, not var(--ink): the ground under it is brand yellow in both
   themes, so the label must stay charcoal even when --ink has flipped to bone */
.btn-ink:hover { color: #2B2A29; }
.btn-ghost { background: transparent; color: var(--ink); }
.btn-ghost:hover { background: var(--yellow); color: #2B2A29; border-color: var(--ink); }
.btn-small { padding: 8px 16px; font-size: 13.5px; }
.bl-short { display: none; }

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

.hero {
  position: relative;
  overflow: hidden;
  padding: 88px 28px 68px;
  display: flex;
  align-items: center;
  min-height: 76vh;
}
/* The two logo crescents, at watermark strength. GSAP swings them inward on
   load and parallaxes them on scroll, so the SVG must not clip its own paths:
   a rotating lune sweeps well past the viewBox. */
.hero-arcs {
  position: absolute;
  right: -40px;
  top: 50%;
  /* the `translate` property, NOT transform: GSAP's scroll parallax writes to
     `transform`, and the two compose. Centring via transform instead would be
     overwritten by that tween and drop the mark half a height down the page. */
  translate: 0 -50%;
  width: min(520px, 54vw);
  height: auto;
  overflow: visible;
  opacity: var(--mark-opacity);
  color: var(--ink);
  pointer-events: none;
}
.hero-inner { max-width: var(--shell); margin: 0 auto; width: 100%; position: relative; z-index: 2; }

.hero-eyebrow {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 24px;
}
.tick { width: 26px; height: 3px; background: var(--lime); display: inline-block; flex: none; }

.hero-title {
  font-size: clamp(46px, 6.6vw, 82px);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -0.028em;
  margin-bottom: 26px;
  max-width: 15ch;
}
/* overflow:hidden makes each line a mask for the word-rise entrance. The
   padding keeps Source Serif's descenders (y, p) from being shaved by it. */
.ht-line { display: block; overflow: hidden; padding-bottom: 0.06em; }
.ht-word { display: inline-block; }
.hl-accent { position: relative; white-space: nowrap; }
.hl-sweep {
  position: absolute;
  /* 0.17em ~= Source Serif's descender depth, so the band's top edge lands on
     the baseline and reads as a highlighter stroke rather than a loose rule */
  left: -0.04em; right: -0.04em; bottom: 0.17em;
  height: 0.20em;
  background: var(--yellow);
  z-index: -1;
  transform-origin: left center;
  /* resting state is drawn — with JS off (no .js on <html>) the sweep is simply
     there. The animated-from-zero state only exists once JS arms it. */
  transform: scaleX(1);
}
.js .hl-sweep { transform: scaleX(0); }

.hero-sub {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(19px, 2.2vw, 23px);
  line-height: 1.46;
  color: var(--ink-soft);
  max-width: 42ch;
  margin-bottom: 34px;
}
.hero-sub .accent { color: var(--lime-deep); font-weight: 600; font-style: italic; }

.hero-cta { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 46px; }

/* auto-flow rather than a fixed column count: the home strip carries three
   cells and the role page three, but a role page with two would otherwise get
   a dead column and a divider pointing at nothing */
.hero-facts {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
  box-shadow: 6px 6px 0 var(--yellow);
  max-width: 700px;
}
.hf-cell { padding: 14px 20px; border-right: 1px solid var(--line); min-width: 0; }
.hf-cell:last-child { border-right: 0; }
.hf-key {
  display: block;
  font-family: var(--mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--slate);
  margin-bottom: 4px;
}
.hf-val { font-size: 15.5px; font-weight: 550; line-height: 1.35; }
/* the counting number in the fact strip — tabular so the width does not jitter
   while GSAP ticks it from 0 */
.hf-count {
  font-family: var(--mono);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  font-size: 17px;
  color: var(--lime-deep);
}

/* ---------- ribbon ---------- */

/* Left on CSS rather than moved to GSAP with the rest: a marquee needs no
   scroll position, no timeline and no plugin, and this way it still runs on a
   page where the vendor bundle 404s. */
.ribbon {
  background: var(--slab);
  color: var(--slab-fg);
  overflow: hidden;
  padding: 11px 0;
  border-top: 3px solid var(--yellow);
  border-bottom: 3px solid var(--lime);
}
.ribbon-track {
  display: flex;
  /* max-content, not the default 100%: the loop shifts by -50% of the TRACK,
     which only equals exactly one copy if the track is as wide as its content */
  width: max-content;
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 12.5px;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  will-change: transform;
  animation: ribbon 38s linear infinite;
}
/* child combinator throughout: the marquee copies are direct children, but the
   separators are spans too, one level deeper */
.ribbon-track > span { flex-shrink: 0; }
@keyframes ribbon { to { transform: translateX(-50%); } }
.ribbon .dot { color: var(--lime); padding: 0 4px; }

/* ---------- sections ---------- */

.section { padding: 84px 28px; }
.section-mist { background: var(--mist); }
.section-inner { max-width: var(--shell); margin: 0 auto; }

.sec-head { display: flex; align-items: center; gap: 15px; margin-bottom: 12px; }
/* the counter-rotating loader from the challenge portal, shrunk to a heading
   ornament. overflow:visible for the same reason as .hero-arcs. */
.sec-crescent { width: 40px; height: 45px; flex: none; overflow: visible; color: var(--ink); }
.sec-head h2 {
  font-size: clamp(29px, 4vw, 42px);
  font-weight: 600;
  letter-spacing: -0.022em;
}
.sec-rule { width: 88px; height: 3px; background: var(--lime); border: 0; margin: 0 0 30px; }
.sec-lede { margin-bottom: 26px; font-size: 18px; color: var(--ink-soft); max-width: 62ch; }

.lead-copy p { font-size: 18.5px; max-width: 64ch; margin-bottom: 16px; color: var(--ink-soft); }
.lead-copy p:last-child { margin-bottom: 0; }
.lead-copy strong { color: var(--ink); }

/* ---------- callout box ---------- */

.callout {
  display: flex;
  margin-top: 40px;
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
  box-shadow: 7px 7px 0 var(--yellow);
}
.callout-band { width: 12px; flex: none; background: var(--yellow); }
.callout-body { padding: 26px 30px; min-width: 0; }
.callout-body h3 { font-size: 23px; margin-bottom: 12px; }
.callout-body p { margin-bottom: 11px; max-width: 62ch; color: var(--ink-soft); }
.callout-body p:last-child { margin-bottom: 0; }
.callout-quiet { box-shadow: none; background: var(--lime-wash); }
.callout-quiet .callout-band { background: var(--lime); }

/* ---------- architecture diagram ---------- */

.arch {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 48px 0 12px;
}
.arch-node {
  font-family: var(--serif);
  font-weight: 600;
  font-size: 25px;
  letter-spacing: -0.02em;
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
  padding: 13px 34px;
  text-align: center;
}
.arch-node .arch-tag {
  display: block;
  font-family: var(--mono);
  font-weight: 400;
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--slate);
  margin-top: 5px;
}
.arch-self { background: var(--slab); color: var(--slab-fg); box-shadow: 5px 5px 0 var(--yellow); }
.arch-self .arch-tag { color: var(--slab-tag); }
.arch-link { width: 3px; height: 30px; background: var(--line-strong); }
.arch-chips { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; margin-top: 26px; }
.arch-chip {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border: 1px solid var(--line-strong);
  border-radius: 99px;
  background: var(--paper);
  padding: 7px 16px;
}
.arch-chip a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--lime); }
.arch-chip a:hover { color: var(--lime-deep); }

/* ---------- openings cards ----------
   Every variable-length zone carries a min-height floor (title / blurb / tags)
   and the button is pushed down with margin-top: auto. That is what makes a row
   of cards align band-to-band instead of only agreeing on their outer edges. */

.openings {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
  gap: 24px;
}

.opening {
  display: flex;
  flex-direction: column;
  min-height: 380px;
  padding: 26px 24px 24px;
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
  text-decoration: none;
  color: inherit;
  min-width: 0;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.opening:hover {
  transform: translate(-3px, -3px);
  box-shadow: 7px 7px 0 var(--yellow);
}

/* title floor — two-line titles must not push a one-line card's blurb up */
.op-title {
  font-size: 21px;
  line-height: 1.2;
  min-height: 3rem;
  margin-bottom: 12px;
  display: flex;
  align-items: flex-start;
}
.opening:hover .op-title { color: var(--lime-deep); }

.op-blurb {
  min-height: 4.5rem;
  margin-bottom: 18px;
  font-size: 15.5px;
  line-height: 1.55;
  color: var(--ink-soft);
  /* three lines, then ellipsis — the card teases, the JD page tells */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.op-meta { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.op-row { display: flex; align-items: center; gap: 9px; min-width: 0; }
.op-row svg { width: 15px; height: 15px; flex: none; color: var(--lime-deep); }
.op-row span {
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.op-tags { min-height: 2.5rem; margin-bottom: 18px; display: flex; flex-wrap: wrap; gap: 7px; align-content: flex-start; }
.op-tag {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--lime-deep);
  background: var(--lime-wash);
  border: 1px solid var(--line-strong);
  border-radius: 3px;
  padding: 5px 9px;
  line-height: 1;
}

/* mt:auto is what pins the button to the card floor regardless of body length */
.op-foot { margin-top: auto; }
.op-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  font-weight: 600;
  font-size: 14px;
  padding: 12px 18px;
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  background: var(--ink);
  color: var(--paper);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  transition: color 0.25s ease;
}
.op-cta::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: var(--yellow);
  transform: translateX(-101%);
  transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1);
}
.opening:hover .op-cta::after { transform: translateX(0); }
.opening:hover .op-cta { color: #2B2A29; }
.op-cta svg { width: 15px; height: 15px; }

/* a role whose full JD is not written yet: card is real, the door is not open */
.opening-soon { cursor: default; }
.opening-soon:hover { transform: none; box-shadow: none; }
.opening-soon:hover .op-title { color: inherit; }
.op-cta-soon {
  background: var(--paper);
  color: var(--slate);
  border-color: var(--line-strong);
}
.op-cta-soon::after { display: none; }
.opening-soon:hover .op-cta { color: var(--slate); }

/* closing "nothing fits?" panel */
.open-app {
  margin-top: 34px;
  border: 2px dashed var(--lime);
  border-radius: var(--radius);
  background: var(--paper);
  padding: 26px 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}
.open-app h3 { font-size: 21px; margin-bottom: 6px; }
.open-app p { color: var(--ink-soft); font-size: 16px; max-width: 52ch; }

/* ---------- fact list (marker list) ---------- */

.fact-list { list-style: none; max-width: 68ch; }
/* the openings section runs callout -> marker list; the callout's own 40px top
   margin has no bottom counterpart, so the list would butt against it */
.callout + .fact-list { margin-top: 34px; }
.fact-list li {
  padding: 15px 0 15px 34px;
  border-bottom: 1px solid var(--line);
  position: relative;
  color: var(--ink-soft);
}
.fact-list li:last-child { border-bottom: 0; }
.fact-list li::before {
  content: "";
  position: absolute; left: 4px; top: 25px;
  width: 10px; height: 10px;
  background: var(--lime);
  /* one corner squared off — the mark reads as a pointer, not a bullet */
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
}

/* ---------- trait cards ---------- */

/* explicit columns, not auto-fit: the trait count is odd, so the last card is
   told to fill the remainder rather than leaving a ragged half-row */
.trait-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
}
.trait-grid .trait-card:last-child { grid-column: 1 / -1; }
@media (max-width: 1080px) {
  .trait-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.trait-card {
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
  padding: 24px 22px 22px;
  position: relative;
}
.tc-num {
  position: absolute; top: -15px; left: 18px;
  font-family: var(--mono);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.06em;
  background: var(--yellow);
  color: #2B2A29;
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  padding: 3px 8px;
  line-height: 1;
}
.trait-card h3 { font-size: 20px; margin: 6px 0 9px; }
.trait-card p { font-size: 15.5px; color: var(--ink-soft); line-height: 1.56; }

/* ---------- "not needed" list ---------- */

.notneed { margin-top: 46px; }
.notneed h3 { font-size: 23px; margin-bottom: 16px; }
.nn-list { list-style: none; max-width: 66ch; }
.nn-list li {
  padding: 13px 0 13px 40px;
  position: relative;
  border-bottom: 1px solid var(--line);
  color: var(--ink-soft);
}
.nn-list li:last-child { border-bottom: 0; }
.nn-list li::before {
  content: "";
  position: absolute; left: 6px; top: 26px;
  width: 16px; height: 2px;
  background: var(--lime);
}

/* ---------- accordions ---------- */

.acc-list { display: flex; flex-direction: column; gap: 12px; }
.acc {
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
  overflow: hidden;
}
.acc summary {
  cursor: pointer;
  list-style: none;
  display: flex; align-items: center; gap: 14px;
  font-family: var(--serif);
  font-size: 20px; font-weight: 600;
  padding: 15px 22px;
  user-select: none;
}
.acc summary::-webkit-details-marker { display: none; }
.acc summary::after {
  content: "+";
  margin-left: auto;
  font-family: var(--sans);
  font-weight: 400; font-size: 26px; color: var(--lime-deep);
  line-height: 1;
  transition: transform 0.2s ease;
}
.acc[open] summary::after { transform: rotate(45deg); }
.acc[open] summary { background: var(--yellow-wash); }
.acc-n {
  font-family: var(--mono);
  font-weight: 600; font-size: 11.5px;
  flex: none;
  padding: 4px 8px;
  border-radius: var(--radius);
  background: var(--yellow);
  color: #2B2A29;
  line-height: 1;
}
.acc p { padding: 0 22px 16px; max-width: 68ch; color: var(--ink-soft); font-size: 16px; }
.acc p:first-of-type { padding-top: 15px; }

/* ---------- timeline (hiring process) ---------- */

.timeline { position: relative; margin: 32px 0 10px; --tl-gap: 14px; }
/* The rule must start and end ON a dot, and a dot sits at the centre of its
   column. A naive 50%/N inset lands ~6px off, because the grid gap means a
   column is (100% - (N-1)*gap)/N, not 100%/N. --tl-cols is set inline on
   .timeline, next to the nodes, so the two cannot drift apart unnoticed. */
.tl-line {
  position: absolute; top: 11px;
  left: calc((100% - (var(--tl-cols, 4) - 1) * var(--tl-gap)) / var(--tl-cols, 4) / 2);
  right: calc((100% - (var(--tl-cols, 4) - 1) * var(--tl-gap)) / var(--tl-cols, 4) / 2);
  height: 3px; background: var(--line);
}
.tl-line-fill { height: 100%; width: 0; background: var(--lime); }
/* no JS: the rule is simply drawn, since GSAP is what animates it from zero */
html:not(.js) .tl-line-fill { width: 100%; }
.tl-nodes { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: var(--tl-gap); }
.tl-node { text-align: center; }
.tl-dot {
  display: block; margin: 0 auto 15px;
  width: 24px; height: 24px;
  border-radius: 50%;
  border: 4px solid var(--ink);
  background: var(--paper);
  position: relative; z-index: 2;
}
.tl-dot-hot { background: var(--yellow); box-shadow: 0 0 0 6px var(--yellow-tint); }
.tl-node h3 { font-size: 18px; margin-bottom: 3px; }
.tl-node p { font-size: 14.5px; color: var(--slate); line-height: 1.5; }
.tl-step {
  display: block;
  font-family: var(--mono);
  font-size: 10.5px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--lime-deep); margin-bottom: 5px;
}
.tl-note { margin-top: 30px; color: var(--ink-soft); max-width: 62ch; }

/* ---------- deal rows ---------- */

.deal-list { list-style: none; border-top: 2px solid var(--ink); }
.deal-row {
  display: flex;
  align-items: flex-start;
  gap: 22px;
  padding: 22px 6px;
  border-bottom: 2px solid var(--ink);
}
.dr-num {
  font-family: var(--mono);
  font-weight: 600; font-size: 13px;
  width: 44px; height: 44px; flex: none;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--ink); border-radius: var(--radius);
  background: var(--yellow); color: #2B2A29;
}
.dr-body { flex: 1; min-width: 0; }
.dr-body h3 { font-size: 21px; margin-bottom: 5px; }
.dr-body p { color: var(--ink-soft); font-size: 16px; }

/* ---------- apply / rules ---------- */

.section-apply { background: var(--mist); border-top: 3px solid var(--ink); }

.rule-list { list-style: none; counter-reset: rule; max-width: 70ch; }
.rule-list li {
  counter-increment: rule;
  padding: 20px 0 20px 60px;
  position: relative;
  border-bottom: 1px solid var(--line);
  color: var(--ink-soft);
}
.rule-list li:last-child { border-bottom: 0; }
.rule-list li::before {
  content: "0" counter(rule);
  position: absolute; left: 0; top: 20px;
  font-family: var(--mono);
  font-weight: 600; font-size: 12px;
  width: 40px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid var(--ink); border-radius: var(--radius);
  background: var(--paper);
  color: var(--ink);
}
.rule-list li h4 { font-family: var(--serif); font-size: 19px; font-weight: 600; color: var(--ink); margin-bottom: 5px; }
/* scoped to `.rule-list li` — the base rule is (0,1,1) and would otherwise
   out-specify a bare `.rule-hero`, silently dropping the padding */
.rule-list li.rule-hero {
  background: var(--paper);
  outline: 2px solid var(--ink);
  outline-offset: -2px;
  border-bottom: 0;
  border-radius: var(--radius);
  box-shadow: 6px 6px 0 var(--yellow);
  padding: 22px 24px 22px 72px;
  margin: 14px 0 18px;
}
.rule-list li.rule-hero::before { background: var(--yellow); color: #2B2A29; left: 16px; top: 22px; }

.tipbox {
  display: flex; gap: 18px; align-items: flex-start;
  border: 2px dashed var(--lime);
  border-radius: var(--radius);
  padding: 20px 24px;
  background: var(--paper);
  max-width: 74ch;
  margin-top: 30px;
}
.tip-label {
  font-family: var(--mono);
  font-weight: 600; font-size: 10.5px;
  letter-spacing: 0.18em; text-transform: uppercase;
  background: var(--yellow); color: #2B2A29;
  padding: 5px 12px; border-radius: var(--radius);
  flex: none;
  margin-top: 2px;
}
.tipbox div p { color: var(--ink-soft); margin-bottom: 9px; font-size: 16px; }
.tipbox div p:last-child { margin-bottom: 0; }

.closing {
  margin-top: 40px;
  padding-top: 26px;
  border-top: 2px solid var(--ink);
  font-family: var(--serif);
  font-size: 23px;
  line-height: 1.4;
  max-width: 40ch;
}
.closing .accent { color: var(--lime-deep); }

/* the contact block — where an application actually goes. Same three-cell rule
   as the hero fact strip, so the page opens and closes on the same object. */
.contact {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: 34px;
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  background: var(--paper);
  box-shadow: 6px 6px 0 var(--yellow);
}
.ct-item { min-width: 0; padding: 18px 24px; border-right: 1px solid var(--line); }
.ct-item:last-child { border-right: 0; }

/* Scoped to this pairing rather than raising .contact's own margin: the arch's
   12px bottom collapses into the contact's 34px top. Only the home page puts
   these two adjacent. */
.arch + .contact { margin-top: 44px; }
.ct-key {
  display: block;
  font-family: var(--mono);
  font-size: 10.5px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--slate); margin-bottom: 4px;
}
/* the address is long enough to overrun a third of the strip at body size */
.ct-val { font-size: 17px; font-weight: 550; overflow-wrap: anywhere; }
.ct-val a { color: var(--lime-deep); text-decoration: none; border-bottom: 1px solid var(--lime); }
.ct-val a:hover { border-bottom-color: var(--lime-deep); }
/* a value the JD has not been given yet — visibly a hole, not a typo */
.ct-val .tofill, .hf-val .tofill { color: var(--slate); font-style: italic; font-weight: 400; }

/* ---------- foot navigation ----------
   A slim strip at the end of a role page. Deliberately quiet: it sits directly
   after the JD's closing line, which is the strongest sentence in the document,
   and a panel there would blunt it. */

.page-nav { padding: 0 28px; }
.page-nav-inner {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 24px 0 34px;
  border-top: 1px solid var(--line);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px 28px;
  flex-wrap: wrap;
}
.page-nav a {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--lime-deep);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  white-space: nowrap;
}
.page-nav a:hover { border-bottom-color: var(--lime-deep); }
.pn-back::before { content: "\2039"; margin-right: 9px; }
.pn-next::after { content: "\203A"; margin-left: 9px; }
/* the label is context, the role name is the link target */
.pn-next em { font-style: normal; color: var(--slate); margin-right: 8px; }

@media (max-width: 820px) {
  .page-nav { padding: 0 18px; }
  .page-nav-inner { padding: 20px 0 26px; gap: 12px; }
  .page-nav a { font-size: 11px; letter-spacing: 0.1em; }
}

/* ---------- footer ---------- */

.site-foot {
  background: var(--slab);
  color: var(--slab-muted);
  padding: 52px 28px 58px;
  text-align: center;
}
.foot-logo { height: 28px; width: auto; color: var(--slab-fg); margin-bottom: 18px; }
.site-foot p { font-size: 15px; margin-bottom: 8px; }
.site-foot strong { color: var(--slab-fg); }
.foot-small { color: var(--slab-muted); font-size: 13px; max-width: 60ch; margin: 14px auto 0; line-height: 1.55; }
.foot-div { color: var(--lime); font-family: var(--mono); font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; }
.site-foot a { color: var(--slab-fg); text-decoration: none; border-bottom: 1px solid var(--lime); }

/* ---------- theme toggle ----------
   Deliberately tiny and half-faded at rest: this is a preference control on a
   hiring page, not a feature. The mark is a half-filled circle, which reads at
   13px where a sun or moon turns to mush, and rotating it 180 degrees on switch
   is the whole state indicator. */

.theme-toggle {
  position: fixed;
  right: 14px;
  bottom: 14px;
  z-index: 60;
  width: 26px;
  height: 26px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: var(--paper);
  color: var(--slate);
  cursor: pointer;
  opacity: 0.45;
  transition: opacity 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
}
.theme-toggle:hover { opacity: 1; color: var(--lime-deep); border-color: var(--lime); }
.theme-toggle:focus-visible { opacity: 1; outline: 2px solid var(--lime-deep); outline-offset: 2px; }
.theme-toggle:active { transform: scale(0.9); }
.theme-toggle svg { width: 13px; height: 13px; display: block; transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle svg { transform: rotate(180deg); }
}
:root[data-theme="dark"] .theme-toggle svg { transform: rotate(180deg); }

@media (prefers-reduced-motion: reduce) {
  .theme-toggle svg { transition: none; }
}

/* ---------- animation arming ----------
   `.js` is set by the inline head script, BEFORE first paint. Everything below
   is the hidden state GSAP animates out of; without it the page renders whole.
   Both halves matter: no JS at all, and JS present but the vendor bundle 404s
   (app.js's fallback branch clears these inline). */

.reveal, .reveal-load { opacity: 1; }
.js .reveal, .js .reveal-load { opacity: 0; }

/* The heading hides as OPACITY, never as a transform.
   Learned the hard way: `.js .ht-word { transform: translateY(110%) }` looks
   like the obvious resting state, but GSAP reads an element's computed matrix
   and cannot tell a percentage from pixels — it books that 110% into its `y`
   channel as 74px. A `yPercent: 110 -> 0` tween then rides on top of that
   baseline and lands back exactly where it started, so the words animate off
   screen and stay there. Nothing errors; the heading is simply never visible.
   GSAP owns the word transform outright, and the only thing CSS holds back is
   the title's opacity, which is safe because opacity does not accumulate. */
.js .hero-title { opacity: 0; }
/* the crescents are swung in from +-80 degrees; unarmed they are just drawn */
.js .hero-arcs .arc-lemon, .js .hero-arcs .arc-green { opacity: 0; }

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

@media (max-height: 900px) {
  .hero { min-height: auto; padding: 52px 28px 56px; }
  .hero-title { font-size: clamp(42px, 5.6vw, 66px); margin-bottom: 20px; }
  .hero-sub { margin-bottom: 26px; }
  .hero-cta { margin-bottom: 32px; }
}

@media (max-width: 820px) {
  body { font-size: 16px; }

  .site-head { padding: 10px 16px; gap: 10px; }
  .head-logo svg { height: 20px; }
  .head-role { display: none; }
  .head-back { font-size: 10px; letter-spacing: 0.1em; }

  .openings { grid-template-columns: 1fr; gap: 18px; }
  .opening { min-height: 0; padding: 22px 18px 20px; }
  .opening:hover { transform: none; box-shadow: none; }
  .op-title { font-size: 19px; min-height: 0; }
  .op-blurb { min-height: 0; }
  .op-tags { min-height: 0; }
  .open-app { flex-direction: column; align-items: flex-start; padding: 20px 18px; }
  .open-app .btn { width: 100%; text-align: center; }
  .bl-long { display: none; }
  .bl-short { display: inline; }

  .hero { padding: 40px 20px 44px; min-height: auto; }
  .hero-arcs { opacity: calc(var(--mark-opacity) * 0.75); right: -28vw; width: 78vw; }
  .hero-title { font-size: clamp(38px, 10vw, 56px); max-width: none; }
  .hero-sub { font-size: 18px; max-width: none; }
  .hero-cta { gap: 10px; }
  .hero-cta .btn { flex: 1 1 100%; text-align: center; padding: 15px 20px; }
  .hero-facts { grid-auto-flow: row; box-shadow: 4px 4px 0 var(--yellow); }
  .hf-cell { border-right: 0; border-bottom: 1px solid var(--line); }
  .hf-cell:last-child { border-bottom: 0; }

  .ribbon-track { font-size: 11px; }

  .section { padding: 52px 18px; }
  .sec-head { gap: 12px; }
  .sec-head h2 { font-size: 27px; }
  .sec-crescent { width: 32px; height: 36px; }
  .sec-rule { margin-left: 44px; width: 64px; margin-bottom: 24px; }
  .lead-copy p { font-size: 17px; }

  .callout { flex-direction: column; box-shadow: 5px 5px 0 var(--yellow); }
  .callout-band { width: 100%; height: 10px; }
  .callout-body { padding: 20px 18px; }
  .callout-body h3 { font-size: 20px; }

  .arch { margin: 34px 0 8px; }
  .arch + .contact { margin-top: 34px; }
  .arch-node { font-size: 20px; padding: 12px 22px; }
  .fact-list li { padding: 13px 0 13px 28px; }
  .fact-list li::before { left: 0; top: 23px; }

  .trait-grid { grid-template-columns: 1fr; gap: 26px; }
  .trait-card { padding: 22px 18px 18px; }

  .deal-row { flex-wrap: wrap; gap: 14px; padding: 18px 4px; }
  .dr-num { width: 38px; height: 38px; font-size: 12px; }

  .contact { grid-template-columns: 1fr; box-shadow: 4px 4px 0 var(--yellow); }
  .ct-item { border-right: 0; border-bottom: 1px solid var(--line); }
  .ct-item:last-child { border-bottom: 0; }

  .tl-line { display: none; }
  .tl-nodes { grid-auto-flow: row; gap: 20px; }
  .tl-node { display: grid; grid-template-columns: 22px 1fr; column-gap: 14px; text-align: left; }
  .tl-dot { grid-row: 1 / span 3; width: 18px; height: 18px; border-width: 3px; margin: 4px 0 0; }
  .tl-step, .tl-node h3, .tl-node p { grid-column: 2; }

  .rule-list li { padding: 18px 0 18px 52px; }
  .rule-list li.rule-hero { padding: 18px 16px 18px 60px; box-shadow: 4px 4px 0 var(--yellow); }
  .rule-list li.rule-hero::before { left: 12px; top: 18px; }
  .tipbox { flex-direction: column; gap: 12px; padding: 18px; }
  .closing { font-size: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ribbon-track { animation: none; }
  /* app.js never adds .js under reduced motion, so these are belt-and-braces
     for a preference that flips while the page is already open */
  .js .reveal, .js .reveal-load, .js .hero-title { opacity: 1; }
  .js .hero-arcs .arc-lemon, .js .hero-arcs .arc-green { opacity: 1; }
  .js .hl-sweep, .hl-sweep { transform: scaleX(1); }
  .tl-line-fill { width: 100%; }
}

/* ---------- print / PDF ----------
   The export runs Chrome's print pipeline, so this block is what the PDF is.
   Rules that only matter on screen (sticky, marquee, reveal) are undone here.

   GSAP writes its states as INLINE styles, which beat a plain declaration.
   Every rule that has to undo one carries !important — a stylesheet !important
   does outrank a non-important inline style, which is the only reason a page
   mid-animation still prints complete. */

@page {
  size: A4;
  margin: 14mm 13mm 15mm;
}

@media print {
  html, body { overflow: visible; }
  body { font-size: 10.2pt; line-height: 1.5; }

  /* Chrome lays print out at the page width (~793px for A4), so the 820px
     "mobile" breakpoint is live here. Anything that block-stacks below 820px
     has to be put back explicitly. */

  .site-head { position: static; backdrop-filter: none; background: var(--paper); padding: 0 0 9px; margin-bottom: 18px; }
  .head-logo svg { height: 20px; }
  .head-role { display: block; }
  .head-cta { display: none; }

  .hero { min-height: 0; padding: 2px 0 20px; }
  /* the crescents can only be cropped by the page edge here, and a part-drawn
     lune reads as a printing artifact — drop them */
  .hero-arcs { display: none; }
  .hero-inner { max-width: none; }
  .hero-title { font-size: 30pt; margin-bottom: 12px; max-width: none; }
  .ht-line { overflow: visible; }
  .ht-word { transform: none !important; opacity: 1 !important; }
  .hero-sub { font-size: 12pt; margin-bottom: 18px; max-width: none; }
  .hero-cta { display: none; }
  .hero-facts {
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    box-shadow: 4px 4px 0 var(--yellow);
    max-width: none;
  }
  .hf-cell { border-right: 1px solid var(--line); border-bottom: 0; padding: 11px 15px; }
  .hf-cell:last-child { border-right: 0; }
  .hf-val { font-size: 10.5pt; }
  .js .hl-sweep, .hl-sweep { transform: scaleX(1) !important; }

  /* wrap rather than clip: the marquee's max-content track is wider than A4,
     and overflow:hidden would silently cut the line in half */
  .ribbon { padding: 6px 0; }
  .ribbon-track {
    animation: none;
    width: 100%;
    white-space: normal;
    justify-content: center;
    font-size: 7pt;
    letter-spacing: 0.12em;
  }
  /* hide the duplicate marquee copy — `>` matters: a descendant selector here
     also matches the separator spans and silently eats three of them */
  .ribbon-track > span:nth-child(n + 2) { display: none; }

  .section { padding: 18px 0; }
  .section-inner { max-width: none; }
  .section-mist, .section-apply { background: var(--paper); border-top: 0; }
  .sec-head { margin-bottom: 8px; }
  .sec-head h2 { font-size: 18pt; }
  /* the loader is mid-spin when print is invoked; reset it or the two lunes
     print frozen at an arbitrary angle */
  .sec-crescent { width: 30px; height: 34px; }
  .sec-crescent use { transform: none !important; }
  .sec-rule { margin-bottom: 18px; width: 64px; margin-left: 0; }
  .sec-lede { font-size: 10.6pt; margin-bottom: 16px; }
  .lead-copy p { font-size: 10.6pt; margin-bottom: 11px; }

  .trait-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
  .trait-card { padding: 16px 16px 14px; }
  /* the badge overhangs the card by 15px, and Chrome does not fold an
     absolutely-positioned child into the break-inside box — so it strands on
     the previous page. Inline it for print. */
  .tc-num { position: static; display: inline-block; margin-bottom: 7px; }
  .trait-card h3 { font-size: 13pt; margin: 0 0 5px; }
  .trait-card p { font-size: 9.6pt; }

  /* the min-height floors exist to align cards in a live grid; on paper they
     just leave holes, and the 3-line clamp would hide copy the reader cannot
     click through to */
  .openings { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
  .opening { min-height: 0; padding: 16px; }
  .op-title, .op-blurb, .op-tags { min-height: 0; }
  .op-blurb { display: block; overflow: visible; }
  .op-cta { display: none; }
  .head-back { display: none; }

  .opening, .open-app { break-inside: avoid; }
  .trait-card, .callout, .acc, .deal-row, .tipbox, .contact, .hero-facts, .arch-node, .arch { break-inside: avoid; }
  .fact-list li, .nn-list li, .rule-list li, .tl-node, .notneed, .timeline { break-inside: avoid; }
  .sec-head, .sec-rule, .sec-lede { break-after: avoid; }
  h2, h3, h4 { break-after: avoid; }

  .arch { margin: 24px 0 10px; }
  .callout { margin-top: 20px; }
  .callout-body { padding: 16px 20px; }
  .callout-body h3 { font-size: 13.5pt; margin-bottom: 8px; }

  .acc p { display: block !important; }
  .acc summary::after { display: none; }

  .tl-line { display: none; }
  .timeline { --tl-gap: 12px; }
  .tl-nodes { grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: var(--tl-gap); }
  .tl-node { display: block; text-align: center; }
  .tl-dot { margin: 0 auto 10px; }
  .tl-node h3 { font-size: 11.5pt; }
  .tl-node p { font-size: 9.4pt; }

  .contact {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    box-shadow: 4px 4px 0 var(--yellow);
  }
  .ct-item { border-right: 1px solid var(--line); border-bottom: 0; padding: 14px 18px; }
  .ct-item:last-child { border-right: 0; }

  /* the blanket undo for every GSAP-hidden element */
  .js .reveal, .js .reveal-load, .js .hero-title { opacity: 1 !important; transform: none !important; }
  .js .hero-arcs .arc-lemon, .js .hero-arcs .arc-green { opacity: 1 !important; }

  .theme-toggle { display: none; }
  .page-nav { display: none; }

  .site-foot { padding: 22px 0 0; background: var(--paper); color: var(--slate); text-align: left; }
  .foot-logo { color: var(--ink); height: 20px; margin-bottom: 10px; }
  .site-foot strong { color: var(--ink); }
  .site-foot a { color: var(--ink); }
  .foot-small { margin-left: 0; }

  a { text-decoration: none; color: inherit; }
  .ct-val a { color: var(--lime-deep); }
}
