/* ==========================================================================
   Softbitrix — Reset, base typography, layout primitives, accessibility
   ========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* keeps in-page anchors clear of the sticky header */
  scroll-padding-top: calc(var(--sb-header-h) + var(--sb-space-6));
  /* guards against any single element forcing a sideways scrollbar */
  overflow-x: hidden;
}

body {
  font-family: var(--sb-font-body);
  font-size: var(--sb-text-base);
  font-weight: var(--sb-weight-normal);
  line-height: var(--sb-leading-relaxed);
  letter-spacing: var(--sb-tracking-normal);
  color: var(--sb-ink);
  background-color: var(--sb-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-synthesis-weight: none;
  overflow-x: hidden;
  min-height: 100vh;
}

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

img { height: auto; }

/* Icons are emitted without width/height attributes so they can be sized in
   CSS. This baseline keeps any icon that lacks a bespoke rule at text size
   rather than falling back to the 300x150 SVG replaced-element default, and
   gives it paint it can inherit. Brand marks are solid rather than stroked,
   and opt out via stroke="none". */
svg {
  width: 1em;
  height: 1em;
  flex: none;
}

svg:not([stroke="none"]) {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

svg[stroke="none"] { fill: currentColor; }

input,
button,
textarea,
select {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

button { background: none; border: 0; }

p,
li,
figcaption {
  overflow-wrap: break-word;
  text-wrap: pretty;
}

ul[class],
ol[class] {
  list-style: none;
  padding: 0;
}

/* --------------------------------------------------------------- headings */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--sb-font-display);
  font-weight: var(--sb-weight-bold);
  line-height: var(--sb-leading-snug);
  letter-spacing: var(--sb-tracking-tight);
  color: var(--sb-ink);
  text-wrap: balance;
}

h1 { font-size: var(--sb-text-h1); line-height: var(--sb-leading-tight); letter-spacing: var(--sb-tracking-display); }
h2 { font-size: var(--sb-text-h2); letter-spacing: var(--sb-tracking-display); }
h3 { font-size: var(--sb-text-h3); }
h4 { font-size: var(--sb-text-h4); font-weight: var(--sb-weight-semibold); }
h5 { font-size: var(--sb-text-lg); font-weight: var(--sb-weight-semibold); }
h6 { font-size: var(--sb-text-md); font-weight: var(--sb-weight-semibold); }

a {
  color: var(--sb-primary-ink);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color var(--sb-dur-fast) var(--sb-ease);
}
a:hover { color: var(--sb-primary); }

strong, b { font-weight: var(--sb-weight-semibold); }

code, kbd, samp, pre {
  font-family: var(--sb-font-mono);
  font-size: 0.92em;
}

hr {
  border: 0;
  border-top: 1px solid var(--sb-line);
}

::selection {
  background: var(--sb-violet-200);
  color: var(--sb-navy-900);
}

/* ---------------------------------------------------------------- focus */
:focus { outline: none; }

:focus-visible {
  outline: 2px solid var(--sb-focus);
  outline-offset: 3px;
  border-radius: var(--sb-radius-xs);
}

/* Violet only reaches 2.8:1 against the navy surfaces, so the ring turns
   white wherever the background is dark. */
.sb-section--deep :focus-visible,
.sb-cta__panel :focus-visible,
.sb-footer :focus-visible,
.sb-offices :focus-visible,
.sb-drawer :focus-visible {
  outline-color: #FFFFFF;
}

/* ------------------------------------------------------- layout primitives */
.sb-container {
  width: 100%;
  max-width: var(--sb-container);
  margin-inline: auto;
  padding-inline: var(--sb-gutter);
}

.sb-container--wide { max-width: var(--sb-container-wide); }

.sb-section { padding-block: var(--sb-section-y); }
.sb-section--sm { padding-block: var(--sb-section-y-sm); }

.sb-section--alt { background: var(--sb-bg-alt); }
.sb-section--deep {
  background: var(--sb-bg-deep);
  color: var(--sb-on-deep);
}
.sb-section--deep h2,
.sb-section--deep h3,
.sb-section--deep h4 { color: var(--sb-on-deep); }

/* ------------------------------------------------------- a11y utilities */
.sb-visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.sb-skip-link {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -120%);
  z-index: var(--sb-z-toast);
  padding: var(--sb-space-3) var(--sb-space-5);
  background: var(--sb-navy-900);
  color: #FFFFFF;
  font-family: var(--sb-font-display);
  font-size: var(--sb-text-sm);
  font-weight: var(--sb-weight-semibold);
  text-decoration: none;
  border-radius: 0 0 var(--sb-radius-sm) var(--sb-radius-sm);
  transition: transform var(--sb-dur) var(--sb-ease-out);
}
.sb-skip-link:focus-visible {
  transform: translate(-50%, 0);
  color: #FFFFFF;
  outline-offset: -4px;
}

/* stops the page jumping when the mobile drawer locks scrolling */
body.sb-scroll-locked {
  overflow: hidden;
  padding-right: var(--sb-scrollbar-w, 0px);
}

/* ------------------------------------------------- scroll reveal (opt-in) */
/* Elements start hidden only once JS confirms it can observe them, so the
   page remains fully readable if JavaScript never runs. */
[data-reveal] { --sb-reveal-shift: 18px; }

/* Uses the standalone `translate` property rather than `transform` so hover
   effects can still use `transform` without the two overwriting each other.
   Browsers without it simply fade the element in, which is a fine fallback. */
/* Opacity-only reveals — avoid translate shifts that can score as CLS. */
html.sb-js [data-reveal] {
  opacity: 0;
  transition: opacity var(--sb-dur-slow) var(--sb-ease-out);
  transition-delay: var(--sb-reveal-delay, 0ms);
}

html.sb-js [data-reveal].sb-revealed {
  opacity: 1;
}

/* Set by reveal.js when the animation is not worth attempting or did not
   land, so the end state is applied outright instead of being transitioned
   towards. Placed after the rules above so `transition: none` wins at equal
   specificity. */
html.sb-reveal-settled [data-reveal] {
  opacity: 1;
  transition: none;
}

/* ------------------------------------------------------- reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  html.sb-js [data-reveal] {
    opacity: 1;
  }
}

@media print {
  .sb-header, .sb-footer, .sb-skip-link { display: none; }
  body { background: #fff; color: #000; }
}
