/* Site enhancements, v20261007b. Loaded after glass.css. */

/* ---------- Light grey sections ----------
   The site's own colour variables are remapped, so components re-colour
   themselves. Contrast on #D9D9D9: text 13.9:1, body ~10:1, dim 5.9:1,
   small orange text (#A82E18) 4.85:1. */
.sec--light {
  --bg: #D9D9D9;
  --bg-alt: #D1D1D2;
  --surface: #E4E4E5;
  --surface-2: #ECECED;
  --border: #B8BBC1;
  --text: #0A0B0F;
  --text-body: #2E3138;
  --text-dim: #4A4E57;
  --text-faint: #50545C;
  --accent-2: #A82E18;
  background: var(--bg);
  color: var(--text);
}
.sec--light .tag { color: #A82E18; }
.th-rail__viewport::before { background: linear-gradient(90deg, var(--bg), transparent); }
.th-rail__viewport::after { background: linear-gradient(270deg, var(--bg), transparent); }

/* ---------- About: same near-black as the 30 Years banner's lower edge,
   so the two read as one block ---------- */
#about { background: #010101; }

/* ---------- Image bleed: letterboxed images sit on a blurred copy of
   themselves instead of black bars ---------- */
.has-bleed { background: var(--surface, #171a22) !important; overflow: hidden; }
.proj-hero.has-bleed { position: relative; }
.has-bleed::before {
  content: "";
  position: absolute;
  inset: -40px;
  z-index: 0;
  background: var(--bleed) center / cover no-repeat;
  filter: blur(36px) saturate(115%);
  opacity: .9;
  pointer-events: none;
}
.has-bleed > img { position: relative; z-index: 1; }
.carousel.has-scrub,
.proj-hero:has(> img) { background: var(--surface, #171a22); }

/* ---------- Carousel scrubber (replaces arrows and dots) ---------- */
.cs-wrap { position: relative; min-width: 0; }
.carousel.has-scrub { touch-action: pan-y; cursor: grab; }
.carousel.has-scrub:active { cursor: grabbing; }
.carousel.has-scrub .carousel__arrow,
.carousel.has-scrub .carousel__dots { display: none !important; }
.carousel.has-scrub img { -webkit-user-drag: none; user-select: none; }
.cs {
  --p: 0;
  position: relative;
  height: 28px;
  margin-top: 10px;
  cursor: pointer;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  outline: none;
}
.cs__line,
.cs__fill {
  position: absolute;
  left: 0;
  top: 50%;
  height: 2px;
  margin-top: -1px;
  border-radius: 1px;
  pointer-events: none;
}
.cs__line { right: 0; background: var(--border, #272c38); }
.cs__fill { width: calc(var(--p) * (100% - 14px) + 7px); background: var(--text-dim, #9aa0ad); transition: width .35s ease; }
.cs__mark {
  position: absolute;
  top: 50%;
  left: calc(var(--m) * (100% - 14px) + 7px);
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: var(--border, #272c38);
  pointer-events: none;
  transition: background .3s ease;
}
.cs__mark.is-past { background: var(--text-dim, #9aa0ad); }
.cs__dot {
  position: absolute;
  top: 50%;
  left: calc(var(--p) * (100% - 14px));
  z-index: 1;
  width: 14px;
  height: 14px;
  margin-top: -7px;
  border-radius: 50%;
  background: var(--text, #f2f1ee);
  box-shadow: 0 0 0 4px var(--bg, #0a0b0f);
  transition: left .35s cubic-bezier(.23, 1, .32, 1), scale .15s ease;
  pointer-events: none;
}
.cs:hover .cs__dot { scale: 1.15; }
.cs.is-scrubbing .cs__dot { scale: 1.25; transition: scale .15s ease; }
.cs:focus-visible .cs__dot { outline: 2px solid var(--accent-2, #E5FF53); outline-offset: 3px; }

/* ---------- Staggered reveal + parallax ---------- */
.st > * {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s ease, transform .8s cubic-bezier(.2, .7, .2, 1);
  transition-delay: calc(var(--i, 0) * 90ms);
}
.st.is-in > * { opacity: 1; transform: none; }
#how-i-work .aiops__card > * { translate: 0 var(--py, 0px); }
#how-i-work .aiops__card .role {
  display: inline-block;
  transition: letter-spacing .9s cubic-bezier(.2, .7, .2, 1), color .9s ease;
}
#how-i-work .aiops__grid:not(.is-in) .aiops__card .role { letter-spacing: .5em; }

/* ---------- Client voices as a messaging thread (no box: the messages
   sit straight on the section, the scroll area fades at the top) ---------- */
.chat { max-width: 820px; margin: 8px auto 0; }
.chat__body {
  height: min(600px, 72vh);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 36px 4px 12px;
  scroll-behavior: smooth;
  outline: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 56px);
          mask-image: linear-gradient(to bottom, transparent 0, #000 56px);
  scrollbar-width: thin;
}
.chat__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 16px; }
.msg {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  max-width: 88%;
  opacity: 0;
  transform: translateY(14px) scale(.98);
  transform-origin: 0 100%;
  transition: opacity .45s ease, transform .5s cubic-bezier(.2, .9, .3, 1.2);
}
.msg:not(.is-in) { display: none; }
.msg.is-in { display: flex; animation: msgIn .5s cubic-bezier(.2, .9, .3, 1.2) both; opacity: 1; transform: none; }
@keyframes msgIn { from { opacity: 0; transform: translateY(14px) scale(.96); } to { opacity: 1; transform: none; } }
.msg__avatar {
  flex: none;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--surface-2);
}
.msg__bubble {
  position: relative;
  padding: 12px 16px 14px;
  border-radius: 18px 18px 18px 6px;
  background: var(--surface-2);
  border: 1px solid var(--border);
}
.msg__who { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin-bottom: 6px; }
.msg__who strong { font-size: 13.5px; color: var(--text); }
.msg__who span { font-size: 12px; color: var(--text-faint); }
.msg__text { margin: 0; }
.msg__text p { margin: 0; font-size: 15.5px; line-height: 1.55; color: var(--text-body); }
.chat__typing {
  display: none;
  gap: 4px;
  align-items: center;
  width: max-content;
  margin: 16px 0 0 46px;
  padding: 12px 14px;
  border-radius: 18px 18px 18px 6px;
  background: var(--surface-2);
  border: 1px solid var(--border);
}
.chat__typing.is-on { display: flex; }
.chat__typing span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--text-dim);
  animation: typing 1.1s infinite ease-in-out;
}
.chat__typing span:nth-child(2) { animation-delay: .15s; }
.chat__typing span:nth-child(3) { animation-delay: .3s; }
@keyframes typing { 0%, 60%, 100% { transform: translateY(0); opacity: .45; } 30% { transform: translateY(-4px); opacity: 1; } }
@media (max-width: 640px) {
  .chat__body { height: min(540px, 74vh); padding: 28px 0 10px; }
  .msg { max-width: 96%; }
  .msg__text p { font-size: 15px; }
}

@media (prefers-reduced-motion: reduce) {
  .st > * { opacity: 1; transform: none; transition: none; }
  #how-i-work .aiops__card > * { translate: none; }
  .msg, .msg.is-in { display: flex; opacity: 1; transform: none; animation: none; }
  .cs__dot, .cs__fill { transition: none; }
}

/* Parallax lives on the card contents; the card boxes stay put so the
   1px grid lines never double up */
#how-i-work .aiops__card { overflow: hidden; }

/* Tool icons: no extra hairlines above and below the animated marks
   (the row dividers stay) */
#how-i-work .tool-row__marks::before { border-top: 0; border-bottom: 0; }

/* Metadata pills: same family as the project tags */
.meta-pills { display: flex; flex-wrap: wrap; gap: 8px; }
.meta-pill {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-dim);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .08em;
  line-height: 1.2;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Pull quote in "How I work": no box. Set as a large typographic
   statement with a hanging opening mark and a small source line. */
#how-i-work .aiops__quote {
  position: relative;
  max-width: 980px;
  margin-left: auto;
  margin-right: auto;
  padding: 8px 0 0 clamp(28px, 4vw, 56px);
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  font-size: clamp(22px, 2.4vw, 32px);
  line-height: 1.38;
  letter-spacing: -.01em;
  color: var(--text);
}
#how-i-work .aiops__quote::before {
  content: "\201C";
  position: absolute;
  left: 0;
  top: -.18em;
  font-family: Georgia, "Times New Roman", serif;
  font-size: 2.6em;
  line-height: 1;
  color: var(--accent);
}
#how-i-work .aiops__quote span {
  display: block;
  margin-top: 18px;
  font-size: 13px;
  letter-spacing: 0;
  line-height: 1.4;
  color: var(--text-dim);
}

/* Pull quote between "The shift" and Selected proof (same family as the
   How I work quote) */
.pullquote {
  position: relative;
  max-width: 980px;
  margin: clamp(56px, 7vw, 96px) auto 0;
  padding: 8px 0 0 clamp(28px, 4vw, 56px);
  border: 0;
}
.pullquote p {
  margin: 0;
  font-size: clamp(22px, 2.4vw, 32px);
  line-height: 1.38;
  letter-spacing: -.01em;
  color: var(--text);
}
.pullquote::before {
  content: "\201C";
  position: absolute;
  left: 0;
  top: -.18em;
  font-family: Georgia, "Times New Roman", serif;
  font-size: clamp(57px, 6.2vw, 83px);
  line-height: 1;
  color: var(--accent);
}

/* Pop-up forms: no accent line down the left edge */
.signup-modal__inner::before,
.enquiry-modal__inner::before { display: none; }

/* Featured document: weServed Brand Guidelines under "What I delivered" */
.doc-strip.doc-strip--feature {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  align-items: stretch;
  gap: 0;
  margin: 28px 0 32px;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius, 14px);
  background: var(--surface);
  text-decoration: none;
  color: var(--text);
  transition: border-color .25s ease, transform .4s cubic-bezier(.2, .7, .2, 1), box-shadow .4s ease;
}
.doc-strip.doc-strip--feature:hover {
  border-color: var(--text-dim);
  transform: translateY(-2px);
  box-shadow: 0 24px 50px -30px rgba(0, 0, 0, .5);
}
.doc-strip--feature .doc-strip__thumb {
  order: -1;
  position: relative;
  display: block;
  width: auto;
  height: auto;
  min-height: 260px;
  margin: 0;
  border-radius: 0;
  overflow: hidden;
}
.doc-strip--feature .doc-strip__thumb img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .8s cubic-bezier(.2, .7, .2, 1);
}
.doc-strip--feature:hover .doc-strip__thumb img { transform: scale(1.03); }
.doc-strip--feature .doc-strip__title {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
  padding: clamp(22px, 3vw, 36px);
  font-size: clamp(20px, 2vw, 26px);
  font-weight: 700;
  line-height: 1.2;
}
.doc-strip--feature .doc-strip__title small {
  display: block;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.5;
  color: var(--text-body);
}
.doc-strip--feature .doc-strip__cta {
  position: static;
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  width: auto;
  height: 42px;
  margin-top: 8px;
  padding: 0 18px;
  border: 1px solid var(--text);
  border-radius: 999px;
  background: var(--text);
  color: var(--bg);
  font: 600 14px/1 var(--font);
  transition: background .2s ease, color .2s ease;
}
.doc-strip--feature:hover .doc-strip__cta { background: transparent; color: var(--text); }
@media (max-width: 720px) {
  .doc-strip.doc-strip--feature { grid-template-columns: 1fr; }
  .doc-strip--feature .doc-strip__thumb { min-height: 0; aspect-ratio: 16 / 10; }
}

/* Grey sections: cards sit on the grey as clean panels, no hairline
   stroke (the stroke never traced the image corners exactly) */
.sec--light .proof-card {
  border: 0;
  box-shadow: none;
  overflow: hidden;
  background: var(--surface);
}
.sec--light .proof-card img { border-radius: 0; }

/* ---------- Scrubber dot (v20261007b) ----------
   One "you are here" control across every scrubber: brand yellow,
   50% larger (21px), a mid-grey chevron pointing the way you can go
   (forward, flipping back once you reach the end), a soft drop shadow
   so it reads as something to grab on light and dark sections, and a
   slow yellow breath to invite interaction. No ring. */
.th-rail__progress span,
.cs__dot,
.cf-scrub__dot {
  width: 21px !important;
  height: 21px !important;
  margin-top: -10.5px !important;
  left: calc(var(--p) * (100% - 21px)) !important;
  background: #E5FF53 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.5 6.5 15 12l-5.5 5.5' fill='none' stroke='%23464A53' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 15px 15px no-repeat !important;
  border: 0 !important;
  box-shadow: 0 2px 8px rgba(10, 11, 15, .28), 0 0 0 0 rgba(229, 255, 83, .55) !important;
  animation: thDotBreath 2.8s ease-out infinite;
}
.th-rail__progress.is-end span,
.cs.is-end .cs__dot,
.cf-scrub.is-end .cf-scrub__dot {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M14.5 6.5 9 12l5.5 5.5' fill='none' stroke='%23464A53' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important;
}
.th-rail__progress::after,
.cs__fill,
.cf-scrub::after {
  width: calc(var(--p) * (100% - 21px) + 10.5px) !important;
}
.th-rail__progress.is-scrubbing span,
.cs.is-scrubbing .cs__dot,
.cf-scrub.is-scrubbing .cf-scrub__dot { animation: none; }
@keyframes thDotBreath {
  0%   { box-shadow: 0 2px 8px rgba(10, 11, 15, .28), 0 0 0 0 rgba(229, 255, 83, .55); }
  70%  { box-shadow: 0 2px 8px rgba(10, 11, 15, .28), 0 0 0 10px rgba(229, 255, 83, 0); }
  100% { box-shadow: 0 2px 8px rgba(10, 11, 15, .28), 0 0 0 0 rgba(229, 255, 83, 0); }
}
.cs:focus-visible .cs__dot { outline: none; box-shadow: 0 2px 8px rgba(10, 11, 15, .28), 0 0 0 4px rgba(229, 255, 83, .5) !important; }

/* ---------- Close buttons (v20261007b) ----------
   Same language as the scrubber dot: yellow disc, dark cross, soft drop
   shadow, no ring. Keyboard focus shows a soft yellow halo instead of a
   hard (and, inside the grey project view, red) outline. */
.cf-close,
.promo-modal__close,
.th-rail__close,
.reel-lightbox__close,
.reel-modal__close,
.signup-modal__close,
.cv-modal__close,
.enquiry-modal__close {
  width: 40px !important;
  height: 40px !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 50% !important;
  background: #E5FF53 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M7.5 7.5l9 9M16.5 7.5l-9 9' fill='none' stroke='%230A0B0F' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E") center / 20px 20px no-repeat !important;
  color: transparent !important;
  font-size: 0 !important;
  box-shadow: 0 3px 12px rgba(10, 11, 15, .32) !important;
  -webkit-backdrop-filter: none !important;
          backdrop-filter: none !important;
  outline: none !important;
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease;
}
.cf-close > *,
.promo-modal__close > *,
.th-rail__close > *,
.reel-lightbox__close > *,
.reel-modal__close > *,
.signup-modal__close > *,
.cv-modal__close > *,
.enquiry-modal__close > * { display: none !important; }
.cf-close:hover,
.promo-modal__close:hover,
.th-rail__close:hover,
.reel-lightbox__close:hover,
.reel-modal__close:hover,
.signup-modal__close:hover,
.cv-modal__close:hover,
.enquiry-modal__close:hover { transform: scale(1.06); box-shadow: 0 5px 16px rgba(10, 11, 15, .38) !important; }
.cf-close:focus-visible,
.promo-modal__close:focus-visible,
.th-rail__close:focus-visible,
.reel-lightbox__close:focus-visible,
.reel-modal__close:focus-visible,
.signup-modal__close:focus-visible,
.cv-modal__close:focus-visible,
.enquiry-modal__close:focus-visible { box-shadow: 0 3px 12px rgba(10, 11, 15, .32), 0 0 0 5px rgba(229, 255, 83, .45) !important; }

@media (prefers-reduced-motion: reduce) {
  .th-rail__progress span, .cs__dot, .cf-scrub__dot { animation: none; }
  .cf-close, .promo-modal__close, .th-rail__close, .reel-lightbox__close { transition: none; }
}

/* Client voices: the window grows with the conversation (v20261007a).
   Height is set by enhance.js to fit the messages so far; the top fade
   only applies once the window is full and starts scrolling inside. */
.chat--grow .chat__body {
  min-height: 0;
  transition: height .6s cubic-bezier(.22, .8, .24, 1);
  -webkit-mask-image: none;
          mask-image: none;
}
.chat--grow.chat--full .chat__body {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 56px);
          mask-image: linear-gradient(to bottom, transparent 0, #000 56px);
}
.chat--grow .chat__body { overflow-y: hidden; }
.chat--grow.chat--full .chat__body { overflow-y: auto; }
@media (prefers-reduced-motion: reduce) {
  .chat--grow .chat__body { transition: none; }
}
