/* ============================================
   LACCINO DIGITAL SITE CSS
   Type System: Helvetica Now Display + Suisse Int'l Mono
   Brand palette (2026):
     Evergreen Leaf     #479C73  PRIMARY - the page ground and controls
     Near White         #F6F5F3  primary light: cards, type, CTA
     Burnt Orange       #D4622C  accent: marks, rules, large emphasis
     Sun Yellow         #F0C845  accent: highlights, attention states
     Sky Blue           #7EADDB  secondary blue
     Aqua               #6DBEC6  supporting teal-blue
     Sand               #E6D4BE  warm neutral
     Grant Purple       #9967CA  scoped dashboard/product accent
   Contrast rule: Burnt Orange is 3.45:1 on Near White and about 1.2:1 on
   Leaf, so it never carries small text. Use it for marks, rules and large
   display type on light surfaces; small labels stay deep green.
   Type is near-white. #F6F5F3 is the same hue as the old bone (40deg) and a
   few steps lighter, and it is the one light value: the floating cards, the
   footer logo and lockup, the footer copy, and every light label use it.
   ============================================ */
:root {
  /* ── Palette ─────────────────────────────────────────────────────────── */
  /* The six brand colours. Everything below aliases these. */
  --leaf:         #479C73;
  --burnt-orange: #D4622C;
  --sun:          #F0C845;
  --sky:          #7EADDB;
  --aqua:         #6DBEC6;
  --sand:         #E6D4BE;
  --grant-purple: #9967CA;
  /* Carbon: the one black. It carries the hero, the product panels and the
     dark feature sections, so the green reads as an accent, not the ground. */
  --carbon:        #0B0C0B;
  --carbon-raised: #151816;   /* cards and controls that sit on carbon */

  /* Muted values stay in the family of the colour they support. They are
     translucent versions of the primary, not unrelated grey additions. */
  --leaf-muted:   rgba(71, 156, 115, 0.72);
  --sky-muted:    rgba(126, 173, 219, 0.72);
  --aqua-muted:   rgba(109, 190, 198, 0.72);

  --green:  var(--leaf);   /* PRIMARY - the page ground */
  --button-green: var(--green); /* leaf-green primary for interactive fills */
  --sage:   var(--aqua);   /* retired: Tidal Sage folds into Aqua */
  --peri:   var(--sky);
  --slate:  var(--aqua);
  --terra:  var(--burnt-orange);
  --gold:   var(--sun);
  --ground: #479c73;
  /* Forest green is the ink on light surfaces; carbon (above) is the dark
     surface. No other near-black belongs in the interface. */
  --deep:   var(--green-strong);
  /* The light band shares the site's near-white surface, with deep ink for
     clear, consistent contrast. */
  --warm:   var(--white);
  /* The near-white. Same hue as the bone it replaces, a few steps lighter. */
  --white:  #F6F5F3;

  --green-bg:   var(--ground);
  /* Strong evergreen foreground for labels and text on translucent cards. */
  --green-strong: #26503C;
  --green-text: var(--green-strong);

  /* Semantic aliases. Components reference these, so the palette lives in one
     place and every name resolves to one of the values above. */
  --bg:           var(--ground);
  --surface:      var(--ground);
  --surface-deep: var(--warm);
  /* The floating cards and the footer are the near-white surface. */
  --panel:        var(--white);
  --text:         var(--white);
  --ink:          var(--green-strong);  /* accessible type on near-white panels */
  --accent:       var(--green);
  --accent-2:     var(--slate);
  --green-accent: var(--green);
  --olive: var(--white);
  --teak:  var(--white);
  --lime:  var(--white);
  --text-muted:  rgba(246, 245, 243, 0.78);
  --text-subtle: rgba(246, 245, 243, 0.70);
  --muted: var(--text-muted);
  --font-suisse: "Suisse Int'l Mono", monospace;
  --line:   rgba(246, 245, 243, 0.15);
  --line-2: rgba(246, 245, 243, 0.25);
  --cream:  var(--white);
  --orange: var(--burnt-orange);
  /* Small eyebrow text on light bands: deep green for contrast; the orange
     goes on the eyebrow's marker and rule instead (see sections/home.css). */
  --orange-deep: var(--green-strong);
  --tan:    var(--sand);
  --forest-deepest: var(--warm);
  --forest-deep:    var(--ground);
  --forest:         var(--ground);
  --forest-lift:    var(--ground);
  --type-mono-xs:  clamp(12px, 0.7418rem + 0.0329vw, 12.5px);
  --type-mono-sm:  clamp(12px, 0.7336rem + 0.0658vw, 13px);
  --type-mono-md:  clamp(14px, 0.8421rem + 0.1316vw, 16px);
  --type-mono-lg:  clamp(22px, 1.2105rem + 0.6579vw, 32px);
  --type-disp-sm:  clamp(16px, 0.9671rem + 0.1316vw, 18px);
  --type-disp-md:  clamp(18px, 1.0263rem + 0.3947vw, 24px);
  --type-disp-lg:  clamp(28px, 1.1579rem + 2.3684vw, 64px);
  --type-disp-xl:  clamp(48px, 2.2105rem + 3.1579vw, 96px);
  --type-disp-2xl: clamp(56px, 2.3158rem + 4.7368vw, 128px);
  --track-display: -0.022em;
  --track-display-lg: -0.032em;
  --track-mono: 0.04em;
  --measure: 68ch;          /* readable max line length for body copy */
  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;  --space-4: 16px;
  --space-5: 24px;  --space-6: 32px;  --space-7: 48px;  --space-8: 64px;
  --space-9: 80px;  --space-10: 104px; --space-11: 136px; --space-12: 176px;
  --gutter: clamp(20px, 2.6vw, 50px);        /* was a hard 50px -> 20px jump at 768 */
  --section-y: clamp(56px, 7.2vw, 120px);    /* vertical section rhythm */
  --r-xs: 3px; --r-sm: 6px; --r-md: 10px; --r-lg: 16px; --r-xl: 24px;
  --r-full: 999px;
  /* Was a self-reference (var(--ease-out-expo)), which is invalid, so every
     transition using it computed to nothing and snapped. Restored to the
     curve it replaced. */
  --ease-out-expo:  cubic-bezier(0.19, 1, 0.22, 1);
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);
  --ease-in-out:    cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring:    cubic-bezier(0.34, 1.4, 0.64, 1);
  --dur-fast:   180ms;
  --dur-base:   300ms;
  --dur-slow:   560ms;
  --dur-slower: 900ms;
  /* Homepage Naka layer: new names preserve existing global token consumers. */
  --naka-r-sm: 16px;
  --naka-r-md: 24px;
  --naka-r-lg: 40px;
  --r-btn: 14px;
  --shadow-sm: 0 1px 2px rgb(21 23 20 / 4%), 0 2px 6px rgb(21 23 20 / 4%);
  --shadow-md: 0 2px 4px rgb(21 23 20 / 4%), 0 8px 24px rgb(21 23 20 / 6%);
  --shadow-lg: 0 4px 8px rgb(21 23 20 / 5%), 0 16px 48px rgb(21 23 20 / 8%);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --reveal-dur: 600ms;
  --hover-dur: 250ms;
  --card-pad: 24px;
  color-scheme: dark;
}

/* === RESET & BASE === */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: auto; overflow-x: clip; }
body { margin: 0; background: var(--bg); color: var(--text); font-family: 'Helvetica Now Display', arial, sans-serif; overflow-x: hidden; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }

/* No scrollbar down the right-hand edge. The page still scrolls by wheel,
   trackpad, touch, keyboard (arrows, Page Up/Down, Home/End, space) and by
   the smooth-scroll calls in main.js - only the bar itself is gone, the same
   way the mockup panels drop theirs in design-system.css.

   scrollbar-width covers Firefox; ::-webkit-scrollbar covers Chromium and
   Safari. Both are set on html AND body because the two engines disagree
   about which element owns the viewport's scrollbar. */
html { scrollbar-width: none; -ms-overflow-style: none; }
body { scrollbar-width: none; -ms-overflow-style: none; }
html::-webkit-scrollbar,
body::-webkit-scrollbar { display: none; width: 0; height: 0; }
a { text-decoration: none; color: inherit; }
ul, ol { list-style: none; margin: 0; padding: 0; }
img { max-width: 100%; height: auto; display: block; }
button { border: none; background: none; cursor: pointer; font-family: inherit; }
.no-list { list-style: none; padding: 0; margin: 0; }

/* === FONTS === */
/* ── Type system ─────────────────────────────────────────────────────────────
   Two typefaces, three roles — used consistently site-wide:
     • Helvetica Now Display  400  → body copy              (.f-hnd-*)
     • Helvetica Now Display  700  → display / headings     (.f-hndb-*)
     • Suisse Int'l Mono      400  → labels, eyebrows, meta  (.f-s-*)
   The two Helvetica weights are ONE family, selected via font-weight (so a bold
   usage must set font-weight: 700, otherwise it falls back to the 400 file). */
@font-face {
    font-display: swap;
    font-family: 'Helvetica Now Display';
    font-style: normal;
    font-weight: 400;
    src: url('../assets/fonts/HelveticaNowDisplay-Regular.woff2') format('woff2');
}
@font-face {
    font-display: swap;
    font-family: 'Helvetica Now Display';
    font-style: normal;
    font-weight: 700;
    src: url('../assets/fonts/HelveticaNowDisplay-Bold.woff2') format('woff2');
}
@font-face {
    font-display: swap;
    font-family: "Suisse Int'l Mono";
    font-style: normal;
    font-weight: 400;
    src: url('../assets/fonts/SuisseIntlMono-Regular-WebS.woff2') format('woff2');
}

/* === TYPOGRAPHY CLASSES ===
   Class names are unchanged (the markup references them). What changed behind
   them: sizes come from the capped fluid scale, display sizes carry negative
   tracking (large type needs to be pulled tighter), and body line-height opens
   from a cramped 120% to 150%. */
.f-s-12-100  { font-family: "Suisse Int'l Mono", monospace; font-size: var(--type-mono-xs); font-weight: 400; line-height: 100%; letter-spacing: var(--track-mono); }
.f-s-13-100  { font-family: "Suisse Int'l Mono", monospace; font-size: var(--type-mono-sm); font-weight: 400; line-height: 100%; letter-spacing: var(--track-mono); }
.f-s-16-100  { font-family: "Suisse Int'l Mono", monospace; font-size: var(--type-mono-md); font-weight: 400; line-height: 100%; letter-spacing: var(--track-mono); }
.f-s-32-100  { font-family: "Suisse Int'l Mono", monospace; font-size: var(--type-mono-lg); font-weight: 400; line-height: 106%; letter-spacing: 0.01em; }
.f-hnd-18-120  { font-family: 'Helvetica Now Display', arial; font-size: var(--type-disp-sm); font-weight: 400; line-height: 150%; }
.f-hnd-24-110  { font-family: 'Helvetica Now Display', arial; font-size: var(--type-disp-md); font-weight: 400; line-height: 128%; letter-spacing: -0.01em; }
.f-hndb-18-120 { font-family: 'Helvetica Now Display', arial; font-size: var(--type-disp-sm); font-weight: 700; line-height: 132%; }
.f-hndb-64-100 { font-family: 'Helvetica Now Display', arial; font-size: var(--type-disp-lg); font-weight: 700; line-height: 100%; letter-spacing: var(--track-display); }
.f-hndb-96-90  { font-family: 'Helvetica Now Display', arial; font-size: var(--type-disp-xl); font-weight: 700; line-height: 92%; letter-spacing: var(--track-display); }
.f-hndb-128-90 { font-family: 'Helvetica Now Display', arial; font-size: var(--type-disp-2xl); font-weight: 700; line-height: 90%; letter-spacing: var(--track-display-lg); }
.f-hndb-180-90 { font-family: 'Helvetica Now Display', arial; font-size: clamp(56px, 9.375vw, 270px); font-weight: 700; line-height: 90%; letter-spacing: var(--track-display-lg); }
.f-hndb-250-90 { font-family: 'Helvetica Now Display', arial; font-size: clamp(56px, 13.021vw, 250px); font-weight: 700; line-height: 90%; letter-spacing: var(--track-display-lg); }

/* Headings break on sense rather than at the edge of the box; body copy holds
   a readable measure instead of running the full column width. */
.f-hndb-64-100, .f-hndb-96-90, .f-hndb-128-90,
.f-hndb-180-90, .f-hndb-250-90 { text-wrap: balance; }
p.f-hnd-18-120, p.f-hnd-24-110 { max-width: var(--measure); text-wrap: pretty; }

/* === COLOR CLASSES === */
.color-black { color: var(--ink); }
.color-white { color: var(--text); }
.color-green { color: var(--green-text); }
.color-gray-light { color: var(--text); }
.color-gray { color: var(--text-muted); }

/* === BACKGROUND CLASSES === */
.background-black { background: var(--bg); }
.background-gray-dark { background: var(--surface); }
.background-gray-light { background: var(--panel); }
.background-gray-super-dark { background: var(--surface); }

/* === UTILITY === */
.text-uppercase { text-transform: uppercase; }
.d-block { display: block; }
.d-flex { display: flex; }
.d-none { display: none; }
.d-inline-block { display: inline-block; }
.position-relative { position: relative; }
.position-absolute { position: absolute; }
.overflow-hidden { overflow: hidden; }
.no-select { user-select: none; -webkit-user-select: none; }
.z-index-1 { z-index: 1; }
.w-100 { width: 100%; }
.h-100 { height: 100%; }
.flex-column { flex-direction: column; }
.align-items-center { align-items: center; }
.align-items-start { align-items: flex-start; }
.justify-content-center { justify-content: center; }
.justify-content-between { justify-content: space-between; }
.flex-wrap { flex-wrap: wrap; }
.mt-auto { margin-top: auto; }
.mb-auto { margin-bottom: auto; }
.no-wrap { white-space: nowrap; }
.events-none { pointer-events: none; }
.events-auto { pointer-events: auto; }
/* Available to assistive tech, removed from the visual layout. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

.container-fluid { margin-left: auto; margin-right: auto; padding-left: var(--gutter); padding-right: var(--gutter); width: 100%; }

/* === DOTTED LINE ===
   Reference technique: 1px repeating gradient (33% dot / 5px cell), not a border. */
.dotted-line { background-image: linear-gradient(90deg, rgba(71, 156, 115, 0.55) 33%, rgba(246, 245, 243, 0) 0); background-position: left bottom; background-repeat: repeat-x; background-size: 5px 1px; }
.dotted-line.--position-top { background-position: left top; }

/* === HEADER === */
header { position: fixed; top: 0; left: 0; width: 100%; z-index: 120; }
/* Shared header shell: every page uses the same top container, dimensions,
   position, and scroll lifecycle. Page content never redefines this chrome. */
header.site-header,
header[data-shared-header] { display: block; visibility: visible; opacity: 1; }
header.site-header .top-wrap,
header[data-shared-header] .top-wrap {
  display: flex;
  align-items: flex-start;
  box-sizing: border-box;
  width: 100%;
  min-height: 96px;
  padding: 12px 32px 0;
  transition: transform 0.7s var(--ease-out-expo), background-color 0.3s ease, height 0.3s ease;
}
header .top-wrap .menu-wrap {
  display: grid;
  /* Logo + 9 items on one row: Home, Capabilities, Work, Pricing, Company,
     Resources, Contact, Book a Call, Sign in. Columns are equal until a
     label needs more, so none spills into its neighbour. */
  grid-template-columns: minmax(150px, 13vw) repeat(9, minmax(max-content, 1fr));
  align-items: flex-start;
  column-gap: clamp(14px, 1.8vw, 40px);
  flex: 1 1 auto;
  width: 100%;
}
header .top-wrap .menu-wrap .menu-item-logo { align-self: flex-start; }
header .top-wrap .menu-wrap .menu-item-logo .logo { display: block; width: fit-content; transform: translateY(-1px); }
header .top-wrap .menu-wrap li { min-width: 0; }
header .menu-segment { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
header .menu-segment--contact { min-width: 0; }
header .header-nav-link { display: block; color: var(--text); text-align: left; }
header .nav-text-button { padding: 0; cursor: pointer; }
header .header-nav-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: #F6F5F3;
  line-height: 100%;
  letter-spacing: 0.01em;
  transition: opacity 0.3s ease, color 0.3s ease;
}
header .header-nav-link:hover .header-nav-label,
header .nav-text-button:hover .header-nav-label { opacity: 0.62; }
header .header-nav-marker { display: inline-block; min-width: 9px; }
/* The Home control keeps the original inline marker. Only its direction
   changes for the inner-page back action. */
header .header-nav-home-marker {
  display: inline-block;
  min-width: 9px;
  margin-right: 4px;
  transform-origin: 50% 50%;
}
header .header-nav-home-marker--back { transform: rotate(180deg); }
header .header-nav-link--home:hover .header-nav-home-marker,
header .header-nav-link--home:focus-visible .header-nav-home-marker { transform: translateX(4px); }
header .header-nav-link--back-home:hover .header-nav-home-marker {
  transform: translateX(-4px) rotate(180deg);
}
header .header-nav-link--back-home:focus-visible .header-nav-home-marker {
  transform: translateX(-4px) rotate(180deg);
}
/* Dropdowns: related pages sit behind one trigger. The item spans the full
   height of the banner so its panel can hang a fixed distance below it;
   js/main.js (initNavDropdowns) toggles .is-open on hover, click and keys. */
header .top-wrap .menu-wrap { align-self: stretch; }
header .top-wrap .menu-wrap .menu-dropdown { position: relative; align-self: stretch; justify-content: center; }
header .header-nav-trigger { font-size: inherit; text-align: left; }
header .header-nav-caret {
  display: inline-block;
  font-size: 0.72em;
  opacity: 0.7;
  transform: rotate(90deg);
  transition: transform 0.5s var(--ease-out-expo);
}
header .menu-dropdown.is-open .header-nav-caret { transform: rotate(-90deg); }
header .header-submenu {
  position: absolute;
  /* 6px is the banner's bottom padding; the panel floats 8px below it. */
  top: calc(100% + 14px);
  left: -24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 220px;
  padding: 20px 24px;
  background: var(--white);
  box-shadow: 0 18px 40px -20px rgba(38, 80, 60, 0.55), 0 0 0 1px rgba(38, 80, 60, 0.08);
  opacity: 0;
  visibility: hidden;
  transform: translate3d(0, -8px, 0);
  transition: opacity 0.3s ease, transform 0.5s var(--ease-out-expo), visibility 0s linear 0.3s;
}
/* Bridges the gap so the pointer can travel from trigger to panel. */
header .header-submenu::before { content: ''; position: absolute; right: 0; bottom: 100%; left: 0; height: 14px; }
header .menu-dropdown.is-open .header-submenu { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
header .header-submenu .header-nav-link { white-space: nowrap; }
@media (prefers-reduced-motion: reduce) {
  header .header-submenu,
  header .header-nav-caret { transition: none; }
}
header .top-wrap .menu-wrap .menu-item-cart { cursor: pointer; }

header .hamburger-wrap { display: none; align-items: center; gap: 20px; }
header .hamburger-wrap .hamburger { width: 30px; height: 20px; cursor: pointer; }
header .hamburger-wrap .line-wrap { width: 100%; height: 100%; gap: 6px; }
header .hamburger-wrap .line { width: 100%; height: 2px; background: var(--bg); transition: all 0.3s ease; }

/* Hero and footer media retain their restrained, monochrome treatment. */
.hero .video-thumb video,
footer .video-thumb video { filter: grayscale(1) contrast(0.74) brightness(1.22); }

/* === HERO ===
   Three equally padded statement groups share one clean grid. */
.hero { display: flex; flex-direction: column; justify-content: space-between; height: 100vh; position: relative; z-index: 1; overflow: hidden; background: var(--ground); }
/* The video now lives inside a dedicated media wrapper. The wrapper owns the
   negative layer so the film stays above the hero's own background paint;
   putting the negative z-index on the nested video hides it behind that
   background in the Next.js markup. */
.hero__media { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; pointer-events: none; }
.hero__background { position: absolute; inset: 0; z-index: auto; width: 100%; height: 100%; object-fit: cover; object-position: center; }
.hero::after { content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: linear-gradient(90deg, rgba(14, 42, 30, 0.78) 0%, rgba(14, 42, 30, 0.32) 48%, rgba(14, 42, 30, 0.56) 100%), linear-gradient(0deg, rgba(14, 42, 30, 0.58) 0%, rgba(14, 42, 30, 0.08) 42%, rgba(14, 42, 30, 0.3) 100%); }
.hero::before,
.video-thumb::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.12;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.72'/%3E%3C/svg%3E");
  background-size: 180px 180px;
  mix-blend-mode: soft-light;
  animation: film-grain 0.22s steps(2, end) infinite;
}
.hero::before { z-index: 0; }
.video-thumb { position: relative; }
.video-thumb::after { z-index: 1; border-radius: 0; }
.video-thumb .button { z-index: 2; }
@keyframes film-grain {
  0% { background-position: 0 0; }
  25% { background-position: 32px -18px; }
  50% { background-position: -14px 26px; }
  75% { background-position: 22px 12px; }
  100% { background-position: -20px -24px; }
}
.hero .inner-wrap { display: flex; flex-direction: column; height: 100%; }
.hero .top-wrap { position: relative; height: 100%; }
.hero .text-list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: center; gap: 0; height: 100%; width: 100%; margin: 0; padding: clamp(148px, 16vh, 190px) clamp(28px, 5vw, 96px) clamp(88px, 11vh, 128px); }
.hero .text-list li { display: flex; align-items: flex-start; width: 100%; min-width: 0; margin: 0; padding-inline: clamp(18px, 2.2vw, 42px); }
/* The hero now stands on a plain green surface, so its three statements use
   a single, high-contrast type treatment instead of competing colours. */
.hero .text-list .js-scramble-text {
  color: var(--white);
}
.hero .bullet-green { padding-left: 18px; }
.hero .bullet-green::before { top: 0.34em; width: 7px; height: 7px; background: var(--white); }
.hero .video-thumb { position: absolute; left: 0; bottom: 30px; width: 430px; height: 228px; z-index: 2; }
.hero .video-thumb video { width: 100%; height: 100%; object-fit: cover; border: 1px solid rgba(246, 245, 243, 0.35); border-radius: 0; }
.hero .top-wrap .button-frame { position: absolute; right: 0; bottom: 30px; display: table; }
/* Reserve room at the bottom so the tech line clears the fixed floating scroll
   menu (centred pill at bottom:40px, z-index 10000) that draws over this band. */
.hero .bottom-wrap { display: flex; align-items: flex-start; justify-content: space-between; gap: clamp(20px, 3vw, 56px); padding: 16px 0 clamp(112px, 10vh, 132px); }
.hero .bottom-wrap .scroll-cue { gap: 10px; cursor: pointer; flex: 0 0 auto; align-items: flex-start; }
.hero .bottom-wrap .scroll-cue svg { margin-left: 5px; transition: transform 0.7s var(--ease-out-expo); }
.hero .bottom-wrap .scroll-cue:hover svg { transform: translate3d(0, 3px, 0); transition: transform 0.5s var(--ease-out-expo); }

@media (min-width: 1024px) {
    .hero .text-list { display: block; position: relative; }
    .hero .text-list li {
        position: absolute;
        top: var(--hero-text-y, 18%);
        left: var(--hero-text-x, 7%);
        width: min(28vw, 330px);
        padding-inline: 18px;
    }
    /* Fixed composition. The left statement stops at 50% so it clears the
       video thumbnail that sits in the lower-left corner. */
    .hero .text-list li:nth-child(1) { --hero-text-x: 7%; --hero-text-y: 50%; }
    .hero .text-list li:nth-child(2) { --hero-text-x: 40%; --hero-text-y: 22%; }
    .hero .text-list li:nth-child(3) { --hero-text-x: 66%; --hero-text-y: 58%; transform: translateY(-32px); }
}

@media (prefers-reduced-motion: reduce) {
    .hero__background { display: none; }
    .hero::before,
    .video-thumb::after { animation: none; }
}

/* Netlify adds this promotional iframe at runtime. Keep hosting credits out of
   the public site chrome; the deployment platform remains unchanged. */
#nl-badge-frame {
  display: none !important;
}

/* Reference play affordance: 47px green disc that scales up on hover while
   the glyph eases down — 0.6s expo. (Shared by hero and footer thumbs.) */
.video-thumb .button { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 47px; height: 47px; display: grid; place-content: center; background: none; border-radius: 50%; cursor: pointer; }
.video-thumb .button::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--deep); border-radius: 50%; z-index: -1; }
.video-thumb .button svg, .video-thumb .button::before { transform-origin: 50% 50%; transition: transform 0.6s var(--ease-out-expo), background-color 0.25s ease; }
.video-thumb .button svg path { fill: var(--white); transition: fill 0.25s ease; }
.video-thumb .button:hover::before { transform: scale(1.2); }
.video-thumb .button:hover svg { transform: scale(0.9); }
.video-thumb .button:hover::before { background: var(--white); }
.video-thumb .button:hover svg path { fill: var(--deep); }

/* Bullet green — reference: 5x5 square, no radius */
.bullet-green { position: relative; padding-left: 20px; }
.bullet-green::before { content: ''; position: absolute; left: 0; top: 5px; width: 5px; height: 5px; background: var(--green); }

/* === FRAME BUTTON ===
   Reference hover: the fill wipes UP from the bottom edge (rect.hover slides
   from translateY(102%) to 0 over 1s expo) while the label switches color.
   Laccino keeps its green as the fill color. */
.button-frame { display: block; position: relative; cursor: pointer; }
.button-frame svg.plaisio { height: auto; width: clamp(303px, 15.781vw, 15.781vw); display: block; }
/* The CTA carries the primary colour at rest, not just on hover: --green
   filled with a near-black label is 5.68:1, and it is the one place the
   primary reads at full strength on every page. */
/* The block adapts to what is behind it: the deep green by default, and the
   primary green inside deep-green bands where the default would vanish.
   --btn-fill / --btn-label are set by those bands below. */
.button-frame svg.plaisio .bg { fill: var(--btn-fill, var(--deep)); }
/* Outline removed: the masked path inside the frame drew the 1px border.
   The button is a solid block now. On the green ground a near-black fill
   is 5.68:1 with a bone label at 15.97:1 on top. */
.button-frame svg.plaisio g > path { fill: transparent; }
.button-frame svg.plaisio .hover { fill: var(--green); transform: translate3d(0, 102%, 0); transform-origin: 50% 100%; transition: transform 1s var(--ease-out-expo); }
.button-frame:hover svg.plaisio .hover { transform: translate3d(0, 0, 0); }
.button-frame .label-wrap { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 100%; display: flex; align-items: center; justify-content: center; gap: 0; }
.button-frame .label-wrap span { color: var(--btn-label, var(--white)); transition: color 1s var(--ease-out-expo); }
.button-frame .label-wrap svg.icon-arrow { margin-left: 20px; }
.button-frame .label-wrap svg.icon-arrow path { fill: var(--btn-label, var(--white)); transition: fill 1s var(--ease-out-expo); }
/* The light hover fill uses deep ink so the CTA label remains high contrast. */
.button-frame:hover .label-wrap span { color: var(--deep); }
.button-frame:hover .label-wrap svg.icon-arrow path { fill: var(--deep); }
.button-frame svg.mobile_plaisio { display: none; }
/* Must be `g > path`, not a descendant selector: the mask holds a <path> too,
   and blanking that one blanks the mask, which hides the whole button. */
.button-frame.theme-white svg.plaisio g > path { fill: transparent; stroke: none; }
.button-frame.theme-white svg.plaisio .hover { fill: var(--green); }
.button-frame.theme-white .label-wrap span { color: var(--btn-label, var(--white)); }
.button-frame.theme-white .label-wrap svg path { fill: var(--btn-label, var(--white)); }
.button-frame.theme-white:hover .label-wrap span { color: var(--deep); }
.button-frame.theme-white:hover .label-wrap svg path { fill: var(--deep); }

/* === FLOATING SCROLL MENU ===
   Reference: visible from load; exits (fade + 20px drop) before the footer. */
.floating-scroll-menu { position: fixed; bottom: 40px; left: 0; width: 100%; display: flex; justify-content: center; z-index: 10000; pointer-events: none; opacity: 0; transform: translateY(20px); transition: opacity 0.5s ease, transform 0.5s ease; }
.floating-scroll-menu.visible { opacity: 1; transform: translateY(0); }
.floating-scroll-menu .inner-wrap { pointer-events: auto; display: flex; flex-wrap: nowrap; gap: 40px; padding: 20px 30px; background: var(--panel); border: 1px solid var(--surface); border-radius: 0; }
.floating-scroll-menu button { background: none; border: none; cursor: pointer; }
.floating-scroll-menu button span { transition: background-size 1s var(--ease-out-expo), color 1s var(--ease-out-expo); }
.floating-scroll-menu button:hover span,
.floating-scroll-menu button.active span { background-image: linear-gradient(var(--ink), var(--ink)); background-position: 0 100%; background-repeat: no-repeat; background-size: 100% 1px; }

/* === SECTION 01 ===
   The studio and typography statement stack in normal document flow.
   Only the capability cards below retain their desktop pinned transitions. */
._01 { margin-top: 0; padding-top: 0; z-index: 2; }
._01 .inner-wrap { position: relative; z-index: 2; }
/* Breathing room above the "01/ THE STUDIO" label (clears the 100px header). */
._01 > .inner-wrap { padding-top: var(--section-y); }
@media (min-width: 1024px) and (prefers-reduced-motion: no-preference) {
    ._01 > .inner-wrap { position: relative; width: 100%; padding-top: 140px; padding-bottom: 80px; z-index: 1; }
    ._01 .hand-animation { z-index: 0; }
    /* The statement scrolls in normal flow, without an extra pinned reading interval. */
    ._01 .sections { margin-top: 0; }
    .sections .section-products,
    .sections .section-systems,
    .sections .section-system-apps,
    .sections .section-automation,
    .sections .section-core-agents { margin-top: 300px; }
}
._01 .info-section { display: grid; gap: 40px 150px; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: repeat(2, minmax(0, 1fr)); height: 100vh; padding: var(--space-7) var(--gutter); }
._01 .info-section .title { max-width: clamp(730px, 38.021vw, 38.021vw); }
._01 .info-section .image-wrap { grid-area: 1 / 2 / -1 / -1; aspect-ratio: 835 / 889; width: auto; max-width: 100%; margin-left: auto; }
._01 .info-section .image-wrap img { width: 100%; height: 100%; object-fit: cover; }
._01 .info-section .description { margin-top: auto; }
._01 .info-section .description strong { font-family: 'Helvetica Now Display', arial; font-weight: 700; display: block; }

/* === HAND ANIMATION / TYPOGRAPHY SECTION (pinned board) === */
.hand-animation { position: relative; height: 100vh; z-index: 2; }
.hand-animation .image-wrap { position: absolute; top: 0; left: 0; width: 100%; height: 100vh; z-index: 0; }
.hand-animation .image-wrap img { width: 100%; height: 100vh; object-fit: cover; }

.typography-section { display: flex; flex-direction: column; height: 100vh; max-height: 1300px; justify-content: space-between; padding: 80px 50px; position: relative; }
.typography-section .inner-wrap { display: flex; flex: 1; flex-direction: column; justify-content: space-between; min-height: 100%; }
.typography-section .row-wrap { display: grid; gap: 30px; grid-template-columns: 1fr auto; align-items: end; }
.typography-section .row-wrap .list-wrap { text-align: right; }
.typography-section .row-wrap .button-wrap { display: flex; flex-direction: column; gap: 15px; align-items: flex-end; }
.typography-section.theme-small .row-wrap .title { font-size: clamp(56px, 9.375vw, 270px); }
/* "Where ideas become working systems": a step above the section titles
   (f-hndb-96-90) rather than poster size, and small enough that "working
   systems" holds one line beside its label on desktop. */
.hand-animation .typography-section.theme-small .row-wrap .title { font-size: clamp(40px, 6.6vw, 128px); }
@media (min-width: 1024px) {
  .hand-animation .typography-section.theme-small .row-wrap .title { white-space: nowrap; }
}
/* Board variant (reference): centered rows, tighter cap, full-bleed backdrop */
.hand-animation .typography-section { justify-content: center; max-height: 1200px; min-height: 100vh; }
.hand-animation .typography-section .inner-wrap { position: relative; z-index: 2; max-height: 930px; height: 100%; flex: 0 1 auto; margin-top: auto; margin-bottom: auto; }
.hand-animation .typography-section .board-backdrop {
  position: absolute;
  top: -1%;
  left: -1%;
  width: 102%;
  height: 102%;
  z-index: 0;
  transform: translate3d(var(--system-shift-x, 0), var(--system-shift-y, 0), 0) scale(1.012);
  transition: transform 420ms cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}
.hand-animation .typography-section .board-backdrop img { width: 100%; height: 100%; object-fit: cover; }
.hand-animation .typography-section.theme-small {
  --system-pixel-1: #17261f;
  --system-pixel-2: #263b31;
  --system-pixel-3: #415b4d;
  --system-pixel-4: #789184;
  background: #10281e;
  isolation: isolate;
  overflow: hidden;
  padding-top: clamp(132px, 16vh, 164px);
  padding-bottom: 48px;
}
.hand-animation .typography-section.theme-small::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 68% 58% at 48% 48%, rgba(3, 10, 7, 0.88), rgba(3, 10, 7, 0.26) 62%, transparent 100%),
    linear-gradient(180deg, rgba(3, 10, 7, 0.18), rgba(3, 10, 7, 0.34));
}
.hand-animation .typography-section.theme-small::before {
  display: none;
}
.hand-animation .typography-section .system-pixels {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100vw;
  height: 100vh;
  pointer-events: none;
  opacity: 0;
  transition: none;
}
.hand-animation .typography-section .system-pixels.is-ready.is-visible {
  opacity: 1;
}
@media (max-width: 1023px) {
  /* Keep the pixel field inside its section as it enters the viewport.
     A fixed canvas paints over the preceding Studio content on phones. */
  .hand-animation .typography-section .system-pixels {
    position: absolute;
    width: 100%;
    height: 100%;
  }
}

/* === FEATURES SECTIONS ===
   Reference: block flow, solid ink top rule, right visual rail 485px wide and
   full height (absolute, flush right), text column capped at 34.688vw. */
.sections { position: relative; z-index: 2; }
.sections .section { position: relative; height: 100vh; padding: var(--space-6) 0 0 var(--gutter); overflow: hidden; }
/* Each capability section slides over the last: a soft shadow on its top
   edge carries that overlap, where a hard rule used to. */
.sections .section { box-shadow: 0 -28px 48px -30px rgba(71, 156, 115, 0.35); }
.sections .section .title { display: block; margin: 40px 0 20px; max-width: clamp(666px, 34.688vw, 34.688vw); }
/* The rail is a tall 485px column (it held a portrait Lottie in the reference).
   Our product shots are 4:3, so the old 110/125px padding squeezed them into a
   235x679 slot and `cover` threw away ~74% of each frame. Pad vertically only
   and let the shot sit full-width, centred. */
.sections .section .lottie-container { position: absolute; top: 0; right: 0; width: clamp(620px, 52vw, 1040px); height: 100%; padding: clamp(28px, 3.4vw, 60px) 0; overflow: hidden; display: flex; align-items: center; justify-content: center; }
.sections .section .text-wrap { max-width: clamp(666px, 34.688vw, 34.688vw); }
.sections .section .text-wrap .list { margin-top: 30px; }
.sections .section .text-wrap .list li { padding: 5px 0; }
.sections .section .text-wrap .button-frame { margin-top: 50px; }

/* === SECTION 02 ===
   Reference: 2x2 grid — media left spanning both rows (bottom-aligned, max 570),
   title + button top-right, description bottom-right. */
._02 { position: relative; z-index: 2; }
._02 .inner-wrap { background: var(--bg); padding: var(--section-y) var(--gutter); display: flex; flex-direction: column; }
._02 .inner-wrap .header { margin-bottom: 40px; }
/* Rows size to their content (was two equal rows in a fixed 980px box, which
   pushed the description ~330px below the heading and button). */
._02 .experience { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto auto; gap: 40px; }
._02 .experience .media-wrap { grid-area: 1 / 1 / -1; margin-top: auto; }
._02 .experience .media-wrap .image-wrap { max-width: 570px; display: block; }
._02 .experience .media-wrap img { width: 100%; height: auto; object-fit: cover; }
._02 .experience .text-wrap { grid-column: 2; display: flex; flex-direction: column; }
._02 .experience .text-wrap .button-frame { margin: 48px 15% 0 auto; }
._02 .experience .description { grid-column: 2; margin-top: var(--space-5); max-width: clamp(740px, 38.542vw, 38.542vw); }
._02 .experience .description strong { font-family: 'Helvetica Now Display', arial; font-weight: 700; display: block; }

/* Trail effect */
.trail-effect { display: grid; place-content: center; height: 100vh; margin-bottom: 50vh; position: relative; overflow: hidden; z-index: 1; }
.trail-effect img { position: absolute; width: 300px; height: auto; opacity: 0; pointer-events: none; will-change: transform, opacity; }
.trail-effect .title { z-index: 10; pointer-events: none; }
.trail-effect .cta-wrap { position: absolute; bottom: 80px; left: 50px; z-index: 10; }

/* === SECTION 03 TESTIMONIALS ===
   Reference: the swiper fills the whole section (absolute, z0) with full-bleed
   slide images; text overlays; green dotted bottom bar; 10px dot pagination. */
/* _03 must stack ABOVE the pinned trail curtain so the slideshow rises to cover
   "ANY INDUSTRY" (the intended reveal) instead of being hidden behind it. */
._03 { min-height: calc(100vh + 90px); padding: var(--section-y) 0 calc(var(--section-y) * 1.6); position: relative; overflow: hidden; z-index: 2; }
._03 .header { padding: 0 50px; margin-bottom: 40px; }
/* Scaled up + re-graded to the lighter muted grey (matches the hero cover video). */
/* Cinematic scrim (reference darkens the slide image) so the white quote stays
   readable over the product mockup — weighted to the left where the quote sits. */
/* Keep the overlay legible now that the slide image is lighter/brighter. */
.underlined-button--color-2 { background-image: linear-gradient(#F6F5F3, #F6F5F3); background-position: 0 100%; background-repeat: no-repeat; background-size: 100% 1px; }

/* === FOOTER ===
   Reference: glass panel over the fixed video, sticky mark, grid
   16.146vw + 4x1fr with rows 1fr/auto/20px; page links span two columns each
   with dotted rules; wordmark + video thumb live inside the grid (area 2/4/-1/-1). */
footer { display: flex; flex-direction: column; align-items: flex-start; justify-content: space-between; min-height: 100lvh; padding: 50px; position: relative; z-index: 2; width: 100%; }
/* Shared footer shell: this white container is part of the site chrome on
   every page, not a home-only surface or a decorative overlay. */
footer.site-footer,
footer[data-shared-footer] {
  background: var(--panel);
  isolation: isolate;
}
footer::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--panel); z-index: -1; pointer-events: none; }
footer .top-wrap,
footer .inner-wrap { position: relative; z-index: 2; }
footer .top-wrap { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: flex-end; gap: 16px 20px; width: 100%; }
footer .inner-wrap { display: grid; grid-template-columns: 16.146vw minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: 1fr auto 20px; align-items: flex-end; gap: 60px 0; width: 100%; margin-top: auto; min-height: calc(100vh - 300px); }
footer .inner-wrap .info { grid-column: 1 / -1; align-self: flex-start; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
footer .inner-wrap .info > li { grid-column: span 2; padding: 35px 0; }
footer .inner-wrap .info li a:hover { opacity: 0.6; }

/* Footer sitemap: five clearly named groups across the .info grid. */
/* Centre the columns as a group (balanced left/right margins) rather than
   stretching them edge-to-edge, which reads unbalanced on wide screens. */
footer .inner-wrap .info--cols {
  --footer-column-gap: clamp(28px, 3.2vw, 52px);
  --footer-item-gap: 16px;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  column-gap: var(--footer-column-gap);
  row-gap: 0;
  align-items: start;
  justify-self: center;
  width: 100%;
  max-width: 1380px;
}
footer .inner-wrap .info--cols > li {
  grid-column: span 1;
  min-width: 0;
  padding: 0;
}
.footer-col nav, .footer-col address {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 100%;
  font-style: normal;
}
.footer-col__head { display: block; margin: 0 0 24px; opacity: 0.9; }
footer :is(.footer-newsletter__label, .footer-newsletter__consent).f-hnd-18-120 { font-size: 14px; line-height: 1.4; }
.footer-col__links {
  display: grid;
  width: 100%;
  gap: var(--footer-item-gap);
}
.footer-col__links > li, .footer-col__contact > li { margin: 0; }
.footer-col__links a,
.footer-col__action { display: inline-flex; min-height: 24px; align-items: center; line-height: 1.35; }
.footer-col__links a span { transition: opacity 0.25s ease; }
/* "Cookie settings" is a button (it opens a dialog, it goes nowhere), dressed
   exactly like the links around it. */
.footer-col__action { padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.footer-col__action span { transition: opacity 0.25s ease; }
.footer-col__action:hover span { opacity: 0.6; }
.footer-col__action:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
.footer-newsletter { width: 100%; max-width: none; margin-top: 24px; }
.footer-newsletter__label { display: block; margin-bottom: 12px; font-weight: 600; }
.footer-newsletter__row { display: grid; grid-template-columns: minmax(0, 1fr) 42px; background: #fff; }
.footer-newsletter__row input {
  min-width: 0;
  min-height: 42px;
  padding: 10px 12px;
  border: 0;
  border-radius: 0;
  background: #fff;
  color: var(--green-strong);
}
.footer-newsletter__row button {
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 0;
  background: var(--green);
  cursor: pointer;
}
.footer-newsletter__row button .icon-arrow path { fill: var(--white); }
.footer-newsletter__row button:hover,
.footer-newsletter__row button:focus-visible { background: var(--sky); }
.footer-newsletter__row button:hover .icon-arrow path,
.footer-newsletter__row button:focus-visible .icon-arrow path { fill: var(--deep); }
.footer-newsletter__row input:focus-visible,
.footer-newsletter__row button:focus-visible { outline: 2px solid var(--green-strong); outline-offset: 2px; }
.footer-newsletter__consent { margin-top: 10px; }
.footer-newsletter .form-status { margin-top: 8px; min-height: 0; }
.footer-col__contact a, .footer-col__contact .footer-ci-row { display: flex; align-items: flex-start; }
.footer-col__contact span { min-width: 0; overflow-wrap: break-word; }
@media (min-width: 768px) { .footer-col__contact span { white-space: nowrap; } }
/* Contact strings are long in the monospace footer face; nudge down a touch so
   the email holds one line on desktop and only wraps (after @) when truly narrow. */
.footer-col__contact span[class] { font-size: 15px; }
.footer-contact-button { display: inline-flex; align-items: center; justify-content: space-between; gap: 20px; min-width: 180px; padding: 13px 16px; border: 1px solid rgba(20, 43, 32, 0.28); border-radius: 999px; transition: color 0.25s ease, background-color 0.25s ease, border-color 0.25s ease; }
.footer-contact-button .icon-arrow { flex: none; transition: transform 0.3s var(--ease-out); }
.footer-contact-button:hover, .footer-contact-button:focus-visible { opacity: 1 !important; color: var(--panel); background: var(--green-dark); border-color: var(--green-dark); }
.footer-contact-button:hover .icon-arrow, .footer-contact-button:focus-visible .icon-arrow { transform: translateX(4px); }
.footer-contact-button:focus-visible { outline: 2px solid var(--green-dark); outline-offset: 3px; }
footer .inner-wrap .sign { display: flex; flex-direction: column; gap: 5px; grid-area: 3 / 1 / auto / 2; align-self: flex-end; padding-right: clamp(16px, 2vw, 32px); }
/* The tagline wrapped to the full column and ran straight into the credits
   line; the right padding keeps a gutter between them. */
footer .inner-wrap .credits { display: flex; flex-direction: column; gap: 5px; grid-area: 3 / 2 / auto / 3; align-self: flex-end; }
footer .inner-wrap .credits a:hover { opacity: 0.6; }
footer .inner-wrap .local-clock { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; grid-area: 2 / 1 / 3 / 2; align-self: flex-end; }
footer .inner-wrap .local-clock .clock-label { opacity: 0.9; }
/* Hidden until main.js has a time to show, so no placeholder is ever read. */
footer .inner-wrap .local-clock:not(.is-ready) { visibility: hidden; }
footer .inner-wrap .local-clock .clock-time { font-variant-numeric: tabular-nums; letter-spacing: 0; }


/* === MODALS === */
.modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 9999; display: none; }
.modal.active { display: flex; align-items: center; justify-content: center; }
.modal .blocker { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(71, 156, 115, 0.7); }
.modal .modal-blocker { position: relative; z-index: 1; width: 90%; max-width: 1200px; }
.modal .close-button { position: absolute; top: 20px; right: 20px; z-index: 10; cursor: pointer; }
.modal .media-video { width: 100%; aspect-ratio: 16/9; background: #479c73; }
.modal .media-video iframe,
.modal .media-video video { width: 100%; height: 100%; border: none; object-fit: contain; display: block; }

/* === MOBILE MENU ===
   Reference: full-screen takeover on an opaque bone blocker, links with
   dotted rules, inner padding 170/20/60. */
.modal-menu { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 110; pointer-events: none; opacity: 0; visibility: hidden; transition: opacity 0.5s ease, visibility 0.5s ease; }
.modal-menu.active { pointer-events: auto; opacity: 1; visibility: visible; }
.modal-menu .blocker { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: var(--panel); z-index: -1; }
.modal-menu .inner-wrap { position: relative; z-index: 1; width: 100%; height: 100%; padding: 170px 20px 60px; display: flex; flex-direction: column; justify-content: space-between; overflow-y: auto; }
.modal-menu .bottom-menu li a { display: block; padding: 9px 0; background-image: linear-gradient(90deg, rgba(71, 156, 115, 0.55) 33%, rgba(246, 245, 243, 0) 0); background-position: left bottom; background-repeat: repeat-x; background-size: 5px 1px; }

/* === PAGE LOADER === */
#loader { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 99999; pointer-events: none; }
#loader .blocker { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: var(--panel); transition: opacity 0.6s ease; }
#loader .shape-overlays { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }

/* === ANIMATIONS === */
[data-animate-in] { opacity: 0; transform: translateY(36px); transition: opacity 0.9s var(--ease-out-expo), transform 0.9s var(--ease-out-expo); }
[data-animate-in].animated { opacity: 1; transform: translateY(0); }

/* Masked char rise (reference lineParent/charParent): the word wrapper crops,
   the chars rise from below it. Built + tweened by js/main.js (chars-anim). */
.charMask { display: inline-block; white-space: nowrap; overflow: hidden; vertical-align: bottom; }
.charMask .char { display: inline-block; will-change: transform; }

/* Image reveal */
.image-wrap[data-animate-in="image-reveal"] { overflow: hidden; }
.image-wrap[data-animate-in="image-reveal"] img { transform: scale(1.2); transition: transform 1.2s var(--ease-out-expo); }
.image-wrap[data-animate-in="image-reveal"].animated img { transform: scale(1); }

/* === LOTTIE === */
.js-lottie-element { width: 100%; height: 100%; }

/* === SWIPER OVERRIDES === */
.swiper { position: relative; overflow: hidden; }
.swiper-wrapper { display: flex; transition: transform 0.3s ease; }
.swiper-slide { flex-shrink: 0; width: 100%; }

/* === RESPONSIVE ===
   Reference breakpoints: 1280 (hero list padding), 1023 (tablet/mobile), 549 (small). */
@media (max-width: 1280px) {
    .hero .text-list { padding: clamp(138px, 15vh, 176px) clamp(20px, 4vw, 52px) clamp(82px, 10vh, 112px); }
}
@media (max-width: 1023px) {
    header .top-wrap { padding: 25px 20px; }
    header .top-wrap .menu-wrap li:not(.menu-item-logo):not(.menu-item-cart) { display: none; }
    header .hamburger-wrap { display: flex; flex: none; margin-left: auto; }
    header .hamburger-wrap .hamburger { display: grid; width: 44px; height: 44px; place-items: center; }
    header .hamburger-wrap .line-wrap { width: 30px; height: 20px; }
    /* The desktop grid kept reserving five hidden 112px segment columns, which
       pushed the menu button 10px past the right edge on phones and tablets. */
    header .top-wrap .menu-wrap { grid-template-columns: auto; width: auto; }
    .hero .inner-wrap { padding: 0 clamp(18px, 4vw, 32px); }
    .hero .text-list { grid-template-columns: 1fr; align-content: center; align-items: stretch; gap: 0; height: auto; min-height: 680px; padding: clamp(142px, 18vh, 176px) 0 clamp(84px, 11vh, 112px); }
    .hero .text-list li,
    .hero .text-list li:first-child,
    .hero .text-list li:nth-child(2),
    .hero .text-list li:nth-child(3) { display: flex; margin: 0; padding: 16px clamp(14px, 4vw, 28px); }
    .hero .video-thumb { position: relative; left: auto; bottom: auto; width: 333px; height: 176px; margin: 0 auto; }
    .hero .top-wrap { display: flex; flex-direction: column; }
    .hero .top-wrap .button-frame { position: relative; right: auto; bottom: 0; margin: 30px auto; }
    .hero .bottom-wrap .scroll-cue { display: none; }
    /* The tech line now lives in the hero; let it grow instead of force-fitting
       100vh (which would compress the reserve and let the fixed pill overlap the
       marks). Reserve here clears the pill, which sits at bottom:10px on ≤1023. */
    .hero { height: auto; min-height: 100vh; }
    .hero .bottom-wrap { padding-bottom: clamp(64px, 8vh, 84px); }
    ._01 .info-section { grid-template-columns: 1fr; grid-template-rows: none; height: auto; padding: 45px 20px 70px; }
    ._01 .info-section .image-wrap { grid-area: auto; margin-left: 0; }
    .sections .section { height: auto; padding: 35px 20px 70px; position: relative; z-index: 1; overflow: visible; }
    .sections .section .lottie-container { position: relative; width: 50%; height: auto; padding: clamp(16px, 3vw, 32px) 0; }
    .sections .section .text-wrap { margin-top: 30px; max-width: calc(50% - 20px); }
    ._02 .experience { grid-template-columns: 1fr; grid-template-rows: none; margin-top: 20px; min-height: 0; }
    ._02 .experience .media-wrap { grid-area: auto; grid-row: 2; }
    ._02 .experience .media-wrap .image-wrap { max-width: none; width: 100%; }
    ._02 .experience .text-wrap,
    ._02 .experience .description { grid-column: 1; }
    .typography-section { min-height: 0; }
    .typography-section .row-wrap { grid-template-columns: 1fr; }
    .trail-effect { display: none; margin-bottom: 0; }
    .floating-scroll-menu { bottom: 10px; padding: 0 20px; }
    .floating-scroll-menu .inner-wrap { overflow-x: auto; padding: 19px 15px; gap: 20px; }
    footer { padding: 30px 20px; }
    footer .top-wrap { flex-flow: row nowrap; align-items: stretch; gap: 12px; }
    footer .top-wrap .button-frame {
      flex: 1 1 0;
      width: auto;
      min-width: 0;
      padding-inline: clamp(12px, 3vw, 24px);
    }
    footer .top-wrap .button-frame .label-wrap { gap: 10px; }
    footer .inner-wrap {
      grid-template-columns: minmax(0, 1.1fr) minmax(120px, 0.9fr);
      grid-template-rows: none;
      column-gap: clamp(20px, 6vw, 48px);
      row-gap: 40px;
      min-height: 0;
    }
    footer .inner-wrap .info { grid-column: 1 / -1; grid-template-columns: 1fr; }
    footer .inner-wrap .info--cols { row-gap: 0; }
    footer .inner-wrap .info--cols > li {
      display: grid;
      grid-column: 1;
      grid-template-columns: minmax(92px, 0.8fr) minmax(0, 1.2fr);
      column-gap: clamp(18px, 6vw, 44px);
      padding: 28px 0;
      border-top: 1px solid rgba(38, 80, 60, 0.22);
    }
    footer .inner-wrap .info--cols > li:last-child { border-bottom: 1px solid rgba(38, 80, 60, 0.22); }
    footer .footer-col nav {
      display: grid;
      grid-column: 1 / -1;
      grid-template-columns: subgrid;
      align-items: start;
    }
    footer .footer-col__head { margin: 0; }
    footer .footer-col__links { justify-items: end; text-align: right; }
    footer .footer-col__links a,
    footer .footer-col__action { justify-content: flex-end; text-align: right; }
    footer .footer-newsletter { grid-column: 2; justify-self: end; }
    footer .footer-newsletter__consent,
    footer .footer-newsletter .form-status { text-align: left; }
    footer .inner-wrap .local-clock { grid-area: 2 / 1; align-self: end; }
    footer .inner-wrap .sign { grid-area: 3 / 1; padding-right: 0; }
    footer .inner-wrap .credits { grid-area: 3 / 2; align-items: flex-end; text-align: right; }
}

@media (max-width: 549px) {
    .hero .inner-wrap { padding: 0; }
    .hero .text-list { grid-template-columns: 1fr; gap: 0; height: auto; min-height: 620px; padding: 142px 20px 72px; }
    .hero .text-list li { max-width: none; padding: 14px 0; }
    .hero .video-thumb { width: min(333px, calc(100vw - 40px)); height: auto; aspect-ratio: 333 / 176; }
    /* inner-wrap padding is zeroed here, so pad the tech line to the edges. */
    .hero .bottom-wrap { padding-left: 20px; padding-right: 20px; }
    .sections .section .lottie-container { width: 100%; }
    .sections .section .text-wrap { max-width: 100%; }
    .typography-section { padding-top: 40px; padding-bottom: 40px; }
    .button-frame svg.plaisio { display: block; width: 100%; max-width: 303px; }
    footer .footer-newsletter { grid-column: 1 / -1; width: 100%; }
    .hero::before,
    .video-thumb::after { animation: none; }
}

@media (max-width: 767px) {
    .modal-menu .bottom-menu li a,
    .modal-menu .bottom-menu li button { display: flex; min-height: 48px; align-items: center; padding-block: 12px; }
    footer .footer-col__links a,
    footer .footer-col__action { min-height: 44px; }
    footer .footer-newsletter__row input { min-height: 48px; font-size: 16px; }
    footer .footer-newsletter__row button { min-width: 48px; min-height: 48px; }
    footer .video-thumb .button { min-width: 48px; min-height: 48px; }
}

@media (min-width: 1024px) {
    .d-md-block { display: block; }
}

/* ============================================
   LACCINO DIGITAL OVERRIDES
   Brand palette: ground #26503c, bone #F6F5F3, green #479c73
   ============================================ */

/* Logo images */
/* Sized by height: the 2026 mark is a tall letterform (204x320), where the
   old lion badge was near square, so a width clamp made it far too tall. */
header .logo img { height: clamp(52px, 3.2vw, 64px); width: auto; display: block; }

/* Header: transparent, segmented, and spacious. Hide on scroll down / at footer
   via the 0.7s expo translate; desktop keeps the dark mono text from the
   reference header over the gray media grade. */
header .top-wrap { transition: transform 0.7s var(--ease-out-expo); }
header.is-hidden .top-wrap, header.is-bottom .top-wrap { transform: translate3d(0, -100%, 0); }
header.is-bottom { pointer-events: none; }
/* The Home control keeps one geometry across every page. Its arrow changes
   meaning with the page context: inward on Home, back toward Home elsewhere. */
header .header-nav-label--home .header-nav-home-marker {
  transition: transform 0.7s var(--ease-out-expo), opacity 0.35s ease;
}
body.loaded header .header-nav-label--home .header-nav-home-marker {
  animation: home-arrow-arrive 0.8s var(--ease-out-expo) both;
}
@keyframes home-arrow-arrive {
  from { opacity: 0; transform: translateX(-8px); }
  to { opacity: 1; transform: translateX(0); }
}
header .header-nav-link--back-home .header-nav-home-marker { animation-name: home-arrow-back-arrive; }
@keyframes home-arrow-back-arrive {
  from { opacity: 0; transform: translateX(8px) rotate(180deg); }
  to { opacity: 1; transform: translateX(0) rotate(180deg); }
}

/* The homepage opens on the near-white surface. Its text, controls and the
   header all use the leaf-green primary, giving the first screen one clear
   brand colour without sacrificing legibility. */
.hero { background: var(--white); color: var(--green); }
.hero .text-list .js-scramble-text { color: var(--white); }
.hero .bullet-green::before { background: var(--green); }
.hero .video-thumb video { border-color: color-mix(in srgb, var(--green) 42%, transparent); }
.hero .video-thumb .button::before { background: var(--green); }
.hero .video-thumb .button:hover::before { background: var(--sky); }
.hero .video-thumb .button:hover svg path { fill: var(--deep); }
.hero .button-frame { --btn-fill: var(--green); --btn-label: var(--white); }
.hero .button-frame svg.plaisio .bg { fill: var(--green); }
.hero .button-frame svg.plaisio .hover { fill: var(--sky); }
.hero .button-frame:hover .label-wrap span { color: var(--deep); }
.hero .button-frame:hover .label-wrap svg.icon-arrow path { fill: var(--deep); }
.hero .bottom-wrap span { color: var(--green); }
.hero .bottom-wrap svg path { fill: var(--green); }
.hero .bottom-wrap.dotted-line { background-image: linear-gradient(90deg, color-mix(in srgb, var(--green) 50%, transparent) 33%, transparent 0); }

header .header-nav-label { color: var(--green); }
header .header-nav-link--back-home {
  display: inline-flex;
  width: fit-content;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}
/* Home remains the same-sized navigation item on the homepage and inner
   pages. Only its existing marker icon changes direction. */
header .header-nav-label--back-home {
  color: var(--green);
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
}
header .hamburger .line { background: var(--green); }
header.menu-open .hamburger .line { background: var(--green); }
header .logo .logo-light { display: none; }
header .logo .logo-dark { display: block; filter: brightness(0) saturate(100%) invert(58%) sepia(12%) saturate(1577%) hue-rotate(98deg) brightness(91%) contrast(83%); }
/* Once the hero is behind it, the bar gets its own light surface, preserving
   the same leaf-green navigation over every page section. */
header .top-wrap { transition: transform 0.7s var(--ease-out-expo), background-color 0.3s ease, height 0.3s ease; }
header.is-scrolled:not(.menu-open) .top-wrap {
    height: auto;
    padding-bottom: 18px;
    background: rgba(246, 245, 243, 0.88);
    -webkit-backdrop-filter: blur(14px);
            backdrop-filter: blur(14px);
}
header.is-scrolled .logo img { height: clamp(48px, 3.4vw, 64px); transition: height 0.3s ease; }
@media (min-width: 1281px) {
    header.is-scrolled { mix-blend-mode: normal; }
    header.is-scrolled .header-nav-label { color: var(--green); }
    header.is-scrolled:hover .logo .logo-dark { display: block; }
    header.is-scrolled:hover .logo .logo-light { display: none; }
}

/* Feature visuals inside the former lottie frames */
.lottie-container { position: relative; }
/* Capability media is a full-bleed panel. It should reach every edge of the
   rail; fading or containing the source leaves exposed bands that make the
   card look unfinished. */
.sections .section .lottie-container {
  background: var(--surface-deep);
  padding: 0;
}
.lottie-container img.capability-visual {
  width: 100%;
  height: 100%;
  max-height: none;
  object-fit: contain;
  object-position: center;
  display: block;
  -webkit-mask-image: none;
  mask-image: none;
}

/* Trail-effect images: consistent editorial crop */
.trail-effect img { object-fit: cover; aspect-ratio: 4 / 3; }


/* Footer config note */
.config-note { border: 1px dashed rgba(71, 156, 115, 0.4); padding: 12px 16px; display: inline-block; margin-top: 10px; }

/* Focus visibility (never removed) */
a:focus-visible, button:focus-visible, [role="button"]:focus-visible { outline: 2px solid var(--accent-2); outline-offset: 3px; }

/* Reduced motion: settle content immediately, stop marquee-style loops.
   The curtain/pin/dwell rules are already gated behind
   (prefers-reduced-motion: no-preference), so the page stacks statically. */
@media (prefers-reduced-motion: reduce) {
    [data-animate-in] { opacity: 1 !important; transform: none !important; transition: none !important; }
    .button-frame svg.plaisio .hover,
    .button-frame .label-wrap span,
    .button-frame .label-wrap svg.icon-arrow path,
    .hero .bottom-wrap .scroll-cue svg,
    .video-thumb .button svg,
    .video-thumb .button::before,
    header .top-wrap { transition: none; }
    }

/* Frame buttons hug their SVG frame so the label centers inside it */
.button-frame { width: fit-content; }
.button-frame.d-block { width: fit-content; }

/* At tablet width the collapsed menu already shows a Start-a-project label;
   hide the duplicate desktop nav entry */
@media (max-width: 1023px) {
    header .top-wrap .menu-wrap .menu-item-cart { display: none; }
}

/* Prevent browser scroll anchoring from jumping the page when the swiper
   or animations mutate layout */
body { overflow-anchor: none; }

/* Mobile menu buttons: comfortable touch targets */
.modal-menu .bottom-menu li button { display: block; width: 100%; text-align: left; padding: 15px 0; min-height: 44px; }

/* The system statement sits over a generated, near-dark mineral field. Its
   square-cell canvas uses the same green and sage range, fading behind the
   headline and reaching full intensity in the decorative zone. */
.hand-animation .typography-section .title.st-large { color: var(--text); }
.hand-animation .typography-section .color-green { color: var(--green); }
.hand-animation .typography-section .image-wrap img { filter: saturate(0.88) brightness(0.78) contrast(0.98); }

@media (max-width: 767px) {
  .hand-animation .typography-section .system-pixels.is-ready.is-visible { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .hand-animation .typography-section .system-pixels { transition: none; }
  .hand-animation .typography-section .system-pixels.is-ready.is-visible { opacity: 1; }
  .hand-animation .typography-section .board-backdrop { transform: none; transition: none; }
  .hand-animation .typography-section.theme-small::before { display: none; }
}

/* ============================================
   SECONDARY PAGES (capabilities, work, products, about, contact)
   ============================================ */
.page-main { background: var(--bg); position: relative; z-index: 1; min-height: 100vh; }
.page-intro { padding: 210px 50px 90px; border-bottom: 1px dashed var(--line); }
.page-intro .eyebrow { display: block; margin-bottom: 38px; }
.page-intro .lead { max-width: 60ch; margin-top: 34px; }
.page-section { padding: 90px 50px; }
.page-section.alt { background: var(--surface); }
.page-section .section-label { display: block; margin-bottom: 46px; }

/* Pillar rows: text + media */
.pillar { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center; padding: 64px 0; border-top: 1px dashed var(--line); }
.pillar:first-of-type { border-top: none; padding-top: 12px; }
.pillar .num { display: block; margin-bottom: 20px; }
.pillar .p-title { margin-bottom: 22px; }
.pillar .p-prop { margin-bottom: 22px; max-width: 42ch; }
.pillar .p-list { margin-top: 26px; }
.pillar .p-list li { padding: 15px 0; border-bottom: 1px dashed var(--line); }
.pillar .p-list li:first-child { border-top: 1px dashed var(--line); }
/* Product shots vary between 4:3 and 16:9, so the frame takes each shot's own
   shape: every photo fills it edge to edge with nothing cropped and no
   backdrop strip left above or below it. */
.pillar .media { display: block; border-radius: 0; overflow: hidden; background: var(--surface-deep); }
.pillar .media img { width: 100%; height: auto; display: block; }
.pillar.reverse .text { order: 2; }

/* Card grids: work / products */
.cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.cards .card { background: var(--bg); padding: 44px; display: flex; flex-direction: column; }
.card .status { display: flex; justify-content: space-between; margin-bottom: 22px; }
.card .c-title { margin-bottom: 16px; }
.card .c-media { aspect-ratio: 16 / 10; margin-bottom: 26px; overflow: hidden; border-radius: 0; background: var(--surface); }
.card .c-media img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Numbered process / belief lists */
.stack-list li { display: grid; grid-template-columns: 64px 1fr; gap: 22px; padding: 30px 0; border-top: 1px dashed var(--line); align-items: baseline; }
.stack-list li .st-num { color: var(--green-text); }
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; }

/* Contact form */
.contact-grid { display: grid; grid-template-columns: 1.4fr 1fr; gap: 70px; align-items: start; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.field { margin-bottom: 24px; }
.field.full { grid-column: 1 / -1; }
.field label { display: block; margin-bottom: 12px; }
.field input, .field select, .field textarea { width: 100%; background: transparent; border: 1px solid var(--line-2); color: var(--text); padding: 15px 16px; font-family: 'Helvetica Now Display', arial; font-size: 16px; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: #F6F5F3; outline: none; }
.field select option { background: var(--bg); color: var(--text); }
.form-note { border: 1px dashed rgba(71, 156, 115, 0); border-color: #F6F5F3; padding: 14px 16px; margin-bottom: 26px; }
.form-status { margin-top: 16px; min-height: 1.2em; }
/* Netlify honeypot: present in the DOM, hidden from people. */
.hidden-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.contact-follow { margin-top: 34px; }
.contact-direct { margin-top: 34px; }
.contact-direct__list { display: grid; gap: 16px; margin-top: 16px; }
.contact-direct__list li { display: grid; gap: 6px; }
.contact-direct__list span { opacity: 0.65; }
.contact-direct__list a { width: fit-content; overflow-wrap: anywhere; padding-block: 12px; margin-block: -12px; }
.contact-direct__list a:hover { opacity: 0.7; }
.contact-social { display: flex; gap: 20px; flex-wrap: wrap; margin-top: 16px; }
.contact-social a { display: inline-block; padding: 15px; margin: -15px; }
.contact-social a:hover { opacity: 0.7; }
.newsletter-form { margin-top: 34px; padding-top: 28px; border-top: 1px dashed var(--line); }
.newsletter-form p { margin: 12px 0 18px; }

/* Account access */
.auth-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.auth-panel { background: var(--bg); padding: 44px; }
.auth-panel__title { margin: 18px 0 32px; }
.auth-panel--methods { display: flex; flex-direction: column; }
.auth-methods { display: flex; flex-direction: column; gap: 12px; }
.auth-method-button {
  display: grid;
  grid-template-columns: 42px 1fr;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 58px;
  padding: 8px 14px;
  border: 1px solid var(--line-2);
  text-align: left;
  transition: border-color 0.3s ease, background-color 0.3s ease, opacity 0.3s ease;
}
.auth-method-button[hidden] { display: none !important; }
.auth-method-button:hover,
.auth-method-button:focus-visible { border-color: var(--green); background: rgba(71, 156, 115, 0.10); }
.auth-method-button__mark {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border: 1px solid var(--line-2);
  color: var(--green-text);
  font: 400 12px/1 var(--font-suisse);
}
.auth-panel .button-frame,
.auth-panel .button-frame { margin-top: 8px; }
.auth-panel button[disabled],
.client-portal button[disabled] { opacity: 0.55; cursor: wait; }
.client-portal[hidden],
.auth-grid[hidden] { display: none !important; }

/* Client portal */
.client-portal { border: 1px solid var(--line); background: var(--bg); }
.portal-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 32px;
  padding: 44px;
  border-bottom: 1px solid var(--line);
}
.portal-header h2 { margin: 16px 0 10px; }
.portal-button,
.portal-mini-button {
  min-height: 44px;
  border: 1px solid var(--green);
  color: var(--white);
  background: rgba(71, 156, 115, 0.18);
  padding: 12px 18px;
  font: 400 12px/1 var(--font-suisse);
  text-transform: uppercase;
  transition: background-color 0.25s ease, border-color 0.25s ease, opacity 0.25s ease;
}
.portal-button:hover,
.portal-button:focus-visible,
.portal-mini-button:hover,
.portal-mini-button:focus-visible { background: rgba(71, 156, 115, 0.32); }
.portal-button--quiet,
.portal-mini-button--quiet {
  border-color: var(--line-2);
  background: transparent;
  color: var(--muted);
}
.portal-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-bottom: 1px solid var(--line);
}
.portal-stats article { padding: 30px 36px; border-right: 1px solid var(--line); }
.portal-stats article:last-child { border-right: 0; }
.portal-stats strong { display: block; margin-top: 12px; }
.portal-tabs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-bottom: 1px solid var(--line);
}
.portal-tabs button {
  min-height: 64px;
  border-right: 1px solid var(--line);
  color: var(--muted);
  font: 400 12px/1 var(--font-suisse);
  text-transform: uppercase;
  transition: color 0.25s ease, background-color 0.25s ease;
}
.portal-tabs button:last-child { border-right: 0; }
.portal-tabs button.is-active,
.portal-tabs button:hover,
.portal-tabs button:focus-visible { color: #F6F5F3; background: rgba(71, 156, 115, 0.12); }
.portal-panel { display: none; padding: 44px; }
.portal-panel.is-active { display: block; }
.portal-panel__head {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(280px, 0.6fr);
  gap: 40px;
  align-items: end;
  margin-bottom: 34px;
}
.portal-panel__head h3 { margin: 0; }
.portal-panel__head p { margin: 0; }
.portal-form {
  border: 1px solid var(--line);
  padding: 30px;
  margin-bottom: 34px;
}
.portal-form--compact { max-width: 820px; }
.portal-list { display: grid; gap: 14px; }
.portal-empty { padding: 28px 0; border-top: 1px dashed var(--line); }
.portal-card {
  display: grid;
  gap: 16px;
  border: 1px solid var(--line);
  padding: 26px;
  background: rgba(246, 245, 243, 0.018);
}
.portal-card--compact { gap: 12px; }
.portal-card h4 { margin: 0; }
.portal-card p { margin: 0; }
.portal-card__meta { letter-spacing: 0; }
.portal-card__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.portal-card__actions .portal-card__meta { margin-right: auto; }
.portal-progress {
  width: 100%;
  height: 8px;
  overflow: hidden;
  background: var(--line);
}
.portal-progress span {
  display: block;
  height: 100%;
  background: var(--gold);
  transition: width 0.3s ease;
}

/* Deep-link offset so footer "Services" anchors clear the fixed 100px header */
.pillar[id] { scroll-margin-top: 120px; }

/* Long-form legal pages (privacy, terms) */
.legal-doc { max-width: 74ch; }
.legal-doc .legal-updated { display: block; margin-bottom: 42px; }
.legal-doc h2 { margin: 52px 0 18px; }
.legal-doc h2:first-of-type { margin-top: 0; }
.legal-doc p { margin-bottom: 18px; max-width: 74ch; }
.legal-doc ul { margin: 0 0 20px; padding-left: 22px; }
.legal-doc li { margin-bottom: 10px; list-style: disc; }
.legal-doc a { text-decoration: underline; text-underline-offset: 3px; }
.legal-doc a:hover { opacity: 0.7; }

/* Minimal "in progress" pages (careers, blog, insights, docs) */
.notice-block { margin-top: 40px; display: flex; flex-direction: column; gap: 22px; align-items: flex-start; }

@media (max-width: 1024px) {
  .page-intro { padding: 160px 30px 70px; }
  .page-section { padding: 70px 30px; }
  .contact-grid { grid-template-columns: 1fr; gap: 44px; }
  .auth-grid { grid-template-columns: 1fr; }
  .portal-header,
  .portal-panel__head { grid-template-columns: 1fr; }
  .portal-header { flex-direction: column; }
  .portal-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .portal-stats article:nth-child(2n) { border-right: 0; }
}
@media (max-width: 768px) {
  .page-intro { padding: 140px 20px 56px; }
  .page-section { padding: 56px 20px; }
  .pillar { grid-template-columns: 1fr; gap: 28px; padding: 48px 0; }
  .pillar.reverse .text { order: 0; }
  .cards { grid-template-columns: 1fr; }
  .two-col { grid-template-columns: 1fr; gap: 30px; }
  .form-row { grid-template-columns: 1fr; }
  .stack-list li { grid-template-columns: 44px 1fr; gap: 14px; }
  .portal-header,
  .portal-panel,
  .portal-form { padding: 24px; }
  .portal-stats,
  .portal-tabs { grid-template-columns: 1fr; }
  .portal-stats article,
  .portal-tabs button { border-right: 0; border-bottom: 1px solid var(--line); }
  .portal-stats article:last-child,
  .portal-tabs button:last-child { border-bottom: 0; }
  .portal-card__actions { align-items: stretch; }
  .portal-mini-button { width: 100%; }
}

.cards.three { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 768px) { .cards.three { grid-template-columns: 1fr; } }

/* === FEATURED PROJECT (work page) === */
.featured .f-head { display: flex; gap: 20px 40px; flex-wrap: wrap; align-items: baseline; justify-content: space-between; }
.featured .f-media { position: relative; margin-top: 44px; border-radius: 0; overflow: hidden; border: 1px solid var(--line); background: var(--surface); }
.featured .f-media .shot { width: 100%; display: block; }
.featured .f-media .mobile-inset { position: absolute; right: 3.5%; bottom: -2px; width: 15%; min-width: 118px; border-radius: 0; border: 5px solid var(--ground); }
.featured .f-foot { display: flex; gap: 22px 40px; flex-wrap: wrap; align-items: center; justify-content: space-between; margin-top: 30px; }
.featured .f-tags { display: flex; gap: 10px; flex-wrap: wrap; }
.featured .f-tags .tag { border: 1px solid var(--line-2); padding: 8px 12px; }
.link-arrow { display: inline-flex; align-items: center; gap: 12px; padding-block: 15px; margin-block: -15px; }
.link-arrow span { background-image: linear-gradient(var(--green), var(--green)); background-position: 0 100%; background-repeat: no-repeat; background-size: 100% 1px; padding-bottom: 3px; }
.link-arrow:hover span { opacity: 0.75; }
@media (max-width: 768px) {
  .featured .f-media .mobile-inset { display: none; }
}

/* === OUR PRODUCTION TOOLCHAIN (logo marquee) ===
   After the reference strip, on the brand green: one small centred caption,
   and a single row of logo lockups in one flat grey, fading out at both
   edges. Each lockup is the mark plus the name in the display face, so the
   pair reads as a wordmark. Brand colour appears only on hover. */
.powered-by {
  position: relative;
  z-index: 2;
  /* Keep the Leaf Green surface identical to the Studio section below it.
     Only the foreground content should move; a gradient here used to leave
     with this band and made the incoming Studio background look like it
     dissolved and then reappeared. */
  background: var(--leaf, #479c73);
  opacity: 1;
  transition: none;
  animation: none;
  padding: clamp(40px, 5vw, 64px) 0 clamp(48px, 6vw, 80px);
  overflow: hidden;
}
.pb-caption {
  text-align: center;
  letter-spacing: 0.22em;
  color: var(--green-strong, #26503c);
  margin: 0 0 clamp(28px, 3.2vw, 44px);
}
.pb-marquee {
  position: relative; overflow: hidden;
  max-width: 1180px; margin-inline: auto;
  -webkit-mask-image: linear-gradient(90deg, transparent, #479c73 14%, #479c73 86%, transparent);
          mask-image: linear-gradient(90deg, transparent, #479c73 14%, #479c73 86%, transparent);
}
.pb-track { display: flex; width: 100%; }
.pb-row-set {
  --pb-gap: clamp(44px, 4.6vw, 72px);
  display: flex; align-items: center; flex: 0 0 auto;
  gap: var(--pb-gap); padding: 0 var(--pb-gap) 0 0; margin: 0;
  list-style: none;
}
.pb-logo {
  --pb-grey: rgba(16, 40, 30, 0.78);
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--pb-grey);
  transition: color 0.3s ease;
}
.pb-logo__mark { display: inline-flex; width: clamp(24px, 2.1vw, 30px); height: clamp(24px, 2.1vw, 30px); }
.pb-logo__mark svg { width: 100%; height: 100%; display: block; }
/* Every mark goes monochrome at rest, including the multi-colour ones whose
   paths carry their own fills. */
.pb-logo__mark svg,
.pb-logo__mark svg * { fill: currentColor; transition: fill 0.3s ease; }
.pb-logo__mark svg [fill="none"] { fill: none; }
.pb-logo__name {
  font-family: 'Helvetica Now Display', arial, sans-serif; font-weight: 700;
  font-size: clamp(20px, 1.9vw, 28px); line-height: 1; letter-spacing: -0.03em;
  white-space: nowrap;
}
@media (hover: hover) {
  .pb-logo:hover { color: var(--brand-color); }
}
@media (max-width: 768px) {
  .pb-row-set { --pb-gap: 36px; }
  .pb-logo__name { font-size: 19px; }
  .pb-logo__mark { width: 22px; height: 22px; }
}

/* Mobile chrome sits directly over the page. Keep the light mark and menu
   strokes visible without reintroducing the translucent scrolled banner. */
@media (max-width: 1023px) {
  header .top-wrap,
  header.is-scrolled:not(.menu-open) .top-wrap {
    background: transparent;
    -webkit-backdrop-filter: none;
            backdrop-filter: none;
    box-shadow: none;
  }
  header .logo .logo-light { display: block; filter: none; }
  header .logo .logo-dark { display: none; }
  header .hamburger .line,
  header.menu-open .hamburger .line { background: var(--white, #f6f5f3); }

  /* This is the first section immediately below the hero. Give mobile its
     own explicit opaque paint layer so no reveal or compositing state can
     expose the page underneath it. */
  body[data-page='home'] .powered-by {
    background-color: #479c73;
    background-image: none;
    opacity: 1;
    filter: none;
    mix-blend-mode: normal;
    transition: none;
    animation: none;
  }
}


/* === SCROLL REVEAL ===
   Content eases up into place as it enters the viewport, staggered per group.
   The hiding rule is scoped to .has-reveal on <html>, which main.js adds only
   immediately before it starts the observer — so if JS is off, blocked or
   throws, nothing is ever left permanently invisible. Honours reduced-motion.
   Tune per element with data-reveal="left|right|scale" and --reveal-shift. */
.has-reveal [data-reveal] {
  opacity: 0;
  transform: translate3d(0, var(--reveal-shift, 26px), 0);
  transition: opacity var(--dur-slow) var(--ease-out-quart),
              transform var(--dur-slow) var(--ease-out-expo);
  transition-delay: calc(var(--reveal-i, 0) * 85ms);
  will-change: opacity, transform;
}
.has-reveal [data-reveal="left"]  { transform: translate3d(calc(var(--reveal-shift, 26px) * -1.5), 0, 0); }
.has-reveal [data-reveal="right"] { transform: translate3d(calc(var(--reveal-shift, 26px) *  1.5), 0, 0); }
.has-reveal [data-reveal="scale"] { transform: scale(0.965); }
/* Must follow the variants so it wins the transform back to rest. */
.has-reveal [data-reveal].is-revealed { opacity: 1; transform: none; }
.has-reveal [data-reveal].is-revealed { will-change: auto; }

@media (prefers-reduced-motion: reduce) {
  .has-reveal [data-reveal],
  .has-reveal [data-reveal].is-revealed {
    opacity: 1; transform: none; transition: none; transition-delay: 0s;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MEDIA PRESENTATION
   How images and slides are framed across the homepage. Appended last so it
   layers over the base rules above rather than fighting them.

   Direction: imagery sits on a lit accent panel rather than a flat dark rail,
   framing is consistent and generous, and media has a little depth so it reads
   as an object on the page. The accent is the brand green throughout — no new
   hue is introduced. Structure and copy are untouched; this is presentation
   only.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Capability visuals ───────────────────────────────────────────────────
   Was a flat --surface-deep rail. Now a lit panel: a soft green pool rising
   from below the product shot, so the mockup sits in light instead of on a
   dead deep-green block. The existing top/bottom feather mask still applies and
   now fades into the panel. */
.sections .section .lottie-container {
  background: var(--ground);
  background: var(--forest-deep);
  border-radius: 0;
  overflow: hidden;
}
/* The dark panel already stands off the light ground; no outline needed. */
.sections .section .lottie-container::after {
  display: none;
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: 0;
  border: 1px solid rgba(71, 156, 115, 0.22);
}
.lottie-container img.capability-visual {
  transition: transform var(--dur-slower) var(--ease-out-expo);
}
.sections .section .lottie-container:hover img.capability-visual { transform: none; }

@media (min-width: 1024px) {
  .sections .section .title,
  .sections .section .text-wrap { max-width: min(40vw, 720px); }
  .sections .section-system-apps,
  .sections .section-automation,
  .sections .section-core-agents { box-shadow: 0 -28px 48px -30px rgba(71, 156, 115, 0.35); }
  .sections .section .text-wrap > .sx-btn { margin-top: 50px; }
}

/* ── Marquee slide imagery ────────────────────────────────────────────────
   The slides were fully greyscaled (grayscale(1)), which on a green-branded
   page flattens every panel to the same dead tone. Easing that back lets the
   imagery carry some colour; the heavy scrim above it still guarantees the
   overlaid text stays legible, so nothing is lost in contrast. */

/* ── Standalone media blocks ──────────────────────────────────────────────
   Consistent framing so every image on the page is cut the same way. */
._02 .experience .media-wrap .image-wrap {
  border-radius: 0;
  overflow: hidden;
}
._02 .experience .media-wrap .image-wrap img {
  transition: transform var(--dur-slower) var(--ease-out-expo);
}
._02 .experience .media-wrap .image-wrap:hover img { transform: scale(1.035); }

.trail-effect img { border-radius: 0; }



.typography-section .board-backdrop { border-radius: 0; overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .lottie-container img.capability-visual,
  ._02 .experience .media-wrap .image-wrap img { transition: none; }
  .sections .section .lottie-container:hover img.capability-visual,
  ._02 .experience .media-wrap .image-wrap:hover img { transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   SECTION 03 — WHO WE BUILD FOR (static editorial grid)

   Replaces the continuous right-to-left marquee. The old treatment panned five
   full-viewport panels forever at 8s each, which had three real problems:
   the copy moved while you were trying to read it; a visitor who wanted panel
   two waited ~40s for the cycle; and the only pause affordance was hover,
   which does not exist on touch — failing WCAG 2.2.2 (Pause, Stop, Hide).

   This content is comparative — five audience types, each saying "if you are
   this, here is what you get" — so it wants to be scannable side by side, not
   revealed serially. All five are now visible at once. Entrance life comes
   from the existing scroll-reveal system instead of a permanent loop.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Release the section from the full-viewport geometry the swiper needed. */
._03 { min-height: 0; }
._03 .header { padding: 0 var(--gutter); margin-bottom: var(--space-8); }

.aud { padding-inline: var(--gutter); position: relative; z-index: 1; }
.aud__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-9) var(--space-8);
  max-width: 1440px;
  margin-inline: auto;
}
/* Four audiences: one row on desktop, two by two on tablets. */
@media (max-width: 1100px) {
  .aud__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .aud__grid { grid-template-columns: 1fr; }
}

/* Open column beneath a dotted rule, square and unfilled. Motion follows the
   live-work cards without adding a new surface or changing the image colour. */
.aud__card {
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5) 0 var(--space-6);
  transform: translateZ(0);
  transition: transform var(--dur-slower) var(--ease-out-expo);
}

.aud__media {
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--forest-deepest);
  transform: translateZ(0);
  box-shadow: 0 10px 28px -24px rgba(14, 42, 30, 0.72);
  transition: box-shadow var(--dur-slower) var(--ease-out-expo);
}
.aud__media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  /* Muted so five thumbnails read as one set rather than five competing
     photographs — but not fully desaturated, which would kill the green. */
  filter: grayscale(0.55) saturate(1.06) contrast(0.92) brightness(1.06);
  transition: transform var(--dur-slower) var(--ease-out-expo);
}
.aud__card:hover { transform: translate3d(0, -6px, 0); }
.aud__card:hover .aud__media { box-shadow: 0 24px 48px -30px rgba(14, 42, 30, 0.82); }
.aud__card:hover .aud__media img { transform: scale(1.015); }
.aud__item:nth-child(4) .aud__media img { object-position: 50% 46%; }

.aud__meta { display: flex; align-items: baseline; gap: var(--space-3); color: var(--white); }
.aud__index { font-variant-numeric: tabular-nums; }
.aud__index::after { content: '/'; margin-left: 2px; }
.aud__name { display: block; color: var(--text); }
/* Sentence case, not uppercase: at ~150 characters all-caps strips word-shape
   cues and costs 10-15% reading speed for no gain. */
.aud__copy { color: rgba(246, 245, 243, 0.72); color: color-mix(in srgb, var(--text) 72%, transparent); }
.aud__tag {
  margin-top: auto;
  padding-top: var(--space-4);
  color: var(--text-subtle);
  text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .aud__card,
  .aud__media,
  .aud__media img { transition: none; transform: none; }
  .aud__card:hover,
  .aud__card:hover .aud__media img { transform: none; }
}


/* ── Single scrolling logo line ───────────────────────────────────────────
   Was two rows counter-scrolling. Now one row travelling left, shifted by
   exactly one set width per cycle so the loop is seamless. The set is
   repeated in JS until the rail exceeds twice the viewport, which is what
   keeps a short list from leaving a gap. */
.pb-row-single {
  display: flex;
  flex-wrap: nowrap;
  width: max-content;
  will-change: transform;
  animation: pb-line var(--pb-duration, 32s) linear infinite;
}
@keyframes pb-line {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(calc(var(--pb-shift, 800px) * -1), 0, 0); }
}
.pb-marquee:hover .pb-row-single,
.pb-marquee:focus-within .pb-row-single { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .pb-row-single { animation: none; }
  .pb-marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }
  .pb-row-set-dup { display: none; }
}

/* Work entries awaiting a device mockup. Renders a marked slot at the same
   aspect as a real shot, rather than a broken <img>. Delete the rule once
   every entry has its imagery. */
.work-shot--pending {
  aspect-ratio: 16 / 10;
  display: grid;
  place-content: center;
  background: var(--deep);
  border: 1px dashed var(--line-2);
  color: var(--text-subtle);
  margin: 0;
}

#main-content:focus { outline: none; }


/* Buttons use deep ink at rest and white on hover, independent of the page
   surface underneath. */
.hero, .background-gray-super-dark {
  --btn-fill: var(--deep);
  --btn-label: var(--white);
}
/* The warm bands are light, so their button is the deep green with a
   near-white label: 12.36:1 against the band. */
.hx--deep, .sx--deep {
  --btn-fill: var(--deep);
  --btn-label: var(--white);
}
