/* Page styles carried over from the design canvas (The principal). */
body{margin:0;background:#FAF8F5}
a{color:#14181B;text-decoration:underline;text-decoration-color:#8F3F49;text-underline-offset:0.15em;transition:color 150ms ease}
a:hover{color:#8F3F49}

/* Header nav */
.nav-link{font:400 15px/1.5 'IBM Plex Sans',system-ui,sans-serif;color:#5C5853;text-decoration:none;white-space:nowrap;transition:color 150ms ease}
.nav-link:hover{color:#14181B}
.nav-link[aria-current="page"]{color:#14181B;text-decoration:underline;text-decoration-color:#14181B;text-underline-offset:0.3em;text-decoration-thickness:1px}

/* Hairline link button.
   The site has no filled buttons, so this is the [data-cta] idiom on the home
   page reduced to a single control: a rule box around an interface-font label,
   square corners, no fill, no shadow and no mark. Hover moves nothing; it takes
   the border and the label to eosin and back, on the same 150ms as every other
   link. Overrides the global underline on `a`, which a bordered control does not
   need. */
[data-linkbtn]{display:inline-flex;align-items:center;box-sizing:border-box;padding:13px 22px;border:1px solid #DCD7CE;font:500 15px/1.5 'IBM Plex Sans',system-ui,sans-serif;color:#14181B;text-decoration:none;transition:color 150ms ease,border-color 150ms ease}
[data-linkbtn]:hover{color:#8F3F49;border-color:#8F3F49}

/* Counters */
[data-figure]{transition:color 150ms ease}
[data-figure][data-pending]{color:#DCD7CE !important}
@media (prefers-reduced-motion:reduce){[data-figure]{transition:none}}

/* Responsive */
@media (max-width:1079px){
[data-anchors]{grid-template-columns:repeat(2,minmax(0,1fr)) !important}
[data-anchors]>div{padding:44px 24px !important;border-left:1px solid #DCD7CE !important;border-top:1px solid #DCD7CE}
[data-anchors]>div:nth-child(odd){border-left:0 !important;padding-left:0 !important}
[data-anchors]>div:nth-child(even){padding-right:0 !important}
[data-anchors]>div:nth-child(1),[data-anchors]>div:nth-child(2){border-top:0}
[data-anchors]>div:nth-child(5){grid-column:1 / -1}
[data-anchors] [data-figure]{font-size:clamp(34px,5vw,52px) !important}
}
@media (max-width:659px){
[data-anchors]{grid-template-columns:minmax(0,1fr) !important}
[data-anchors]>div{border-left:0 !important;border-top:1px solid #DCD7CE !important;padding:36px 0 !important}
[data-anchors]>div:nth-child(1){border-top:0 !important}
[data-anchors] [data-figure]{font-size:44px !important}
}
@media (max-width:899px){
[data-top]{grid-template-columns:minmax(0,1fr) !important;gap:64px !important}
[data-portrait]{max-width:420px}
}
@media (max-width:759px){
[data-footer-grid]{grid-template-columns:minmax(0,1fr) !important;gap:48px !important}
}
@media (max-width:659px){
[data-partner]{grid-template-columns:minmax(0,1fr) !important;gap:32px !important}
}
html{-webkit-text-size-adjust:100%}
img,svg{max-width:100%}
@media (max-width:659px){
header>div{flex-direction:column !important;align-items:flex-start !important;gap:16px !important}
header nav{justify-content:flex-start !important;gap:4px 20px !important}
header nav a{min-height:44px;display:inline-flex;align-items:center}
footer nav a,footer address a{min-height:32px;display:inline-flex;align-items:center}
main>section:first-child,main>section:first-child>div{padding-top:96px !important}
}

/* Paper grain.
   One fixed, non-interactive overlay: fine achromatic noise from an inline
   feTurbulence, multiplied into the page so the warm ground reads as stock
   rather than as screen white. Multiply is deliberate. It preserves hue exactly
   on the light grounds, and it leaves the ink bands and the footer alone
   (near-black multiplied by noise is still near-black), so the grain never
   turns into video noise on the reversed sections.
   Measured on the 200px tile: per-pixel sd 1.6/255, mean darkening 2.3/255.
   Below the threshold where it reads as texture, which is the point. */
body::after{
content:"";
position:fixed;
inset:0;
z-index:9999;
pointer-events:none;
opacity:0.03;
mix-blend-mode:multiply;
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='paper-grain' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 0 1'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='3' intercept='-1'/%3E%3CfeFuncG type='linear' slope='3' intercept='-1'/%3E%3CfeFuncB type='linear' slope='3' intercept='-1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23paper-grain)'/%3E%3C/svg%3E");
background-size:200px 200px;
}
/* Printing, forced colours and a raised-contrast preference all want the flat ground. */
@media print,(prefers-contrast:more),(forced-colors:active){
body::after{display:none}
}

/* Section reveals.
   Everything lives inside no-preference, so a reduced-motion visitor gets no
   rule at all and the page is simply static. js/reveal.js only stamps
   [data-reveal] when it has already decided to animate, so the hidden state can
   never strand content: no script, no attribute, nothing hidden. If the OS
   setting is flipped mid-session the rules stop applying and any half-revealed
   element resolves to its normal state.
   Opacity and transform only. Nothing moves horizontally, nothing overshoots,
   and hover is untouched. */
@media (prefers-reduced-motion:no-preference){
[data-reveal]{opacity:0;transform:translateY(20px);transition:opacity 600ms cubic-bezier(0.22,0.61,0.36,1),transform 600ms cubic-bezier(0.22,0.61,0.36,1)}
[data-reveal="in"]{opacity:1;transform:translateY(0)}
}
