/* Site additions on top of the Webflow export. */

/* ------------------------------------------------------------ brand tokens
   LK Brand v2.1 (docs/brand/brand-digest.md). The Webflow variables are the
   template's names; pointing them at the brand values rethemes every surface
   without touching webflow.css. Volt #E6DE2E, Ink #161617/#222223, Paper
   #FAFAF7. The template's orange survives only as a variable name: anything
   still reading it gets Volt. */
:root {
  --bg-colors--cream: #FAFAF7;            /* Paper, the lead light surface */
  --bg-colors--creamy: #EDEAE2;           /* brand cream, secondary light */
  --bg-colors--black: #161617;            /* Ink deep */
  --bg-colors--black-gray: #222223;       /* Ink */
  --bg-colors--brand-background: #222223; /* Ink */
  --bg-colors--orange: #E6DE2E;           /* orange is banned; alias to Volt */
  --bg-colors--yellow-main: #E6DE2E;      /* Volt */
  --text-colors--black: #161617;          /* Ink-deep text on Paper */
  --text-colors--dark-gray: #77777A;      /* brand n500 */
  --line-colors--dark-gray: #48484A;      /* hairline on Ink */
  --line-colors--medium-gray: #A8A8AB;    /* brand n400 */
}

/* Text selection carries the signal. */
::selection { background: #E6DE2E; color: #161617; }

/* Headings promoted to h1 for semantics keep their original visual size. */
.u-h2 { font-size: var(--_typography---heading-size--h2); line-height: var(--_typography---heading-line-height--h2-line-height); letter-spacing: var(--_typography---letter-spacing--2px); margin-top: 0; margin-bottom: 0; font-weight: 500; }
.u-h3 { font-size: var(--_typography---heading-size--h3); line-height: var(--_typography---heading-line-height--h3-line-height); letter-spacing: var(--_typography---letter-spacing--2px); margin-top: 0; margin-bottom: 0; font-weight: 500; }
.u-h4 { font-size: var(--_typography---heading-size--h4); line-height: var(--_typography---heading-line-height--h4-line-height); letter-spacing: var(--_typography---letter-spacing--1-5px); margin-top: 0; margin-bottom: 0; font-weight: 600; }
.u-h5 { font-size: var(--_typography---heading-size--h5); line-height: var(--_typography---heading-line-height--h5-line-height); letter-spacing: var(--_typography---letter-spacing--1-5px); margin-top: 0; margin-bottom: 0; font-weight: 500; }

/* Every image element now carries its intrinsic width/height so the browser can
   reserve space before the file loads (Cumulative Layout Shift). Those also
   act as presentational hints, so an image whose CSS constrains only one axis
   (the logos are max-width:200px with no height) would otherwise be forced to
   its full intrinsic height and squash. height:auto restores aspect-ratio
   sizing. Deliberately a bare element selector: any Webflow rule that sets a
   real height, such as .work-thumbnail-image, outranks it and still wins. */
img {
  height: auto;
}

/* Visible keyboard focus. Gold-600 rather than Volt: Volt on Paper measures
   1.6:1 and disappears, and the same ring has to work on both surfaces. */
:focus-visible { outline: 2px solid #A47E1B; outline-offset: 2px; }
.w-nav-button:focus-visible { outline: 2px solid #A47E1B; }

.faq-accordion { cursor: pointer; }

/* Respect reduced motion: stop animations and reveal scroll-hidden content. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  [data-w-id] { opacity: 1 !important; transform: none !important; filter: none !important; }
}

/* Skip link: hidden until keyboard focus. */
.skip-link {
  position: absolute;
  left: -9999px;
  z-index: 1000;
  padding: 12px 20px;
  background: var(--bg-colors--brand-background, #222223);
  color: #fff;
  border-radius: 0 0 8px 0;
}
.skip-link:focus {
  left: 0;
  top: 0;
}

/* Service/Expertise stack: cards are position:sticky and pile up on scroll.
   The template spaces them with a transparent flex gap, so the pinned card
   underneath peeks through while two cards overlap (visible with bright
   images). Move the spacing into the cards so the incoming card covers the
   previous one seamlessly. */
.service-section-content {
  grid-row-gap: 0;
}
.service-item {
  padding-bottom: 48px;
}
.service-item:last-child {
  padding-bottom: 0;
}
@media screen and (max-width: 991px) {
  .service-item {
    padding-bottom: 100px;
  }
  .service-item:last-child {
    padding-bottom: 0;
  }
}

/* Footer newsletter wrappers, restored verbatim from the live template CSS
   (zephyr-studio.webflow.io, .footer-newsletter-*): the Exflow scrape kept
   .footer-field/.footer-submit-button in webflow.css but dropped these three
   wrapper classes together with the form markup. ".footer-newsletter-from"
   (sic) is the template's own class name. */
.footer-newsletter-block {
  width: 100%;
  max-width: 310px;
}
.footer-newsletter-form-block {
  margin-bottom: 0;
}
.footer-newsletter-from {
  justify-content: flex-start;
  align-items: center;
  display: flex;
  position: relative;
}
@media screen and (max-width: 991px) {
  .footer-newsletter-block {
    max-width: 290px;
  }
}
@media screen and (max-width: 479px) {
  .footer-newsletter-block {
    max-width: 100%;
  }
}

/* The scroll parallax translates card images vertically inside an unclipped
   card, so an image can poke above its card's top border into the previous
   card of the stack. Clip the card box (clip, not hidden: keeps sticky). */
.service-item {
  overflow: clip;
}

/* Article body typography.
   Markdown in a post renders real h2/h3 elements inside .blog-rich-text, and the
   site's element styles size headings for page titles (h2 is 92px at desktop).
   Dropped into running copy that reads as display type wedged between two
   paragraphs with no space around it. The template's original posts used bold
   lead-ins rather than headings, so this never came up. Scope article headings
   to a reading scale and give the flow real vertical rhythm. */
/* Section eyebrow dot ("Selected", "Shortly", "Projects"). The template paints
   it with the near-black brand background, which reads as a stray grey speck.
   It is the one repeated accent mark on the page, so give it the brand yellow. */
.sub-title-dot {
  background-color: #E6DE2E; /* Volt, exact */
}

/* Focus-area bullets.
   The row is a flex line with align-items:center, so the 6px dot centres
   against the whole text block. On one line that looks right; as soon as the
   text wraps the dot drifts into the gap between the two lines. Pin it to the
   optical centre of the first line instead, and stop it being squashed when
   the text is long. */
.pricing-card-features-list-block {
  align-items: flex-start;
}
.pricing-card-features-list-dot {
  flex: 0 0 auto;
  /* half a line box, less half the dot: sits on the first line at any width */
  margin-top: calc((1.5em - 6px) / 2);
}

/* The light logo exists only for the open mobile menu (see below). It has to
   be hidden everywhere else, including desktop, so this rule sits outside the
   breakpoint that shows it. */
.nav-brand-logo-open {
  display: none;
}

/* Mobile menu.
   Webflow's mobile panel is a 200px card floating under the burger: the page
   shows through it, the items sit in a cramped column, and on the light pages
   the dark logo and burger disappear against whatever is behind them. Replace
   it with a full-screen surface.

   .w-nav-overlay is the element Webflow shows and hides, so everything hangs
   off it and no extra JavaScript is needed. Webflow writes an inline height
   (the whole document height, several thousand pixels) onto it, which is why
   the height below has to be !important. svh is the viewport iOS actually
   shows, excluding the browser chrome. */
@media screen and (max-width: 991px) {
  .navbar .w-nav-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: 100vh !important;
    height: 100svh !important;
  }

  .navigation-menu-wrapper {
    width: 100%;
    height: 100%;
    /* [data-nav-menu-open] ships min-width:200px and text-align:center, which
       is what made the panel a narrow centred card. */
    min-width: 0;
    max-width: none;
    text-align: left;
    margin: 0;
    /* 96px clears the 62px navbar with room to breathe; 25px is the site
       gutter, so the menu items line up with the page content behind them. */
    padding: 96px 25px 40px;
    border-radius: 0;
    background-color: #161617;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    align-items: flex-start;
    overflow-y: auto;
  }

  /* Webflow's [data-nav-menu-open] carries display:block !important, so the
     wrapper cannot be a flex container and cannot centre anything itself. Let
     the inner column fill the wrapper's content box and centre there instead:
     the four links and the button sit in the middle of the screen rather than
     bunched under the logo with half a screen of black below them. */
  .navigation-menu {
    flex-flow: column;
    justify-content: center;
    align-items: flex-start;
    gap: 24px;
    width: 100%;
    min-height: 100%;
  }
  .navigation-menu .navigation-link-text {
    color: var(--text-colors--white, #fff);
    font-size: 32px;
    line-height: 1.25;
  }
  /* The button is the last item in the same column; give it its own step of
     air rather than letting it read as a fifth link. */
  .navigation-menu .nav-button.none {
    margin-top: 16px;
  }

  /* The bar itself has to stay above the panel, or the burger cannot be
     tapped again to close it. */
  .navbar .nav-content-wrapper {
    position: relative;
    z-index: 2;
  }

  /* Sub pages carry a dark logo and dark burger lines for their cream
     background. Over the open panel they would be invisible, so swap both to
     the light treatment while it is open. (The second logo is hidden by a base
     rule outside this media query, or it would show on desktop too.) */
  .navbar:has(.w-nav-button.w--open) .nav-brand-logo.on-light {
    display: none;
  }
  .navbar:has(.w-nav-button.w--open) .nav-brand-logo-open {
    display: block;
  }
  .navbar:has(.w-nav-button.w--open) .menu-icon-top,
  .navbar:has(.w-nav-button.w--open) .menu-icon-middle,
  .navbar:has(.w-nav-button.w--open) .menu-icon-bottom {
    background-color: var(--text-colors--white, #fff);
  }

  /* Stop the page scrolling underneath the open panel. */
  html:has(.w-nav-button.w--open),
  body:has(.w-nav-button.w--open) {
    overflow: hidden;
  }
}

/* Inline form confirmation (see the fetch handler in site.js).
   Webflow ships .w-form-done as centred text on #ddd and .w-form-fail on
   #ffdede, which belong to no palette on this site. These are shown in place of
   the form after a successful send, so they need to sit in the surface they
   replace: cream on the contact page, black in the footer. */
.w-form-done,
.w-form-fail {
  text-align: left;
  padding: 22px 24px;
  border-radius: var(--_border-radius---border-radius-10, 10px);
  font-size: 16px;
  line-height: 1.5;
}
.w-form-done {
  background: rgba(0, 0, 0, 0.04);
  border: 1px solid rgba(0, 0, 0, 0.14);
  color: #000;
}
.w-form-fail {
  background: rgba(168, 30, 20, 0.07);
  border: 1px solid rgba(168, 30, 20, 0.28);
  color: #8c1711;
  margin-top: 12px;
}

/* The footer sits on black, so the newsletter's confirmation inverts. */
.footer-newsletter-block .w-form-done,
.footer-newsletter-block .w-form-fail {
  padding: 14px 16px;
  font-size: 15px;
}
.footer-newsletter-block .w-form-done {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.22);
  color: #fdf8e7;
}
.footer-newsletter-block .w-form-fail {
  background: rgba(255, 133, 119, 0.12);
  border-color: rgba(255, 133, 119, 0.35);
  color: #ff9d92;
}

/* Article card excerpt on the blog listing. Clamped to three lines so cards in
   a row keep the same height regardless of how long a description runs. */
.blog-excerpt {
  margin: 10px 0 0;
  font-size: 15px;
  line-height: 1.5;
  opacity: 0.72;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.blog-rich-text h2 {
  font-size: 32px;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 56px 0 16px;
}
.blog-rich-text h3 {
  font-size: 24px;
  line-height: 1.3;
  font-weight: 600;
  margin: 40px 0 12px;
}
.blog-rich-text h2:first-child,
.blog-rich-text h3:first-child {
  margin-top: 0;
}
.blog-rich-text p {
  margin: 0 0 20px;
}
.blog-rich-text p:last-child {
  margin-bottom: 0;
}
.blog-rich-text ul,
.blog-rich-text ol {
  margin: 0 0 20px;
  padding-left: 22px;
}
.blog-rich-text li {
  margin-bottom: 8px;
}
/* Inline bold in article copy.
   webflow.css styles a bare `strong` as a standalone emphasis block:
   font-size: var(--_typography---text-size--text-large), which is 40px at
   desktop. Inside a 16px paragraph that renders a bolded phrase two and a half
   times the size of the sentence around it. Inline emphasis has to inherit the
   text it sits in; only the weight should change. */
.blog-rich-text strong,
.blog-rich-text b {
  font-size: inherit;
  line-height: inherit;
  letter-spacing: inherit;
  color: inherit;
  font-weight: 600;
}
.blog-rich-text code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.92em;
  background: rgba(0, 0, 0, 0.06);
  padding: 2px 5px;
  border-radius: 4px;
}
@media screen and (max-width: 767px) {
  .blog-rich-text h2 {
    font-size: 26px;
    margin-top: 40px;
  }
  .blog-rich-text h3 {
    font-size: 21px;
    margin-top: 32px;
  }
}

/* ---------------------------------------------------------------- mobile fixes
   Three problems that only appear on narrow screens. */
@media screen and (max-width: 991px) {
  /* 1. The hero is height:82vh with overflow:hidden on the wrapper, so its
     content is silently cut off when it does not fit. At a 320px viewport
     (an iPhone with Display Zoom set to Larger Text) the title wraps to five
     lines instead of four and the service tags were clipped by 125px. A fixed
     box holding variable-length text can only ever be a guess; let it grow.

     82vh also left a band of empty cream under the hero on shorter phones
     while the text above it looked cramped. The card inside the hero is inset
     by the same few pixels on every side, so the section is a full viewport
     tall and the gap under the card matches the gaps beside and above it.
     svh is the viewport excluding browser chrome, which is what iOS actually
     shows; vh stays as the fallback for older engines. */
  .hero-section {
    height: auto;
    min-height: 82vh;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
  }
  .hero-content-wrapper {
    height: auto;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
  }
  .hero-content {
    height: auto;
    flex: 1 1 auto;
    padding-bottom: 28px;
  }

  /* 2. One mobile gutter, everywhere.
     Measured across the site there were five different left edges at 393px:
     18, 23, 25, 40 and 48. On /works/ the page title sat at 40 while the cards
     below it sat at 25, on the same screen. The containers are the source, so
     fix it there rather than per section: everything that uses a page
     container now starts at the same 25px the cards and Expertise items use. */
  .container-large,
  .container-medium,
  .container-small {
    padding-left: 25px;
    padding-right: 25px;
  }

  /* 3. The category label flips to "View Work" on hover: two lines stacked in a
     20px window with overflow:hidden, so only one shows. The block is a fixed
     130px, and at mobile widths "Product Design" wraps to two lines, making the
     window 40px and revealing both at once. Keep each label on one line. */
  .work-category-block {
    width: auto;
    max-width: 62%;
  }
  .work-category {
    white-space: nowrap;
  }

  /* 4. The Experience table is the template's awards table, which swaps columns
     by breakpoint: desktop shows Position and Company, mobile shows "Awards
     Name" and "Awards Title" instead. Used as an experience list that surfaces
     leftover template headings and a second line per row ("Creative
     Excellence", "Top Campaign"). Show the same two columns as desktop. */
  .awards-hide-wrap {
    display: none;
  }
  .awards-info-block.n {
    display: block;
  }
  .awards-row,
  .awards-row-title {
    flex-wrap: nowrap;
    justify-content: space-between;
    align-items: baseline;
    gap: 16px;
  }
  /* The position takes the space it needs and wraps inside its own column; the
     company stays on the right rather than dropping to a line of its own, so
     every row reads the same way whether the job title is short or long. */
  .awards-row > .awards-info-block.n,
  .awards-row-title > .awards-info-block.n {
    flex: 1 1 auto;
    min-width: 0;
  }
  .awards-row > .awards-info-block:not(.n),
  .awards-row-title > .awards-info-block:not(.n) {
    /* Shrinkable, not fixed: "Unikrn (Acquired by Entain)" is wider than the
       space left over and would otherwise overflow into the job title. */
    flex: 0 1 auto;
    min-width: 0;
    text-align: right;
  }

  /* 5. The About portrait sat at a 12px inset while the heading and intro above
     it use the 40px container gutter, so the photo hung wider than the text it
     belongs to. Match them. (The template's class name carries a typo,
     "iamge"; kept verbatim because renaming it would break the export.) */
  .about-top-bg-iamge-wrapper {
    padding-left: 25px;
    padding-right: 25px;
  }
}

/* Work card label scrim.
   .work-info (title, year, category) is white text positioned absolutely over
   the thumbnail, with nothing behind it. The template's stock photos happened
   to be dark along their bottom edge; real project photography often is not (a
   pale sofa, a light desk), and the labels then measure as low as 1.2:1 against
   WCAG AA's 4.5:1. This gradient darkens only the bottom of the image, fading
   out entirely by mid-card. It is invisible on images that are already dark
   there, and it keeps the labels legible no matter which photo is swapped in
   later. Sits inside the wrapper's overflow:hidden so it follows the 16px
   radius; .work-info paints above it by virtue of coming later in the DOM. */
.work-thumbnail-image-wrapper {
  position: relative;
}
.work-thumbnail-image-wrapper::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 50%;
  pointer-events: none;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.66) 0%,
    rgba(0, 0, 0, 0.6) 14%,
    rgba(0, 0, 0, 0.34) 40%,
    rgba(0, 0, 0, 0.1) 70%,
    rgba(0, 0, 0, 0) 100%
  );
}

/* ------------------------------------------------------- audit fixes 2026-08
   From the accessibility/visual audit: tap targets and conversion path. */

/* The burger glyph is 30x20; the tappable area has to be 48x48 without moving
   the visual. */
.menu-button.w-nav-button {
  padding: 14px 9px;
  margin: -14px -9px;
}

/* Nav text links: full-height hit boxes instead of 20px text lines. */
.navigation-link {
  padding-top: 10px;
  padding-bottom: 10px;
}

/* Contact form fields: bottom-border inputs measured ~30px tall, under the
   44px touch guideline, and the tap area was invisible. */
.contact-field.w-input,
.contact-field.w-select,
.footer-field.w-input {
  min-height: 48px;
}

/* Mobile: the only conversion path was inside the closed menu. Keep a compact
   "Let's talk" pill visible next to the burger. */
@media screen and (max-width: 991px) {
  .nav-right .nav-button {
    display: flex;
  }
  .nav-right .nav-button .button {
    padding: 10px 18px;
  }
  .nav-right {
    display: flex;
    align-items: center;
    gap: 18px;
  }
}

/* Footer helpers added with the review fixes. */
.footer-newsletter-note {
  margin: 0 0 10px;
  font-size: 14px;
  line-height: 1.5;
  color: #A8A8AB;
}
.footer-quiet-line {
  font-size: 14px;
  color: #77777A;
  letter-spacing: 0.04em;
}

/* Byline link on posts: quiet, present. */
.blog-byline-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid #E6DE2E;
}
