/* ==========================================================================
   Self-hosted webfonts. Merged in from fonts.css so the page needs one
   stylesheet instead of two: a second blocking request cost a round trip on
   every first visit for 1.2 KiB of @font-face rules.
   ========================================================================== */
/* Self-hosted fonts (Instrument Serif, Hanken Grotesk, Space Mono).
   Generated from the Google Fonts CSS2 API; files live in assets/fonts/.
   No third-party requests at runtime. */
/* cyrillic-ext */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpQ59CjCQ.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* vietnamese */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpS59CjCQ.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpT59CjCQ.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpd59A.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpQ59CjCQ.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* vietnamese */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpS59CjCQ.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpT59CjCQ.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpd59A.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpQ59CjCQ.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* vietnamese */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpS59CjCQ.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpT59CjCQ.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpd59A.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpQ59CjCQ.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* vietnamese */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpS59CjCQ.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpT59CjCQ.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/ieVn2YZDLWuGJpnzaiwFXS9tYtpd59A.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Instrument Serif';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/jizHRFtNs2ka5fXjeivQ4LroWlx-6zAjgn7MsNo.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Instrument Serif';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/jizHRFtNs2ka5fXjeivQ4LroWlx-6zAjjH7M.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/jizBRFtNs2ka5fXjeivQ4LroWlx-6zsTjmbI.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Instrument Serif';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/jizBRFtNs2ka5fXjeivQ4LroWlx-6zUTjg.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/i7dPIFZifjKcF5UAWdDRYE58RWq7.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/i7dPIFZifjKcF5UAWdDRYE98RWq7.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/i7dPIFZifjKcF5UAWdDRYEF8RQ.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/i7dMIFZifjKcF5UAWdDRaPpZUFqaHjyV.woff2) format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/i7dMIFZifjKcF5UAWdDRaPpZUFuaHjyV.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/i7dMIFZifjKcF5UAWdDRaPpZUFWaHg.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   Mauro Perrella — personal branding landing page
   Standalone static port of the Claude Design ".dc" template.
   Accent colour: oklch(0.8 0.1 80)  (warm gold)
   ========================================================================== */

/* Motion tokens, mirrored from the design system's tokens/spacing.css so the
   timing of everything on this page comes from one place. */
:root {
  --mp-ease: cubic-bezier(0.65, 0, 0.35, 1);
  /* Reveals use an ease-out instead: an ease-in-out spends its middle at high
     speed and its ends crawling, which on a long opacity fade reads as a hold
     followed by a rush. This one moves immediately and settles. */
  --mp-ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);
  --mp-dur-fast: .25s;
  --mp-dur-mid: .5s;
  --mp-dur-reveal: .7s;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: #100f0d;
  color: #ece7df;
  font-family: 'Hanken Grotesk', sans-serif;
  min-height: 100vh;
  /* `clip` guards against accidental horizontal overflow exactly like `hidden`,
     but without turning <body> into a scroll container — which would break
     position:sticky on the nav. `hidden` stays first as the fallback. */
  overflow-x: hidden;
  overflow-x: clip;
}
input, textarea { font-family: inherit; }
a { -webkit-tap-highlight-color: transparent; }

@keyframes mp-spin { to { transform: rotate(360deg); } }

/* ---- Scroll-reveal ------------------------------------------------------ */
section[data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s ease, transform .7s ease;
}
section[data-reveal][data-revealed] {
  opacity: 1;
  transform: none;
}

/* ---- Nav ----------------------------------------------------------------
   Full-width sticky bar; the <nav> inside stays on the 1320px column so the
   hairline runs edge to edge while the content stays aligned. At the top the
   bar is invisible and the nav simply sits on the page — it only materialises
   once content starts passing underneath. Padding never changes: altering the
   height of an in-flow sticky element would shift everything below it.
   Opaque, per the design system: blur is reserved for the mobile menu. */
.nav-bar {
  position: sticky;
  top: 0;
  z-index: 8500;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background var(--mp-dur-fast) var(--mp-ease),
              border-bottom-color var(--mp-dur-fast) var(--mp-ease);
}
.nav-bar.is-stuck {
  background: #100f0d;
  border-bottom-color: rgba(236,231,223,0.12);
}

.nav-links a {
  color: #8c857a;
  text-decoration: none;
  transition: color .25s;
}
.nav-links a:hover { color: oklch(0.8 0.1 80); }

.lang-btn {
  border: none;
  background: transparent;
  cursor: pointer;
  padding: 2px 4px;
  font-family: inherit;
  font-size: 13px;
  letter-spacing: .04em;
  transition: color .25s;
  color: #8c857a;
}
.lang-btn.active { color: oklch(0.8 0.1 80); }

/* Cookie policy — the "← Home" link. It must NOT reuse .nav-links: that class
   is the desktop menu, which the 760px breakpoint hides in favour of the
   hamburger — and this page has no hamburger to fall back to, so the link
   simply vanished on mobile. */
.cp-home {
  color: #8c857a;
  text-decoration: none;
  transition: color var(--mp-dur-fast) var(--mp-ease);
}
.cp-home:hover { color: oklch(0.8 0.1 80); }

/* ---- Hover states -------------------------------------------------------
   The base value of every animated property lives HERE, not in the element's
   inline style. An inline declaration outranks any selector, so a base value
   left inline silently kills its own :hover rule.
   Easing and durations mirror the design system tokens (--mp-ease, .25s/.5s).
   ------------------------------------------------------------------------ */
.btn-accent { transition: opacity var(--mp-dur-fast) var(--mp-ease); }
.btn-accent:hover { opacity: .85; }

.link-underline {
  border-bottom: 1px solid rgba(236,231,223,0.3);
  transition: border-color var(--mp-dur-fast) var(--mp-ease);
}
.link-underline:hover { border-color: oklch(0.8 0.1 80); }

/* Hero portrait — matches the design system's ImageFrame: grayscale clears on
   hover with a gentle scale. Frame ratio equals the photo's (2/3), so the image
   is shown whole; only the hover scale crops, and only while hovered. */
.hero-portrait .hero-img {
  filter: grayscale(.1);
  transition: filter var(--mp-dur-fast) var(--mp-ease),
              transform var(--mp-dur-mid) var(--mp-ease);
}
.hero-portrait:hover .hero-img {
  filter: grayscale(0);
  transform: scale(1.04);
}

.press-card .press-img {
  filter: grayscale(.3);
  transition: filter var(--mp-dur-fast) var(--mp-ease),
              transform var(--mp-dur-mid) var(--mp-ease);
}
.press-card:hover .press-img {
  filter: grayscale(0);
  transform: scale(1.04);
}

.press-more-btn {
  border: 1px solid rgba(236,231,223,0.22);
  color: #ece7df;
  transition: border-color var(--mp-dur-fast) var(--mp-ease),
              color var(--mp-dur-fast) var(--mp-ease);
}
.press-more-btn:hover:not(:disabled) {
  border-color: oklch(0.8 0.1 80);
  color: oklch(0.8 0.1 80);
}
.press-more-btn:disabled { cursor: default; }

/* A gold rule grows at the left edge as the row slides over — it fills the
   space the padding shift opens up, so the movement reads as intentional. */
.case-row {
  position: relative;
  padding: 30px 18px;
  transition: background var(--mp-dur-mid) var(--mp-ease),
              padding-left var(--mp-dur-mid) var(--mp-ease);
}
.case-row::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 2px;
  height: 0;
  background: oklch(0.8 0.1 80);
  transform: translateY(-50%);
  transition: height var(--mp-dur-mid) var(--mp-ease);
}
.case-row:hover {
  background: rgba(236,231,223,0.03);
  padding-left: 30px;
}
.case-row:hover::before { height: 54%; }

.partner-band .partner-img {
  filter: grayscale(.25);
  transition: filter var(--mp-dur-mid) var(--mp-ease),
              transform .7s var(--mp-ease);
}
.partner-band:hover .partner-img {
  filter: grayscale(0);
  transform: scale(1.04);
}

.partner-by {
  color: #8c857a;
  transition: color var(--mp-dur-fast) var(--mp-ease);
}
.partner-by:hover { color: oklch(0.8 0.1 80); }

.footer-cookie {
  color: #8c857a;
  transition: color var(--mp-dur-fast) var(--mp-ease);
}
.footer-cookie:hover { color: #ece7df; }

/* ==========================================================================
   Cookie consent — banner + preferences modal
   ========================================================================== */
/* Slides in instead of appearing. transform and opacity are composited, so the
   entrance costs no layout shift — and a banner that materialises instantly at
   the bottom of the viewport reads as a glitch. */
@keyframes mp-banner-in {
  from { opacity: 0; transform: translateY(100%); }
  to   { opacity: 1; transform: none; }
}
.cc-banner {
  animation: mp-banner-in var(--mp-dur-reveal) var(--mp-ease-out);
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 9500;
  background: #16140f;
  border-top: 1px solid rgba(236,231,223,0.14);
  box-shadow: 0 -16px 40px rgba(0,0,0,0.45);
}
.cc-banner-inner {
  max-width: 1320px;
  margin: 0 auto;
  padding: 22px 48px;
  display: flex;
  align-items: center;
  gap: 32px;
  flex-wrap: wrap;
}
.cc-banner-text { flex: 1 1 380px; min-width: 260px; }
.cc-banner-title {
  font-family: 'Instrument Serif', serif;
  font-size: 22px;
  line-height: 1.1;
  margin-bottom: 6px;
  color: #ece7df;
}
.cc-banner-text p {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: #8c857a;
}
.cc-banner-text a { color: oklch(0.8 0.1 80); text-decoration: none; border-bottom: 1px solid rgba(236,231,223,0.25); }
.cc-banner-text a:hover { border-color: oklch(0.8 0.1 80); }
.cc-banner-actions {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}

/* Buttons (shared by banner + modal) */
.cc-btn {
  font-family: 'Space Mono', monospace;
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 13px 22px;
  border-radius: 2px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: opacity .25s, border-color .25s, color .25s, background .25s;
  white-space: nowrap;
}
.cc-btn-primary { background: oklch(0.8 0.1 80); color: #100f0d; border-color: oklch(0.8 0.1 80); font-weight: 700; }
.cc-btn-primary:hover { opacity: .85; }
.cc-btn-secondary { background: transparent; color: #ece7df; border-color: rgba(236,231,223,0.4); }
.cc-btn-secondary:hover { border-color: #ece7df; }
.cc-btn-ghost { background: transparent; color: #8c857a; border-color: rgba(236,231,223,0.18); }
.cc-btn-ghost:hover { color: oklch(0.8 0.1 80); border-color: oklch(0.8 0.1 80); }

/* Preferences modal */
.cc-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 9600;
  background: rgba(16,15,13,0.82);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 28px;
  overflow-y: auto;
}
.cc-modal {
  width: 100%;
  max-width: 620px;
  background: #16140f;
  border: 1px solid rgba(236,231,223,0.14);
  border-radius: 4px;
  padding: 36px;
  margin: auto;
}
.cc-modal-title {
  font-family: 'Instrument Serif', serif;
  font-weight: 400;
  font-size: 30px;
  margin: 0 0 12px;
  color: #ece7df;
}
.cc-modal-intro {
  font-size: 14px;
  line-height: 1.6;
  color: #8c857a;
  margin: 0 0 24px;
}
.cc-cat {
  padding: 20px 0;
  border-top: 1px solid rgba(236,231,223,0.1);
}
.cc-cat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.cc-cat-name { font-size: 16px; font-weight: 600; color: #ece7df; }
.cc-cat-desc { margin: 8px 0 0; font-size: 13px; line-height: 1.6; color: #8c857a; }
.cc-cat-always {
  font-family: 'Space Mono', monospace;
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: oklch(0.8 0.1 80);
}
.cc-modal-actions {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
  flex-wrap: wrap;
  margin-top: 28px;
}

/* Toggle switch */
.cc-switch { position: relative; display: inline-block; width: 46px; height: 26px; flex: none; }
.cc-switch input { opacity: 0; width: 0; height: 0; }
.cc-slider {
  position: absolute;
  cursor: pointer;
  inset: 0;
  background: #3a352d;
  border-radius: 26px;
  transition: background .25s;
}
.cc-slider::before {
  content: "";
  position: absolute;
  height: 18px; width: 18px;
  left: 4px; bottom: 4px;
  background: #ece7df;
  border-radius: 50%;
  transition: transform .25s;
}
.cc-switch input:checked + .cc-slider { background: oklch(0.8 0.1 80); }
.cc-switch input:checked + .cc-slider::before { transform: translateX(20px); background: #100f0d; }
.cc-switch input:focus-visible + .cc-slider { outline: 2px solid oklch(0.8 0.1 80); outline-offset: 2px; }

@media (max-width: 760px) {
  .cc-banner-inner { padding: 20px 22px; gap: 18px; }
  .cc-banner-actions { width: 100%; }
  .cc-banner-actions .cc-btn { flex: 1 1 auto; text-align: center; }
  .cc-modal { padding: 28px 22px; }
  .cc-modal-actions .cc-btn { flex: 1 1 auto; text-align: center; }
}

/* ---- Responsive: tablet ------------------------------------------------- */
@media (max-width: 1024px) {
  .press-grid { grid-template-columns: 1fr 1fr !important; }
}

/* ---- Responsive: mobile ------------------------------------------------- */
@media (max-width: 760px) {
  nav { padding: 20px 22px !important; }
  .nav-links { display: none !important; }
  .nav-burger { display: inline-flex !important; }
  header.hero {
    grid-template-columns: 1fr !important;
    gap: 36px !important;
    padding: 36px 22px 64px !important;
  }
  section[data-reveal] { padding: 64px 22px !important; }
  .about-grid { grid-template-columns: 1fr !important; gap: 28px !important; }
  .about-inner { grid-template-columns: 1fr !important; }
  .stats-grid { grid-template-columns: 1fr 1fr !important; gap: 28px !important; }
  .press-grid { grid-template-columns: 1fr !important; }
  /* Avatar and client name stay side by side; only the metrics drop below.
     A single column stacked all three, so the name wrapped underneath its own
     portrait and the row read as three unrelated blocks. */
  .case-row {
    grid-template-columns: 84px 1fr !important;
    gap: 40px 20px !important;
  }
  .case-row > :last-child { grid-column: 1 / -1; }
  .partner-band { flex-direction: column !important; gap: 24px !important; }
  .contact-grid { grid-template-columns: 1fr !important; gap: 48px !important; }
  footer { padding: 40px 22px !important; }
}

/* ==========================================================================
   Craft layer
   One idea, applied consistently: the page sets itself like editorial type —
   things arrive in reading order rather than all at once. Everything below
   stays inside the design system's rules: no second hue, no gradients, no
   shadows, no bounces, no loops.
   ========================================================================== */

/* ---- Typographic detail ------------------------------------------------- */
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
html { hanging-punctuation: first last; }

/* Headings break into even lines instead of leaving a single orphaned word;
   body copy avoids orphans too. Costs nothing, and it is the difference
   between type that was set and type that was merely poured in. */
h1, h2 { text-wrap: balance; }
p { text-wrap: pretty; }

::selection { background: oklch(0.8 0.1 80); color: #100f0d; }

/* ---- Keyboard focus ----------------------------------------------------- */
:focus-visible {
  outline: 2px solid oklch(0.8 0.1 80);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---- Hero: the page sets itself on load --------------------------------- */
@keyframes mp-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
.hero-copy > * { animation: mp-rise var(--mp-dur-reveal) var(--mp-ease) backwards; }
.hero-copy > *:nth-child(1) { animation-delay: .06s; }
.hero-copy > *:nth-child(2) { animation-delay: .15s; }
.hero-copy > *:nth-child(3) { animation-delay: .24s; }
.hero-copy > *:nth-child(4) { animation-delay: .33s; }

/* The frame holds an MP plate while the photo loads, so the space is never empty
   and the border has something to enclose. Flat surface, no texture: the letters
   carry it on their own. The monogram matches assets/favicon.svg. The plate sits
   underneath the photo, which fades slowly over it once the browser reports it
   decoded. Gated on `.js`: without JavaScript the photo is simply there. */
.hero-portrait {
  border: 1px solid rgba(236,231,223,0.1);
  background: #1a1814;
}
/* Five layers, bottom to top: photo · curtain · grey monogram · photographic
   monogram · scrim. Explicit z-index throughout — the overlays are positioned
   and the <img> is not, so without it they would paint over the photo for good. */
.hero-portrait .hero-img { position: relative; z-index: 1; }
.hero-curtain { position: absolute; inset: 0; z-index: 2; background: #161412; }
.hero-placeholder { z-index: 3; color: #6b655c; }
.hero-mono {
  z-index: 4;
  /* The letters are a window cut into the photograph itself: same image, same
     cover-fit, same centring as the <img> below, so the glyphs frame exactly
     the pixels that will be there when the curtain lifts. That congruence is
     what makes the handover invisible. */
  color: transparent;
  background-image: url(assets/portrait-mauro.webp?v=61e2c019);
  background-size: cover;
  background-position: center;
  -webkit-background-clip: text;
  background-clip: text;
  filter: grayscale(.1);       /* matches the photo's resting grade */
  opacity: 0;
}
.hero-placeholder,
.hero-mono {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Instrument Serif', Georgia, serif;
  /* Large on purpose: the bigger the glyphs, the more of the photograph shows
     through them, so the monogram reads as a window rather than a label. */
  font-size: clamp(96px, 13vw, 176px);
  line-height: 1;
  letter-spacing: .06em;
  text-indent: .06em;          /* offsets the trailing letter-space, optically centring MP */
  user-select: none;
}
.hero-portrait .hero-scrim { z-index: 5; }

/* Without JavaScript none of the overlay layers show: the photo and its scrim
   are simply there, unanimated. The curtain only exists to be lifted. */
.hero-curtain,
.hero-placeholder { opacity: 0; }
.js .hero-curtain,
.js .hero-placeholder { opacity: 1; }
.js .hero-scrim { opacity: 0; }

/* Promote the moving layers so their opacity animates on the compositor. The
   monogram carries both a clipped background and a filter, which is exactly the
   kind of layer that stutters when it has to be re-rasterised every frame. */
.js .hero-curtain,
.js .hero-placeholder,
.js .hero-mono,
.js .hero-scrim { will-change: opacity; }

/* The handover, once the photo is decoded (.is-ready). The photograph does not
   replace the monogram, it comes out of it:
     0 → 0.9s     the grey monogram develops into the photographic one
     0.85 → 3.35s the curtain lifts, so the photograph spreads from inside the
                  letters out to the whole frame; the letter layer then dissolves
                  into pixels it already matches, so nothing visibly ends.
   The grey layer does NOT cross-fade with the photographic one — two opposing
   fades would both sit near half opacity in the middle and the letters would go
   pale. It holds at full strength and is dissolved later, underneath a monogram
   that already covers it. The phases overlap so the second movement
   starts before the first has stopped. */
@keyframes mp-mono {
  0%   { opacity: 0; }
  26%  { opacity: 1; }
  62%  { opacity: 1; }
  100% { opacity: 0; }
}
.js .hero-portrait.is-ready .hero-placeholder {
  opacity: 0;
  transition: opacity 1.4s var(--mp-ease-out) 1s;
}
.js .hero-portrait.is-ready .hero-mono {
  animation: mp-mono 3.4s var(--mp-ease-out) forwards;
}
.js .hero-portrait.is-ready .hero-curtain {
  opacity: 0;
  transition: opacity 2.5s var(--mp-ease-out) .85s;
}
.js .hero-portrait.is-ready .hero-scrim {
  opacity: 1;
  transition: opacity 2.5s var(--mp-ease-out) .85s;
}

/* ---- Sections: children arrive in reading order ------------------------- */
.stagger > * {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .55s var(--mp-ease), transform .55s var(--mp-ease);
}
[data-revealed] .stagger > * { opacity: 1; transform: none; }

.stagger > *:nth-child(1)  { transition-delay: 0s;    }
.stagger > *:nth-child(2)  { transition-delay: .06s;  }
.stagger > *:nth-child(3)  { transition-delay: .12s;  }
.stagger > *:nth-child(4)  { transition-delay: .18s;  }
.stagger > *:nth-child(5)  { transition-delay: .24s;  }
.stagger > *:nth-child(6)  { transition-delay: .30s;  }
.stagger > *:nth-child(7)  { transition-delay: .36s;  }
.stagger > *:nth-child(8)  { transition-delay: .42s;  }
.stagger > *:nth-child(9)  { transition-delay: .48s;  }
.stagger > *:nth-child(n+10) { transition-delay: .52s; }

/* ---- The numbers: the one place this page raises its voice --------------
   "Numbers carry the argument" — so the figures are the only thing that gets
   a reveal of its own: each numeral rises into its line like a slug of type
   dropping into place, and its label fades in just behind it. */
.stat-num {
  clip-path: inset(105% 0 -0.18em 0);
  transform: translateY(.14em);
  transition: clip-path .75s var(--mp-ease), transform .75s var(--mp-ease);
}
[data-revealed] .stat-num {
  clip-path: inset(-0.3em 0 -0.18em 0);
  transform: none;
}
.stat-label { opacity: 0; transition: opacity var(--mp-dur-mid) var(--mp-ease); }
[data-revealed] .stat-label { opacity: 1; }

.stat:nth-child(1) .stat-num { transition-delay: .05s; }
.stat:nth-child(2) .stat-num { transition-delay: .17s; }
.stat:nth-child(3) .stat-num { transition-delay: .29s; }
.stat:nth-child(4) .stat-num { transition-delay: .41s; }
.stat:nth-child(1) .stat-label { transition-delay: .30s; }
.stat:nth-child(2) .stat-label { transition-delay: .42s; }
.stat:nth-child(3) .stat-label { transition-delay: .54s; }
.stat:nth-child(4) .stat-label { transition-delay: .66s; }

/* ---- Back to top -------------------------------------------------------
   Static styling lives here, not inline, because two pages share the button
   (index.html and cookie-policy.html) and they must not drift apart.
   Behaviour is in backtop.js. */
.backtop {
  position: fixed;
  right: 26px;
  bottom: 26px;
  z-index: 8000;
  width: 48px;
  height: 48px;
  border: none;
  border-radius: 50%;
  background: oklch(0.8 0.1 80);
  color: #100f0d;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px) scale(.94);
  transition: opacity var(--mp-dur-fast) var(--mp-ease),
              transform var(--mp-dur-fast) var(--mp-ease),
              visibility 0s var(--mp-dur-fast);
}
.backtop.is-visible {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity var(--mp-dur-fast) var(--mp-ease),
              transform var(--mp-dur-fast) var(--mp-ease);
}
.backtop.is-visible:hover { transform: translateY(-3px); }

/* ---- Reduced motion: show the same page, without the choreography ------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0ms !important;
    transition-duration: .001ms !important;
    transition-delay: 0ms !important;
  }
  section[data-reveal] { opacity: 1; transform: none; }
  .stagger > * { opacity: 1; transform: none; }
  .stat-num { clip-path: none; transform: none; }
  .stat-label { opacity: 1; }
}
