/* ==========================================================================
   Neomi Livshitz — UX Portfolio

   One type scale, one label, one list, one figure, one quote. The serif is
   reserved for the wordmark and appears nowhere else, so the pages read as a
   single system rather than two. Warm paper, one coral accent, generous air.
   Light theme, committed.

   Enforced by site/audit.py — see GOAL.md for the budgets.
   ========================================================================== */

/* --------------------------------------------------------------- webfonts ---
   Served from this origin, not from Fontshare and Google's CDNs, so the page
   makes no third-party request and the CSP can say font-src 'self'. Subset and
   licensed — see assets/fonts/README.md. */

@font-face {
  font-family: "General Sans";
  src: url("assets/fonts/general-sans-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "General Sans";
  src: url("assets/fonts/general-sans-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "General Sans";
  src: url("assets/fonts/general-sans-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Instrument Serif";
  src: url("assets/fonts/instrument-serif-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Instrument Serif";
  src: url("assets/fonts/instrument-serif-400-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

:root {
  color-scheme: light;

  /* Ground */
  --paper:        #FBFAF7;
  --paper-raised: #FFFFFF;
  --paper-sunk:   #F4F1EB;

  /* Ink */
  --ink:    #191713;
  --ink-2:  #57534A;
  --ink-3:  #8B857A;
  --ink-4:  #B3ADA1;

  /* Lines */
  --rule:        rgba(25, 23, 19, 0.10);
  --rule-strong: rgba(25, 23, 19, 0.18);

  /* Accent — the coral from the monogram */
  --accent:      #D8452A;
  --accent-soft: #FBEBE6;

  /* Per-project tint, overridden inline. Defaults to accent family. */
  --tint:     #F3E3DA;
  --tint-ink: #A85434;

  /* Provenance */
  --measured-bg: #E4EDE4;  --measured-ink: #3F6B41;
  --target-bg:   #F5EAD4;  --target-ink:   #8A6420;
  --proposed-bg: #E4EAF2;  --proposed-ink: #3F6285;
  --open-bg:     #F1EDE7;  --open-ink:     #6B655B;

  /* ---- Type scale — eight steps, nothing outside them -------------------
     label  uppercase markers, chips, table heads, meta
     xs     captions, citations, chrome
     sm     secondary body: notes, list items, card fields
     base   body copy
     md     ledes, brief panels, card titles
     lg     pull quotes, big numerals, the wordmark
     xl     page and section headings
     2xl    the hero, and the closing invitation                          */
  --t-label: 11.5px;
  --t-xs:    13px;
  --t-sm:    14.5px;
  --t-base:  16.5px;
  --t-md:    17.5px;
  --t-lg:    23px;
  --t-xl:    clamp(26px, 3.6vw, 38px);
  --t-2xl:   clamp(30px, 4.8vw, 48px);

  --r-s:  8px;
  --r-m:  14px;
  --r-pill: 999px;

  --font: "General Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
          "Helvetica Neue", Arial, sans-serif;
  --font-display: "Instrument Serif", "Iowan Old Style", Georgia, serif;

  --wrap: 1120px;
  --gutter: 28px;
}

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

/* Deliberately NOT scroll-behavior: smooth. The page runs to ~33,000px, and
   Chrome animates long jumps at near-constant velocity — a nav click to
   Contact would crawl for several seconds. Instant jumps are the right call
   at this length. */

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--t-base);
  line-height: 1.62;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* clip, not hidden: `hidden` would make <body> a scroll container
     (overflow-y computes to auto) and break sticky/anchor behaviour. */
  overflow-x: clip;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; }

::selection { background: var(--accent); color: #fff; }

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

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

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --------------------------------------------------------------------------
   The label — the only uppercase style in the stylesheet

   Every small marker on the site is this one declaration: block labels,
   chips, table heads, definition terms, pager kickers, the index divider,
   walkthrough chapters. They used to be ten near-copies at eight sizes,
   which is what made the pages feel like different websites. Colour and
   spacing vary by context below; size and tracking never do.
   -------------------------------------------------------------------------- */

.label,
.chip,
.data th,
.persona dt,
.about-grid dt,
.pager small,
.index-break span,
.wt-chapter {
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* A block label announces a section, with the project's tint as a marker. */
.label {
  display: flex;
  font-weight: 600;
  align-items: center;
  gap: 9px;
  margin: 0 0 16px;
}
.label::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 2px;
  background: var(--tint-ink);
  flex: none;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.masthead {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--paper);
  border-bottom: 1px solid transparent;
  transition: border-color .25s ease;
}

.masthead.is-stuck { border-bottom-color: var(--rule); }

.masthead .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  height: 66px;
}

/* The one place the display face appears. */
.monogram {
  display: inline-flex;
  align-items: baseline;
  gap: 1px;
  text-decoration: none;
  font-family: var(--font-display);
  font-size: var(--t-lg);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--accent);
}
.monogram i { font-style: italic; margin-left: -3px; }

.masthead nav {
  display: flex;
  align-items: center;
  gap: 26px;
  font-size: var(--t-sm);
  font-weight: 500;
}

.masthead nav a {
  text-decoration: none;
  color: var(--ink-2);
  position: relative;
  padding-block: 2px;
  transition: color .18s ease;
}
.masthead nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .22s cubic-bezier(.2,.7,.3,1);
}
.masthead nav a:hover { color: var(--ink); }
.masthead nav a:hover::after { transform: scaleX(1); }

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.hero {
  padding: clamp(64px, 11vw, 128px) 0 clamp(48px, 7vw, 84px);
  text-align: center;
}

.hero h1 {
  margin: 0 auto 26px;
  font-size: var(--t-2xl);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.032em;
  /* No measure cap: this is a one-line greeting, not a paragraph, and 17ch was
     breaking it after the first name at every width. The .wrap container is the
     real limit; balance keeps the break even on a phone narrow enough to need one. */
  text-wrap: balance;
}
/* keeps a phrase from breaking across lines (hero name + wave) */
.nb { white-space: nowrap; }

.hero h1 .wave {
  display: inline-block;
  font-size: 0.82em;
  margin-left: 0.12em;
  transform-origin: 70% 80%;
}

.hero-lede {
  margin: 0 auto 18px;
  max-width: 58ch;
  font-size: var(--t-md);
  line-height: 1.62;
  color: var(--ink-2);
}
.hero-lede strong { color: var(--ink); font-weight: 600; }
.hero-lede:last-of-type { margin-bottom: 34px; }

.inline-link {
  color: var(--ink);
  text-decoration: none;
  background-image: linear-gradient(var(--accent), var(--accent));
  background-size: 100% 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  padding-bottom: 1px;
  transition: color .18s ease, background-size .22s ease;
}
.inline-link:hover { color: var(--accent); }

.hero-note {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: 4px;
  padding: 7px 15px 7px 11px;
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  font-size: var(--t-xs);
  color: var(--ink-3);
  background: var(--paper-raised);
}
.hero-note::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

/* --------------------------------------------------------------------------
   Work index
   -------------------------------------------------------------------------- */

.index { padding-bottom: clamp(56px, 8vw, 96px); }

.index-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(28px, 4.2vw, 54px) clamp(24px, 3.4vw, 42px);
}

.tile {
  display: block;
  text-decoration: none;
  color: inherit;
}

.tile-art {
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: var(--r-m);
  background: var(--tint);
  overflow: hidden;
  transition: transform .38s cubic-bezier(.2,.7,.3,1),
              box-shadow .38s cubic-bezier(.2,.7,.3,1);
}
.tile-art svg { width: 100%; height: 100%; }

.tile:hover .tile-art,
.tile:focus-visible .tile-art {
  transform: translateY(-5px);
  box-shadow: 0 22px 42px -26px rgba(25, 23, 19, 0.42);
}

/* photographic tiles fill the frame; the drawn ones are <svg> above */
.tile-art img,
.tile-art video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* full-width divider between the ServiceNow work and the earlier work */
.index-break {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 18px;
  margin: clamp(10px, 2.5vw, 26px) 0 0;
}
.index-break::before,
.index-break::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--rule);
}
.index-break span { color: var(--ink-4); white-space: nowrap; }

.tile-meta {
  text-align: center;
  padding: 18px 8px 0;
}
.tile-meta h3 {
  margin: 0 0 3px;
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.3;
}
.tile-meta p {
  margin: 0;
  font-size: var(--t-sm);
  color: var(--ink-3);
}
.tile:hover .tile-meta h3 { color: var(--accent); }

/* --------------------------------------------------------------------------
   Project pages

   Three levels, everywhere: the title, a label per block, body copy. No
   fourth level — named items inside a block use <strong> inline.
   -------------------------------------------------------------------------- */

.project {
  padding: clamp(34px, 5vw, 56px) 0 clamp(64px, 9vw, 108px);
  scroll-margin-top: 78px;
}

.project-body {
  max-width: 900px;
  margin-inline: auto;
}

.project-head { margin-bottom: 42px; }

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 26px;
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--ink-3);
  text-decoration: none;
  transition: color .18s ease, gap .18s ease;
}
.back-link:hover { color: var(--tint-ink); gap: 13px; }

.project-index {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 14px;
}
.project-index .num {
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--tint-ink);
  font-variant-numeric: tabular-nums;
}
.project-index .stage {
  font-size: var(--t-xs);
  color: var(--ink-3);
  padding-bottom: 3px;
}
.project-index .stage b { color: var(--tint-ink); font-weight: 500; }

.project-head h1 {
  margin: 0 0 14px;
  font-size: var(--t-xl);
  font-weight: 600;
  letter-spacing: -0.028em;
  line-height: 1.12;
  max-width: 20ch;
}

.project-dek {
  margin: 0 0 26px;
  font-size: var(--t-md);
  color: var(--ink-2);
  max-width: 56ch;
  line-height: 1.6;
}

.factline {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 0;
  padding-top: 20px;
  border-top: 1px solid var(--rule);
  font-size: var(--t-xs);
  color: var(--ink-3);
}
.factline > span { display: inline-flex; align-items: center; }
.factline > span:not(:last-child)::after {
  content: "";
  width: 1px; height: 12px;
  background: var(--rule-strong);
  margin-inline: 16px;
}
.factline b { color: var(--ink-2); font-weight: 500; }

.block { margin-bottom: clamp(42px, 5.5vw, 64px); }
.block:last-child { margin-bottom: 0; }

.project p {
  max-width: 66ch;
  margin: 0 0 16px;
  color: var(--ink-2);
}
.project p:last-child { margin-bottom: 0; }
.project p strong { color: var(--ink); font-weight: 600; }

/* An aside that qualifies the claim above it. */
.note {
  font-size: var(--t-sm);
  line-height: 1.58;
  color: var(--ink-3);
  padding-left: 15px;
  border-left: 2px solid var(--rule-strong);
  max-width: 66ch;
}

/* Pull quote — a customer's words, in the body face. */
.pull {
  margin: 24px 0;
  padding-left: 22px;
  border-left: 2px solid var(--tint-ink);
  max-width: 60ch;
}
.pull p {
  font-size: var(--t-lg);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0 0 9px;
  max-width: none;
}
.pull cite::before { content: "\2014\00a0"; }
.pull cite {
  font-style: normal;
  display: block;
  font-size: var(--t-xs);
  color: var(--ink-3);
}

/* Brief panel */
.brief {
  background: var(--tint);
  border-radius: var(--r-m);
  padding: clamp(22px, 3vw, 32px);
}
.brief p {
  margin: 0;
  max-width: 60ch;
  color: color-mix(in srgb, var(--tint-ink) 78%, var(--ink));
  font-size: var(--t-md);
  line-height: 1.6;
}
.brief p + p { margin-top: 12px; }
.brief .label { color: color-mix(in srgb, var(--tint-ink) 82%, transparent); }
.brief q { font-style: italic; quotes: "\201C" "\201D"; }

/* --------------------------------------------------------------------------
   The one list

   Bulleted by default, numbered with .list--num. Both put their marker in
   the left gutter so body copy stays on one measure down the page. This
   replaces the four list treatments the pages used to carry.
   -------------------------------------------------------------------------- */

.list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
  max-width: 72ch;
}
.list > li {
  position: relative;
  padding-left: 22px;
  font-size: var(--t-sm);
  line-height: 1.58;
  color: var(--ink-2);
}
.list > li::before {
  content: "";
  position: absolute;
  left: 2px; top: 10px;
  width: 7px; height: 1.5px;
  background: var(--tint-ink);
}
.list b { color: var(--ink); font-weight: 600; }
.list q { font-style: italic; color: var(--ink); }

.list--num {
  counter-reset: item;
  gap: 4px;
}
.list--num > li {
  counter-increment: item;
  padding: 15px 0 16px 44px;
  border-bottom: 1px solid var(--rule);
  font-size: var(--t-base);
}
.list--num > li:last-child { border-bottom: 0; }
.list--num > li::before {
  content: counter(item, decimal-leading-zero);
  left: 0; top: 16px;
  width: auto; height: auto;
  background: none;
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--tint-ink);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Personas
   -------------------------------------------------------------------------- */

.personas {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(224px, 1fr));
  gap: 16px;
}

.persona {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: var(--r-m);
  padding: 20px 21px 18px;
}
.persona h3 {
  margin: 0 0 3px;
  font-size: var(--t-base);
  font-weight: 600;
  letter-spacing: -0.012em;
}
.persona .role {
  display: block;
  font-size: var(--t-xs);
  font-weight: 500;
  color: var(--tint-ink);
  margin-bottom: 13px;
}
.persona dl { margin: 0; }
.persona dt { color: var(--ink-4); margin-bottom: 3px; }
.persona dd {
  margin: 0 0 11px;
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--ink-2);
}
.persona dd:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Figures — the one media component

   A single image, a video, or a grid of either. The grid is auto-fit, so a
   two-up and a three-up need no separate class.
   -------------------------------------------------------------------------- */

.figure { margin: 26px 0; }
.figure img,
.figure video {
  width: 100%;
  height: auto;
  border-radius: var(--r-m);
  background: var(--tint);
}
.figure figcaption {
  margin-top: 11px;
  font-size: var(--t-xs);
  line-height: 1.55;
  color: var(--ink-3);
  max-width: 72ch;
}

.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 16px;
  margin: 26px 0;
}
.figures .figure { margin: 0; }

/* --------------------------------------------------------------------------
   Video — local poster, YouTube only loaded on click
   -------------------------------------------------------------------------- */

.video-embed { margin: 26px 0 0; }

.vid-poster {
  display: block;
  position: relative;
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: var(--r-m);
  overflow: hidden;
  background: var(--tint);
  cursor: pointer;
  line-height: 0;
}
.vid-poster img {
  width: 100%;
  height: auto;
  transition: transform .5s cubic-bezier(.2,.7,.3,1), filter .3s ease;
}
.vid-poster:hover img { transform: scale(1.02); filter: brightness(.92); }

.vid-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 10px 30px -8px rgba(25, 23, 19, .55);
  transition: transform .25s cubic-bezier(.2,.7,.3,1);
}
.vid-play::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0; height: 0;
  border-style: solid;
  border-width: 11px 0 11px 18px;
  border-color: transparent transparent transparent #fff;
  transform: translateX(2px);
}
.vid-poster:hover .vid-play { transform: scale(1.08); }

.vid-dur {
  position: absolute;
  right: 12px;
  bottom: 12px;
  padding: 3px 8px;
  border-radius: var(--r-s);
  background: rgba(0, 0, 0, .74);
  color: #fff;
  font-size: var(--t-xs);
  font-weight: 500;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
}

.video-embed iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border: 0;
  border-radius: var(--r-m);
  background: #000;
}

.vid-chapters {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 14px;
}
.vid-chapter {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  padding: 6px 11px;
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  background: var(--paper-raised);
  color: var(--ink-2);
  font: inherit;
  font-size: var(--t-xs);
  cursor: pointer;
  transition: color .16s ease, border-color .16s ease;
}
.vid-chapter:hover { color: var(--tint-ink); border-color: var(--tint-ink); }
.vid-chapter .vid-at {
  font-weight: 600;
  color: var(--ink-4);
  font-variant-numeric: tabular-nums;
}
.vid-chapter:hover .vid-at { color: var(--tint-ink); }

.video-embed figcaption,
.live-demo figcaption,
.wt-text {
  margin-top: 14px;
  font-size: var(--t-sm);
  line-height: 1.58;
  color: var(--ink-3);
  max-width: 72ch;
}
.video-embed figcaption b,
.live-demo figcaption b,
.wt-text b { color: var(--ink); font-weight: 600; }
.video-embed figcaption a { color: var(--tint-ink); text-decoration: none; }
.video-embed figcaption a:hover { text-decoration: underline; }
.video-embed figcaption span { color: var(--ink-4); }

/* --------------------------------------------------------------------------
   Live demo — a real prototype embedded in a browser-ish frame
   -------------------------------------------------------------------------- */

.live-demo { margin: 26px 0 0; }
.live-demo + .live-demo { margin-top: 40px; }

.demo-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 14px;
  border: 1px solid var(--rule);
  border-bottom: 0;
  border-radius: var(--r-m) var(--r-m) 0 0;
  background: var(--paper-sunk);
  font-size: var(--t-xs);
  font-weight: 500;
}
.demo-bar i {
  flex: none;
  width: 38px;
  height: 8px;
  background-image: radial-gradient(circle, var(--ink-4) 3.6px, transparent 3.7px);
  background-size: 13px 8px;
  background-repeat: repeat-x;
  opacity: .55;
}
.demo-bar span {
  flex: 1;
  min-width: 0;
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.demo-bar a {
  flex: none;
  color: var(--tint-ink);
  text-decoration: none;
  white-space: nowrap;
}
.demo-bar a:hover { text-decoration: underline; }

.live-demo iframe {
  display: block;
  width: 100%;
  height: var(--demo-h, 620px);
  border: 1px solid var(--rule);
  border-radius: 0 0 var(--r-m) var(--r-m);
  background: var(--paper-raised);
}

@media (max-width: 720px) {
  /* an embedded desktop canvas is unusable at phone width — send them out to it */
  .live-demo iframe { height: 380px; }
}

/* --------------------------------------------------------------------------
   Prototype walkthrough
   -------------------------------------------------------------------------- */

.walkthrough { margin: 26px 0 0; }

.wt-stage {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-m);
  overflow: hidden;
  background: var(--tint);
  box-shadow: 0 1px 2px rgba(25, 23, 19, .05),
              0 18px 40px -26px rgba(25, 23, 19, .38);
}

.wt-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s ease;
}
.wt-frame.is-current { opacity: 1; visibility: visible; }

.wt-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
}

.wt-btn {
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 50%;
  background: var(--paper-raised);
  color: var(--ink-2);
  cursor: pointer;
  transition: color .16s ease, border-color .16s ease, background .16s ease;
}
.wt-btn:hover { color: var(--tint-ink); border-color: var(--tint-ink); }
.wt-btn svg { width: 16px; height: 16px; }

.wt-toggle .i-pause { display: none; }
.wt-toggle.is-playing .i-play { display: none; }
.wt-toggle.is-playing .i-pause { display: block; }

.wt-ticks {
  flex: 1;
  display: flex;
  gap: 3px;
  min-width: 0;
}
.wt-tick {
  flex: 1;
  min-width: 0;
  height: 14px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  position: relative;
}
.wt-tick::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 6px;
  height: 2px;
  border-radius: 2px;
  background: var(--rule-strong);
  transition: background .16s ease, height .16s ease, top .16s ease;
}
.wt-tick:hover::before { background: var(--ink-3); }
.wt-tick.is-on::before {
  background: var(--tint-ink);
  height: 4px;
  top: 5px;
}

.wt-count {
  flex: none;
  font-size: var(--t-xs);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.wt-count b { color: var(--ink); font-weight: 600; }
.wt-count i { font-style: normal; }

.wt-cap {
  margin-top: 14px;
  min-height: 3.4em;
  max-width: 72ch;
}
.wt-chapter {
  display: block;
  color: var(--tint-ink);
  margin-bottom: 5px;
}
.wt-text { display: block; margin-top: 0; }

@media (max-width: 560px) {
  .wt-ticks { display: none; }
  .wt-cap { min-height: 5em; }
}

/* --------------------------------------------------------------------------
   User flows
   -------------------------------------------------------------------------- */

.flows {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: var(--r-m);
  padding: clamp(20px, 3vw, 28px);
  display: grid;
  gap: 24px;
}
.flow-name {
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 11px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.flow-name .who { font-weight: 500; color: var(--ink-3); }
.flow-name .who::before { content: "\2014\00a0"; }

.flows ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
}
.flows ol li {
  display: inline-flex;
  align-items: center;
  font-size: var(--t-xs);
  line-height: 1.35;
  color: var(--ink-2);
  background: var(--paper-sunk);
  border: 1px solid transparent;
  border-radius: 7px;
  padding: 6px 11px;
}
.flows ol li::after {
  content: "→";
  margin-left: 11px;
  margin-right: -4px;
  color: var(--ink-4);
}
.flows ol li:last-child::after { content: none; }
.flows ol li.terminal {
  background: color-mix(in srgb, var(--tint) 72%, var(--paper));
  color: color-mix(in srgb, var(--tint-ink) 84%, var(--ink));
  font-weight: 500;
}
.flows ol li.gap {
  background: var(--accent-soft);
  color: #A33520;
  font-weight: 500;
}
.flows ol li.gap::before {
  content: "!";
  display: grid;
  place-items: center;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: var(--t-label);
  font-weight: 600;
  line-height: 1;
  margin-right: 7px;
}

/* --------------------------------------------------------------------------
   KPIs
   -------------------------------------------------------------------------- */

.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(196px, 1fr));
  gap: 14px;
}
.kpi {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: var(--r-m);
  padding: 18px 19px 17px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.kpi b {
  font-size: var(--t-lg);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.05;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.kpi p {
  margin: 0;
  font-size: var(--t-sm);
  line-height: 1.45;
  color: var(--ink-2);
  max-width: none;
  flex: 1;
}

/* Provenance chip — how much this number can be trusted. */
.chip {
  align-self: flex-start;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  letter-spacing: 0.1em;
}
.chip[data-kind="measured"] { background: var(--measured-bg); color: var(--measured-ink); }
.chip[data-kind="target"]   { background: var(--target-bg);   color: var(--target-ink); }
.chip[data-kind="proposed"] { background: var(--proposed-bg); color: var(--proposed-ink); }
.chip[data-kind="open"]     { background: var(--open-bg);     color: var(--open-ink); }

/* --------------------------------------------------------------------------
   Data table
   -------------------------------------------------------------------------- */

.data-scroll { overflow-x: auto; margin-inline: -4px; padding-inline: 4px; }
table.data {
  width: 100%;
  min-width: 520px;
  border-collapse: collapse;
  font-size: var(--t-sm);
}
table.data caption {
  text-align: left;
  font-size: var(--t-xs);
  color: var(--ink-3);
  padding-bottom: 12px;
}
.data th, .data td {
  text-align: left;
  padding: 11px 14px 11px 0;
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
  color: var(--ink-2);
}
.data th {
  color: var(--ink-4);
  border-bottom-color: var(--rule-strong);
}
.data td b { color: var(--ink); font-weight: 600; }
.data tr:last-child td { border-bottom-color: var(--rule-strong); }
.data .flag { color: var(--accent); font-weight: 600; }

/* --------------------------------------------------------------------------
   About, Approach, Contact
   -------------------------------------------------------------------------- */

.band {
  padding: clamp(72px, 9vw, 112px) 0;
  border-top: 1px solid var(--rule);
  scroll-margin-top: 78px;
}

.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 68px);
  max-width: 980px;
  margin-inline: auto;
  align-items: start;
}

.about-grid > div p {
  margin: 0 0 18px;
  color: var(--ink-2);
}
.about-grid > div p:last-child { margin-bottom: 0; }
.about-grid strong { color: var(--ink); font-weight: 600; }

.about-grid dl {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 18px;
  align-items: baseline;
  font-size: var(--t-sm);
}
.about-grid dt {
  color: var(--ink-4);
  padding-top: 12px;
  white-space: nowrap;
  border-top: 1px solid var(--rule);
}
.about-grid dd {
  margin: 0;
  padding-top: 10px;
  color: var(--ink-2);
  line-height: 1.5;
  border-top: 1px solid var(--rule);
}
.about-grid dt:first-of-type,
.about-grid dd:first-of-type { border-top: 0; padding-top: 0; }

@media (max-width: 820px) {
  .about-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 480px) {
  .about-grid dl { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .about-grid dt { padding-top: 14px; }
  .about-grid dd { border-top: 0; padding-top: 2px; }
}

.section-head {
  text-align: center;
  max-width: 54ch;
  margin: 0 auto clamp(38px, 5vw, 56px);
}
.section-head h2 {
  margin: 0 0 12px;
  font-size: var(--t-xl);
  font-weight: 600;
  letter-spacing: -0.028em;
  line-height: 1.15;
}
.section-head p {
  margin: 0;
  color: var(--ink-2);
  font-size: var(--t-md);
}

.principles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(238px, 1fr));
  gap: clamp(24px, 3.4vw, 40px);
  max-width: 980px;
  margin-inline: auto;
}
.principle .n {
  display: block;
  font-size: var(--t-lg);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--accent);
  margin-bottom: 12px;
  font-variant-numeric: tabular-nums;
}
.principle h3 {
  margin: 0 0 8px;
  font-size: var(--t-base);
  font-weight: 600;
  letter-spacing: -0.015em;
}
.principle p {
  margin: 0;
  font-size: var(--t-sm);
  color: var(--ink-2);
  line-height: 1.6;
}

.contact {
  padding-bottom: clamp(56px, 7vw, 84px);
  text-align: center;
}
/* h1 as well as h2: 404.html reuses this closing treatment, and a page with no
   other heading has to carry its <h1> here. */
.contact h1,
.contact h2 {
  margin: 0 0 16px;
  font-size: var(--t-2xl);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.12;
}
.contact p {
  margin: 0 auto 30px;
  max-width: 50ch;
  color: var(--ink-2);
  font-size: var(--t-md);
}

.social {
  display: flex;
  justify-content: center;
  gap: 12px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.social a {
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  border: 1px solid var(--rule);
  border-radius: 50%;
  color: var(--ink-2);
  background: var(--paper-raised);
  transition: color .2s ease, border-color .2s ease, transform .2s ease;
}
.social a:hover {
  color: var(--accent);
  border-color: var(--accent);
  transform: translateY(-2px);
}
.social svg { width: 17px; height: 17px; }

/* --------------------------------------------------------------------------
   Prev / next pager
   -------------------------------------------------------------------------- */

.pager {
  border-top: 1px solid var(--rule);
  padding: 38px 0 46px;
}
.pager .wrap {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px;
}
.pager a {
  display: flex;
  flex-direction: column;
  gap: 5px;
  max-width: 46%;
  text-decoration: none;
  color: var(--ink);
}
.pager a.next { text-align: right; align-items: flex-end; }
.pager small { color: var(--ink-4); }
.pager b {
  font-size: var(--t-base);
  font-weight: 600;
  letter-spacing: -0.018em;
  line-height: 1.3;
  transition: color .18s ease;
}
.pager a:hover b { color: var(--accent); }

@media (max-width: 560px) {
  .pager .wrap { flex-direction: column; gap: 22px; }
  .pager a, .pager a.next {
    max-width: none;
    text-align: left;
    align-items: flex-start;
  }
}

.colophon {
  border-top: 1px solid var(--rule);
  padding: 26px 0 34px;
  font-size: var(--t-xs);
  color: var(--ink-4);
}
.colophon .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  justify-content: space-between;
  align-items: center;
}
.colophon a { color: var(--ink-3); text-decoration: none; }
.colophon a:hover { color: var(--accent); }

/* --------------------------------------------------------------------------
   Motion
   -------------------------------------------------------------------------- */

@keyframes rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes wave {
  0%, 60%, 100% { transform: rotate(0deg); }
  15%           { transform: rotate(15deg); }
  30%           { transform: rotate(-9deg); }
  45%           { transform: rotate(12deg); }
}

.hero > .wrap > * {
  animation: rise .72s cubic-bezier(.2,.7,.3,1) both;
}
.hero > .wrap > *:nth-child(1) { animation-delay: .04s; }
.hero > .wrap > *:nth-child(2) { animation-delay: .13s; }
.hero > .wrap > *:nth-child(3) { animation-delay: .20s; }
.hero > .wrap > *:nth-child(4) { animation-delay: .27s; }
.hero > .wrap > *:nth-child(5) { animation-delay: .34s; }

.hero h1 .wave { animation: wave 2.4s ease-in-out .9s 2; }

/* Scoped to .js (set by an inline head script, and withdrawn again if
   portfolio.js never arrives) so the page is never blank without JS. */
.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity .7s cubic-bezier(.2,.7,.3,1),
              transform .7s cubic-bezier(.2,.7,.3,1);
}
.js .reveal.is-in { opacity: 1; transform: none; }
.js .index-grid .tile.reveal:nth-child(2n) { transition-delay: .08s; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .js .reveal { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .masthead nav { gap: 18px; }
}

@media (max-width: 720px) {
  :root { --gutter: 20px; }

  .index-grid { grid-template-columns: minmax(0, 1fr); gap: 34px; }

  .masthead nav a[data-optional] { display: none; }

  /* One fact per line — drop the inline separators so none dangle. */
  .factline { flex-direction: column; align-items: flex-start; gap: 5px; }
  .factline > span:not(:last-child)::after { display: none; }

  .pull { padding-left: 16px; }

  .flows ol li { padding: 5px 9px; }
  .flows ol li::after { margin-left: 8px; }

  .list--num > li { padding-left: 34px; }
}

/* Once the steps stack one-per-line, a rightward arrow reads as dangling.
   Turn the chain vertical and point the arrows down instead. */
@media (max-width: 560px) {
  .flows ol { flex-direction: column; align-items: flex-start; gap: 0; }
  .flows ol li { position: relative; margin-bottom: 20px; }
  .flows ol li:last-child { margin-bottom: 0; }
  .flows ol li::after {
    content: "↓";
    position: absolute;
    left: 13px;
    bottom: -17px;
    margin: 0;
    line-height: 1;
  }
}

@media (max-width: 480px) {
  .kpis { grid-template-columns: minmax(0, 1fr); }
}

@media print {
  .masthead, .social, .reveal { position: static; }
  .reveal { opacity: 1; transform: none; }
  .project { break-inside: avoid; }
}
