/* ==========================================================================
   Bullshxrk.io — base stylesheet
   Design tokens, resets, shared chrome behaviour and responsive rules.
   Section-level layout stays inline in the markup so the built pages remain
   pixel-identical to the approved design.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Archivo, self-hosted
   One variable file covers every weight the design uses (300/400/500/600), so
   the site has no third-party font request and nothing to block first paint.
   The family is named "Archivo" so `font-family: Archivo` resolves to it.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/fonts/archivo-latin-wght-normal.woff2") format("woff2-variations");
  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;
}

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/assets/fonts/archivo-latin-ext-wght-normal.woff2") format("woff2-variations");
  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;
}

/* --------------------------------------------------------------------------
   1. Design tokens
   -------------------------------------------------------------------------- */
:root {
  --ink: #201e1d;
  --ink-82: rgba(32, 30, 29, 0.82);
  --ink-70: rgba(32, 30, 29, 0.7);
  --ink-66: rgba(32, 30, 29, 0.66);
  --ink-58: rgba(32, 30, 29, 0.58);
  --ink-50: rgba(32, 30, 29, 0.5);
  --ink-48: rgba(32, 30, 29, 0.48);
  --ink-40: rgba(32, 30, 29, 0.4);
  --ink-10: rgba(32, 30, 29, 0.1);

  --blue: #1434ff;
  --blue-hover: #1a3dff;
  --blue-active: #0f2ad6;

  --white: #ffffff;
  --bone: #f3f2f2;
  --bone-warm: #f6f5f4;

  --shadow-dark-btn: inset 0 1px 0 rgba(255, 255, 255, 0.14), inset 0 -1px 0 rgba(0, 0, 0, 0.3);
  --shadow-nav-pill: inset 0 1px 0 #ffffff, 0 8px 26px rgba(32, 30, 29, 0.1);

  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
}

/* --------------------------------------------------------------------------
   2. Resets and element defaults
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: auto;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--white);
  color: var(--ink);
  font-family: Archivo, "Helvetica Neue", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  color: var(--ink);
  text-decoration: none;
}

a:hover {
  color: var(--blue);
}

img {
  display: block;
  max-width: 100%;
}

p {
  text-wrap: pretty;
}

summary {
  list-style: none;
  cursor: pointer;
}

summary::-webkit-details-marker {
  display: none;
}

::selection {
  background: rgba(20, 52, 255, 0.16);
  color: var(--ink);
}

:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
}

/* The hero H1 is real text in the markup and is re-typed by script. Reserve
   its box up front so the intro cannot shift the page. */
[data-hero-h1] {
  min-height: 2.06em;
}

/* --------------------------------------------------------------------------
   3. Skip link
   -------------------------------------------------------------------------- */
.skip-link {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 200;
  display: inline-flex;
  align-items: center;
  height: 44px;
  padding: 0 20px;
  border-radius: 8px;
  background: var(--ink);
  color: var(--white);
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  transition: top 180ms ease;
}

.skip-link:focus {
  top: 16px;
  color: var(--white);
}

[data-main]:focus {
  outline: none;
}

/* --------------------------------------------------------------------------
   4. Hero intro guard
   A tiny inline script in <head> sets .bs-intro when the hero intro is going
   to run, so the elements it animates never flash at full opacity first.
   home.js clears the flag as it takes over, and the inline script clears it
   on a timeout if the script never boots — content can never stay hidden.
   -------------------------------------------------------------------------- */
.bs-intro [data-intro],
.bs-intro [data-intro-chrome],
.bs-intro [data-hero-art],
.bs-intro [data-hero-rule] {
  opacity: 0;
}

/* --------------------------------------------------------------------------
   4b. Keyframes
   -------------------------------------------------------------------------- */
@keyframes bsBlink {
  0%,
  48% {
    opacity: 1;
  }
  52%,
  100% {
    opacity: 0;
  }
}

/* --------------------------------------------------------------------------
   5. Hover and press states
   Generated from the design's style-hover / style-active attributes.
   Inline styles outrank classes, so these declarations need !important.
   -------------------------------------------------------------------------- */
.hv-blue:hover { color: #1434FF !important; }
.hv-blue-btn:hover { background: #1a3dff !important; box-shadow: inset 0 1px 0 rgba(255,255,255,0.3),inset 0 -1px 0 rgba(0,0,0,0.14) !important; }
.hv-chip:hover { background: #1434FF !important; box-shadow: inset 0 1px 0 rgba(255,255,255,0.24),inset 0 -1px 0 rgba(0,0,0,0.16) !important; }
.hv-ghost:hover { background: #f6f5f4 !important; border-color: rgba(32,30,29,0.34) !important; }
.hv-ink:hover { color: #201e1d !important; }
.hv-outline:hover { background: rgba(255,255,255,0.12) !important; box-shadow: inset 0 0 0 1px rgba(255,255,255,0.7) !important; }
.hv-rule:hover { color: #201e1d !important; border-bottom-color: #201e1d !important; }
.hv-sheet:hover { background: #f3f2f2 !important; color: #201e1d !important; }
.hv-white-text:hover { color: #ffffff !important; }

.ac-press:active { background: #0f2ad6 !important; box-shadow: inset 0 1px 3px rgba(0,0,0,0.3) !important; }
.ac-press-flat:active { background: #0f2ad6 !important; }
.ac-press-soft:active { background: #0f2ad6 !important; box-shadow: inset 0 1px 3px rgba(0,0,0,0.28) !important; }
.ac-white:active { background: rgba(255,255,255,0.2) !important; }

/* --------------------------------------------------------------------------
   6. Responsive — 880px and below
   The prototype is desktop-first with fluid clamp() type, so mobile is
   expressed as overrides. Inline styles win on specificity, hence !important.
   -------------------------------------------------------------------------- */
@media (max-width: 880px) {
  [data-nav-desktop] { display: none !important; }
  [data-nav-mobile] { display: flex !important; }
  [data-nav-sheet][open] [data-nav-caret] { transform: rotate(-135deg); }

  [data-wrap] { padding-left: 20px !important; padding-right: 20px !important; }
  [data-split] { grid-template-columns: minmax(0, 1fr) !important; gap: 20px !important; }
  [data-hide-m] { display: none !important; }

  [data-foot-grid] { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; gap: 32px 22px !important; }
  [data-foot-grid] > div:first-child { grid-column: 1 / -1 !important; }
  [data-foot-base] { margin-top: 44px !important; padding-bottom: 92px !important; }

  [data-stats4] { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
  [data-stats4] > div { padding: 22px 0 !important; border-right: 0 !important; }
  [data-stats4] > div:nth-child(odd) { padding-right: 16px !important; border-right: 1px solid rgba(32, 30, 29, 0.14) !important; }
  [data-stats4] > div:nth-child(even) { padding-left: 16px !important; }
  [data-stats4] > div:nth-child(n + 3) { border-top: 1px solid rgba(32, 30, 29, 0.14) !important; }

  /* The results strip stays centred in its columns on mobile too, so the
     padding has to stay symmetric rather than hugging one side. */
  [data-results-stats] > div:nth-child(odd),
  [data-results-stats] > div:nth-child(even) { padding-left: 16px !important; padding-right: 16px !important; }

  /* Home — hero */
  [data-hero-sec] { padding-top: 92px !important; padding-bottom: calc(min(38vh, 300px) + 28px) !important; }
  [data-hero-art] { left: -160% !important; right: -160% !important; height: min(62vh, 520px) !important; }
  [data-hero-art] img { bottom: -4% !important; }

  /* Home — clients strip */
  [data-clients] { gap: 16px 26px !important; }
  [data-clients-sec] { padding-top: 84px !important; padding-bottom: 88px !important; }

  /* Home — the pinned storyboard unpins and stacks vertically */
  [data-story] { height: auto !important; }
  [data-story-pin] { position: static !important; height: auto !important; display: block !important; }
  [data-story-head] { display: none !important; }
  [data-story-view] { display: block !important; overflow: visible !important; }
  [data-story-track] { flex-direction: column !important; transform: none !important; height: auto !important; width: 100% !important; }
  [data-story-track] > [data-pad] { display: none !important; }
  [data-stage] { width: 100% !important; opacity: 1 !important; padding: 30px 0 36px !important; }
  [data-stage] + [data-stage] { border-top: 1px solid rgba(255, 255, 255, 0.12); }
  [data-fig-box] { height: 168px !important; }
  [data-stage-body] { padding-left: 20px !important; padding-right: 20px !important; margin-top: 24px !important; }
  [data-detail] { opacity: 1 !important; transform: none !important; }

  /* Home — case study rows */
  [data-case-grid] { display: flex !important; flex-direction: column !important; gap: 24px !important; padding-top: 32px !important; padding-bottom: 36px !important; }
  [data-case-name] { order: 1; align-items: flex-start !important; gap: 12px !important; }
  [data-case-name] h3 { text-align: left !important; max-width: none !important; font-size: clamp(38px, 12vw, 60px) !important; }
  [data-case-logo] { order: 2; align-self: flex-start !important; justify-content: flex-start !important; }
  [data-case-logo] img { opacity: 1 !important; transform: none !important; max-width: 148px !important; max-height: 78px !important; }
  [data-case-lead] { order: 3; gap: 16px !important; }
  [data-case-stats] { order: 4; }

  /* Pricing */
  [data-plan] { padding: 26px 22px !important; }
  [data-cta-row] { grid-template-columns: minmax(0, 1fr) !important; gap: 26px !important; }
  [data-cta-row] > div:last-child { justify-content: flex-start !important; }
  [data-price-cta] { padding-top: 88px !important; padding-bottom: 92px !important; }
  [data-rope] { top: 380px !important; left: -150% !important; right: -150% !important; }
  [data-rope-veil] { background: radial-gradient(150% 26% at 50% 30%, rgba(255, 255, 255, 0.96) 0%, rgba(255, 255, 255, 0.8) 46%, rgba(255, 255, 255, 0) 78%) !important; }
}

@media (max-width: 520px) {
  [data-wrap] { padding-left: 16px !important; padding-right: 16px !important; }
}

/* --------------------------------------------------------------------------
   6b. Pricing plans
   Two plans, both full-width cards with a meta column beside the inclusions
   list. The columns unstack well before either side gets cramped.
   -------------------------------------------------------------------------- */
@media (max-width: 1100px) {
  [data-plan-grid] { grid-template-columns: minmax(0, 1fr) !important; gap: 34px !important; }
  /* Stacked, the header and body cells are already separated by the grid gap,
     and the empty alignment cell would only add a second one. */
  [data-plan-spacer] { display: none !important; }
  [data-plan-body] { margin-top: 0 !important; }
  [data-plan-statement] { justify-content: flex-start !important; }
}

@media (max-width: 620px) {
  [data-plan-list] { grid-template-columns: minmax(0, 1fr) !important; }
}

/* --------------------------------------------------------------------------
   6c. Team
   Four cards beside the section intro. The portraits come from four different
   sources — a mono photo, an office shot, an illustrated avatar, a landscape —
   so they are desaturated to read as one set, and return to colour on hover.
   Delete the filter declarations to ship them in full colour.
   Four across needs roughly 1280px; below that they go two up, then one.
   -------------------------------------------------------------------------- */
[data-team-photo] img {
  filter: grayscale(1) contrast(1.04);
  transition: filter 420ms ease, transform 700ms var(--ease-out-expo);
}

[data-team-card]:hover [data-team-photo] img,
[data-team-card]:focus-within [data-team-photo] img {
  filter: grayscale(0) contrast(1);
  transform: scale(1.03);
}

@media (max-width: 1280px) {
  [data-team-grid] { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}

@media (max-width: 420px) {
  [data-team-grid] { grid-template-columns: minmax(0, 1fr) !important; }
}

/* --------------------------------------------------------------------------
   6d. Closing CTA stack
   Each line is a small word beside a large one. On hover the large word
   underlines and the small one is nudged away from it, so the pair opens up
   instead of only changing colour. The underline is laid out permanently and
   revealed by colour, so nothing reflows. Which way the small word moves
   depends on which side of the big word it sits.
   -------------------------------------------------------------------------- */
[data-end-stack] a {
  text-decoration: none;
}

[data-cta-key] {
  display: inline-block;
  text-decoration-line: underline;
  text-decoration-color: transparent;
  text-decoration-thickness: 0.045em;
  text-underline-offset: 0.1em;
  transition: text-decoration-color 240ms ease;
}

[data-end-stack] a:hover [data-cta-key],
[data-end-stack] a:focus-visible [data-cta-key] {
  text-decoration-color: currentColor;
}

/* inline-block would trim the space this span carries, so keep it literal. */
[data-cta-sub] {
  display: inline-block;
  white-space: pre;
  transition: transform 340ms var(--ease-out-expo);
}

[data-end-stack] a:hover [data-cta-sub],
[data-end-stack] a:focus-visible [data-cta-sub] {
  transform: translateX(-0.42em);
}

[data-end-stack] a:hover [data-cta-sub][data-cta-after],
[data-end-stack] a:focus-visible [data-cta-sub][data-cta-after] {
  transform: translateX(0.42em);
}

/* --------------------------------------------------------------------------
   7. Reduced motion
   Scripted effects check prefers-reduced-motion themselves; this covers the
   declarative transitions and the caret blink.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  [data-caret] {
    display: none !important;
  }
}
