/* /resume — now wearing the tube.

   It used to load base.css + home.css, the design language from before JET/OS
   (both now in _lab/attic/ — nothing loads them any more),
   which is exactly why it read as a different site. The reason given for
   keeping it plain was that ATS software parses it — that was wrong. ATS
   parsing applies to the file you UPLOAD, and the guidance there is DOCX or a
   text-based PDF. Nobody feeds a URL into an ATS. So the page is free to look
   like the rest of the site, and the ATS-safe artifact is /resume.pdf, which is
   the thing that actually gets attached to an application. */

/* ⚠️ 12vh OF AN iPAD IS 150pt OF NOTHING BEFORE THE NAME. Measured Sep 1 2026:
   ~250pt sat above "Juan Ernesto Turcios" on a 13" iPad — a quarter of the one
   screen this page is guaranteed, spent on air, on the page a recruiter opens
   FIRST. A vh top pad is a percentage of a viewport that only gets taller, so
   the taller the screen the more of it this wasted. Clamped instead: it still
   breathes on a phone and it stops growing past the point where breathing
   becomes a gap. */
/* 🔴 THE SPACE ABOVE THE FIRST DIVIDER IS A SECTION BREAK, NOT A GROUP GAP.
   Juan, Sep 3 2026: "I hate how close the page divider is from the View PDF to
   the divider. It's just too close." Measured at 1440x900 it was 45px above the
   rule and 45px below it — symmetric, and symmetry is the mistake. That rule
   ENDS the header; what sits immediately above it is a glowing amber button
   whose box-shadow reads ~10px past its own box, so a group-sized gap put a
   hairline inside the button's halo.
   `--sp-5` above (the step os.css § THE SPACING SCALE reserves for section
   boundaries) against `.cv`'s `--sp-4` below. The asymmetry is the point: more
   air before a divider than after it is what makes it read as a break rather
   than as a line that drifted into the content.
   ⚠️ The TOP padding stays as it was — it is the page's opening margin, not a
   step in this scale, and the print block below overrides both anyway. */
.doc--cv .doc__head {
  min-height: auto;
  padding-block: clamp(34px, 6vh, 76px) var(--sp-5);
}

/* ---------------------------------------------------------- the headline ---
   ⚠️ THE 16ch CAP WAS DOING TWO KINDS OF DAMAGE AT ONCE, and they turned out to
   be one problem. Measured at 1440x900: the column is 738px wide and the h1 was
   capped at 624px, so it broke into three lines and left "on" alone on the last
   one — and the 114px it refused to use is most of the empty right-hand side
   this page was pulled up for. Widening the measure fixes the rag AND fills the
   column; they were never two issues.

   `text-wrap: balance` is what makes it safe at every width rather than just at
   the one that was measured. At 402px the line still has to break three ways,
   and balance spends the breaks evenly instead of leaving a two-letter widow.
   It is a progressive enhancement — a browser that ignores it gets exactly the
   greedy wrap it would have got anyway, which is why the measure is widened
   too rather than leaning on it. */
.doc--cv .doc__h1 { max-width: 24ch; text-wrap: balance; }
/* and the lede matches the sections below it (.cv is 66ch) instead of stopping
   10ch short of them, which read as a ragged right edge down the whole page */
.doc--cv .doc__lede { max-width: var(--measure); }

/* ⚠️ THE OPT-OUT THAT USED TO BE HERE NEVER WORKED, and it is gone rather than
   kept as reassurance. `.doc--cv { scroll-snap-type: none }` was meant to spare
   the résumé the site's vertical snapping — but the snap container was `html`,
   and `scroll-snap-type` on a DESCENDANT cannot switch off an ancestor's
   snapping. It only declares whether that element is itself a snap container,
   which .doc--cv never was. The rule read as a fix and did nothing.
   🟢 Moot now: the site no longer snaps vertically anywhere (work.css § PANELS,
   VERTICAL AGAIN), so the résumé scrolls normally because every page does. */

.cv__name {
  margin: 0 0 6px;
  font-size: clamp(15px, 1.6vw, 18px); font-weight: 700; letter-spacing: -.01em;
  color: var(--fg);
}

.facts {
  list-style: none; margin: 26px 0 30px; padding: 0;
  display: flex; flex-wrap: wrap; gap: clamp(18px, 3vw, 38px);
}
.facts li { display: flex; flex-direction: column; gap: 4px; }
/* the address and its two verbs on one line — § the two actions, in resume.html.
   ⚠️ A div, NOT a span: `.facts span` below is the caption style (mono, uppercase,
   dimmed) and it would have inherited straight onto the glyph buttons. */
.fact__act { display: flex; align-items: center; gap: 6px; }
/* the hero overlaps its icon pair on purpose; here they sit beside a word and
   the overlap reads as a collision (os.css § .lk--icon + .lk--icon) */
.fact__act .lk--icon + .lk--icon { margin-left: 0; }
/* 🟢 THESE TWO WEAR A RING, AND THAT IS NOT A REVERSAL OF os.css § .lk--icon.
   Juan's call Sep 3 2026: "the copy and email buttons should be wrapped in a
   circular container just so it seems more polished." The frameless rule in
   os.css was decided for the HERO pair, where GitHub and LinkedIn sat in a row
   of worded buttons and a border made two marks "the only controls wearing a
   frame". Here the opposite is true: these two glyphs sit against a plain
   address with nothing else in the row, so a frame is what tells you they are
   controls at all rather than decoration trailing the text.
   Scoped to `.fact__act` on purpose — the hero pair keeps its own decision. */
.fact__act .lk--icon {
  width: 32px; height: 32px;
  border: 1px solid rgba(220, 230, 221, .18);
  border-radius: 50%;
  background: rgba(220, 230, 221, .04);
  transition: border-color .2s ease, background .2s ease;
}
.fact__act .lk--icon .brandmark { width: 15px; height: 15px; }
.fact__act .lk--icon:hover,
.fact__act .lk--icon:focus-visible {
  border-color: rgba(47, 217, 197, .5);
  background: rgba(220, 230, 221, .08);
}
/* the ring answers the copy too, so the confirmation is not carried by a 15px
   glyph alone — see the .is-copied note below */
.fact__act .lk--icon.is-copied {
  border-color: var(--amber);
  background: rgba(255, 176, 74, .1);
}
/* ⚠️ AND THE TOUCH TARGET COMES BACK. os.css grows `.lk--icon` to 46px under
   `max-width: 560px` for the 44px minimum, but `.fact__act .lk--icon` is a
   two-class selector and outranks it, so these two shrank to 30px on exactly the
   devices that need them biggest. Restated here at the same specificity. */
@media (max-width: 560px) {
  .fact__act .lk--icon { width: 44px; height: 44px; }
}
/* 🔴 COPY FEEDBACK WITHOUT TEXT. copy.js swaps `textContent` to "Copied" and back,
   which on an icon-only button would DELETE the svg and restore an empty string —
   the icon would never come back. It checks for `.lk--icon` and toggles this class
   instead; see copy.js § the icon case. */
.lk--icon.is-copied .brandmark { fill: var(--amber); opacity: 1; }
@media print { .fact__act .lk--icon { display: none !important; } }
.facts b {
  font-size: var(--t-md); font-weight: 600; color: var(--fg);
  letter-spacing: -.005em;
}
.facts span {
  font-family: var(--mono); font-size: var(--t-2xs); letter-spacing: .2em;
  text-transform: uppercase; color: var(--fg-dim); opacity: .75;
}

.cv {
  /* 🔴 66ch -> the shared reading measure, Sep 3 2026. The site was carrying
     THREE reading measures — 62ch on rail pages, 66ch here, and ~82ch inside
     .wrap — and 62ch is the one that is inside the 45–75ch guidance. 43px of
     difference, and one fewer number that looks like a decision. */
  max-width: var(--measure);
  /* --sp-4 IS the clamp this used to spell out (34/5vh/56) — same value, now
     named, so a change to the scale reaches it. See os.css § THE SPACING SCALE. */
  padding-block: var(--sp-4);
  border-top: 1px solid rgba(220, 230, 221, .09);
}
.cv__h {
  margin: 4px 0 20px;
  font-size: var(--t-2xl); line-height: 1.12;
  letter-spacing: -.014em; font-weight: 800; color: var(--fg);
}
.cv__note {
  margin: -10px 0 24px;
  font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .14em;
  text-transform: uppercase; color: var(--fg-dim);
}
.cv__note a { color: var(--amber); }

.cv p {
  margin: 0 0 12px;
  font-size: clamp(14.5px, 1.45vw, 16px); line-height: 1.68; color: var(--fg-dim);
}

/* --------------------------------------------------------- strengths --- */
.strengths { list-style: none; margin: 0; padding: 0; counter-reset: s; }
.strengths li { margin-bottom: 26px; counter-increment: s; }
.strengths h3 {
  margin: 0 0 8px;
  font-size: clamp(16px, 1.7vw, 19px); font-weight: 700; color: var(--fg);
  letter-spacing: -.008em;
}
.strengths h3::before {
  content: "0" counter(s);
  font-family: var(--mono); font-size: 10px; font-weight: 400;
  letter-spacing: .2em; color: var(--amber);
  margin-right: 12px; vertical-align: 2px;
}

/* -------------------------------------------------------------- roles --- */
.cv__role { margin-bottom: 30px; }
.cv__role h3 {
  margin: 0 0 8px;
  font-size: clamp(16px, 1.7vw, 19px); font-weight: 700; color: var(--fg);
}
.cv__role h3 span {
  display: block; margin-top: 3px;
  font-family: var(--mono); font-size: 10px; font-weight: 400;
  letter-spacing: .18em; text-transform: uppercase; color: var(--amber);
}

/* ----------------------------------------------------------- timeline --- */
.tl { list-style: none; margin: 0; padding: 0; }
.tl li {
  display: grid; grid-template-columns: 108px 1fr; gap: 18px;
  padding: 13px 0;
  border-top: 1px solid rgba(220, 230, 221, .06);
}
.tl li:first-child { border-top: none; }
.tl b {
  font-family: var(--mono); font-size: 10px; font-weight: 400;
  letter-spacing: .16em; color: var(--amber); padding-top: 4px;
}
.tl div {
  font-size: clamp(14px, 1.4vw, 15.5px); line-height: 1.62; color: var(--fg-dim);
}
.tl strong { color: var(--fg); font-weight: 600; }

@media (max-width: 620px) {
  .tl li { grid-template-columns: 1fr; gap: 4px; }
  .tl b { padding-top: 0; }
  .facts { gap: 14px 24px; }
}

/* =========================================================== PRINT / PDF ===
   THIS is the ATS-safe artifact, and it is where "ATS-safe" actually belongs:
   a text-based file you attach to an application. Parsers want real selectable
   text in a single column, not a screenshot and not a CRT.

   One source, two presentations — the page can wear the tube because the PDF
   does not. Everything decorative is removed, the palette inverts to black on
   white, and the layout collapses to one column. */
@media print {
  :root { --fg: #111; --fg-dim: #333; --amber: #222; --void: #fff; }

  .field, .field__bloom, .field__hi, .stars,
  .crt-glow, .crt-glass, .crt-bulge, .svg-defs,
  .hud, .back, .index, .gate, .power, .boot, .skip { display: none !important; }

  html, body, .tube, .phosphor {
    background: #fff !important;
    color: #111 !important;
    filter: none !important;          /* the chroma filter would smear the text */
    min-height: 0 !important;
  }

  /* text-shadow DUPLICATES the text in the PDF. Chrome's export paints a
     shadowed run twice — once for the shadow, once for the fill — so every
     element carrying one appears TWICE in the extracted text layer. The
     correlation was exact: the only two `.eyebrow` elements on this page were
     the only two duplicated lines, while their `.item__k` siblings (same size,
     same mono, no shadow) printed clean. A résumé that states its own subtitle
     twice reads as a copy-paste error to a human and as a doubled keyword to a
     parser. `filter` was already reset here for the same class of reason;
     `text-shadow` was the one that got missed.

     ⚠️ And a trap worth keeping: PDFKit's `.string()` ALSO reported every
     `ct`/`ch` word broken mid-token — `produ` + `ct`, `tou` + `ch` — which
     looks exactly like a font-ligature bug splitting the keywords this document
     is searched for. It is not. `font-variant-ligatures: none` changed nothing,
     and pypdf — far closer to what an ATS actually runs — reads `product`,
     `production`, `destructive` and `structure` contiguously. That was PDFKit's
     own line reconstruction, not the file. The README already warns that a
     hand-rolled regex lies about this file and to reach for PDFKit; the fuller
     rule is that BOTH extractors lie, in different places, so a defect only
     counts once a second one agrees.

     box-shadow is the same bug with a visible face. `.lk--go` carries a 26px
     amber glow; `background` was already reset here but the glow was not, so it
     printed as a tan block bleeding out from behind the email address — a
     highlighter smear across the contact line, on page one, where a human looks
     first. Invisible to every text-layer probe, which is why this needed a
     rendered page and not another extraction. */
  * { text-shadow: none !important; box-shadow: none !important; }
  .wrap { max-width: 100% !important; padding: 0 !important; }
  .doc--cv .doc__head { padding: 0 0 14pt !important; min-height: 0 !important; }
  .doc__foot { border-top: 1px solid #ccc !important; padding: 12pt 0 0 !important; }

  .doc__h1 { font-size: 20pt !important; color: #111 !important; margin: 0 0 6pt !important; max-width: 100% !important; }
  .doc__lede, .cv p, .tl div { font-size: 10pt !important; color: #222 !important; line-height: 1.45 !important; }
  .cv { max-width: 100% !important; padding: 10pt 0 !important; border-top: 1px solid #ddd !important;
        break-inside: avoid; }
  .cv__h { font-size: 13pt !important; color: #111 !important; margin: 2pt 0 8pt !important; }
  .item__k, .eyebrow { font-size: 8pt !important; color: #555 !important; letter-spacing: .12em !important; }
  .strengths h3, .cv__role h3 { font-size: 11pt !important; color: #111 !important; }
  .cv__role h3 span, .tags { color: #555 !important; font-size: 8.5pt !important; }
  .tl b { color: #555 !important; font-size: 8.5pt !important; }
  .tl strong { color: #111 !important; }
  .facts { gap: 10pt 22pt !important; margin: 10pt 0 12pt !important; }
  .facts b { font-size: 9.5pt !important; color: #111 !important; }
  .facts span { font-size: 7.5pt !important; color: #666 !important; }
  .cv__note { display: none !important; }
  .cv__name { font-size: 15pt !important; color: #111 !important; margin: 0 0 3pt !important; }

  /* links print as text plus their target, so a printed copy is still usable */
  .links { gap: 8pt !important; margin-top: 8pt !important; }
  .lk { border: none !important; background: none !important; padding: 0 !important;
        color: #111 !important; font-size: 9pt !important; text-decoration: underline;
        /* os.css uppercases .lk; an address is easier to parse and to read as
           it was actually written */
        text-transform: none !important; letter-spacing: 0 !important;
        font-family: inherit !important; }
  .lk[href^="/"], .lk[download] { display: none !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 7.5pt; color: #666; }

  @page { margin: 14mm 15mm; }
}
