/* ==========================================================================
   Andrew Ashton — Folio 2026
   --------------------------------------------------------------------------
   Grid system (from Figma):
     Desktop 1440  · margin 48 · gutter 24 · 12 columns
     Tablet   834  · margin 64 · gutter 20 ·  8 columns
     Mobile   402  · margin 32 · gutter 12 ·  6 columns
   Breakpoints used:
     desktop ≥ 1100px · tablet 621–1099px · mobile ≤ 620px
   ========================================================================== */

:root {
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
          "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* Colour */
  --ink:      #444345;   /* primary text / dark surfaces */
  --body:     #5F5F5F;   /* secondary text */
  --accent:   #FF4D37;   /* brand accent + rollovers */
  --line:     #D1D1D1;   /* keylines, chip borders, title rollover */
  --chip-hl:  #D900FF;   /* highlighted "AI Innovation" chip */
  --bg:       #FBFBFB;   /* page background */
  --dot:      #D9D9D9;   /* separator dots in "Selected work" */
  --ghost:    rgba(255, 255, 255, .5); /* unlinked items in the overlay menu */

  /* Grid */
  --margin: 48px;
  --gutter: 24px;
  --content-max: 1344px; /* 1440 − 2 × 48 */

  /* Motion */
  --ease-out: cubic-bezier(.22, .61, .36, 1);
}

/* ---------- Reset ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--font);
  font-weight: 400;
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* No text orphans anywhere: never leave a single word alone on the last
     line of a paragraph. Inherited, so it covers every block on the site. */
  text-wrap: pretty;
  /* Sticky footer: the footer always sits at the very bottom of the page */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
body > main { flex: 1; }
img { display: block; max-width: 100%; height: auto; }
a { text-decoration: none; color: inherit; }
button { font: inherit; border: 0; background: none; cursor: pointer; }

/* ---------- Layout helpers --------------------------------------------- */
.container {
  width: min(var(--content-max), 100% - 2 * var(--margin));
  margin-inline: auto;
}

/* ---------- Buttons ----------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: 10px 20px;
  border-radius: 30px;
  background: var(--accent);
  color: #fff;
  font-size: 16px;
  font-weight: 500;
  box-shadow: inset 0 0 0 1px var(--accent);
  transition: background .25s var(--ease-out), color .25s var(--ease-out);
}
.btn:hover,
.btn:focus-visible {
  background: var(--bg);
  color: var(--accent);
}

/* ==========================================================================
   Header (desktop)
   ========================================================================== */
.site-header {
  padding-top: 40px;
}
.site-header .container {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
}
.logo img { width: 72px; height: 77px; }

.header-right {
  display: flex;
  align-items: center;   /* nav text sits on the same line as the CTA text */
  gap: 24px;
  padding-top: 19px;
}

.site-nav { position: relative; }
.site-nav ul {
  list-style: none;
  display: flex;
  gap: 24px;
}
.site-nav a {
  font-size: 16px;
  font-weight: 500;
  color: var(--ink);
  transition: color .2s var(--ease-out);
}
.site-nav a:hover,
.site-nav a:focus-visible { color: var(--accent); }

/* Keyline highlighter — slides gracefully to the active item (JS sets
   left/width via transform). */
.nav-keyline {
  position: absolute;
  bottom: -16px;
  left: 0;
  height: 2px;
  width: 44px;
  background: var(--accent);
  transform-origin: left;
  transition: transform .55s cubic-bezier(.65, 0, .35, 1),
              width .55s cubic-bezier(.65, 0, .35, 1);
}

/* Hamburger — hidden on desktop */
.menu-toggle { display: none; }

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  margin-top: 132px; /* 249 from page top − header (40 + 77) */
  text-align: center;
}
.hero-inner { width: min(1116px, 100% - 2 * var(--margin)); margin-inline: auto; }
.hero h1 {
  font-size: 81px;
  line-height: 92px;
  font-weight: 700;
  text-wrap: balance;
}
.hero h1 .accent { color: var(--accent); }
.hero .hero-sub {
  margin-top: 20px;
  font-size: 32px;
  line-height: 42px;
  color: var(--ink);
}
.hero .hero-sub strong { font-weight: 600; } /* company names slightly bolder */

/* ==========================================================================
   Selected work strap
   ========================================================================== */
.selected-work { margin-top: 124px; }
.selected-work .strap {
  display: flex;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  column-gap: 40px;
  row-gap: 12px;
  font-size: 32px;
}
.selected-work .strap-label { font-weight: 500; }
.selected-work .strap-label .dash { font-weight: 400; }
.selected-work .strap-items {
  display: flex;
  align-items: center;
  column-gap: 20px;
  font-weight: 300;
}
.selected-work .sep {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--dot);
  flex: none;
}

/* ==========================================================================
   Case studies
   --------------------------------------------------------------------------
   HOW TO ADD A NEW PRODUCT:
   duplicate one <article class="case-study"> block in home.html, swap the
   image, title, description and skill chips. Everything below styles all
   case studies alike. Use class "cs-breakout" on the media wrapper if the
   artwork should spill outside the 8-column image area (like the ION phone).
   ========================================================================== */
.case-study { margin-top: 124px; }

.cs-media {
  width: 66.07%;             /* 888 / 1344 — 8 of 12 columns */
  margin-inline: auto;
  position: relative;
}
.cs-media a { display: block; }

/* Soft floor shadow under iPad shots */
.cs-media.has-shadow::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 13px;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(0,0,0,.28), rgba(0,0,0,0) 70%);
  filter: blur(3px);
  z-index: -1;
}

/* Artwork that spills wider than the image column (ION phone).
   The composite's gradient card is exactly 888×458 at (256,146) within the
   1146×877 image, so these offsets pin the card to the 8-column slot. */
.cs-breakout img {
  width: 129.05%;            /* 1146 / 888 */
  max-width: none;
  margin-left: -28.83%;      /* -256 / 888 */
  margin-top: -3.38%;        /* card top stays where the old artwork's was */
  margin-bottom: -7.59%;     /* phone overlaps the gap under it in Figma */
}

.cs-text {
  width: 66.07%;
  margin-inline: auto;
}
.cs-title {
  display: inline-block;
  margin-top: 32px;
  font-size: 32px;
  font-weight: 500;
  color: var(--ink);
  transition: color .2s var(--ease-out);
}
a.cs-title:hover,
a.cs-title:focus-visible { color: var(--line); }
.cs-desc {
  margin-top: 12px;
  font-size: 16px;
  line-height: 24px;
  color: var(--body);
}
.cs-skills-label {
  margin-top: 16px;
  font-size: 16px;
  line-height: 24px;
  font-weight: 600;      /* matches every other sub-heading */
  color: var(--ink);
}
.cs-chips {
  margin-top: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.chip {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 10px 16px;
  border-radius: 30px;
  background: #fff;
  border: 1px solid var(--line);
  font-size: 16px;
  color: var(--body);
  white-space: nowrap;
}
/* Highlighted chip — gradient keyline (Figma: D900FF → 1C1EFF 52% → 00C8FF) */
.chip.chip-highlight {
  border: 2px solid transparent;
  background:
    linear-gradient(#fff, #fff) padding-box,
    linear-gradient(90deg, #D900FF 0%, #1C1EFF 52%, #00C8FF 100%) border-box;
}

/* ==========================================================================
   About
   ========================================================================== */
.about { margin-top: 124px; text-align: center; }
.about-figure {
  position: relative;
  width: min(598px, 100%);
  margin-inline: auto;
}
.about-figure::after {         /* fade the photo into the background */
  content: "";
  position: absolute;
  left: -4%;
  right: -4%;
  bottom: 0;
  height: 38%;
  background: linear-gradient(to bottom, rgba(251,251,251,0) 4.5%, var(--bg) 57%);
}
.about h2 {
  position: relative;
  margin-top: -79px;           /* headline rides up over the faded photo */
  font-size: 67px;
  line-height: 82px;
  font-weight: 700;
}
.about h2 .accent { color: var(--accent); }
.about-body {
  width: min(1116px, 100%);
  margin: 12px auto 0;
  font-size: 24px;
  line-height: 32px;
  color: var(--body);
}
.about-body p + p { margin-top: 32px; }
.about .btn { margin-top: 38px; min-width: 204px; }

/* ==========================================================================
   Recommendations — auto-rotating carousel
   ========================================================================== */
.recommendations { margin-top: 80px; }
.recommendations h2 {
  text-align: center;
  font-size: 32px;
  font-weight: 500;
}
.carousel {
  position: relative;
  width: 66.07%;
  margin: 51px auto 0;
}
.carousel-track {
  display: grid;               /* stack slides on top of each other       */
}                              /* JS fixes its height to the tallest slide,
                                  so the dots and footer never move       */
.slide {
  grid-area: 1 / 1;
  align-self: start;
  opacity: 0;
  visibility: hidden;
  transition: opacity .8s var(--ease-out), visibility 0s linear .8s;
}
.slide.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity .8s var(--ease-out);
}
.slide blockquote {
  font-size: 16px;
  line-height: 22px;
  color: var(--body);
}
.slide blockquote p + p { margin-top: 22px; }
.slide-footer { margin-top: 24px; }
.slide-footer cite {
  font-style: normal;
  font-size: 16px;
  line-height: 20px;
  color: var(--body);
}
.slide-footer cite .name {
  display: block;
  font-weight: 600;
  color: var(--ink);
}
.carousel-dots {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin-top: 32px;   /* 32px from the end of the text on every breakpoint */
}
.carousel-dots button {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--ink);
  padding: 0;
  transition: background .3s var(--ease-out), transform .3s var(--ease-out);
}
.carousel-dots button:hover { transform: scale(1.25); }
.carousel-dots button.is-active { background: var(--accent); }

/* ==========================================================================
   About page
   ========================================================================== */
.about-hero { margin-top: 132px; text-align: center; }
.about-hero h1 {
  position: relative;
  margin-top: -79px;           /* headline rides up over the faded photo */
  font-size: 66px;
  line-height: 1.2;
  font-weight: 700;
  width: min(1148px, 100%);
  margin-inline: auto;
  text-wrap: balance;
}
.about-intro {
  width: min(1116px, 100%);
  margin: 20px auto 0;
  font-size: 24px;
  line-height: 32px;
  color: var(--body);
  text-align: center;
}
.about-intro p + p { margin-top: 32px; }

/* "Whilst at …" sections */
.whilst { text-align: center; }
.whilst h2 {
  margin-top: 56px;
  font-size: 32px;
  line-height: 32px;
  font-weight: 500;
  color: var(--ink);
}
.whilst p {
  width: min(1116px, 100%);
  margin: 24px auto 0;
  font-size: 24px;
  line-height: 32px;
  color: var(--body);
}
.whilst p strong { font-weight: 600; }

.about-closing {
  width: min(1116px, 100%);
  margin: 56px auto 0;
  font-size: 24px;
  line-height: 32px;
  color: var(--body);
  text-align: center;
}
.about-closing p + p { margin-top: 32px; }
.about-closing strong { font-weight: 600; }
.about-cta { text-align: center; }
.about-cta .btn { margin-top: 56px; min-width: 204px; }

/* My previous experience */
.experience { margin-top: 124px; text-align: center; }
.experience h2 {
  font-size: 32px;
  font-weight: 500;
  color: var(--ink);
}
.logo-grid {
  width: min(1116px, 100%);
  margin: 56px auto 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}
.logo-card {
  background: #fff;
  border-radius: 2px;
  height: 124px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Logo sizes relative to their card, straight from the Figma desktop grid
   (356px cards) — generous whitespace around each mark, and because they are
   percentages they scale down with the cards on tablet and mobile. */
.logo-card img { height: auto; }
.logo-card .logo-gs       { width: 30%; }
.logo-card .logo-hsbc     { width: 25%; }
.logo-card .logo-nokia    { width: 38%; }
.logo-card .logo-e3       { width: 26%; }
.logo-card .logo-lseg     { width: 30%; }
.logo-card .logo-vodafone { width: 12.5%; }

/* Page-specific rhythm */
body.page-about .recommendations { margin-top: 124px; }

/* ==========================================================================
   Work page
   --------------------------------------------------------------------------
   Each project graphic is a composite export from Figma with built-in
   transparency, so devices "break out" of the background card exactly as
   designed. Two media variants set the card height the caption aligns to:
     (default)          — 448-tall background (ION phone, Smart Alerts, REIT)
     .work-media--short — 388-tall background (LSEG iPad, X-Trade, FX Portal)
   ========================================================================== */
.work-hero { margin-top: 132px; text-align: center; }
.work-hero h1 {
  width: min(1116px, 100%);
  margin-inline: auto;
  font-size: 81px;
  line-height: 92px;
  font-weight: 700;
  text-wrap: balance;
}
.work-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 24px;
  row-gap: 124px;
  margin-top: 104px;
}
.work-media {
  position: relative;
  aspect-ratio: 660 / 448;
}
.work-media--short { aspect-ratio: 660 / 388; }
.work-media a {          /* the anchor covers the whole card area */
  display: block;
  position: absolute;
  inset: 0;
  z-index: 1;
}
.work-media img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: auto;
  max-width: none;
  z-index: 1;
}
/* Phones that rise above their background card. The offsets are percentages
   of the card HEIGHT (109/448 and 91/448 from Figma), which lines the
   coloured backgrounds inside these composites up exactly with the top of
   the neighbouring card in the same row. */
.work-media--rise-16 img { top: -24.33%; }
.work-media--rise-14 img { top: -20.31%; }

.work-caption { position: relative; z-index: 2; }
.work-media + .work-caption { margin-top: 20px; }
.work-media--short + .work-caption { margin-top: 80px; } /* room for overflow */

.work-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.work-title {
  font-size: 24px;
  font-weight: 500;
  color: var(--ink);
  transition: color .2s var(--ease-out);
}
a.work-title:hover,
a.work-title:focus-visible { color: var(--line); }
.work-role {
  margin-top: 4px;
  font-size: 20px;
  line-height: 32px;
  color: var(--body);
}
/* Figma: the third row sits 25px lower to give the rising REIT phone room */
.work-grid .work-item:nth-child(n+5) { padding-top: 25px; }

.chip-soon {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 10px 20px;
  border: 1px solid var(--body);
  border-radius: 30px;
  background: transparent;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  flex: none;
}
body.page-work .site-footer { margin-top: 124px; }

/* ==========================================================================
   Case-study pages
   ========================================================================== */
.csp-hero { margin-top: 132px; }
.csp-hero h1 {
  font-size: 81px;
  line-height: 1.19;
  font-weight: 700;
  /* Fill each line as far as possible (no early balanced wrapping);
     `pretty` is inherited from body and still prevents orphans. */
  text-wrap: pretty;
}
.csp-role {
  font-size: 32px;
  line-height: 42px;
  color: var(--body);
}
.csp-hero-media {
  position: relative;
  margin-top: 100px;
}
.csp-hero-media > img { width: 100%; border-radius: 4px; }

/* "My Impact" panel — floats over the hero image on desktop */
.impact-panel {
  position: absolute;
  top: -45px;
  right: 88px;
  width: 372px;
  background: #fff;
  border-radius: 2px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .12);
  padding: 30px 32px 32px;
  z-index: 2;
}
.impact-panel::before {          /* the orange attention bar */
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 6px;
  background: var(--accent);
  border-radius: 2px 2px 0 0;
}
.impact-panel h2 {
  font-size: 24px;
  font-weight: 500;
  color: var(--ink);
}
/* Panel sub-headings — same treatment as every other sub-heading on the
   site: Semi-Bold in the primary ink, text running directly underneath. */
.impact-panel h3 {
  margin-top: 24px;
  font-size: 16px;
  line-height: 24px;
  font-weight: 600;
  color: var(--ink);
}
.impact-panel h2 + h3 { margin-top: 20px; }
.impact-panel p {
  margin-top: 4px;
  font-size: 16px;
  line-height: 20px;
  color: var(--body);
}
.impact-panel h3 + p { margin-top: 0; }

/* Text sections — on desktop the text sits on the same narrower column as
   the About page (936px), aligned with the images below it. */
.csp-section { margin-top: 56px; }
.csp-section .container > * {
  width: 69.64%;             /* 936 / 1344 — the About-page text column */
  margin-left: auto;
  margin-right: auto;
}
.csp-section h2 {
  font-size: 32px;
  line-height: normal;
  font-weight: 500;
  color: var(--ink);
}
.csp-body { margin-top: 12px; }
.csp-body p {
  font-size: 16px;
  line-height: 24px;
  color: var(--body);
}
.csp-body p + p { margin-top: 24px; }
/* Sub-headings inside a section ("Users", "My role", "Validating decisions"…).
   Semi-Bold in the primary ink colour, with their text running directly
   underneath — no gap, exactly as the Figma text blocks read. */
.csp-body .csp-subhead {
  margin-top: 24px;
  font-weight: 600;
  color: var(--ink);
}
.csp-body .csp-subhead + p,
.csp-body .csp-subhead + ul { margin-top: 0; }
/* Bullets run straight on from their intro line ("…included:"), then the
   following paragraph gets the normal paragraph gap. */
.csp-body ul {
  margin-top: 0;
  padding-left: 24px;
}
.csp-body li {
  font-size: 16px;
  line-height: 24px;
  color: var(--body);
}
.csp-body ul + p { margin-top: 24px; }
.csp-line {
  border: 0;
  border-top: 1px solid var(--line);
  margin-top: 56px;
}

/* Figures */
.csp-fig {
  width: 69.64%;               /* 936 / 1344 — aligned with the text column */
  margin: 56px auto 0;
}
.csp-fig--wide {
  width: 72.84%;               /* 979 / 1344 — panel overlaps to the right */
  margin-left: 15.18%;         /* left edge stays aligned with the others */
  margin-right: auto;
}
.csp-fig img { width: 100%; }

/* ION case study
   --------------------------------------------------------------------------
   These composites carry transparent padding around the phones (the hero
   phone breaks out above its card; the phone spreads have empty space top
   and bottom). The negative margins below cancel exactly that padding, so
   the VISIBLE edges sit on the same 56px rhythm as every other figure.
   Percentages resolve against the container width, so they scale. */
.csp-hero-media--ion {
  margin-top: calc(101px - 9.08%);  /* card top lands 101px under the hero text */
  margin-bottom: -4.31%;            /* cancels the empty strip under the card */
}
@media (min-width: 1100px) {
  /* Anchor the panel to the CARD inside the composite (card top = 15.174%
     of the image height), 45px above it — identical to the other studies,
     and it scales with every desktop width. */
  .csp-hero-media--ion .impact-panel { top: calc(15.174% - 45px); }
}
/* Bottom margins cancel the transparent padding down to the phones' solid
   shadow edge, so headings sit 56px under the artwork like everywhere else. */
.csp-fig--phones1 {
  width: calc(91.37% + var(--margin));
  margin: calc(56px - 5.51%) calc(-1 * var(--margin)) -16.49% 8.63%;
}
.csp-fig--phones2 {
  width: calc(93.15% + var(--margin));
  margin: calc(56px - 4.65%) calc(-1 * var(--margin)) -16.47% 6.85%;
}

/* Next case study */
.csp-next {
  width: 69.64%;
  margin: 41px auto 0;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 40px;
}
.csp-next-label {
  display: inline-block;
  border-left: 4px solid var(--accent);
  padding-left: 16px;
  font-size: 32px;
  line-height: 40px;
  font-weight: 500;
  color: var(--ink);
  transition: color .2s var(--ease-out);
}
a:hover .csp-next-label,
a:focus-visible .csp-next-label { color: var(--line); }
.csp-next-card { width: 51.3%; flex: none; }   /* 480 / 936 */
.csp-next-card img { width: 100%; border-radius: 4px; }
.csp-next-card .next-title {
  display: block;
  margin-top: 12px;
  font-size: 16px;
  line-height: 22px;
  font-weight: 500;
  color: var(--ink);
  transition: color .2s var(--ease-out);
}
.csp-next-card:hover .next-title,
.csp-next-card:focus-visible .next-title { color: var(--line); }
.csp-next-card .next-company {
  display: block;
  font-size: 16px;
  line-height: 22px;
  color: var(--body);
}
body.page-casestudy .site-footer { margin-top: 74px; }

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer { margin-top: 72px; }
.site-footer .bar {
  height: 64px;
  background: var(--ink);
  display: flex;
  align-items: center;
}
.site-footer p {
  margin-left: 65px;
  font-size: 16px;
  font-weight: 500;
  color: #fff;
}
.site-footer .strip { height: 4px; background: #000; }

/* ==========================================================================
   Overlay menu (tablet + mobile)
   ========================================================================== */
.menu-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: var(--ink);
  display: flex;
  flex-direction: column;
  opacity: 0;
  visibility: hidden;
  transition: opacity .35s var(--ease-out), visibility 0s linear .35s;
}
.menu-overlay.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity .35s var(--ease-out);
}
body.menu-open { overflow: hidden; }

.menu-overlay .menu-inner {
  padding: 131px 64px 0;      /* tablet: items start 131 from top, margin 64 */
  overflow-y: auto;
  flex: 1;
}
.menu-overlay ul { list-style: none; }
.menu-overlay li { line-height: 40px; margin-bottom: 4px; }
.menu-overlay li.menu-gap { height: 52px; }
.menu-overlay a,
.menu-overlay .menu-ghost {
  font-size: 20px;
  font-weight: 500;
  color: #fff;
}
.menu-overlay a { transition: color .2s var(--ease-out); }
.menu-overlay a:hover,
.menu-overlay a:focus-visible { color: var(--accent); }
.menu-overlay .menu-ghost { color: var(--ghost); }  /* headings, not links */
.menu-overlay .strip { height: 4px; background: #000; }

/* Overlay logo (white) sits exactly where the page logo sits */
.menu-overlay .logo { position: absolute; top: 32px; left: 64px; }
.menu-overlay .logo img { width: 48px; height: 51px; }

/* ==========================================================================
   Hamburger ⇄ close morph
   --------------------------------------------------------------------------
   Recreates the custom Figma mark: middle line full width, top and bottom
   lines shorter and right-aligned. Morphs into the X with easing.
   ========================================================================== */
.menu-toggle {
  position: relative;
  z-index: 100;              /* stays above the overlay */
  width: 35px;
  height: 19px;
  flex: none;
}
.menu-toggle span {
  position: absolute;
  right: 0;
  height: 3px;
  border-radius: 3px;
  background: var(--ink);
  transition: transform .45s var(--ease-out), width .45s var(--ease-out),
              background .3s var(--ease-out), opacity .3s var(--ease-out);
}
.menu-toggle span:nth-child(1) { top: 0;    width: 24px; }
.menu-toggle span:nth-child(2) { top: 8px;  width: 32px; }
.menu-toggle span:nth-child(3) { top: 16px; width: 24px; }

.menu-toggle.is-open span { background: #F2F2F2; }
.menu-toggle.is-open span:nth-child(1) {
  width: 22px;
  transform: translate(-4px, 8px) rotate(45deg);
}
.menu-toggle.is-open span:nth-child(2) {
  opacity: 0;
  transform: scaleX(.2);
}
.menu-toggle.is-open span:nth-child(3) {
  width: 22px;
  transform: translate(-4px, -8px) rotate(-45deg);
}

/* ==========================================================================
   Scroll-in animation — slight but effective
   ========================================================================== */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity .8s var(--ease-out), transform .8s var(--ease-out);
  transition-delay: var(--reveal-delay, 0s);
}
.reveal.is-in {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .slide, .menu-overlay, .nav-keyline, .menu-toggle span { transition: none; }
}

/* ==========================================================================
   Password page
   ========================================================================== */
body.password-page {
  background: var(--ink);
  min-height: 100vh;
}
.password-wrap {
  width: 344px;
  margin-inline: auto;
  padding-top: 256px;        /* logo, text, field and button start 256px down */
}
.password-wrap .logo img { width: 72px; height: 77px; }
.password-wrap label {
  display: block;
  margin-top: 56px;
  font-size: 16px;
  font-weight: 500;
  color: #F2F2F2;
}
.password-wrap input {
  display: block;
  width: 100%;
  height: 32px;
  margin-top: 4px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: transparent;
  color: #F2F2F2;
  font-family: var(--font);
  font-size: 16px;
  outline: none;
  transition: border-color .2s var(--ease-out);
}
.password-wrap input:focus { border-color: #F2F2F2; }
.password-wrap.is-error input { border-color: var(--accent); }
.password-wrap .btn {
  width: 100%;
  margin-top: 24px;
}
.password-wrap.is-error .form-col { animation: shake .4s var(--ease-out); }
/* On the dark password page the CTA inverts to the page colour instead */
.password-page .btn:hover,
.password-page .btn:focus-visible {
  background: var(--ink);
  box-shadow: inset 0 0 0 1px var(--accent);
  color: #fff;
}
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-6px); }
  55% { transform: translateX(5px); }
  80% { transform: translateX(-3px); }
}

/* ==========================================================================
   Case-study placeholder pages
   ========================================================================== */
.cs-page { margin-top: 132px; text-align: center; }
.cs-page h1 { font-size: 48px; font-weight: 700; }
.cs-page p { margin-top: 20px; font-size: 20px; color: var(--body); }
.cs-page .btn { margin-top: 40px; }

/* ==========================================================================
   TABLET — 621px … 1099px  (Figma 834: margin 64 · gutter 20 · 8 cols)
   ========================================================================== */
@media (max-width: 1099px) {
  :root { --margin: 64px; --gutter: 20px; --content-max: 706px; }

  /* Header */
  .site-header { padding-top: 32px; }
  .logo img { width: 48px; height: 51px; }
  .site-nav, .header-right .btn { display: none; }
  .header-right { padding-top: 10px; }
  .menu-toggle { display: block; }

  /* Hero */
  .hero { margin-top: 72px; }        /* 155 − (32 + 51) */
  .hero h1 { font-size: 48px; line-height: normal; }
  .hero .hero-sub { margin-top: 20px; font-size: 24px; line-height: 32px; }

  /* Selected work */
  .selected-work { margin-top: 72px; }
  .selected-work .strap { font-size: 20px; column-gap: 28px; }
  .selected-work .strap-items { column-gap: 12px; font-weight: 400; }
  .selected-work .sep { width: 8px; height: 8px; }

  /* Case studies */
  .case-study { margin-top: 96px; }
  .case-study:first-of-type { margin-top: 72px; } /* strap → first project */
  .cs-media, .cs-text { width: 80%; }         /* 565 / 706 */
  .cs-title { margin-top: 24px; font-size: 20px; }
  .cs-desc { margin-top: 12px; }
  .cs-skills-label { margin-top: 16px; }
  .cs-chips { gap: 12px 8px; }
  .cs-breakout img { margin-bottom: -10.69%; }

  /* About */
  .about { margin-top: 72px; }
  .about-figure { width: min(402px, 100%); }
  .about h2 { margin-top: -74px; font-size: 33px; line-height: 39px; }
  .about-body { width: min(562px, 100%); font-size: 16px; line-height: 22px; }
  .about-body p + p { margin-top: 22px; }
  .about .btn { margin-top: 24px; height: 44px; }

  /* Recommendations */
  .recommendations { margin-top: 68px; }
  .recommendations h2 { font-size: 24px; }
  .carousel { width: 74.2%; margin-top: 57px; }   /* 524 / 706 */

  /* Footer */
  .site-footer { margin-top: 80px; }

  /* Case-study pages */
  .csp-hero { margin-top: 72px; }
  .csp-hero h1 { font-size: 40px; }
  .csp-role { font-size: 24px; line-height: 32px; }
  .csp-hero-media { margin-top: 42px; }
  .impact-panel {
    /* Full-width card in flow directly under the hero image — stays
       position:relative so the orange bar anchors to the card itself,
       sitting after the image and before the text. */
    position: relative;
    top: 0;
    right: auto;
    width: 100%;
    margin-top: 0;
  }
  .csp-section .container > * { width: 100%; }
  .csp-section h2 { font-size: 24px; }
  .csp-fig, .csp-fig--wide { width: 100%; margin-top: 56px; margin-left: auto; }
  .csp-fig--phones1 { width: 100%; margin: calc(56px - 5.80%) auto -17.37%; }
  .csp-fig--phones2 { width: 100%; margin: calc(56px - 4.81%) auto -17.03%; }
  /* The panel drops into the flow here, so it — not the image box — is pulled
     up onto the visible card edge, sitting flush like the other two studies. */
  .csp-hero-media--ion { margin-top: calc(42px - 9.08%); margin-bottom: 0; }
  .csp-hero-media--ion .impact-panel { margin-top: -4.31%; }
  .csp-next { width: 100%; }
  .csp-next-label { font-size: 24px; line-height: 32px; }
  .csp-next-card { width: 51.4%; }   /* 363 / 706 */
  body.page-casestudy .site-footer { margin-top: 56px; }

  /* Work page */
  .work-hero { margin-top: 72px; }
  .work-hero h1 { width: min(564px, 100%); font-size: 40px; line-height: normal; }
  .work-grid {
    grid-template-columns: 1fr;
    row-gap: 72px;
    margin-top: 72px;
  }
  /* Single column: extra room only above the projects whose phones rise */
  .work-grid .work-item { padding-top: 0; }
  .work-grid .work-item:nth-child(2) { padding-top: 15px; }
  .work-grid .work-item:nth-child(5) { padding-top: 22px; }
  .work-media + .work-caption { margin-top: 20px; }
  .work-media--short + .work-caption { margin-top: 82px; } /* clears the iPad overflow */
  .work-title { font-size: 20px; }
  .work-role { font-size: 16px; line-height: 24px; }
  .chip-soon { height: 24px; padding: 4px 13px; font-size: 14px; }
  body.page-work .site-footer { margin-top: 72px; }

  /* About page */
  .about-hero { margin-top: 72px; }
  .about-hero h1 { margin-top: -74px; font-size: 33px; line-height: normal; width: min(564px, 100%); }
  .about-intro { width: min(562px, 100%); margin-top: 12px; font-size: 16px; line-height: 22px; }
  .about-intro p + p { margin-top: 22px; }
  .whilst h2 { margin-top: 40px; font-size: 24px; line-height: normal; }
  .whilst p { width: min(563px, 100%); margin-top: 12px; font-size: 16px; line-height: 22px; }
  .about-closing { width: min(563px, 100%); margin-top: 18px; font-size: 16px; line-height: 22px; }
  .about-closing p + p { margin-top: 22px; }
  .about-cta .btn { margin-top: 32px; height: 44px; }
  .experience { margin-top: 104px; }
  .experience h2 { font-size: 24px; }
  .logo-grid { width: min(564px, 100%); margin-top: 36px; gap: 16px; }
  .logo-card { height: 126px; }
  body.page-about .recommendations { margin-top: 104px; }
}

/* ==========================================================================
   MOBILE — ≤ 620px  (Figma 402: margin 32 · gutter 12 · 6 cols)
   ========================================================================== */
@media (max-width: 620px) {
  :root { --margin: 32px; --gutter: 12px; --content-max: 338px; }

  .menu-overlay .menu-inner { padding: 131px 32px 0; }
  .menu-overlay .logo { left: 32px; }

  /* Hero */
  .hero { margin-top: 56px; }        /* 139 − (32 + 51) */
  .hero h1 { font-size: 32px; line-height: 38px; }
  .hero .hero-sub { margin-top: 12px; font-size: 16px; line-height: 20px; }
  .hero .hero-sub strong { font-weight: 700; }

  /* Selected work — stacked */
  .selected-work { margin-top: 56px; }
  .selected-work .strap {
    flex-direction: column;
    align-items: center;
    row-gap: 16px;
    font-size: 16px;
  }
  .selected-work .strap-items {
    flex-direction: column;
    row-gap: 16px;
    font-weight: 400;
  }

  /* Case studies */
  .case-study { margin-top: 56px; }               /* project → project */
  .case-study:first-of-type { margin-top: 40px; } /* strap → first project */
  .cs-media, .cs-text { width: 100%; }
  .cs-title { margin-top: 16px; font-size: 20px; }
  .cs-desc { margin-top: 12px; line-height: 20px; }
  .cs-chips { gap: 8px; }

  /* ION full-bleed breakout */
  .cs-breakout {
    width: 100vw;
    margin-left: calc(50% - 50vw);
    overflow: hidden;
  }
  .cs-breakout img {
    width: 108.5%;
    margin-left: -24.2%;
    margin-top: -3%;
    margin-bottom: -3.49%;
  }

  /* About */
  .about { margin-top: 72px; }
  .about-figure { width: min(310px, 100%); }
  .about h2 { margin-top: -36px; font-size: 20px; line-height: 24px; }
  .about-body { margin-top: 12px; }
  .about .btn { margin-top: 32px; width: 100%; }

  /* Recommendations */
  .recommendations { margin-top: 56px; }
  .recommendations h2 { font-size: 20px; }
  .carousel { width: 100%; margin-top: 34px; }

  /* Footer */
  .site-footer { margin-top: 56px; }
  .site-footer p { margin-left: 32px; }

  /* Case-study pages */
  .csp-hero { margin-top: 57px; }
  .csp-hero h1 { font-size: 24px; line-height: 29px; }
  .csp-role { font-size: 16px; line-height: 20px; margin-top: 4px; }
  .csp-hero-media { margin-top: 56px; }
  .impact-panel { padding: 24px 24px 28px; }
  .csp-body p { line-height: 22px; }
  .csp-body p + p { margin-top: 22px; }
  .csp-body ul + p { margin-top: 22px; }
  .csp-body li { line-height: 22px; }
  .csp-hero-media--ion { margin-top: calc(56px - 9.08%); margin-bottom: 0; }
  .csp-next { flex-direction: column; margin-top: 38px; gap: 32px; }
  .csp-next-card { width: 100%; }

  /* Work page */
  .work-hero { margin-top: 57px; }
  .work-hero h1 { font-size: 24px; }
  .work-grid { row-gap: 72px; }
  /* A consistent 20px between the bottom of each graphic and its title —
     variants add their graphic's overflow below the card to the margin. */
  .work-media + .work-caption { margin-top: 20px; }
  .work-media--short + .work-caption { margin-top: 53px; }
  .work-media--rise-16 + .work-caption { margin-top: 51px; }
  .work-media--rise-14 + .work-caption { margin-top: 48px; }
  .work-item:nth-child(3) .work-caption { margin-top: 50px; } /* X-Trade composite is 6px shorter */
  /* Chip drops below the role on mobile: title → role → Coming Soon */
  .work-caption { display: flex; flex-direction: column; align-items: flex-start; }
  .work-title-row { display: contents; }
  .work-title { order: 1; line-height: 24px; }
  .work-role { order: 2; margin-top: 8px; }
  .chip-soon { order: 3; margin-top: 8px; }
  body.page-work .site-footer { margin-top: 56px; }

  /* About page */
  .about-hero { margin-top: 57px; }
  .about-hero .about-figure { width: min(310px, 100%); }
  .about-hero h1 { margin-top: -36px; font-size: 20px; line-height: 24px; }
  .about-intro { margin-top: 12px; }
  .whilst h2 { margin-top: 32px; font-size: 20px; }
  .whilst p { margin-top: 12px; }
  .about-closing { margin-top: 32px; }
  .about-cta .btn { margin-top: 40px; width: 100%; }
  .experience { margin-top: 72px; }
  .experience h2 { font-size: 20px; }
  .logo-grid { margin-top: 18px; grid-template-columns: repeat(2, 1fr); gap: 12px; }
  body.page-about .recommendations { margin-top: 72px; }
  body.page-about .carousel { margin-top: 32px; }

  /* Password */
  .password-wrap { width: min(338px, 100% - 64px); }
  .password-wrap .logo img { width: 48px; height: 51px; }
  .password-wrap label { margin-top: 28px; }

  .cs-page h1 { font-size: 32px; }
}

/* Tablet password tweaks */
@media (min-width: 621px) and (max-width: 1099px) {
  .password-wrap .logo img { width: 48px; height: 51px; }
  .password-wrap label { margin-top: 60px; }
}
