/* ---------------------------------------------------------------------------
   Theme tokens, taken from the Grovia template's own stylesheet so the palette,
   type scale, radii, shadows and easings match it value for value.

     backgrounds  #f4f2ee / #f0ece6 / #ede9e6   (warm bone)
     accent       #fef7af                        (pale butter yellow)
     ink          #000 / #212121 / #6d6d6d
     headings     Albert Sans 400, tight tracking
     body         Geist 400, -0.03em, 135% leading

   Swap values here and the whole site follows; nothing below hard-codes a
   colour.
   --------------------------------------------------------------------------- */

@import url('https://fonts.googleapis.com/css2?family=Albert+Sans:wght@300;400;500;600;700&family=Geist:wght@300;400;500;600;700&display=swap');

:root {
  /* --- palette --- */
  --bg-01: #f4f2ee;
  --bg-02: #f0ece6;
  --bg-03: #ede9e6;
  --accent: #fef7af;
  --accent-deep: #efdc87;
  /* Star gold. The butter accent is right for the big quote marks but washes
     out at star size against the cream background, so stars get their own. */
  --star: #e8a33d;

  --ink: #000;
  --ink-soft: #212121;
  --muted: #6d6d6d;

  /* The template's dark panel is an abstract photo under a 65% black scrim.
     Sampled off that section: cool slate overall, cooler at the corners and a
     touch warmer through the middle. */
  --panel: #414952;
  --panel-cool: #3a4450;
  --panel-warm: #4c4a51;
  --n-01: #fafafa;
  --n-02: #f4f4f4;
  --n-03: #eee;
  --n-04: #e6e6e6;
  --n-05: #dadada;
  --n-06: #ccc;
  --n-08: #aeaeae;
  --white: #fff;

  --white-10: #ffffff1a;
  --white-20: #fff3;
  --white-40: #fff6;
  --white-60: #fff9;
  --white-80: #fffc;

  --overlay-01: #00000026;
  --overlay-02: #0000004d;
  --overlay-03: #000000a6;

  /* on light surfaces */
  --fg: var(--ink);
  --fg-muted: var(--muted);

  /* service-card accents (section 3), pastel like the template's thumbnails */
  --a-clay: #e8bfa4;
  --a-sage: #c3d3bd;
  --a-butter: #fef7af;
  --a-stone: #d9d3c9;
  --a-sky: #bed4e6;
  --a-blush: #eec7cd;

  --ok: #3f7d4e;
  --ok-bright: #3ddc84;   /* the same green, for the dark chat header */
  --bad: #b3261e;

  /* --- sizes (the template's own scale) --- */
  --s-4xs: 0.25rem;
  --s-3xs: 0.5rem;
  --s-2xs: 0.75rem;
  --s-xs: 1rem;
  --s-s: 1.25rem;
  --s-m: 1.5rem;
  --s-l: 2rem;
  --s-xl: 2.5rem;
  --s-2xl: 3rem;
  --s-3xl: 4rem;
  --s-4xl: 5rem;
  --s-5xl: 6rem;

  --container: 1200px;
  --container-pad: 5rem;

  /* --- type --- */
  --font-heading: 'Albert Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-body: 'Geist', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;

  --h1: 3.5rem;
  --h2: 2.5rem;
  --h3: 2.25rem;
  --h4: 1.88rem;
  --h5: 1.63rem;
  --h6: 1.25rem;
  --body-l: 1.125rem;
  --body: 1rem;
  --body-s: 0.875rem;

  --lh-s: 110%;
  --lh-m: 125%;
  --lh-l: 135%;

  /* --- motion and depth --- */
  --t-fast: 0.2s ease;
  --t: 0.5s ease;
  --t-slow: 0.6s ease;
  --ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1);
  --reveal: 0.9s;

  --shadow-card: 5px 8px 15px #00000026;
  --shadow-card-soft: 5px 8px 15px #0000001a;
  --shadow-nav: 0 1px 20px #e0d7c680;
  --shadow-panel: 10px 18px 20px #0000001f;
  --shadow-tilt: 2px 8px 20px #0000001a;
}

@media (max-width: 991px) {
  :root {
    --container-pad: 4rem;
    --h1: 3.125rem;
    --h2: 2.25rem;
    --h3: 1.75rem;
    --h4: 1.63rem;
    --h5: 1.5rem;
    --h6: 1.25rem;
    --body-l: 1rem;
  }
}

@media (max-width: 767px) {
  :root {
    --container-pad: 1.5rem;
    --h1: 2rem;
    --h2: 1.88rem;
    --h3: 1.5rem;
    --h4: 1.38rem;
    --h5: 1.25rem;
    --h6: 1.125rem;
  }
}

/* --- base ------------------------------------------------------------------ */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 7rem;
}

body {
  margin: 0;
  background: var(--bg-01);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--body);
  line-height: var(--lh-l);
  letter-spacing: -0.03em;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 400;
  letter-spacing: -0.05em;
  line-height: var(--lh-s);
}

.display-h1 { font-size: var(--h1); }
.display-h2 { font-size: var(--h2); }
.display-h3 { font-size: var(--h3); letter-spacing: -0.045em; }
.display-h4 { font-size: var(--h4); letter-spacing: -0.04em; line-height: var(--lh-m); }
.display-h5 { font-size: var(--h5); letter-spacing: -0.04em; line-height: var(--lh-m); }
.display-h6 { font-size: var(--h6); letter-spacing: -0.035em; line-height: var(--lh-m); }

p { margin: 0; }

/* figure and blockquote carry a 40px UA margin that quietly shrinks every
   grid cell they sit in */
figure,
blockquote {
  margin: 0;
}

.paragraph { font-size: var(--body); line-height: var(--lh-l); }
.large-paragraph { font-size: var(--body-l); line-height: var(--lh-l); }
.small-paragraph { font-size: var(--body-s); line-height: var(--lh-l); }
.t-muted { color: var(--fg-muted); }

a {
  color: inherit;
  text-decoration: none;
}

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

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

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

/* --- layout ---------------------------------------------------------------- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--container-pad);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-xl);
}

.container.centered { align-items: center; }

.section {
  width: 100%;
  padding-block: var(--s-m);
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow: clip;
}

@media (max-width: 991px) {
  .section { padding-block: var(--s-s); }
}

/* a dark panel inset inside a thick bone-coloured frame, as the template does */
.section.inverse {
  background:
    radial-gradient(58% 72% at 60% 54%, color-mix(in srgb, var(--panel-warm) 42%, transparent) 0%, transparent 62%),
    radial-gradient(66% 84% at 4% 2%, color-mix(in srgb, var(--panel-cool) 78%, transparent) 0%, transparent 58%),
    var(--panel);
  border: 20px solid var(--bg-01);
  border-radius: var(--s-2xl);
  padding-block: var(--s-2xl);
  --fg: var(--white);
  --fg-muted: var(--white-80);
  color: var(--white);
}

@media (max-width: 991px) {
  .section.inverse {
    border-width: 8px;
    border-radius: var(--s-l);
    padding-block: var(--s-xl);
  }
}

.section-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-s);
  max-width: 600px;
  text-align: center;
}

/* Centred headers keep the 600px measure. A left-aligned one sits above a full
   width grid, so it runs the same width as the cards under it and ends on the
   same right edge rather than stopping short. */
.section-header.left {
  align-items: flex-start;
  width: 100%;
  max-width: 100%;
  text-align: left;
}

/* a tag pill hugs its text instead of stretching to the column */
.section-header .tag { align-self: center; }
.section-header.left .tag { align-self: flex-start; }

/* Any element that sets `display` in a class outranks the UA stylesheet's
   [hidden] rule, so hiding it via the attribute silently does nothing. */
[hidden] {
  display: none !important;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --- tags and buttons ------------------------------------------------------ */

.tag {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3xs);
  padding: var(--s-4xs) var(--s-2xs);
  border-radius: var(--s-xl);
  background: var(--accent);
  color: var(--ink);
  font-family: var(--font-heading);
  font-size: var(--body-s);
  line-height: var(--lh-m);
  letter-spacing: -0.02em;
}

.tag.number {
  background: var(--ink);
  color: var(--white);
  font-variant-numeric: tabular-nums;
}

.button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2xs);
  height: 44px;
  padding: var(--s-3xs) var(--s-3xs) var(--s-3xs) var(--s-s);
  border: 1px solid var(--ink);
  border-radius: var(--s-xl);
  background: var(--ink);
  color: var(--white);
  font-size: var(--body);
  font-weight: 500;
  line-height: var(--lh-m);
  cursor: pointer;
  transition: background-color var(--t), color var(--t), border-color var(--t), opacity var(--t);
}

.button:hover { opacity: 0.9; }

.button--accent {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--ink);
}

.button--outline {
  background: transparent;
  color: var(--fg);
  border-color: currentColor;
  padding-inline: var(--s-s);
}

.button--outline:hover {
  background: var(--overlay-01);
  opacity: 1;
}

.section.inverse .button--outline:hover { background: var(--white-10); }

.button__icon {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: var(--s-xl);
  background: var(--white);
  color: var(--ink);
  overflow: clip;
}

.button--accent .button__icon,
.button--outline .button__icon {
  background: var(--ink);
  color: var(--white);
}

.button__icon svg { transition: transform var(--t); }
.button:hover .button__icon svg { transform: translateX(2px); }

/* --- reveal-on-scroll ------------------------------------------------------ */
/* Sections arrive rather than just appear: travel, a touch of scale and a blur
   that resolves.
   This is an ANIMATION, not a transition, on purpose. A transition here is
   fragile: any element that declares its own `transition` for hover, as
   .case-study does for its shadow, replaces this one wholesale and the reveal
   silently stops working. An animation cannot be clobbered that way. */
@keyframes reveal-in {
  from {
    opacity: 0;
    transform: translateY(44px) scale(0.97);
    filter: blur(4px);
  }
  /* Clear the blur well before the move finishes. Each property interpolates
     independently, so the travel and fade carry on to 100% while the blur is
     already gone. Letting it run the full duration, which is what happened
     when this became an animation, leaves the page looking soft for too long,
     and it is worst on first paint above the fold. */
  40% {
    filter: blur(0);
  }
  to {
    opacity: 1;
    transform: none;
    filter: none;
  }
}

@keyframes reveal-in-plain {
  from { opacity: 0; transform: translateY(28px); }
  to { opacity: 1; transform: none; }
}

[data-reveal] { opacity: 0; }

[data-reveal].is-in {
  animation: reveal-in var(--reveal) var(--ease-out-quart) var(--reveal-delay, 0ms) both;
}

/* for the banner photo, where blurring a full width bitmap costs more than it adds */
[data-reveal-plain].is-in {
  animation-name: reveal-in-plain;
}

/* Only hint the compositor while an element is still waiting. Leaving
   will-change on fifty elements for the life of the page is how you get a
   sluggish scroll on a phone. */
[data-reveal]:not(.is-in) { will-change: opacity, transform, filter; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  /* the blur has to be cleared here too, or the page just stays fuzzy */
  [data-reveal] { opacity: 1; transform: none; filter: none; }
}
