/* Career site redesign — staged, not yet live.
   Ported from the Claude Design handoff "Simon Ioffe Site.dc.html".
   Per-element styling stays inline in redesign.html, as in the design source. */

html{scroll-behavior:smooth;background:#f7f3ec}
body{margin:0;background:#f7f3ec;color:#1c1a17;font-family:"Instrument Sans",system-ui,sans-serif;font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
*{box-sizing:border-box}
a{color:#1c1a17;text-decoration:none}
a:hover{color:var(--accent,#b35f34)}
img{max-width:100%;display:block}
::selection{background:#1c1a17;color:#f7f3ec}
@keyframes tocIn{from{opacity:0;transform:translate3d(-18px,0,0)}to{opacity:1;transform:none}}
/* Floating resume TOC — behavior preserved from assets/js/custom.js.
   Only presentation changed. Position/reveal math still driven by JS custom props. */
#resume{--resume-content-max:1180px;--resume-toc-width:238px}
#resume .resume-experience-wrap{position:relative;overflow:visible;display:block}
#resume .resume-toc{position:fixed;top:162px;left:max(14px,calc((100vw - var(--resume-content-max))/2 - var(--resume-toc-width) + 34px));z-index:99;width:var(--resume-toc-width);height:auto;pointer-events:none;opacity:calc(var(--toc-vis,0));transform:translate3d(calc((1 - var(--toc-vis,0)) * -10px),0,0);transition:opacity 190ms ease-out,transform 190ms ease-out}
#resume .resume-toc[data-visible="1"]{pointer-events:auto}
#resume .resume-toc-shell{width:100%}
#resume .resume-toc-inner{max-height:calc(100vh - 200px);overflow:auto;scrollbar-width:none}
#resume .resume-toc-inner::-webkit-scrollbar{display:none}
#resume .resume-toc-title{--toc-title-hidden:0;font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:#a09789;margin:0 0 14px 12px;opacity:calc(1 - var(--toc-title-hidden));transform:translate3d(calc(var(--toc-title-hidden) * -30px),0,0);transition:transform 130ms cubic-bezier(.2,.85,.2,1),opacity 130ms ease-out}
#resume .resume-toc-nav ul{list-style:none;padding:0;margin:0}
#resume .resume-toc-nav a{--toc-hidden:0;--toc-shift-sign:-1;--act:0;--hov:0;position:relative;display:block;padding:4px 10px 4px 12px;color:#4a443c;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.28;opacity:calc((1 - var(--toc-hidden)) * (0.88 + var(--act) * 0.12 + var(--hov) * 0.12));transform:translate3d(calc(var(--toc-shift-sign) * var(--toc-hidden) * 38px + var(--hov) * 3px),0,0);transition:transform 130ms cubic-bezier(.2,.85,.2,1),opacity 130ms ease-out,color 160ms ease-out}
#resume .resume-toc-nav a::before{content:"";position:absolute;left:0;top:50%;width:2px;height:0;background:var(--accent,#b35f34);transform:translateY(-50%);transition:height 200ms cubic-bezier(.2,.85,.2,1)}
#resume .resume-toc-nav a[data-act="1"]::before{height:calc(100% - 8px)}
#resume .resume-toc-nav .toc-company>a{font-family:"Newsreader",Georgia,serif;font-size:19px;font-weight:400;letter-spacing:-.01em;color:#1c1a17;padding-top:10px}
#resume .resume-toc-nav .toc-company>a[data-act="1"]{color:var(--accent,#b35f34)}
#resume .resume-toc-nav .toc-roles{margin:2px 0 4px 12px;padding-left:12px;border-left:1px solid rgba(28,26,23,.1)}
#resume .resume-toc-nav .toc-role a{font-size:13px;letter-spacing:.005em;color:#4a443c}
#resume .resume-toc-nav .toc-role a[data-act="1"]{color:#1c1a17}
#resume [data-resume-company],#resume [data-resume-role]{scroll-margin-top:120px}
#resume .resume-content-col{padding-left:0}
@media (min-width:901px){#resume .resume-content-col{padding-left:284px}}
@media (max-width:1200px){#resume{--resume-toc-width:214px}#resume .resume-toc{left:14px}#resume .resume-content-col{padding-left:246px}}
@media (max-width:900px){#resume .resume-toc{display:none}#resume .resume-content-col{padding-left:0}}
/* responsive collapse for the editorial grids */
@media (max-width:1000px){.two-col{grid-template-columns:1fr !important}.hero-grid{grid-template-columns:1fr !important}.rail-grid{grid-template-columns:1fr !important}.focus-grid{grid-template-columns:1fr 1fr !important}}
/* Three awards across a tablet leaves ~120px of text column, which wrapped
   "Employee of the Year" onto three lines. */
@media (max-width:900px){.awards-grid{grid-template-columns:1fr 1fr !important;gap:36px 40px}}
@media (max-width:640px){.focus-grid{grid-template-columns:1fr !important}.awards-grid{grid-template-columns:1fr !important}}
/* Grid items default to min-width:auto, so a wide child can push a column past
   its track and blow out the row. */
.two-col > *,.rail-grid > *,.hero-grid > *,.pf-grid > *{min-width:0}
/* Contact details were a rigid three-column grid that could not shrink. */
.contact-meta{display:flex;flex-wrap:wrap;gap:24px 40px;justify-content:flex-start}
/* The nav is sticky, so an anchor jump would otherwise park the section
   heading underneath it -- and the nav is taller once it wraps to two rows. */
section[id],header[id]{scroll-margin-top:78px}
@media (max-width:820px){section[id],header[id]{scroll-margin-top:116px}}
/* "Scroll" is a desktop affordance and the mail address is long; neither
   earns a line of its own on a phone. */
@media (max-width:700px){
  .hero-foot{gap:10px 18px;font-size:10.5px}
  .hero-foot > span{margin-left:0 !important;width:100%}
}
@media (max-width:480px){.hero-foot > span{display:none}}
.reveal{opacity:var(--in,0);transform:translate3d(0,calc((1 - var(--in,0)) * 16px),0);transition:opacity 620ms cubic-bezier(.22,.8,.24,1),transform 620ms cubic-bezier(.22,.8,.24,1)}
.nav-link:hover{color:var(--accent,#b35f34)}

/* Site nav. Desktop is a single row; below the breakpoint the brand and the
   resume button hold row one and the section links drop to row two, which is
   the only way five links plus a button fit a phone without a menu. */
.site-nav-inner{max-width:1180px;margin:0 auto;padding:14px 32px;display:flex;align-items:center;gap:24px}
.site-nav-spacer{flex:1}
.site-nav-links{display:flex;align-items:center;gap:2px}
.site-nav-links .nav-link{font-size:13.5px;color:#6b645b;padding:8px 13px}
.site-nav-cta{margin-left:12px;font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.08em;text-transform:uppercase;padding:9px 15px;border:1px solid #1c1a17;border-radius:999px;display:inline-flex;align-items:center;gap:6px;white-space:nowrap;flex:none}
.site-nav-cta i{font-size:12px}
@media (max-width:820px){
  .site-nav-inner{flex-wrap:wrap;padding:11px 20px;gap:8px 12px}
  .site-nav-spacer{display:none}
  .site-nav-cta{margin-left:auto}
  .site-nav-links{order:3;width:100%;justify-content:space-between;gap:0;border-top:1px solid rgba(28,26,23,.08);padding-top:7px}
  .site-nav-links .nav-link{font-size:12.5px;padding:5px 2px}
}
@media (max-width:360px){
  .site-nav-cta span,.site-nav-brand span{font-size:10.5px}
  .site-nav-links .nav-link{font-size:11.5px}
}
/* Role chips read as a deliberate block at two per row, rather than the 3 + 1
   that free-flowing wrap happened to produce. Below the breakpoint two of them
   no longer fit side by side, so they stack. */
.hero-tags{display:grid;grid-template-columns:repeat(2,auto);justify-content:start;justify-items:start;gap:10px}
@media (max-width:600px){.hero-tags{grid-template-columns:auto}}
/* Portfolio — one set at a time, stepped through with tabs or the flanking
   arrows. Images keep their natural aspect ratio (the original site used
   Bootstrap .img-fluid); nothing is cropped, so the portrait infographic
   stays a poster instead of a letterboxed strip. */
.pf-tabs{display:flex;flex-wrap:wrap;gap:2px 4px;border-top:1px solid rgba(28,26,23,.12);border-bottom:1px solid rgba(28,26,23,.12);padding:8px 0;margin-bottom:34px}
.pf-tab{position:relative;font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.1em;text-transform:uppercase;background:none;border:none;padding:9px 14px;white-space:nowrap;color:#8a8177;cursor:pointer;border-radius:999px;transition:color 180ms ease,background 180ms ease}
.pf-tab:hover{color:#1c1a17;background:rgba(28,26,23,.045)}
.pf-tab[aria-selected="true"]{color:#f7f3ec;background:var(--accent,#b35f34)}
.pf-tab:focus-visible{outline:2px solid var(--accent,#b35f34);outline-offset:2px}
.pf-tab-n{margin-left:8px;font-size:9.5px;opacity:.6}

/* align-items:center would re-centre the arrows on every set, since the sets
   are different heights -- the cursor would have to chase them between
   clicks. Anchoring to the top pins them to one spot instead. */
.pf-stage{display:flex;align-items:flex-start;gap:18px}
.pf-stage-main{flex:1;min-width:0}
/* Arrows sit outside the frames so they never cover artwork. */
.pf-nav{flex:none;width:46px;height:46px;border-radius:50%;border:1px solid rgba(28,26,23,.2);background:rgba(253,251,247,.8);color:#6b645b;font-size:17px;line-height:1;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:border-color 200ms ease,color 200ms ease,background 200ms ease,transform 200ms ease}
.pf-nav:hover{border-color:var(--accent,#b35f34);color:var(--accent,#b35f34);transform:scale(1.06)}
.pf-nav:focus-visible{outline:2px solid var(--accent,#b35f34);outline-offset:3px}
.pf-stage > .pf-nav{position:sticky;top:132px;margin-top:186px}
.pf-nav-mobile{display:none}

.pf-panel-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px 24px;flex-wrap:wrap;margin-bottom:22px}
.pf-panel-title{font-family:var(--display),Georgia,serif;font-weight:400;font-size:clamp(24px,2.6vw,33px);letter-spacing:-.02em;line-height:1.1;margin:0;color:#1c1a17}
.pf-panel-meta{display:flex;align-items:center;gap:14px;font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.14em;color:#a09789;white-space:nowrap}
.pf-progress{display:block;width:76px;height:1px;background:rgba(28,26,23,.16);position:relative;overflow:hidden}
.pf-progress-bar{position:absolute;left:0;top:0;height:100%;width:0;background:var(--accent,#b35f34);transition:width 420ms cubic-bezier(.22,.8,.24,1)}

.pf-panel[hidden]{display:none}
.pf-panel{animation:pfPanelIn 480ms cubic-bezier(.22,.8,.24,1) both}
@keyframes pfPanelIn{from{opacity:0;transform:translate3d(0,12px,0)}to{opacity:1;transform:none}}
.pf-grid{display:grid;gap:44px 32px;align-items:start}
.pf-grid-multi{grid-template-columns:repeat(2,1fr)}
.pf-grid-solo{grid-template-columns:1fr;justify-items:center}
/* A lone item gets room to breathe. Capping the item (not the image) keeps the
   hover veil exactly on the artwork; the portrait poster gets a tighter cap so
   it does not run off the screen. */
.pf-grid-solo .pf-item{width:100%;max-width:min(100%,940px)}
.pf-grid-solo .pf-item-portrait{max-width:min(100%,470px)}
@media (max-width:900px){.pf-grid-multi{grid-template-columns:1fr}}

.pf-item{margin:0;display:flex;flex-direction:column;gap:14px;min-width:0}
.pf-frame{position:relative;overflow:hidden;background:#eae4da;cursor:pointer;outline:none}
.pf-frame img{display:block;width:100%;height:auto;transition:transform 700ms cubic-bezier(.22,.8,.24,1)}
.pf-frame::after{content:"";position:absolute;inset:0;border:1px solid rgba(28,26,23,.1);pointer-events:none;transition:border-color 320ms ease}
/* The veil's own styling lives here, not inline: an inline opacity:0 outranks
   the :hover rule below, which is what kept the reveal from ever firing. */
.pf-veil{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;padding:28px;background:linear-gradient(to top,rgba(20,18,16,.94),rgba(20,18,16,.55) 55%,rgba(20,18,16,0));opacity:0;transition:opacity 320ms ease}
.pf-veil-title{font-family:var(--display),Georgia,serif;font-size:24px;color:#f7f3ec;letter-spacing:-.02em;margin-bottom:8px}
.pf-veil-body{margin:0;font-size:14px;line-height:1.55;color:rgba(247,243,236,.78);max-width:52ch}
.pf-item:hover .pf-veil,.pf-frame:focus-visible .pf-veil{opacity:1}
.pf-item:hover .pf-frame img,.pf-frame:focus-visible img{transform:scale(1.03)}
.pf-frame:focus-visible::after{border-color:var(--accent,#b35f34);border-width:2px}
.pf-more{position:absolute;top:16px;right:16px;width:30px;height:30px;border-radius:50%;background:rgba(247,243,236,.9);color:#1c1a17;display:flex;align-items:center;justify-content:center;font-family:"IBM Plex Mono",monospace;font-size:15px;line-height:1;transition:opacity 260ms ease,transform 320ms cubic-bezier(.22,.8,.24,1)}
.pf-item:hover .pf-more,.pf-frame:focus-visible .pf-more{opacity:0;transform:rotate(135deg)}
.pf-caption{font-family:var(--display),Georgia,serif;font-size:20px;letter-spacing:-.015em;line-height:1.24;color:#1c1a17;transition:color 200ms ease}
.pf-item:hover .pf-caption{color:var(--accent,#b35f34)}
.pf-touch-body{display:none;margin:0;font-size:14.5px;line-height:1.58;color:#5c554d}
/* Touch: hover never fires, so retire the veil and print the write-up in place. */
@media (hover:none){
  .pf-veil,.pf-more{display:none}
  .pf-touch-body{display:block}
}
/* Narrow: the flanking arrows have nowhere to stand, so they move under the set. */
@media (max-width:820px){
  .pf-stage > .pf-nav{display:none}
  .pf-nav-mobile{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-top:34px;padding-top:20px;border-top:1px solid rgba(28,26,23,.12)}
  .pf-nav-hint{font-family:"IBM Plex Mono",monospace;font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;color:#a09789;text-align:center;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
}
@media (prefers-reduced-motion:reduce){
  .pf-panel{animation:none}
  .pf-frame img,.pf-veil,.pf-more,.pf-progress-bar{transition:none}
}


/* Generative network graphic. It runs across the whole hero rather than just
   behind the portrait, and fills the short column in two places where the
   editorial grid would otherwise leave dead space. Always decorative, always
   behind the text, and it fades out as it falls. */
/* Radial rather than linear: the graphic stays dense at the top right, where
   the portrait is, and clears out of the headline and the role chips. */
.net-hero{-webkit-mask-image:radial-gradient(115% 92% at 100% 0%,#000 0%,#000 26%,rgba(0,0,0,.35) 58%,transparent 82%);mask-image:radial-gradient(115% 92% at 100% 0%,#000 0%,#000 26%,rgba(0,0,0,.35) 58%,transparent 82%)}
/* The fills are a background layer for their whole column, not a block tacked
   on below the text. They pass behind the copy at low weight and come up to
   full strength in the open space underneath it. */
.net-col{position:relative}
.net-col > *{position:relative;z-index:1}
.net-fill{position:absolute;inset:0;z-index:0;display:block;width:100%;height:100%;opacity:.72;pointer-events:none;-webkit-mask-image:linear-gradient(to bottom,rgba(0,0,0,.16) 0%,rgba(0,0,0,.3) 26%,rgba(0,0,0,.72) 48%,#000 66%,#000 82%,transparent 100%);mask-image:linear-gradient(to bottom,rgba(0,0,0,.16) 0%,rgba(0,0,0,.3) 26%,rgba(0,0,0,.72) 48%,#000 66%,#000 82%,transparent 100%)}
/* In the narrow columns the fills only earn their place once the two-column
   grid is actually two columns. */
/* The Education column is only 63% text, unlike the About column's 90%, so its
   graphic can stay nearly clear behind the copy and then hold full strength
   through the open third underneath instead of fading back out. */
.net-fill-open{-webkit-mask-image:linear-gradient(to bottom,rgba(0,0,0,.07) 0%,rgba(0,0,0,.11) 38%,rgba(0,0,0,.26) 56%,rgba(0,0,0,.8) 72%,#000 84%,#000 97%,transparent 100%);mask-image:linear-gradient(to bottom,rgba(0,0,0,.07) 0%,rgba(0,0,0,.11) 38%,rgba(0,0,0,.26) 56%,rgba(0,0,0,.8) 72%,#000 84%,#000 97%,transparent 100%)}
@media (max-width:1000px){.net-fill{display:none}}

/* Company logos link out. They sit on a light ground, so the affordance is a
   lift in saturation and opacity rather than a colour change. */
.company-link{display:inline-flex;flex:none}
.company-link img{transition:filter 220ms ease,opacity 220ms ease}
.company-link:hover img,.company-link:focus-visible img{filter:saturate(1);opacity:.72}
.company-link:focus-visible{outline:2px solid var(--accent,#b35f34);outline-offset:5px;border-radius:2px}
.line-link{border-bottom:1px solid rgba(28,26,23,.25);padding-bottom:2px}
.line-link:hover{border-color:var(--accent,#b35f34)}
