/* ============================================================
   Nik Vlasovs — portfolio
   Direction: pre-press mark-up. The work is print and localisation
   for global tech, so the page is built the way a proof is marked
   up: a narrow annotation margin carrying specs in mono, a wide
   content column, hairline rules, and one colour reserved for
   annotation and interaction.
   ============================================================ */

/* ---------- tokens ---------- */
:root{
  --ink:      #14161A;   /* pressed ink, cool black */
  --ink-2:    #2C3037;
  --paper:    #F2F2F0;   /* uncoated stock, neutral */
  --paper-2:  #E5E5E2;   /* recessed panel */
  --grey:     #6B6E73;   /* secondary text */
  --grey-2:   #9A9CA0;
  --rule:     rgba(20,22,26,.15);
  --rule-2:   rgba(20,22,26,.08);
  --mark:     #C8005A;   /* annotation magenta: mark-up + interaction only */

  --display: "Instrument Sans", "Helvetica Neue", Arial, sans-serif;
  --body:    "Literata", Georgia, serif;
  --spec:    "JetBrains Mono", ui-monospace, Menlo, monospace;

  --gut:   clamp(1.25rem, 4.5vw, 3.5rem);
  --stack: clamp(3.5rem, 9vh, 7rem);
  --maxw:  81rem;
  --margin-col: 11rem;   /* the mark-up margin */
}

*,*::before,*::after{ box-sizing:border-box; }

html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
@media (prefers-reduced-motion:reduce){ html{ scroll-behavior:auto; } }

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--body);
  font-size:clamp(1rem, .3vw + .95rem, 1.0625rem);
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
}

img{ max-width:100%; height:auto; display:block; }
/* the UA default is margin:1em 40px, which insets a bare figure from
   the text block it should align with. Spacing is set per figure. */
figure{ margin:0; }
/* let the browser avoid short last lines and ragged headings.
   Non-breaking spaces in the markup bind the final word pair;
   this catches everything above that. */
p, li, dd, figcaption, td, caption{ text-wrap:pretty; }
.h1, .h2, .h3, .lede{ text-wrap:balance; }
a{ color:inherit; }
strong{ font-weight:600; }

:focus-visible{ outline:2px solid var(--mark); outline-offset:3px; }

.skip{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--ink); color:var(--paper);
  padding:.7rem 1rem; font-family:var(--spec); font-size:.75rem;
}
.skip:focus{ left:0; }

.wrap{ width:100%; max-width:var(--maxw); margin-inline:auto; padding-inline:var(--gut); }

/* ---------- type roles ---------- */
.spec{
  font-family:var(--spec);
  font-size:.6875rem;
  font-weight:400;
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--grey);
  line-height:1.5;
}
.spec--mark{ color:var(--mark); }

/* inline code voice: a product code is a code, not prose, so it takes
   the mono face. The bare character being defined also takes the
   annotation colour, because calling out a character is mark-up. */
code{
  font-family:var(--spec); font-size:.8125em;
  background:var(--paper-2); padding:.15em .4em;
  white-space:nowrap;
}
.ch{
  font-family:var(--spec); font-weight:500; font-size:.9375em;
  color:var(--mark); background:var(--paper-2);
  padding:.15em .45em;
}

.h1{
  font-family:var(--display);
  font-weight:600;
  font-size:clamp(2.25rem, 6.4vw, 5.25rem);
  line-height:.98;
  letter-spacing:-.028em;
  margin:0;
  text-wrap:balance;
}
.h2{
  font-family:var(--display);
  font-weight:600;
  font-size:clamp(1.5rem, 3.2vw, 2.5rem);
  line-height:1.08;
  letter-spacing:-.02em;
  margin:0 0 1.25rem;
  text-wrap:balance;
}
.h3{
  font-family:var(--display);
  font-weight:600;
  font-size:clamp(1.0625rem, 1.5vw, 1.3125rem);
  line-height:1.25;
  letter-spacing:-.012em;
  margin:0 0 .5rem;
}
.lede{
  font-size:clamp(1.125rem, 1vw + .9rem, 1.4375rem);
  line-height:1.5;
  margin:0;
  max-width:38ch;
}
p{ margin:0 0 1.15rem; max-width:64ch; }
p:last-child{ margin-bottom:0; }

/* ============================================================
   MARK-UP MARGIN GRID
   Every block is [annotation margin | content]. On narrow
   screens the margin becomes a label sitting above the content.
   ============================================================ */
.block{
  display:grid;
  gap:.9rem;
  padding-block:var(--stack);
  border-top:1px solid var(--rule);
}
.block--flush{ border-top:0; padding-top:clamp(1.25rem,2.5vh,2rem); }
/* a block that hands straight over to the reel keeps no gap below it,
   so the strip reads as belonging to the paragraph above. */
.block--to-reel{ padding-bottom:0; }
@media (min-width:60rem){
  /* label locks to the first baseline of the client list beside it */
  .block--baseline{ align-items:baseline; }
}
.block__margin > *{ display:block; margin:0 0 .5rem; }
.block__margin > *:last-child{ margin-bottom:0; }

@media (min-width:60rem){
  .block{
    grid-template-columns:var(--margin-col) minmax(0,1fr);
    gap:0 3.5rem;
  }
  .block__margin{
    align-self:start;
    padding-top:0;
  }
}

/* ---------- header ---------- */
.top{
  position:sticky; top:0; z-index:50;
  background:rgba(242,242,240,.86);
  backdrop-filter:blur(8px);
  border-bottom:1px solid var(--rule);
}
.top__in{
  display:flex; align-items:center; justify-content:space-between;
  gap:1rem; min-height:3.5rem;
}
.mark{
  font-family:var(--display); font-weight:600;
  font-size:1rem; letter-spacing:-.02em; text-decoration:none;
}
.top nav{ display:flex; gap:1.5rem; }
.top nav a{
  font-family:var(--spec); font-size:.6875rem; letter-spacing:.1em;
  text-transform:uppercase; text-decoration:none; color:var(--grey);
  padding-block:.3rem;
}
.top nav a:hover{ color:var(--ink); }
.top nav a[aria-current="page"]{ color:var(--ink); box-shadow:0 1px 0 var(--mark); }

/* ============================================================
   HERO — the signature. The headline annotates its own
   typographic settings, the way a proof is marked up. This is
   the first work sample on the page.
   ============================================================ */
.hero{ padding-block:clamp(3rem,10vh,7rem) clamp(1.5rem,3vh,2.25rem); }
.hero__eyebrow{ display:block; margin-bottom:clamp(1.5rem,4vh,2.5rem); }

.hero__type{ position:relative; }
.hero__type .h1{ position:relative; z-index:1; max-width:22ch; }

/* annotation set: three quiet marginal notes with leader lines */
.anno{
  display:none;
  position:absolute;
  font-family:var(--spec); font-size:.625rem; letter-spacing:.08em;
  text-transform:uppercase; color:var(--mark);
  white-space:nowrap; pointer-events:none;
}
.anno::before{
  content:""; position:absolute; top:.55em;
  height:1px; background:var(--mark); opacity:.5;
}
.anno--l{ text-align:right; }
.anno--l::before{ right:-2.25rem; width:2rem; }
.anno--r::before{ left:-2.25rem; width:2rem; }

@media (min-width:78rem){
  .anno{ display:block; }
  .anno--1{ right:calc(100% + 2.5rem); top:.15em; }
  .anno--2{ left:calc(100% - 1rem); top:2.9em; }
  .anno--3{ right:calc(100% + 2.5rem); bottom:.4em; }
}

.hero__sub{ margin-top:clamp(1.75rem,4vh,2.5rem); color:var(--ink-2); }
.hero__meta{
  display:flex; flex-wrap:wrap; gap:.5rem 1.75rem;
  margin-top:clamp(2rem,5vh,3rem);
  padding-top:1.25rem; border-top:1px solid var(--rule);
}

/* ---------- client strip ---------- */
.clients{
  display:flex; flex-wrap:wrap; gap:.6rem 1.5rem;
  font-family:var(--spec); font-size:.6875rem; letter-spacing:.14em;
  line-height:1.5;
  text-transform:uppercase; color:var(--ink-2);
  margin:0; padding:0; list-style:none;
}

/* ---------- work list ---------- */
.work{ list-style:none; margin:0; padding:0; }
.work > li + li{ margin-top:clamp(2.5rem,6vh,4rem); }

.card{
  display:grid; gap:1.25rem;
  text-decoration:none; color:inherit;
  align-items:start;
}
@media (min-width:48rem){
  .card{ grid-template-columns:minmax(0,1.15fr) minmax(0,1fr); gap:2.5rem; align-items:center; }
}
.card__shot{
  background:var(--paper-2);
  border:1px solid var(--rule-2);
  overflow:hidden;
  aspect-ratio:4/3;
}
.card__shot img{
  width:100%; height:100%; object-fit:cover; object-position:center top;
  transition:transform .6s cubic-bezier(.2,.7,.3,1);
}
.card:hover .card__shot img{ transform:scale(1.02); }
.card__meta{ display:flex; flex-wrap:wrap; gap:.4rem 1.25rem; margin-bottom:.9rem; }
.card__desc{ color:var(--grey); max-width:46ch; margin:0 0 1rem; }
.card__cta{
  font-family:var(--spec); font-size:.6875rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--mark);
  display:inline-flex; align-items:center; gap:.5rem;
}
.card:hover .card__cta{ box-shadow:0 1px 0 var(--mark); }

.card--soon{ opacity:.55; }
.card--soon .card__shot{
  display:grid; place-items:center;
  background:
    repeating-linear-gradient(135deg, rgba(20,22,26,.05) 0 1px, transparent 1px 10px),
    var(--paper-2);
}
.card--soon .card__shot span{ font-family:var(--spec); font-size:.625rem; letter-spacing:.12em; text-transform:uppercase; color:var(--grey-2); }

/* ---------- services ---------- */
.svc{ list-style:none; margin:0; padding:0; display:grid; gap:0; }
.svc li{ padding-block:1.4rem; border-top:1px solid var(--rule-2); }
.svc li:first-child{ border-top:0; padding-top:0; }
.svc p{ color:var(--grey); margin:0; max-width:52ch; }

/* ---------- about ---------- */
.facts{ list-style:none; margin:0; padding:0; display:grid; gap:1.4rem; }
@media (min-width:44rem){ .facts{ grid-template-columns:repeat(2,1fr); gap:1.75rem 3rem; } }
.facts dt{ margin-bottom:.35rem; }
.facts dd{ margin:0; }
.facts dd p{ margin:0; max-width:42ch; }

/* ============================================================
   CASE STUDY
   ============================================================ */
.cs-hero{ padding-block:clamp(2.5rem,7vh,4.5rem) 0; }
.cs-hero .h1{ max-width:24ch; font-size:clamp(2rem,5.2vw,4rem); }
.cs-hero__sub{ margin-top:1.5rem; color:var(--ink-2); max-width:44ch; }

.cs-meta{
  display:grid; gap:1.25rem;
  margin-top:clamp(2rem,5vh,3rem);
  padding-top:1.5rem; border-top:1px solid var(--rule);
}
@media (min-width:40rem){ .cs-meta{ grid-template-columns:repeat(2,1fr); } }
@media (min-width:64rem){ .cs-meta{ grid-template-columns:repeat(4,1fr); gap:2rem; } }
.cs-meta div > *{ margin:0; }
.cs-meta .spec{ margin-bottom:.4rem; }
.cs-meta p{ font-family:var(--display); font-weight:500; font-size:.9375rem; line-height:1.35; }

/* full-bleed plate for the cover */
.plate{
  margin-top:clamp(2rem,6vh,4rem);
  background:var(--paper-2);
  border-block:1px solid var(--rule-2);
  padding-block:clamp(2rem,6vh,4.5rem);
}
.plate figure{ margin:0; }
.plate img{ margin-inline:auto; max-height:80vh; max-width:100%; width:auto; }
.plate figcaption{ margin-top:1.5rem; text-align:center; }

/* spread grid */
.spreads{ list-style:none; margin:0; padding:0; display:grid; gap:1.25rem; }
@media (min-width:40rem){ .spreads{ grid-template-columns:repeat(2,1fr); gap:1.5rem; } }
@media (min-width:68rem){ .spreads--3{ grid-template-columns:repeat(3,1fr); } }
.spreads figure{ margin:0; }
.spreads img{
  width:100%; border:1px solid var(--rule-2); background:#fff;
}
.spreads figcaption{ margin-top:.7rem; }

/* specification table: real values from the job */
.specs{ width:100%; border-collapse:collapse; font-size:.9375rem; }
.specs caption{ text-align:left; margin-bottom:1rem; }
.specs th, .specs td{
  text-align:left; padding:.75rem 1rem .75rem 0;
  border-top:1px solid var(--rule-2); vertical-align:top;
}
.specs tr:first-child th, .specs tr:first-child td{ border-top:1px solid var(--rule); }
.specs th{
  font-family:var(--spec); font-size:.6875rem; font-weight:400;
  letter-spacing:.08em; text-transform:uppercase; color:var(--grey);
  width:11rem; white-space:nowrap;
}
.specs td{ font-family:var(--display); font-weight:450; }
.specs td em{ font-style:normal; color:var(--grey); font-weight:400; }
/* short labels (acronyms) do not need the full 11rem stub */
.specs--narrow th{ width:5rem; }

/* swatches */
.swatch-row{ display:flex; flex-wrap:wrap; gap:1.25rem; margin-top:1.5rem; }
.swatch{ display:flex; align-items:center; gap:.7rem; }
.swatch i{
  width:2.25rem; height:2.25rem; display:block; flex:none;
  border:1px solid var(--rule-2);
}

/* localisation expansion strip: shows the real design problem */
.expand{ list-style:none; margin:1.5rem 0 0; padding:0; max-width:34rem; }
.expand li{
  display:grid; grid-template-columns:2.4rem minmax(0,1fr) 3.2rem;
  align-items:center; gap:.9rem;
  padding-block:.6rem; border-top:1px solid var(--rule-2);
}
.expand li:last-child{ border-bottom:1px solid var(--rule-2); }
.expand__lang{ font-family:var(--spec); font-size:.6875rem; letter-spacing:.08em; color:var(--grey); }
.expand__bar{ position:relative; height:1.55rem; display:flex; align-items:center; }
.expand__bar i{
  position:absolute; left:0; top:0; bottom:0;
  background:var(--paper-2); border-left:2px solid var(--mark);
}
.expand__bar span{ position:relative; padding-left:.55rem; font-size:.875rem; white-space:nowrap; }
.expand__pct{ font-family:var(--spec); font-size:.6875rem; color:var(--grey); text-align:right; }
.expand__pct.is-over{ color:var(--mark); }

/* stages: a genuine typed sequence, so it is numbered */
.stages{ list-style:none; margin:0; padding:0; counter-reset:s; }
.stages li{
  display:grid; gap:.5rem;
  padding-block:1.6rem; border-top:1px solid var(--rule-2);
}
.stages li:first-child{ border-top:1px solid var(--rule); }
.stages li:last-child{ border-bottom:1px solid var(--rule); }
@media (min-width:44rem){ .stages li{ grid-template-columns:5.5rem minmax(0,1fr); gap:0 1.5rem; } }
.stages__n{ font-family:var(--spec); font-size:.6875rem; letter-spacing:.08em; color:var(--mark); padding-top:.3rem; }
.stages p{ color:var(--grey); margin:.25rem 0 0; }

/* pull quote / takeaway */
.take{
  margin-top:clamp(1.75rem,4vh,2.5rem);
  padding:clamp(1.25rem,3vw,2rem);
  background:var(--paper-2);
  border-left:2px solid var(--mark);
}
.take p{ margin:0; max-width:58ch; }
.take p + p{ margin-top:.9rem; }

/* next / footer */
.next{
  display:flex; flex-wrap:wrap; gap:1rem 2rem;
  align-items:baseline; justify-content:space-between;
  padding-block:clamp(2.5rem,6vh,4rem);
  border-top:1px solid var(--rule);
}
.btn{
  display:inline-flex; align-items:center; gap:.6rem;
  font-family:var(--spec); font-size:.6875rem; letter-spacing:.1em;
  text-transform:uppercase; text-decoration:none;
  padding:.85rem 1.3rem; background:var(--ink); color:var(--paper);
  transition:background .18s ease;
}
.btn:hover{ background:var(--mark); }
.btn--quiet{ background:none; color:var(--ink); border:1px solid var(--rule); }
.btn--quiet:hover{ background:var(--paper-2); color:var(--ink); border-color:var(--ink); }

.foot{ border-top:1px solid var(--rule); padding-block:2.5rem 3.5rem; }
.foot__in{ display:grid; gap:1.75rem; }
@media (min-width:52rem){ .foot__in{ grid-template-columns:1.4fr 1fr 1fr; gap:3rem; } }
.foot a{ text-decoration:none; box-shadow:0 1px 0 var(--rule); }
.foot a:hover{ box-shadow:0 1px 0 var(--mark); }
.foot ul{ list-style:none; margin:0; padding:0; display:grid; gap:.55rem; }
.foot li{ font-size:.9375rem; }

/* ============================================================
   TYPOGRAPHIC PLATES
   Where a case study has no clearable client artwork, the page
   states the fact in type rather than showing a placeholder.
   Same logic as the hero: the mark-up is the work sample.
   ============================================================ */
.card__shot--plate{
  display:grid; place-items:center; padding:clamp(1.25rem,4vw,2.5rem);
  background:var(--paper-2);
}
.plate-card{ display:grid; gap:1.1rem; justify-items:center; width:100%; max-width:16rem; }
.plate-card .locales{ max-width:13rem; gap:.55rem 1.4rem; }
.plate-card .locales li{
  font-size:clamp(1rem,1.7vw,1.3125rem);
  letter-spacing:.12em; color:var(--ink);
}
.plate-card > .spec{
  padding-top:.95rem; border-top:1px solid var(--rule);
  width:100%; text-align:center;
}
.locales{
  display:flex; flex-wrap:wrap; gap:.4rem .9rem;
  justify-content:center; max-width:16rem;
  margin-inline:auto; margin-block:0; padding:0;
  list-style:none;
}
.locales li{
  font-family:var(--spec); font-size:.6875rem;
  letter-spacing:.14em; line-height:1.5; color:var(--ink-2);
}
.locales li:first-child{ color:var(--mark); }
.card:hover .locales li:first-child{ color:var(--mark); }

/* the opener plate when there is no cover shot to show */
.plate--type{ text-align:center; }
.plate--type .locales{
  max-width:52rem; gap:.8rem 1.75rem;
  padding-inline:var(--gut);
}
.plate--type .locales li{
  font-size:clamp(1.0625rem, 2.6vw, 1.75rem);
  letter-spacing:.1em; color:var(--ink);
}
.plate--type .locales li:first-child{ color:var(--mark); }

/* ---------- page density: real lens counts from the leaflet ---------- */
.dens{ list-style:none; margin:1.75rem 0 0; padding:0; display:grid; gap:1.5rem; }
@media (min-width:40rem){ .dens{ grid-template-columns:repeat(2,1fr); gap:2rem; } }
.dens figure{ margin:0; }
/* the two boxes are the same page. Only the number of slots
   changes, so the slots divide the height between them: that
   division *is* the density argument. */
.dens__page{
  border:1px solid var(--rule); background:#fff;
  aspect-ratio:5/7; max-width:17rem; margin-inline:auto;
  padding:.8rem;
  display:grid; grid-auto-rows:1fr; gap:.28rem;
}
.dens__page i{ display:block; background:var(--paper-2); border-left:2px solid var(--rule-2); }
.dens--roomy i{ border-left-color:var(--mark); }
.dens figcaption{ margin-top:.7rem; text-align:center; }

/* ---------- subtitle format conversion: the two real formats ---------- */
.formats{ display:grid; gap:1.25rem; margin-top:1.75rem; }
@media (min-width:44rem){ .formats{ grid-template-columns:repeat(2,1fr); gap:1.5rem; } }
.formats figure{ margin:0; }
.formats figcaption{ margin-bottom:.7rem; }
.formats pre{
  margin:0; padding:1rem;
  background:var(--paper-2); border-left:2px solid var(--rule);
  font-family:var(--spec); font-size:.75rem; line-height:1.7;
  overflow-x:auto;
}
.formats--out pre{ border-left-color:var(--mark); }
.formats b{ font-weight:400; color:var(--mark); }

/* ============================================================
   CASE STUDY STRUCTURE
   A long case study needs signposting, so the asset sections
   are grouped into parts.
   ============================================================ */
.part{
  margin-top:clamp(3.5rem,9vh,6rem); padding-top:1.5rem;
  border-top:2px solid var(--ink);
  display:flex; align-items:baseline; gap:1.25rem; flex-wrap:wrap;
}
.part .h3{ margin:0; }

/* the localisation spine: one master, then seven */
.master{ list-style:none; margin:1.75rem 0 0; padding:0; display:grid; gap:0; }
.master li{
  display:grid; gap:.5rem 1.5rem; align-items:baseline;
  padding:1.1rem 0; border-top:1px solid var(--rule);
}
.master li:last-child{ border-bottom:1px solid var(--rule); }
@media (min-width:40rem){ .master li{ grid-template-columns:minmax(9rem,14rem) 1fr; } }
.master__code{
  font-family:var(--spec); font-size:1.3125rem; letter-spacing:.12em;
  color:var(--mark);
}
.master__codes{
  font-family:var(--spec); font-size:1.0625rem; letter-spacing:.12em;
  color:var(--ink-2); word-spacing:.35em;
}
.master p{ margin:0; }

/* A tall artefact sits in exactly the same block as the body text:
   same left edge, same right edge, same measure. Never centred at
   some third width that lines up with nothing. No frame either, so
   the artwork's own corners are what align. */
.tall{ margin:1.75rem 0 0; max-width:64ch; }
.tall img{ width:100%; height:auto; display:block; }

/* ---------- the A+ set as one moving line ----------
   Ten modules gridded out dwarf the page, so the set runs as a
   single strip drifting right to left. The track carries the set
   twice over, and every item has an identical trailing margin
   rather than a flex gap, so translating by half the track is
   seamless. Hover or keyboard focus stops it. */
.reel{
  margin-top:clamp(1.25rem,2.5vh,1.75rem);
  overflow:hidden;
  padding-block:clamp(1rem,2vh,1.4rem);
  background:var(--paper-2);
  border-block:1px solid var(--rule-2);
}
.reel__track{
  display:flex; align-items:flex-start;
  list-style:none; margin:0; padding:0; width:max-content;
  animation:reel 90s linear infinite;
}
.reel:hover .reel__track,
.reel:focus-within .reel__track{ animation-play-state:paused; }
.reel figure{ margin:0 1.25rem 0 0; width:13.5rem; flex:0 0 auto; }
.reel img{
  width:100%; aspect-ratio:4/5; object-fit:cover;
  display:block; background:#fff;
}
.reel figcaption{ margin-top:.65rem; }
.reel figcaption b{ font-weight:400; color:var(--mark); }
@keyframes reel{ from{ transform:translateX(0); } to{ transform:translateX(-50%); } }
@media (prefers-reduced-motion: reduce){
  .reel{ overflow-x:auto; }
  .reel__track{ animation:none; }
}

/* video: poster only until the visitor asks for it */
.vid{ margin:1.75rem 0 0; }
.vid video{
  width:100%; height:auto; display:block;
  background:var(--ink); border:1px solid var(--rule-2);
}
.vid figcaption{ margin-top:.7rem; }

/* ---------- motion: one orchestrated load, quiet reveals ---------- */
.rise{ opacity:0; transform:translateY(10px); }
.rise.is-in{
  opacity:1; transform:none;
  transition:opacity .7s ease, transform .7s cubic-bezier(.2,.7,.3,1);
}
.anno{ opacity:0; }
.anno.is-in{ opacity:1; transition:opacity .8s ease .5s; }

@media (prefers-reduced-motion:reduce){
  .rise, .rise.is-in, .anno, .anno.is-in{
    opacity:1; transform:none; transition:none;
  }
  .card__shot img{ transition:none; }
}
