/* ==========================================================================
   Rohit Survase — portfolio
   Light, Swiss-leaning system: cream page, bold tight Manrope headlines,
   lavender with a United Nations Blue secondary, 4px corners, hairline
   borders and warm panels.
   ========================================================================== */

/* Fonts are served from this site (latin subset, one variable file each), so the
   first paint never waits on another server. Manrope is preloaded in layout.html. */
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/fonts/manrope-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2190-2199, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("/fonts/inter-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2190-2199, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Palette taken from conduit.ai: white canvas, warm charcoal ink, warm greys. */
  --bg: #ffffff;           /* canvas */
  --surface: #f7f6f6;      /* raised: inputs, embeds, icon boxes */
  --panel: #f1f0ef;
  --panel-2: #e9e7e2;
  --ink: #29251e;          /* warm charcoal */
  --ink-2: #3a362f;
  --muted: #69655f;
  --faint: #706d67;
  --line: #d9d7d1;
  --line-strong: #c4c1ba;

  --accent: #28241e;       /* coal — fills: buttons, markers */
  --accent-hover: #3a362f;
  --accent-ink: #28241e;   /* text/icons that used the accent */
  --accent-soft: #f1f0ef;
  --secondary: #1040c0;    /* blue */
  --hot-bg: #e6ecf9;
  --hot-ink: #1040c0;

  --on-accent: #ffffff;    /* text on accent fills */
  --nav-bg: rgba(255, 255, 255, 0.92);
  --chip-card: #ffffff;    /* tags on the grey case cards */
  --glass-bg: rgba(255, 255, 255, 0.45);
  --glass-bg-hover: rgba(255, 255, 255, 0.7);
  --glass-line: rgba(255, 255, 255, 0.4);

  --canvas: #efeeec;       /* the board the artboards sit on */
  --canvas-ink: #8d8a85;   /* artboard names */
  --lavender: #a58bff;     /* selected artboard */

  --radius: 4px;

  --display: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  --sans: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  --max: 900px;            /* content width; .wrap adds the gutters outside it */
  --gutter: clamp(16px, 4vw, 40px);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Dark appearance — chosen from the Appearance control in the studio panel. */
html[data-mode="dark"] {
  color-scheme: dark;
  --bg: #161514;
  --surface: #1f1e1c;
  --panel: #262523;
  --panel-2: #302e2b;
  --ink: #f4f2ee;
  --ink-2: #e4e1db;
  --muted: #a9a59e;
  --faint: #928e88;
  --line: #34322f;
  --line-strong: #46433f;
  --accent: #f4f2ee;
  --accent-hover: #e4e1db;
  --accent-ink: #f4f2ee;
  --accent-soft: #262523;
  --hot-bg: #1c2644;
  --hot-ink: #9db8ff;
  --on-accent: #161514;
  --nav-bg: rgba(22, 21, 20, 0.88);
  --chip-card: #302e2b;
  --glass-bg: rgba(22, 21, 20, 0.5);
  --glass-bg-hover: rgba(22, 21, 20, 0.75);
  --glass-line: rgba(255, 255, 255, 0.14);
  --canvas: #0b0b0a;
  --canvas-ink: #7d7a75;
}

/* A palette chosen in the studio panel sets --art-bg and --art-c1..3, which the
   pattern artwork inside the cards reads (see inlineArt in lib/render.js). */

/* ---------- Base ---------- */

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

/* The page sits in a design-tool style frame on wide screens (see "Frame"). */
html {
  background: var(--bg);
  scroll-behavior: smooth;
  scroll-padding-top: 90px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

h1, h2, h3, h4, p, ul, ol, figure, blockquote {
  margin: 0;
}

ul, ol {
  padding: 0;
  list-style: none;
}

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

.skip-link {
  position: absolute;
  left: 16px;
  top: -60px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--bg);
}

.skip-link:focus {
  top: 12px;
}

.wrap {
  width: 100%;
  max-width: calc(var(--max) + 2 * var(--gutter));
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* ---------- Shared pieces ---------- */

.eyebrow {
  font-size: 12px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: 0 16px;
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  transition: background 0.2s, color 0.2s;
}

.btn-lg {
  height: 48px;
  padding: 0 24px;
  font-size: 18px;
}

.btn-accent {
  background: var(--accent);
  color: var(--on-accent);
}

.btn-accent:hover {
  background: var(--accent-hover);
}

.btn-grey {
  background: var(--panel);
  color: var(--ink);
}

.btn-grey:hover {
  background: var(--panel-2);
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  font-size: 14px;
  color: var(--ink);
  transition: color 0.2s;
}

.text-link svg {
  width: 16px;
  height: 16px;
  transition: transform 0.3s var(--ease);
}

.text-link:hover {
  color: var(--accent-ink);
}

.text-link:hover svg {
  transform: translateX(3px);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.chip {
  padding: 3px 8px;
  background: var(--panel);
  color: var(--muted);
  font-size: 14px;
  line-height: 1.4;
}

.chip-hot {
  background: var(--hot-bg);
  color: var(--hot-ink);
}

/* ---------- Announcement + nav ---------- */

.announce {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 34px;
  padding: 6px var(--gutter);
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  color: var(--ink-2);
  text-align: center;
}

.announce svg {
  flex: none;
  width: 16px;
  height: 16px;
  transition: transform 0.3s var(--ease);
}

.announce:hover svg {
  transform: translateX(3px);
}

.announce-badge {
  flex: none;
  padding: 1px 7px;
  background: var(--ink);
  color: var(--bg);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--nav-bg);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

.nav-inner {
  display: flex;
  align-items: center;
  gap: 24px;
  height: 74px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--display);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.03em;
}

.nav-inner > .btn {
  margin-left: auto;
}

.nav-links {
  display: flex;
  gap: 28px;
  margin: 0 auto;
  font-size: 16px;
}

.nav-links a {
  color: var(--ink-2);
  transition: color 0.2s;
}

.nav-links a:hover {
  color: var(--accent-ink);
}

@media (max-width: 820px) {
  .nav-links {
    display: none;
  }

  .nav .btn {
    margin-left: auto;
  }
}

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

.hero {
  padding-top: clamp(64px, 11vw, 140px);
  /* The names strip's full-bleed lines run 100vmax past each side; keep them
     from widening the page on wide screens. */
  overflow-x: clip;
}

.hero-strip {
  height: 200px;
  margin-top: clamp(40px, 6vw, 72px);
  overflow: hidden;
}

.hero-strip svg {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Phones: the pattern is zoomed in 4x, so the strip shows only the middle
   quarter of the graphic and the shapes stay a readable size. */
@media (max-width: 760px) {
  .hero-strip svg {
    width: 400%;
    max-width: none;
    margin-left: -150%;
  }
}

.hero-grid {
  display: grid;
  gap: clamp(32px, 6vw, 96px);
  justify-items: center;
  text-align: center;
}

.hero h1 {
  max-width: 16ch;
  /* Padding keeps descenders inside the box, so the hover fill (which paints
     only within the box) covers them; the margins cancel it out. */
  padding: 0.12em 0.04em;
  margin: calc(18px - 0.12em) auto -0.12em;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(44px, 6.2vw, 82px);
  line-height: 1;
  letter-spacing: -0.035em;
}

/* Under the pointer, a soft round patch of the heading fills with the animated
   pattern. The overlay is a copy of the heading text, masked with a feathered
   gradient; js/dither.js moves the patch (--mx / --my) and turns it on. */
.hero h1 {
  position: relative;
}

@media (prefers-reduced-motion: no-preference) {
  .hero h1::after {
    content: attr(data-text);
    content: attr(data-text) / "";
    position: absolute;
    inset: 0;
    padding: inherit;
    pointer-events: none;
    background: var(--heading-art, url("/public/images/art/heading.svg")) center / 1200px 800px;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    -webkit-mask-image: radial-gradient(closest-side, #000 20%, rgba(0, 0, 0, 0.6) 55%, transparent 100%);
    mask-image: radial-gradient(closest-side, #000 20%, rgba(0, 0, 0, 0.6) 55%, transparent 100%);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: 0 0;
    mask-size: 0 0;
    -webkit-mask-position: var(--mx, 0) var(--my, 0);
    mask-position: var(--mx, 0) var(--my, 0);
  }

  .hero h1.is-lit::after {
    -webkit-mask-size: 160px 160px;
    mask-size: 160px 160px;
  }
}

.hero-lead {
  max-width: 44ch;
  margin: 22px auto 0;
  font-size: clamp(18px, 1.5vw, 20px);
  color: var(--muted);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 36px;
}

/* Right-hand slot for hero artwork. */
.hero-art {
  min-height: 1px;
}

/* Bordered strip of product names, full bleed with gridded cells. */
.names {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  max-width: var(--max);
  margin: clamp(56px, 8vw, 104px) auto 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  position: relative;
}

.names::before,
.names::after {
  content: "";
  position: absolute;
  top: -1px;
  bottom: -1px;
  width: 100vmax;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.names::before { right: 100%; }
.names::after { left: 100%; }

.names li {
  display: grid;
  place-items: center;
  min-height: 74px;
  padding: 0 12px;
  border-left: 1px solid var(--line);
  font-family: var(--display);
  font-size: clamp(16px, 1.7vw, 20px);
  font-weight: 500;
  letter-spacing: -0.03em;
  color: var(--ink-2);
  text-align: center;
}

.names li:last-child {
  border-right: 1px solid var(--line);
}

@media (max-width: 900px) {
  .names {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-left: var(--gutter);
    margin-right: var(--gutter);
  }

  .names li:nth-child(n + 4) {
    border-top: 1px solid var(--line);
  }

  .names li:nth-child(3) {
    border-right: 1px solid var(--line);
  }
}

/* ---------- Sections ---------- */

.section {
  padding-top: clamp(96px, 12vw, 160px);
}

.section-head {
  margin-bottom: clamp(40px, 5vw, 72px);
}

.section-head.center {
  text-align: center;
}

.section-head h2,
.faq-side h2 {
  margin-top: 14px;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(38px, 5vw, 64px);
  line-height: 1.02;
  letter-spacing: -0.035em;
}

.section-head .lead {
  max-width: 50ch;
  margin: 20px auto 0;
  font-size: 18px;
  font-weight: 400;
  color: var(--ink-2);
}

/* ---------- Process cards ---------- */

.process-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

.process-card {
  display: flex;
  flex-direction: column;
  background: var(--surface);
}

.process-card-text {
  padding: clamp(24px, 3vw, 32px);
}

.process-num {
  font-size: 14px;
  color: var(--faint);
}

.process-card h3 {
  margin-top: 14px;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(22px, 2.2vw, 28px);
  line-height: 1.15;
  letter-spacing: -0.03em;
}

.process-card p {
  margin-top: 12px;
  color: var(--muted);
}

/* Dithered gradient panel; the canvas redraws it, and its dots drift on hover.
   The still image underneath is what shows before the script runs. */
.process-art {
  position: relative;
  margin: auto 10px 10px;
  min-height: 200px;
  overflow: hidden;
  background: var(--panel);
}


.process-art canvas,
.process-art svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.process-art:has(svg) { background-image: none; }

@media (max-width: 760px) {
  .process-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- Case cards ---------- */

.case-list {
  display: grid;
  gap: 48px;
}

.case-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
  background: var(--surface);
}

.case-card.is-flipped .case-card-text {
  order: 2;
}

.case-card-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: clamp(24px, 3vw, 36px);
}

/* On the grey card, tags read as white chips. */
.case-card .chip:not(.chip-hot) {
  background: var(--chip-card);
}

.case-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.case-card-head b {
  font-weight: 500;
}

/* The tags sit at the bottom of the card, whatever the headline's length. */
.case-card-text .chips {
  margin-top: auto;
}

.case-card h3 {
  margin: 26px 0 28px;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(20px, 1.9vw, 24px);
  line-height: 1.25;
  letter-spacing: -0.025em;
}

/* The title link stretches over the whole card, so the card is one click target. */
.case-card h3 a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.case-card h3 a:focus-visible {
  outline: none;
}

.case-card h3 a:focus-visible::after {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}


.case-card-media {
  position: relative;
  display: block;
  min-height: 340px;
  margin: 10px;
  overflow: hidden;
  /* A soft gradient with a halftone dither over it; one variation per card. */
  background: var(--panel);
}


.case-card-media > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* The product shot is zoomed in and cropped by the panel's edges, so only
   part of the screen shows. --x / --y / --zoom come from the study's card_crop. */
.case-card-media img {
  position: absolute;
  left: calc(var(--x, 8) * 1%);
  top: calc(var(--y, 13) * 1%);
  width: calc(var(--zoom, 150) * 1%);
  max-width: none;
  height: auto;
  transform-origin: top left;
  transition: transform 1s var(--ease);
}

.case-card:hover .case-card-media img:not(.art-still) {
  transform: scale(1.03);
}

@media (max-width: 900px) {
  .case-card {
    grid-template-columns: 1fr;
  }

  .case-card-text,
  .case-card.is-flipped .case-card-text {
    order: 2;
  }

  .case-card-media {
    min-height: 0;
    aspect-ratio: 16 / 11;
  }
}

/* ---------- Other clients ---------- */

.other-clients {
  margin-top: clamp(56px, 7vw, 88px);
}

.other-clients-title {
  text-align: center;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.client-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin-top: 20px;
}

/* Same card language as the rest of the page: soft surface, 4px corners. */
.client {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 40px;
  min-height: 150px;
  padding: 24px;
  background: var(--surface);
  border-radius: var(--radius);
}

.client-name {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  font-family: var(--display);
  font-size: 20px;
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.03em;
}

.client-badge {
  padding: 2px 8px;
  background: var(--hot-bg);
  color: var(--hot-ink);
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0;
}

.client-desc {
  font-size: 16px;
  line-height: 1.4;
  color: var(--muted);
}

/* The last card is the invitation: filled, like the page's primary buttons. */
.client-cta {
  padding: 0;
  background: var(--accent);
  transition: background 0.2s;
}

.client-cta:hover {
  background: var(--accent-hover);
}

.client-cta a {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: space-between;
  gap: 40px;
  padding: 24px;
  color: var(--on-accent);
}

.client-cta .client-name,
.client-cta .client-desc {
  color: var(--on-accent);
}

.client-cta .client-desc {
  opacity: 0.72;
}

.client-cta .client-name svg {
  width: 20px;
  height: 20px;
  transition: transform 0.3s var(--ease);
}

.client-cta a:hover .client-name svg {
  transform: translateX(3px);
}

@media (max-width: 900px) {
  .client-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 520px) {
  .client-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- Pull quote ---------- */

.pullquote {
  max-width: 920px;
  margin: 0 auto;
  text-align: center;
}

.pullquote-mark {
  display: block;
  height: 64px;
  font-family: var(--display);
  font-size: 120px;
  font-weight: 500;
  line-height: 1;
  color: var(--accent-ink);
}

.pullquote p {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(26px, 3.2vw, 40px);
  line-height: 1.2;
  letter-spacing: -0.035em;
}

/* ---------- Engage ---------- */

.engage-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px; /* the line colour shows through as dividers */
  background: var(--line);
  border: 1px solid var(--line);
}

.engage-card {
  display: flex;
  flex-direction: column;
  padding: 32px;
  background: var(--bg);
}

/* Patterned strip that slides down from the top of the card on hover and
   fades out into the card's background. */
.engage-card {
  position: relative;
  overflow: hidden;
}

.engage-card > :not(.engage-strip) {
  position: relative;
}

.engage-strip {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 50px;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transform: translateY(-100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 30%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 30%, transparent 100%);
  transition: opacity 0.4s var(--ease), transform 0.5s var(--ease);
}

.engage-card:hover .engage-strip,
.engage-card:focus-within .engage-strip {
  opacity: 1;
  transform: none;
}

.engage-strip svg {
  display: block;
  width: 100%;
  height: 100%;
}

.engage-num {
  font-family: var(--display);
  font-size: 14px;
  font-weight: 500;
  color: var(--accent-ink);
}

.engage-card h3 {
  margin-top: 48px;
  font-family: var(--display);
  font-weight: 500;
  font-size: 26px;
  line-height: 1.15;
  letter-spacing: -0.035em;
}

.engage-card > p {
  margin-top: 12px;
  color: var(--muted);
}

.terms {
  margin-top: auto;
  padding-top: 28px;
}

.terms li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-top: 1px solid var(--line);
  font-size: 14px;
  font-weight: 400;
}

.terms li::before {
  content: "";
  width: 6px;
  height: 6px;
  background: var(--accent);
}

@media (max-width: 900px) {
  .engage-grid {
    grid-template-columns: 1fr;
  }
}

/* ---------- FAQ ---------- */

.faq {
  display: grid;
  gap: clamp(28px, 4vw, 40px);
}

.faq .section-head {
  margin-bottom: 0;
}

/* The call card: art on the left (30%), message on the right. */
.ask-card {
  display: grid;
  grid-template-columns: 3fr 7fr;
  background: var(--panel);
  overflow: hidden;
}

/* Inset from the card's edges with its own corners, like the case-card art. */
.ask-art {
  position: relative;
  min-height: 220px;
  margin: 10px;
  overflow: hidden;
  border-radius: var(--radius);
}

.ask-art svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.ask-body {
  align-self: center;
  padding: clamp(24px, 4vw, 48px);
}

.ask-card h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 24px;
  letter-spacing: -0.035em;
}

.ask-card .ask-body > p {
  margin: 6px 0 24px;
  color: var(--muted);
}

.ask-card .ask-mail {
  margin: 20px 0 0;
  font-size: 14px;
}

.ask-mail a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Copy button after an email address; shows a tick for a moment once copied. */
.copy-btn {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  margin-left: 4px;
  padding: 0;
  vertical-align: middle;
  color: inherit;
  background: transparent;
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.2s, background-color 0.2s;
}

.copy-btn:hover,
.copy-btn:focus-visible {
  opacity: 1;
  background: rgba(127, 127, 127, 0.14);
}

.copy-btn svg {
  grid-area: 1 / 1;
  width: 15px;
  height: 15px;
  transition: opacity 0.2s, transform 0.2s;
}

.copy-btn svg:last-child,
.copy-btn.is-copied svg:first-child {
  opacity: 0;
  transform: scale(0.6);
}

.copy-btn.is-copied svg:last-child {
  opacity: 1;
  transform: none;
}

.mail-row {
  display: inline-flex;
  align-items: center;
  margin-top: 8px;
}

.footer-contact .mail-row a {
  margin-top: 0;
}

.faq-list {
  display: grid;
  gap: 12px;
}

.faq-item {
  background: var(--panel);
}

.faq-item summary {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 20px;
  cursor: pointer;
  list-style: none;
  font-size: 18px;
  font-weight: 500;
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

/* Small boxed plus that becomes a minus when open. */
.faq-icon {
  position: relative;
  flex: none;
  width: 28px;
  height: 28px;
}

.faq-icon::before,
.faq-icon::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 14px;
  height: 1.5px;
  background: var(--ink);
  transform: translate(-50%, -50%);
  transition: transform 0.3s var(--ease);
}

.faq-icon::after {
  transform: translate(-50%, -50%) rotate(90deg);
}

.faq-item[open]:not(.is-closing) .faq-icon::after {
  transform: translate(-50%, -50%) rotate(0deg);
}

/* Height and fade are animated by js/dither.js; clipping keeps the answer
   inside the card while it grows or shrinks. */
.faq-answer {
  overflow: hidden;
  padding: 0 20px 22px 68px;
  color: var(--muted);
}

.faq-answer p + p {
  margin-top: 10px;
}

@media (max-width: 900px) {
  .faq-answer {
    padding-left: 20px;
  }
}

@media (max-width: 640px) {
  .ask-card {
    grid-template-columns: 1fr;
  }

  .ask-art {
    min-height: 120px;
  }
}

/* ---------- Closing CTA ---------- */

.cta {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin-top: clamp(112px, 14vw, 180px);
  padding: clamp(80px, 10vw, 128px) 0 clamp(120px, 14vw, 180px);
  border-top: 1px solid var(--line);
}

.cta-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(36px, 5vw, 72px);
  align-items: center;
}

.cta h2 {
  margin-top: 14px;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(42px, 5.6vw, 76px);
  line-height: 1;
  letter-spacing: -0.035em;
}

.cta-lead {
  margin-top: 22px;
  max-width: 36ch;
  font-size: 20px;
  font-weight: 400;
  color: var(--ink-2);
}

.cta-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
  margin-top: 36px;
}

.cta-actions .ask-mail {
  font-size: 14px;
  color: var(--muted);
}

.cta-cal {
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.cta-cal iframe {
  display: block;
  width: 100%;
  height: 620px;
  border: 0;
}

@media (max-width: 920px) {
  .cta-inner {
    grid-template-columns: 1fr;
  }
}

/* ---------- Footer ---------- */

/* Dark footer, as on conduit.ai: charcoal with white text at set opacities. */
.footer {
  padding: 56px 0 0;
  background: #28241e;
  color: #fff;
}

.footer .eyebrow {
  color: rgba(255, 255, 255, 0.56);
}

.footer-top {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 32px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}

.footer-tag {
  color: rgba(255, 255, 255, 0.56);
}

.footer-main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 48px;
  padding: 48px 0;
}

.footer-big {
  max-width: 14ch;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(28px, 3vw, 38px);
  line-height: 1.1;
  letter-spacing: -0.03em;
}

.footer-contact {
  display: flex;
  flex-wrap: wrap;
  gap: 24px 56px;
  margin-top: 36px;
}

.footer-contact a {
  display: inline-block;
  margin-top: 8px;
  font-size: 18px;
  text-decoration: underline;
  text-underline-offset: 4px;
}

.footer-contact a:hover {
  color: rgba(255, 255, 255, 0.7);
}

.footer-cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 32px;
}

.footer-cols ul {
  display: grid;
  gap: 12px;
  margin-top: 18px;
}

.footer-cols a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: rgba(255, 255, 255, 0.8);
  transition: color 0.2s;
}

.footer-cols a:hover {
  color: #fff;
}

.footer-cols svg {
  width: 14px;
  height: 14px;
}

/* Patterned strip along the very bottom of the page. */
.footer-strip {
  height: 150px;
  margin-top: 40px;
  overflow: hidden;
}

.footer-strip svg {
  display: block;
  width: 100%;
  height: 100%;
}

.footer-meta {
  padding-top: 24px;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  font-size: 14px;
  color: rgba(255, 255, 255, 0.5);
}

@media (max-width: 820px) {
  .footer-main {
    grid-template-columns: 1fr;
  }
}

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

/* ---------- Case study page ---------- */

.case-hero {
  padding-top: clamp(40px, 6vw, 72px);
}

/* Opens the voice agent, which walks through this project. */
.explain-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  margin-top: 28px;
  padding: 0 16px;
  overflow: hidden;
  border: 0;
  border-radius: 4px;
  background: linear-gradient(225deg, #b9a6ff 0%, #8f76ee 100%);
  color: #fff;
  font-family: var(--sans);
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: inset 0 0 0 0.5px #7e68d6, inset 0 0 0 1px rgba(255, 255, 255, 0.35);
}

.explain-btn::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  transition: background 0.15s ease-out;
}

.explain-btn:hover::before {
  background: rgba(0, 0, 0, 0.08);
}

.explain-btn:active::before {
  background: rgba(0, 0, 0, 0.14);
}

.explain-btn svg {
  position: relative;
  width: 16px;
  height: 16px;
}

.back-link {
  margin-bottom: clamp(40px, 6vw, 72px);
}

.case-hero h1 {
  margin-top: 14px;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(56px, 9vw, 120px);
  line-height: 0.95;
  letter-spacing: -0.03em;
}

.case-kicker {
  margin-top: 22px;
  max-width: 40ch;
  font-size: clamp(18px, 1.8vw, 22px);
  font-weight: 400;
  line-height: 1.4;
  color: var(--ink-2);
}

.case-studio {
  margin-top: 14px;
  font-size: 15px;
  color: var(--muted);
}

.case-studio a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--line);
  text-underline-offset: 3px;
  transition: text-decoration-color 0.2s;
}

.case-studio a:hover {
  text-decoration-color: currentColor;
}

.case-hero .chips {
  margin-top: 26px;
}

.case-cover {
  position: relative;
  overflow: hidden;
  margin-top: clamp(40px, 5vw, 64px);
  padding: clamp(16px, 4vw, 56px);
  /* Dithered gradient; which one is set per study on the element. */
  background: var(--panel);
}

.case-cover > svg,
.next-media > svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.case-cover img,
.next-media img {
  position: relative;
}

.case-body {
  margin-top: clamp(56px, 7vw, 96px);
}

.case-section {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  padding: clamp(40px, 6vw, 64px) 0;
  border-top: 1px solid var(--line);
}

.case-section-label {
  font-family: var(--display);
  font-size: clamp(18px, 2vw, 24px);
  font-weight: 500;
  letter-spacing: -0.03em;
  color: var(--muted);
}

/* Text keeps a readable measure; screens use the full page width. */
.case-section-body > :not(.shot):not(.shot-row) {
  max-width: 720px;
}

/* Case studies are free-form markdown; an italic-only opening paragraph is
   the problem statement. */
.case-section-body > p:first-child:has(> em:only-child) {
  font-family: var(--display);
  font-size: clamp(22px, 2.2vw, 28px);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.03em;
  color: var(--ink);
}

.case-section-body > p:first-child > em:only-child {
  font-style: normal;
}

.case-section-body h3 {
  margin-top: 36px;
  font-family: var(--display);
  font-size: 22px;
  font-weight: 500;
  letter-spacing: -0.03em;
}

.case-section-body h3:first-child {
  margin-top: 0;
}

.case-section-body p,
.case-section-body ul,
.case-section-body ol,
.case-section-body blockquote {
  margin-top: 12px;
  font-size: 18px;
  line-height: 1.6;
  color: var(--muted);
}

.case-section-body ul { padding-left: 20px; list-style: disc; }
.case-section-body ol { padding-left: 20px; list-style: decimal; }
.case-section-body li + li { margin-top: 6px; }

.case-section-body strong {
  font-weight: 600;
  color: var(--ink);
}

.case-section-body a {
  color: var(--accent-ink);
  text-decoration: underline;
}

.case-section-body blockquote {
  padding-left: 16px;
  border-left: 2px solid var(--accent);
}

.shot {
  margin-top: 32px;
  padding: clamp(16px, 3vw, 40px);
  background: var(--art-bg, var(--study-bg, var(--panel)));
}

.shot figcaption {
  margin-top: 12px;
  font-size: 14px;
  color: var(--art-ink, var(--study-ink, var(--muted)));
}

/* A paragraph of several images: a flow, or a set of phone screens. Each
   row spans the full content width so the screens render large. */
.shot-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  align-items: start;
  gap: clamp(16px, 2.4vw, 32px);
  margin-top: 32px;
  padding: clamp(16px, 3vw, 40px);
  background: var(--art-bg, var(--study-bg, var(--panel)));
}

.shot-row a {
  display: block;
}

.shot-row img {
  width: 100%;
  /* Long scrolling screens are cropped to the fold; the link opens the whole thing. */
  max-height: 640px;
  object-fit: cover;
  object-position: top;
  box-shadow: 0 1px 2px rgba(41, 37, 30, 0.08), 0 8px 24px rgba(41, 37, 30, 0.12);
  transition: transform 0.6s var(--ease);
}

.shot-row a:hover img {
  transform: translateY(-3px);
}

/* Phone screens: one to three across, or two by two for a set of four. */
.shot-row.is-portrait {
  grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr));
  justify-items: center;
}

.shot-row.is-portrait[data-count="1"] { --cols: 1; }
.shot-row.is-portrait[data-count="2"] { --cols: 2; }
.shot-row.is-portrait[data-count="3"] { --cols: 3; }
.shot-row.is-portrait[data-count="4"] { --cols: 2; }
.shot-row.is-portrait:not([data-count="1"]):not([data-count="2"]):not([data-count="3"]):not([data-count="4"]) { --cols: 3; }

.shot-row.is-portrait figure {
  width: 100%;
  max-width: 420px;
}

.shot-row.is-portrait img {
  aspect-ratio: 390 / 844;
  max-height: none;
}

.shot-row figcaption {
  margin-top: 12px;
  font-size: 14px;
  line-height: 1.4;
  color: var(--art-ink, var(--study-ink, var(--muted)));
}

@media (max-width: 760px) {
  /* Phones: sets of screens become a swipeable strip, one and a bit at a time. */
  .shot-row.is-portrait:not([data-count="1"]) {
    display: flex;
    justify-content: flex-start;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
  }

  .shot-row.is-portrait:not([data-count="1"]) figure {
    flex: 0 0 78%;
    max-width: none;
    scroll-snap-align: center;
  }
}

.case-outcome {
  margin-top: 16px;
  padding: clamp(28px, 4vw, 48px);
  background: var(--accent-soft);
  border-left: 3px solid var(--secondary);
}

.case-outcome .eyebrow {
  color: var(--accent-ink);
}

.case-outcome-body p {
  max-width: 34ch;
  margin-top: 14px;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(24px, 2.8vw, 34px);
  line-height: 1.2;
  letter-spacing: -0.035em;
}

.next-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  margin-top: clamp(72px, 9vw, 120px);
  margin-bottom: clamp(72px, 9vw, 120px);
  border: 1px solid var(--line);
}

.next-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: clamp(24px, 3vw, 40px);
}

.next-card h2 {
  margin-top: 14px;
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(40px, 5vw, 64px);
  line-height: 1;
  letter-spacing: -0.035em;
}

.next-text > p:not(.eyebrow) {
  margin: 14px 0 28px;
  color: var(--muted);
}

.next-media {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  padding: clamp(16px, 3vw, 32px);
  background: var(--panel);
  border-left: 1px solid var(--line);
}

.next-media img {
  transition: transform 1s var(--ease);
}

.next-card:hover .next-media img:not(.art-still) {
  transform: scale(1.03);
}

.next-card:hover h2 {
  color: var(--accent-ink);
}

@media (max-width: 760px) {
  .next-card {
    grid-template-columns: 1fr;
  }

  .next-media {
    border-left: 0;
    border-top: 1px solid var(--line);
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation: none !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------- Corners: everything boxy gets the same 4px radius ---------- */

.btn,
.chip,
.announce-badge,
.case-card,
.case-card-media,
.process-card,
.process-art,
.engage-grid,
.ask-card,
.faq-item,
.faq-icon,
.case-cover,
.shot,
.shot img,
.shot-row,
.shot-row img,
.case-outcome,
.next-card,
.case-card-media img,
.next-media img,
.case-cover img {
  border-radius: var(--radius);
}

.case-card,
.next-card,
.engage-grid {
  overflow: hidden;
}


/* ==========================================================================
   Board — every page is an artboard on one canvas (wide screens). The selected
   artboard has a lavender border and corner squares; moving between pages pans
   the canvas. Phones and tablets get the same canvas, one artboard per screen width.
   ========================================================================== */

.frame-label,
.frame-handle {
  display: none;
}

.frame-inner {
  overflow-x: clip;
}

/* ----- floating menu ----- */

.dock {
  position: fixed;
  z-index: 80;
  left: 50%;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: calc(100vw - 16px);
  transform-origin: 50% 100%;
  touch-action: manipulation;
  transform: translateX(-50%);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 13px;
  line-height: 1.4;
}

.dock-bar {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 5px;
  border-radius: 6px;
  background: rgba(24, 24, 24, 0.94);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  color: #ececec;
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.07);
}

.dock svg {
  width: 16px;
  height: 16px;
  flex: none;
}

.dock button {
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.dock-sep {
  width: 1px;
  height: 20px;
  margin: 0 3px;
  background: rgba(255, 255, 255, 0.12);
}

.dock-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 32px;
  padding: 0 12px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  font-weight: 500;
  white-space: nowrap;
  transition: background 0.15s;
}

.dock-btn:hover {
  background: rgba(255, 255, 255, 0.09);
}

/* Lavender gradient button with a thin inner edge and soft white rim. */
.dock-agent-btn {
  position: relative;
  overflow: hidden;
  padding: 0 14px;
  background: linear-gradient(225deg, #b9a6ff 0%, #8f76ee 100%);
  color: #fff;
  box-shadow: inset 0 0 0 0.5px #7e68d6, inset 0 0 0 1px rgba(255, 255, 255, 0.35);
}

.dock-agent-btn::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  transition: background 0.15s ease-out;
}

.dock-agent-btn:hover {
  background: linear-gradient(225deg, #b9a6ff 0%, #8f76ee 100%);
}

.dock-agent-btn:hover::before {
  background: rgba(0, 0, 0, 0.08);
}

.dock-agent-btn:active::before {
  background: rgba(0, 0, 0, 0.14);
}

.dock-agent-btn svg,
.dock-agent-btn span {
  position: relative;
}

/* While a conversation is running the button becomes a live indicator: little bars
   that follow the voice, a status, and a soft pulse. Clicking it minimises or
   restores the panel. */
.agent-bars {
  display: none;
  align-items: center;
  gap: 2px;
  height: 14px;
}

.agent-bars i {
  width: 2.5px;
  height: calc(14px * var(--h, 0.3));
  border-radius: 2px;
  background: #fff;
  transition: height 0.08s linear;
}

.dock-agent-btn.is-live .agent-spark {
  display: none;
}

.dock-agent-btn.is-live .agent-bars {
  display: flex;
}

.dock-agent-btn.is-live .agent-label {
  min-width: 108px;
  text-align: left;
}

.dock-agent-btn.is-live::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  animation: agent-live 2.2s ease-out infinite;
}

.dock-agent-btn.is-live[data-state="speaking"]::after {
  animation-duration: 1.2s;
}

@keyframes agent-live {
  0% {
    box-shadow: 0 0 0 0 rgba(185, 166, 255, 0.7);
  }
  100% {
    box-shadow: 0 0 0 9px rgba(185, 166, 255, 0);
  }
}

.dock-agent-btn.is-ping {
  animation: agent-ping 0.6s var(--ease);
}

@keyframes agent-ping {
  40% {
    transform: scale(1.06);
  }
}

@media (prefers-reduced-motion: reduce) {
  .dock-agent-btn.is-live::after,
  .dock-agent-btn.is-ping {
    animation: none;
  }
}

.dock-agent {
  position: relative;
}

.dock-chip {
  flex: none;
  width: 14px;
  height: 14px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  background: var(--c, #ffb400);
}

.dock-caret {
  width: 12px !important;
  height: 12px !important;
  color: #9a9a9a;
}

.dock-mode {
  position: relative;
  display: flex;
  gap: 2px;
  padding: 2px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.07);
}

/* The pill behind the chosen mode slides across when it changes. */
.dock-mode::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 30px;
  height: 28px;
  border-radius: 4px;
  background: #3b3b3b;
  transition: transform 0.45s cubic-bezier(0.34, 1.4, 0.5, 1);
}

html[data-mode="dark"] .dock-mode::before {
  transform: translateX(32px);
}

.dock-mode button {
  position: relative;
  display: grid;
  place-items: center;
  width: 30px;
  height: 28px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: #9a9a9a;
  transition: background 0.15s, color 0.15s;
}

.dock-mode button:hover {
  color: #fff;
}

.dock-mode button[aria-pressed="true"] {
  color: #fff;
}

.dock-home {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  padding: 0;
  color: #cfcfcf;
  transition: color 0.15s, background 0.15s;
}

.dock-home:hover {
  color: #fff;
  background: rgba(40, 40, 40, 0.96);
}

.dock-home svg {
  width: 18px;
  height: 18px;
}

/* ----- voice panel: frosted glass above the menu ----- */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.voice {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 12px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(380px, calc(100vw - 24px));
  padding: 12px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 6px;
  color: #f4f2ee;
  background:
    linear-gradient(160deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.05) 45%, rgba(165, 139, 255, 0.12) 100%),
    rgba(20, 20, 26, 0.58);
  -webkit-backdrop-filter: blur(28px) saturate(1.7);
  backdrop-filter: blur(28px) saturate(1.7);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.3), inset 0 0 0 1px rgba(255, 255, 255, 0.04);
  opacity: 0;
  transform: translate(-50%, 10px) scale(0.98);
  transform-origin: 50% 100%;
  transition: opacity 0.25s var(--ease), transform 0.3s var(--ease);
}

.voice:not([hidden]) {
  display: flex;
}

/* Closed, the panel is gone; while it fades it must not catch taps meant for
   the page underneath. */
.voice[hidden] {
  display: none;
}

.voice:not(.is-open) {
  pointer-events: none;
}

.voice.is-open {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
}

.voice-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.voice-title {
  display: grid;
  flex: 1;
  min-width: 0;
}

.voice-name {
  font-size: 14px;
  font-weight: 600;
  color: #fff;
}

.voice-status {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.62);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.voice[data-state="speaking"] .voice-status {
  color: #ffd1c9;
}

.voice[data-state="error"] .voice-status {
  color: #ffb4a8;
}

.voice-x {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
}

.voice-x:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}

.voice-stage {
  position: relative;
  height: 184px;
  overflow: hidden;
  border-radius: 4px;
  background:
    radial-gradient(60% 70% at 50% 45%, rgba(165, 139, 255, 0.22), transparent 70%),
    rgba(0, 0, 0, 0.18);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}

/* The same rough-edged, dry-brush filter the pattern art uses, so the ring reads
   as a brush stroke that belongs to the rest of the portfolio. */
.voice-stage canvas {
  display: block;
  width: 100%;
  height: 100%;
  filter: url(#voice-fude);
}

.voice-fude {
  position: absolute;
  width: 0;
  height: 0;
}

.voice-cards {
  display: grid;
  gap: 8px;
  max-height: 224px;
  overflow-y: auto;
  scrollbar-width: none;
}

.voice-hint {
  padding: 4px 2px;
  font-size: 13px;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.6);
}

.voice-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  text-align: left;
  animation: voice-card-in 0.45s var(--ease) both;
}

@keyframes voice-card-in {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.98);
  }
}

.voice-project {
  transition: background 0.15s, border-color 0.15s;
}

.voice-project:hover {
  background: rgba(255, 255, 255, 0.18);
  border-color: rgba(255, 255, 255, 0.3);
}

.voice-project > svg {
  flex: none;
  width: 16px;
  height: 16px;
  color: rgba(255, 255, 255, 0.7);
  transition: transform 0.25s var(--ease);
}

.voice-project:hover > svg {
  transform: translateX(3px);
  color: #fff;
}

.voice-thumb {
  flex: none;
  width: 48px;
  height: 34px;
  overflow: hidden;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.12);
}

.voice-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top left;
}

.voice-card-text {
  display: grid;
  flex: 1;
  min-width: 0;
  gap: 1px;
}

.voice-card-text b {
  font-size: 13px;
  font-weight: 600;
}

.voice-card-text small {
  display: -webkit-box;
  overflow: hidden;
  font-size: 12px;
  line-height: 1.35;
  color: rgba(255, 255, 255, 0.62);
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}

.voice-book {
  display: grid;
  gap: 8px;
  padding: 10px;
}

.voice-book-title {
  font-size: 13px;
  font-weight: 600;
}

.voice-book-row {
  display: flex;
  gap: 8px;
}

.voice-book-row a {
  display: inline-flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 32px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  font-size: 13px;
  font-weight: 500;
  transition: background 0.15s;
}

.voice-book-row a:first-child {
  background: linear-gradient(225deg, #b9a6ff 0%, #8f76ee 100%);
  box-shadow: inset 0 0 0 0.5px #7e68d6, inset 0 0 0 1px rgba(255, 255, 255, 0.3);
}

.voice-book-row a:hover {
  background: rgba(255, 255, 255, 0.24);
}

.voice-book-row a:first-child:hover {
  background: linear-gradient(225deg, #c6b7ff 0%, #9a82f5 100%);
}

.voice-book-row svg {
  width: 15px;
  height: 15px;
}

.voice-foot {
  display: flex;
  align-items: center;
  gap: 8px;
}

.voice-time {
  flex: 1;
  text-align: center;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.55);
  font-variant-numeric: tabular-nums;
}

.voice-time.is-low {
  color: #ffb4a8;
}

.voice-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.09);
  color: #fff;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s;
}

.voice-btn:hover {
  background: rgba(255, 255, 255, 0.16);
}

.voice-btn[aria-pressed="true"] {
  background: rgba(232, 65, 44, 0.35);
  border-color: rgba(232, 65, 44, 0.6);
}

.dock .voice-end {
  background: rgba(255, 255, 255, 0.92);
  border-color: transparent;
  color: #151515;
}

.dock .voice-end:hover {
  background: #fff;
}

.dock :is(button, a):focus-visible {
  outline: 2px solid var(--lavender);
  outline-offset: 2px;
}

@media (max-width: 640px) {
  .dock-agent-btn:not(.is-live) .agent-label {
    display: none;
  }

  .dock-agent-btn.is-live .agent-label {
    min-width: 0;
    font-size: 12px;
  }

  .dock-btn {
    padding: 0 10px;
  }

  .dock-agent-btn {
    padding: 0 10px;
  }

}

/* ----- the canvas -----
   All artboards sit side by side at full height on an open canvas that scrolls
   freely in both directions (trackpad, drag, pinch), with no clipping.

   The canvas scrolls inside its own box, not the page. If the page itself were
   as wide as the canvas, phones would stretch their layout viewport to fit it:
   sticky headers then stick to an edge you cannot see (drawn lower down, jumping
   while scrolling), lazy images all load at once, and Safari zooms out to the
   whole canvas in low-res tiles. */

html,
body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  background: var(--canvas);
}

.board {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  /* As tall as the screen with the browser bars tucked away, so the canvas runs
     on behind Safari's toolbar instead of stopping in a band above it. */
  height: 100vh;
  height: 100lvh;
  overflow: auto;
  overscroll-behavior: none;
  outline: none;
}

/* Phones scroll the page itself up and down, so it runs on behind Safari's
   toolbar, and the board only clips the row of artboards sideways; js/board.js
   moves the row on a sideways drag. No zooming. */
@media (max-width: 760px) {
  html,
  body {
    height: auto;
    overflow-x: clip;
    overflow-y: visible;
    background: var(--canvas);
  }

  .board {
    position: relative;
    height: auto;
    min-height: 100vh;
    overflow: visible;
    overflow-x: clip;
    touch-action: pan-y;
  }
}

/* The pages' sticky navs stick to the top of the board. */
.board-canvas {
  --frame-w: min(1100px, calc(100vw - 48px));
  --frame-gap: 180px;
  /* room beside the first and last artboards, so any of them can be centred */
  padding: 76px calc((100vw - var(--frame-w)) / 2) 200px;
  width: max-content;
  min-width: 100%;
}

.board.is-panning {
  cursor: grabbing;
  user-select: none;
}

.board.can-pan {
  cursor: grab;
}

.strip {
  display: flex;
  gap: var(--frame-gap);
  width: max-content;
  transform-origin: 0 0;
}

.frame {
  position: relative;
  flex: none;
  align-self: flex-start;
  width: var(--frame-w);
  background: var(--bg);
  border: 1px solid transparent;
  cursor: auto;
  transition: border-color 0.3s;
}

.frame.is-selected {
  border-color: var(--lavender);
}

.frame-label {
  position: absolute;
  top: -28px;
  left: 0;
  display: block;
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  color: var(--canvas-ink);
  transition: color 0.3s;
}

.frame.is-selected .frame-label {
  color: var(--lavender);
}

.frame-handle {
  position: absolute;
  z-index: 60;
  display: block;
  width: 9px;
  height: 9px;
  background: #fff;
  border: 1px solid var(--lavender);
  opacity: 0;
  transition: opacity 0.3s;
}

.frame.is-selected .frame-handle {
  opacity: 1;
}

.frame-handle-tl { top: -5px; left: -5px; }
.frame-handle-tr { top: -5px; right: -5px; }
.frame-handle-bl { bottom: -5px; left: -5px; }
.frame-handle-br { bottom: -5px; right: -5px; }

/* Wide screens can also zoom out, so they need half a screen of room per side. */
@media (min-width: 1180px) {
  .board-canvas {
    padding-inline: 50vw;
  }
}

/* A page that has not arrived yet holds its place without any content. */
.frame-inner[data-lazy] {
  min-height: 100vh;
}

/* ---------- Pattern art: a still picture, live SVG on desktop ---------- */

/* Phones and touch screens show each pattern as a still picture of its first
   frame; desktops show the live SVG instead (js/interactions.js). The picture
   fills its box the way the SVG does (cropped to cover, centred). */
.hero-strip,
.footer-strip {
  position: relative;
}

picture.art-pic {
  display: contents;
}

img.art-still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  transform: none;
  transition: none;
}

.hero-strip svg,
.footer-strip svg {
  position: relative;
}

/* Phones and touch screens: no frosted glass. iOS Safari redraws a blurred
   backdrop on every scroll frame, and under a sticky header that shows up as a
   header drawn twice or jumping. The same colours, made solid, look the same. */
@media (max-width: 760px), (hover: none) {
  .nav {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: var(--bg);
  }

  .dock-bar {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: #181818;
  }

  .voice {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background:
      linear-gradient(160deg, rgba(255, 255, 255, 0.16) 0%, rgba(255, 255, 255, 0.04) 45%, rgba(165, 139, 255, 0.12) 100%),
      #1c1b22;
  }
}

/* ---------- Illustration covers ---------- */

/* The mark is drawn on a frosted glass disc over the pattern. */
.case-card-media.is-mark img:not(.art-still),
.case-cover.is-mark img:not(.art-still),
.next-media.is-mark img:not(.art-still) {
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.38);
  -webkit-backdrop-filter: blur(5px) saturate(1.2);
  backdrop-filter: blur(5px) saturate(1.2);
  box-shadow: 0 12px 40px rgba(24, 12, 70, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.45);
}

/* A study shown with an illustration instead of product screens: the mark sits
   centred on the pattern, at a fixed share of the panel. */
.case-card-media.is-mark img:not(.art-still) {
  inset: 0;
  width: min(34.5%, 180px);
  height: auto;
  margin: auto;
}

.case-card:hover .case-card-media.is-mark img:not(.art-still) {
  transform: scale(1.03);
  transform-origin: center;
}

.case-cover.is-mark img:not(.art-still) {
  display: block;
  width: min(31.5%, 285px);
  height: auto;
  margin: clamp(16px, 4vw, 48px) auto;
}

.next-media.is-mark img:not(.art-still) {
  width: min(41%, 150px);
  height: auto;
  transform-origin: center;
}

/* Their components show at three quarters of the content width (full width
   on phones, where smaller would be too small to read). */
.case-body.is-mark .shot img {
  display: block;
  width: 75%;
  margin-inline: auto;
}

.case-body.is-mark .shot figcaption {
  text-align: center;
}

@media (max-width: 760px) {
  .case-body.is-mark .shot img {
    width: 100%;
  }
}

/* ---------- Switching light and dark ---------- */

/* A band of puzzle pieces in the pattern colours sweeps up the screen; just
   behind it the old page (a view-transition snapshot) is cut away from the bottom
   up, so the new theme appears beneath the pieces (js/board.js). Only transform,
   opacity and one clip animate, so it stays smooth. */
::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

::view-transition-old(root) {
  z-index: 1;
  animation: theme-wipe var(--wipe-time) linear var(--wipe-delay) both;
}

@keyframes theme-wipe {
  from {
    clip-path: inset(0 0 0 0);
  }
  to {
    clip-path: inset(0 0 100% 0);
  }
}

::view-transition-new(theme-puzzle),
::view-transition-old(theme-puzzle) {
  animation: none;
}

.theme-puzzle {
  position: fixed;
  inset: 0;
  z-index: 1000;
  pointer-events: none;
  view-transition-name: theme-puzzle;
}

.theme-puzzle i {
  position: absolute;
  border-radius: 2px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
  opacity: 0;
  will-change: transform, opacity;
}

/* While the switch plays, nothing else fades on its own. */
.theme-switching *,
.theme-switching *::before,
.theme-switching *::after {
  transition: none !important;
}

.theme-switching .dock-mode::before {
  transition: transform 0.45s cubic-bezier(0.34, 1.4, 0.5, 1) !important;
}
