/* Доповнення до дизайну (не з мокапу): skip-link, collapse-лого, a11y. */

html, body {
  max-width: 100%;
  overflow-x: hidden;
}

@supports (overflow-x: clip) {
  html, body { overflow-x: clip; }
}

.reveal.rl[data-revealed] {
  transform: none !important;
}

/* Case/service FAQ: довші відповіді не обрізати max-height:260–340px з site.css */
.gm-faq[data-faq-open] .gm-faq-a {
  max-height: 1200px;
}

/* Service SEO longform (markdown body) */
.gm-seo-longform h2 {
  font-family: "Outfit", sans-serif;
  font-weight: 700;
  font-size: 22px;
  color: #F5F5F5;
  margin: 36px 0 14px;
  line-height: 1.25;
}
.gm-seo-longform h3 {
  font-family: "Outfit", sans-serif;
  font-weight: 600;
  font-size: 17px;
  color: #F5F5F5;
  margin: 28px 0 10px;
  line-height: 1.3;
}
.gm-seo-longform p { margin: 0 0 14px; }
.gm-seo-longform ul,
.gm-seo-longform ol {
  margin: 0 0 16px;
  padding-left: 1.25em;
}
.gm-seo-longform li { margin: 0 0 8px; }
.gm-seo-longform a {
  color: #E91E96;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.gm-seo-longform a:hover { color: #FF4DE8; }
.gm-seo-longform strong { color: #F5F5F5; font-weight: 600; }

.gm-hero-h1 {
  max-width: 100%;
  overflow-wrap: anywhere;
}

/* Client proof moves as one calm editorial strip, not a dashboard grid. */
.gm-trusted-marquee {
  position: relative;
  overflow: hidden;
  border-top: 1px solid rgba(255,255,255,.14);
  border-bottom: 1px solid rgba(255,255,255,.14);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}

.gm-trusted-track {
  display: flex;
  width: max-content;
  animation: gm-trusted-loop 72s linear infinite;
  will-change: transform;
}

.gm-trusted-marquee:hover .gm-trusted-track,
.gm-trusted-marquee:focus-within .gm-trusted-track { animation-play-state: paused; }

.gm-trusted-brand {
  position: relative;
  flex: 0 0 clamp(178px, 16vw, 234px);
  min-height: 116px;
  padding: 18px 16px 17px;
  display: flex;
  flex-direction: column;
  color: #F5F5F5;
  border-right: 1px solid rgba(255,255,255,.09);
  opacity: 1;
  text-decoration: none;
  transform: none;
  filter: none;
  transition: background .22s ease, border-color .22s ease;
}

.gm-trusted-brand:hover {
  background: rgba(233,30,150,.08);
  border-color: rgba(233,30,150,.42);
  transform: none;
  filter: none;
}

.gm-trusted-name {
  font-family: 'Outfit', sans-serif;
  font-weight: 800;
  font-size: 20px;
  line-height: .95;
  letter-spacing: -.02em;
  overflow-wrap: anywhere;
}

.gm-trusted-tagline,
.gm-trusted-period {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 400;
  font-size: 8.5px;
  line-height: 1.35;
  letter-spacing: .13em;
  overflow-wrap: anywhere;
}

.gm-trusted-tagline { margin-top: 9px; color: #A8A8A8; }
.gm-trusted-period {
  margin-top: auto;
  padding-top: 11px;
  color: #E91E96;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: .08em;
}

@keyframes gm-trusted-loop { to { transform: translateX(-50%); } }

@media (prefers-reduced-motion: reduce) {
  .gm-trusted-marquee {
    overflow-x: auto;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  }
  .gm-trusted-track { animation: none; }
  .gm-trusted-copy { display: none !important; }
}

@media (max-width: 640px) {
  .gm-trusted-brand { flex-basis: 178px; min-height: 110px; padding: 16px 13px; }
  .gm-trusted-name { font-size: 18px; }
  .gm-trusted-period { font-size: 10px; }
}

/* Contact's concise two-part invitation needs room to read as two phrases on desktop. */
@media (min-width: 1025px) {
  [data-screen-label="Contact hero"] .gm-contact-hero-title {
    font-size: clamp(56px, 5.1vw, 80px) !important;
  }
}

@media (max-width: 720px) {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  body,
  main,
  section,
  footer {
    width: 100%;
    max-width: 100vw;
  }

  main {
    overflow-x: clip;
  }

  main section > div,
  footer > div,
  .gm-hero-grid,
  .gm-cta-grid {
    max-width: 100% !important;
  }

  .gm-hero-grid,
  .gm-cta-grid,
  .gm-filterbar-inner,
  section[data-screen-label="Hero"],
  section[data-screen-label="Trusted by brands"] > div,
  section[data-screen-label="What we do"] > div,
  section[data-screen-label="Featured cases"] > div,
  section[data-screen-label="About"] > div,
  section[data-screen-label="Process"] > div,
  section[data-screen-label="Testimonials"] > div,
  section[data-screen-label="Compare services"] > div,
  section[data-screen-label="Combinations"] > div,
  section[data-screen-label="Featured case"] > div,
  section[data-screen-label="FAQ"] > div,
  section[data-screen-label="Spotlight"] > div,
  section[data-screen-label="CTA"] > div,
  section[data-screen-label="Contact hero"] > div,
  section[data-screen-label="Contact form"] > div,
  section[data-screen-label="Channels"] > div,
  section[data-screen-label="Services hero"] > div,
  section[data-screen-label="Service hero"] > div,
  section[data-screen-label="Problem"] > div,
  section[data-screen-label="Why Grandma"] > div,
  section[data-screen-label="Process overview"] > div,
  section[data-screen-label="Case hero"] > div,
  section[data-screen-label="Case challenge"] > div,
  section[data-screen-label="Our solution"] > div,
  section[data-screen-label="Secondary proof"] > div,
  section[data-screen-label="Before vs after"] > div,
  section[data-screen-label="Client feedback"] > div {
    padding-left: 24px !important;
    padding-right: 24px !important;
  }

  section[data-screen-label="Hero"] {
    overflow: hidden;
  }

  section[data-screen-label="Hero"] > div:first-child,
  .gm-hero-art,
  .gm-case-hero-art,
  .gm-cta-art {
    max-width: 100% !important;
    overflow: hidden;
  }

  section[data-screen-label="Hero"] > div:first-child {
    height: min(92vw, 360px) !important;
  }

  section[data-screen-label="Hero"] > div:last-child {
    width: 100% !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
  }

  section[data-screen-label="Hero"] h1,
  section[data-screen-label="Hero"] .gm-hero-title {
    font-size: clamp(58px, 18vw, 76px) !important;
    overflow-wrap: anywhere;
  }

  section[data-screen-label="Hero"] [style*="margin-top:96px"] {
    margin-top: 42px !important;
  }

  section[data-screen-label="Trusted by brands"] > div {
    height: auto !important;
    min-height: 96px;
    flex-direction: column !important;
    align-items: flex-start !important;
    justify-content: center !important;
    gap: 18px !important;
    overflow: hidden;
  }

  section[data-screen-label="Trusted by brands"] > div > div:last-child {
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    gap: 28px !important;
    padding-bottom: 8px;
  }

  /* .gm-side-note ховається централізовано в @media (max-width: 1279px) — див.
     блок «Бічна рукописна нотатка» вище. Селектори по [style*="left:1378px"]
     прибрано: інлайнової координати більше немає. */

  .gm-srow {
    height: auto !important;
    min-height: 86px;
    align-items: flex-start !important;
    padding: 18px 0 !important;
    gap: 12px !important;
  }

  .gm-srow .gm-stitle {
    width: min(42vw, 160px) !important;
    font-size: 18px !important;
    line-height: 1.1 !important;
  }

  .gm-srow > span:last-child {
    max-width: none !important;
    min-width: 0;
  }

  .gm-pullquote {
    padding: 34px 26px !important;
  }

  .gm-cmp-scroll {
    width: 100%;
    max-width: calc(100vw - 48px);
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
    -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 calc(100% - 28px), transparent 100%);
    mask-image: linear-gradient(90deg, #000 0%, #000 calc(100% - 28px), transparent 100%);
  }

  .gm-cmp-scroll > div {
    min-width: 680px !important;
  }

  .gm-fpills,
  .gm-pills {
    width: 100%;
    max-width: 100%;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch;
  }

  .gm-selrow,
  .gm-sel,
  .gm-sel select {
    width: 100% !important;
    min-width: 0 !important;
  }

  .gm-case-meta {
    width: 100%;
  }

  .gm-case-meta > div {
    min-width: 0;
  }

  .gm-hero-art > div[aria-hidden="true"],
  .gm-case-hero-art > div[aria-hidden="true"],
  .gm-cta-art > div[aria-hidden="true"],
  .gm-cta-art > div:first-child {
    max-width: 100vw !important;
  }

  .gm-bw {
    max-width: 100% !important;
  }

  .gm-gallery {
    max-width: 100% !important;
  }

  .gm-gallery > * {
    min-width: 0;
  }

  .gm-figure,
  .gm-featcase,
  .gm-case-chart,
  .gm-case-result-chart {
    max-width: 100% !important;
    min-width: 0 !important;
  }

  .gm-featcase {
    padding: 28px 20px !important;
  }

  .gm-featcase > div {
    min-width: 0;
    border-left: 0 !important;
    padding-left: 0 !important;
  }

  svg {
    max-width: 100%;
  }

  .gm-spot-art {
    flex-direction: column !important;
  }

.gm-approval-stamp {
    width: 178px;
    height: 178px;
    transform: rotate(-7deg);
  }

}

/* CTA buttons: compact type and no decorative arrow suffixes. Functional
   carousel/pagination controls keep their arrows; marketing CTAs do not. */
.gm-primary,
.gm-secondary,
.gm-cta,
.gm-spot-btn,
.gm-404-cta-button,
.gm-outline-d,
.gm-check-cta {
  font-size: 13px !important;
}

.gm-chan-label { font-size: 14px !important; }
.gm-404-action-link { font-size: 13px !important; }

.gm-svc-ico {
  background: radial-gradient(circle at 50% 42%, rgba(255,255,255,.08), rgba(255,255,255,.02) 58%, transparent 72%);
  box-shadow: 0 0 24px rgba(255,255,255,.06), inset 0 0 18px rgba(255,255,255,.03);
}
.gm-svc-ico svg { filter: drop-shadow(0 0 5px rgba(255,255,255,.25)); }

@media (max-width: 720px) {
  .gm-msg-reasons { grid-template-columns: 1fr !important; }
}

@media (max-width: 720px) {
  section[data-screen-label="Case hero"] .gm-hero-grid,
  section[data-screen-label="Case challenge"] > div,
  section[data-screen-label="Our solution"] > div,
  section[data-screen-label="Secondary proof"] > div,
  section[data-screen-label="Before vs after"] > div,
  section[data-screen-label="Client feedback"] > div,
  .gm-case-cta-wrap {
    padding-left: 24px !important;
    padding-right: 24px !important;
  }

  .gm-case-meta {
    grid-template-columns: 1fr 1fr !important;
    gap: 18px 20px !important;
  }

  .gm-case-hero-art {
    min-height: 0 !important;
  }

  .gm-case-01,
  .gm-case-secondary-proof,
  .gm-case-result-chart,
  .gm-case-cta-grid {
    grid-template-columns: 1fr !important;
  }

  .gm-case-chart,
  .gm-case-result-chart,
  .gm-case-bars {
    padding: 22px 18px !important;
    min-width: 0 !important;
    overflow: hidden !important;
  }

  .gm-case-secondary-proof {
    gap: 48px !important;
  }

  .gm-case-proof-row {
    grid-template-columns: 1fr !important;
    gap: 10px !important;
    padding: 24px 0 !important;
  }

  .gm-case-chart svg,
  .gm-case-result-chart svg {
    max-width: 100% !important;
    height: auto !important;
  }

  .gm-case-steps-wrap {
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    overflow-x: auto !important;
    padding-bottom: 10px !important;
    -webkit-overflow-scrolling: touch;
  }

  /* Grid items otherwise inherit the 5-card track's min-content width (756px)
     and make the entire case section wider than the phone viewport. Keep the
     carousel inside its rail; only the rail may scroll horizontally. */
  section[data-screen-label="Our solution"] > div,
  section[data-screen-label="Secondary proof"] > div,
  section[data-screen-label="Before vs after"] > div,
  section[data-screen-label="Client feedback"] > div {
    width: 100% !important;
    min-width: 0 !important;
    grid-template-columns: minmax(0, 1fr) !important;
  }

  .gm-case-steps-wrap > div[aria-hidden="true"] {
    display: none !important;
  }

  /* Не форсити 5 колонок — кількість кроків різна; хвіст лінії = баг */
  .gm-case-steps {
    grid-template-columns: repeat(var(--gm-case-steps, 3), minmax(132px, 1fr)) !important;
    min-width: calc(var(--gm-case-steps, 3) * 148px) !important;
  }
  .gm-case-steps-wrap[data-steps="2"] { --gm-case-steps: 2; }
  .gm-case-steps-wrap[data-steps="3"] { --gm-case-steps: 3; }
  .gm-case-steps-wrap[data-steps="4"] { --gm-case-steps: 4; }
  .gm-case-steps-wrap[data-steps="5"] { --gm-case-steps: 5; }
  .gm-case-steps-wrap[data-steps="6"] { --gm-case-steps: 6; }

  .gm-case-cta-grid {
    padding: 36px 24px !important;
  }

  section[data-screen-label="Our solution"] h2,
  section[data-screen-label="Secondary proof"] h2,
  section[data-screen-label="Before vs after"] h2,
  .gm-case-cta-grid h2 {
    font-size: clamp(38px, 14vw, 56px) !important;
    overflow-wrap: anywhere;
  }

  section[data-screen-label="Our solution"] h2 span {
    display: block !important;
  }
}

/* skip-link (борг з аудиту — на кожній сторінці) */
.gm-skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: #E91E96; color: #060606; padding: 10px 18px;
  font-family: 'Outfit', sans-serif; font-weight: 600; font-size: 14px;
  text-decoration: none; border-radius: 0 0 6px 0;
}
.gm-skip-link:focus { left: 0; }

/* фокус-контур для клавіатури (a11y) */
a:focus-visible, button:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid #E91E96; outline-offset: 2px;
}

/* ---- Лого-collapse: .grandma → .g при скролі (build-spec 3.3) ----
 * Хвіст "randma" — inline-block span'и в overflow:hidden контейнері;
 * схлопування max-width:0 + opacity:0 зі стаггером 35ms справа наліво.
 * Ширину кожної літери JS пинить у --w (gm-behaviors initHeader). */
.gm-tail { display: inline-flex; overflow: hidden; vertical-align: baseline; }
.gm-tail > span {
  display: inline-block; max-width: var(--w, 1ch); opacity: 1;
  /* Зазор між ізольованими inline-block літерами задається запасом У САМІЙ
     --w (JS, gm-behaviors measureLockupWidths) — letter-spacing НЕ працює
     тут: браузер не додає trailing letter-spacing до intrinsic-ширини
     однолітерного inline-block боксу (перевірено емпірично). */
  transition: max-width .32s cubic-bezier(.2, .8, .2, 1), opacity .26s ease;
}
.gm-lockup.is-collapsed .gm-tail > span { max-width: 0 !important; opacity: 0; }
.gm-lockup.is-collapsed .gm-tail > span:nth-last-child(1) { transition-delay: 0ms; }
.gm-lockup.is-collapsed .gm-tail > span:nth-last-child(2) { transition-delay: 35ms; }
.gm-lockup.is-collapsed .gm-tail > span:nth-last-child(3) { transition-delay: 70ms; }
.gm-lockup.is-collapsed .gm-tail > span:nth-last-child(4) { transition-delay: 105ms; }
.gm-lockup.is-collapsed .gm-tail > span:nth-last-child(5) { transition-delay: 140ms; }
.gm-lockup.is-collapsed .gm-tail > span:nth-last-child(6) { transition-delay: 175ms; }
/* підпис "MARKETING AGENCY" стискається разом з хвостом */
.gm-lockup .gm-sub {
  max-width: 220px; opacity: 1; overflow: hidden; white-space: nowrap;
  transition: max-width .32s cubic-bezier(.2, .8, .2, 1), opacity .26s ease;
}
.gm-lockup.is-collapsed .gm-sub { max-width: 0; opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .gm-tail > span, .gm-lockup .gm-sub { transition: none; }
}

/* ---- Lang-switcher (статичний, замість shadow-DOM веб-компонента) ---- */
/* desktop: dropdown через <details> */
.gm-lang-dd { display: inline-block; position: relative; }
@media (max-width: 1024px) { .gm-lang-dd { display: none; } }
/* Compact outline control, a visual pair to the theme rocker: same height
   class, same restraint, an icon that animates on open. Three languages is
   why this stays a disclosure rather than a two-state toggle — cycling would
   make DE a two-click trip from EN. */
.gm-lang-dd > summary {
  list-style: none; display: inline-flex; align-items: center; gap: 7px;
  height: 34px; padding: 0 10px; cursor: pointer;
  color: var(--gm-lang-ink, #F5F5F5);
  border: 1px solid var(--gm-lang-line, rgba(245,245,245,.22)); border-radius: 8px;
  background: var(--gm-lang-bg, transparent);
  font-family: 'Outfit', sans-serif; font-weight: 600; font-size: 13px; letter-spacing: .06em;
  transition: border-color .22s ease, background .22s ease, color .22s ease;
}
.gm-lang-dd > summary:hover,
.gm-lang-dd[open] > summary { border-color: var(--gm-accent); color: var(--gm-accent); }
.gm-lang-dd > summary::-webkit-details-marker { display: none; }
.gm-lang-dd > summary:focus-visible { outline: 2px solid var(--gm-accent); outline-offset: 2px; }

/* "On air" indicator: a small filled dot with a soft halo, breathing slowly.
   Replaces an outlined globe, whose meridians only drew themselves on open —
   closed, it was a bare ring that read as an unfinished icon. Green is a
   status colour here, deliberately outside the brand palette: it means "this
   language is live", so it must not be confused with the magenta accent.
   The paper value is darker because the dark-theme green is too light to
   register on #F5F3EF. */
.gm-lang-live {
  --gm-live: #22C55E;
  width: 7px; height: 7px; flex: none; border-radius: 999px;
  background: var(--gm-live);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gm-live) 22%, transparent);
  animation: gm-live-pulse 2.6s ease-in-out infinite;
}
html[data-gm-theme="light"] .gm-lang-live { --gm-live: #15803D; }
@keyframes gm-live-pulse {
  0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--gm-live) 20%, transparent); }
  50%      { box-shadow: 0 0 0 5px color-mix(in srgb, var(--gm-live) 8%, transparent); }
}
.gm-lang-dd > summary .caret { font-size: 9px; opacity: .6; transition: transform .2s cubic-bezier(.2,.8,.2,1); }
.gm-lang-dd[open] > summary .caret { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
  .gm-lang-live { animation: none; }
  .gm-lang-dd > summary .caret { transition: none; }
}

/* theme switch + language sit as one group, so the header's space-between
   cannot fling them to opposite ends of the free space */
.gm-header-tools { display: inline-flex; align-items: center; gap: 10px; }
.gm-lang-panel {
  position: absolute; top: calc(100% + 6px); right: 0; min-width: 150px;
  background: #0E0E11; border: 1px solid rgba(255,255,255,.1); border-radius: 6px;
  box-shadow: 0 18px 44px rgba(0,0,0,.5); padding: 6px; z-index: 120;
}
.gm-lang-item {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 11px 12px;
  background: transparent; border: none; border-radius: 6px; color: #F5F5F5;
  font-family: 'Outfit', sans-serif; font-weight: 500; font-size: 14px; text-align: left;
  cursor: pointer; transition: background .18s, color .18s;
}
.gm-lang-item .code { font-weight: 600; letter-spacing: .06em; min-width: 26px; }
.gm-lang-item .name { font-size: 12.5px; color: rgba(245,245,245,.5); }
.gm-lang-item:hover { background: rgba(255,255,255,.05); color: #E91E96; }
.gm-lang-item[aria-current="true"] { color: #E91E96; }
.gm-lang-item[aria-current="true"] .name { color: rgba(233,30,150,.7); }
.gm-lang-item .check { margin-left: auto; color: #E91E96; opacity: 0; font-size: 13px; }
.gm-lang-item[aria-current="true"] .check { opacity: 1; }

/* mobile: segmented */
.gm-lang-seg { display: none; }
@media (max-width: 1024px) {
  .gm-lang-seg {
    display: flex; flex-direction: column; gap: 10px; padding: 2px 0 18px;
    border-bottom: 1px solid rgba(255,255,255,.08); margin-bottom: 18px; width: 100%;
  }
}
.gm-lang-seg .lbl { font-family: 'JetBrains Mono', monospace; font-size: 11px; letter-spacing: .2em; color: rgba(245,245,245,.4); }
.gm-lang-seg .row { display: flex; gap: 8px; }
.gm-lang-seg .seg {
  min-width: 56px; padding: 10px 16px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,.2); background: transparent; color: #F5F5F5;
  font-family: 'Outfit', sans-serif; font-weight: 600; font-size: 14px; letter-spacing: .06em;
  cursor: pointer; transition: border-color .2s, color .2s, background .2s;
}
.gm-lang-seg .seg:hover { border-color: #E91E96; color: #E91E96; }
.gm-lang-seg .seg[aria-current="true"] { border-color: #E91E96; color: #E91E96; background: rgba(233,30,150,.1); }

/* Мобільний фікс: гігантський футер-watermark "GRANDMA" на вузьких екранах
   налазив на соцхкнопки/колонки (декоративний aria-hidden) — ховаємо. */
@media (max-width: 900px) {
  .gm-footer-watermark {
    display: none !important;
    visibility: hidden !important;
    opacity: 0 !important;
    width: 0 !important;
    height: 0 !important;
    overflow: hidden !important;
  }

  footer .gm-social,
  footer .gm-social[aria-hidden="true"] {
    font-size: 11px !important;
    line-height: 1 !important;
    letter-spacing: 0.04em !important;
  }
}

/* ---- Why Us: responsive для нових сіток (6-крок процес, галузі, метрики) ---- */
.gm-spotlight-card {
  --gm-spot-x: 50%;
  --gm-spot-y: 50%;
  --gm-spot-rx: 0deg;
  --gm-spot-ry: 0deg;
  isolation: isolate;
  transform-style: preserve-3d;
  transition: transform .32s cubic-bezier(.2,.8,.2,1), border-color .28s ease, background .28s ease, opacity .28s ease;
}

.gm-spotlight-card::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(220px circle at var(--gm-spot-x) var(--gm-spot-y), rgba(233,30,150,.16), transparent 72%);
  transition: opacity .24s ease;
}

@media (hover: hover) and (pointer: fine) {
  .gm-spotlight-card[data-revealed].is-spotlight-hovered {
    z-index: 2;
    border-color: rgba(233,30,150,.62) !important;
    background-color: rgba(233,30,150,.08) !important;
    transform: perspective(900px) translateY(-5px) rotateX(var(--gm-spot-rx)) rotateY(var(--gm-spot-ry));
  }
  .gm-spotlight-card.is-spotlight-hovered::before { opacity: 1; }
  .gm-why-ind.is-spotlight-active .gm-spotlight-card:not(.is-spotlight-hovered) { opacity: .68; }
}

@media (prefers-reduced-motion: reduce) {
  .gm-spotlight-card, .gm-spotlight-card::before { transition: none !important; }
}

@media (max-width: 1080px) {
  .gm-why-steps { grid-template-columns: repeat(3, 1fr) !important; gap: 34px 22px !important; }
  .gm-why-steps-line { display: none !important; }
  .gm-why-ind { grid-template-columns: repeat(2, 1fr) !important; }
  .gm-why-metrics { grid-template-columns: repeat(2, 1fr) !important; gap: 30px 0 !important; }
}
@media (max-width: 900px) {
  .gm-why-hero { grid-template-columns: 1fr !important; }
  .gm-why-hero-art { order: -1; min-height: 420px !important; }
  .gm-why-ind-grid { grid-template-columns: 1fr !important; }
  .gm-talk-grid { grid-template-columns: 1fr !important; text-align: center; }
  .gm-talk-btns { flex-direction: column !important; align-items: stretch !important; }
  .gm-talk-btns a { justify-content: flex-start !important; }
}
@media (max-width: 640px) {
  .gm-why-points { grid-template-columns: 1fr !important; }
  .gm-why-steps { grid-template-columns: repeat(2, 1fr) !important; }
  .gm-why-ind { grid-template-columns: 1fr !important; }
  .gm-why-metric { padding: 0 16px !important; }
}

/* ---- Фінальний блок каналів (Telegram/WhatsApp/Email) — services + why-us ---- */
@media (min-width: 1025px) {
  .gm-talk-btns > a,
  .gm-cta-btns > a { min-width: 0; white-space: nowrap; }
}

/* ---- Service hero CTA: довгі локалізовані labels не мають ламатись на 2 рядки ---- */
.gm-hero-btns {
  flex-wrap: wrap;
}
.gm-hero-btns > a {
  justify-content: center;
  white-space: nowrap;
  text-align: center;
}
@media (min-width: 960px) {
  .gm-hero-btns > a {
    min-width: 192px;
  }
  .gm-hero-btns > a.gm-secondary {
    min-width: 322px;
  }
}
@media (max-width: 520px) {
  .gm-hero-btns {
    align-items: stretch !important;
  }
  .gm-hero-btns > a {
    width: 100%;
    min-width: 0;
    padding-left: 18px !important;
    padding-right: 18px !important;
    white-space: normal;
  }
}

/* ---- Services hero: дві колонки без окремого зображення ---- */
@media (max-width: 1024px) {
  [data-screen-label="Services hero"] .gm-hero-grid {
    grid-template-columns: 1fr !important;
  }
  .gm-hero-side {
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 22px !important;
  }
}
@media (max-width: 700px) {
  .gm-services-note {
    display: none;
  }
  .gm-hero-side {
    grid-template-columns: 1fr !important;
  }
}

/* ---- Cases hero: 4 стати завжди в один ряд на десктопі, 2×2 нижче 900px ---- */
.gm-cases-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; align-items: center; }
@media (max-width: 900px) {
  .gm-cases-stats { grid-template-columns: 1fr 1fr; gap: 26px 20px; }
}
@media (max-width: 460px) {
  .gm-cases-stats { grid-template-columns: 1fr; }
}

/* ============================================================================
   Кириличний fallback для дисплейних шрифтів (гібридна UA-локалізація).
   Bebas Neue та Outfit — латиниця-лише (див. fonts.css). Замість правок сотень
   inline `font-family` підставляємо кириличні гліфи ПІД ТИМ САМИМ імʼям родини,
   обмежені кириличним unicode-range — браузер сам обирає цю грань для кирилиці.
   Латиниця (EN/DE) далі рендериться Bebas/Outfit; кирилиця (UA) — з fallback.
     Bebas Neue (condensed display) → Oswald (condensed, має кирилицю)
     Outfit    (geometric label)    → Montserrat (geometric, кирилиця вже є)
   Німецькі спецсимволи (ä ö ü ß) — у latin-ext Bebas/Outfit, їх не чіпаємо.
   ========================================================================== */
@font-face {
  font-family: 'Bebas Neue';
  src: url('/static/fonts/oswald-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
  font-weight: 400;
  font-display: swap;
  /* Oswald має cap-height 162 проти 140 у Bebas при 200px (виміряно в Chromium
     через canvas actualBoundingBoxAscent). Без корекції кирилиця виглядає на
     ~16% більшою за латиницю, і в змішаних заголовках ("SEO ДЛЯ ПОСЛУГ",
     "AI З МЕЖАМИ") латинське слово здається меншим. 140/162 = 0.864. */
  size-adjust: 86.4%;
}
@font-face {
  font-family: 'Outfit';
  src: url('/static/fonts/montserrat-400-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Outfit';
  src: url('/static/fonts/montserrat-500-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
  font-weight: 500;
  font-display: swap;
}
@font-face {
  font-family: 'Outfit';
  src: url('/static/fonts/montserrat-600-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: 'Outfit';
  src: url('/static/fonts/montserrat-700-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: 'Outfit';
  src: url('/static/fonts/montserrat-800-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
  font-weight: 800;
  font-display: swap;
}
/* Contact: рукописний конектор нотатка→кнопка «Надіслати». На десктопі
   показуємо довгий конектор (тягнеться до кнопки), на вужчому екрані гріда
   стекається — там лишається мала стрілка біля нотатки. */
.gm-note-arrow-lg { display: none; }
@media (min-width: 1024px) {
  .gm-note-arrow-sm { display: none; }
  .gm-note-arrow-lg { display: block; }
}

/* Permanent Marker (рукописні нотатки) → Caveat: єдиний Google-хендрайт із
   кирилицею, близький за настроєм. Кирилична UA-нотатка більше не падає на
   системний serif. Латиниця (EN-нотатки на кшталт «Hold my coffee») — далі
   Permanent Marker. */
@font-face {
  font-family: 'Permanent Marker';
  src: url('/static/fonts/caveat-700-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
  font-weight: 400;
  font-display: swap;
}

/* Caveat (кирилична підміна Permanent Marker вище) метрично тонший і нижчий
   за той самий кегль — UA-написи читались як шепіт поряд з EN на маркері.
   html[lang="uk"] — єдина кирилична локаль сайту (de лишається на латиниці
   й справжньому Permanent Marker, її не займаємо). Один селектор по
   інлайновому font-family ловить усі написи одразу — без дублювання px у
   кожному шаблоні. zoom, не transform:scale: він не конфліктує з inline
   transform:rotate(...), який стоїть в кожного напису окремо (scale довелось
   би !important-ити разом із чужим rotate і губити нахил). Кегль піднято на
   18% — підібрано по скриншотах contact hero EN/UA (elshot.mjs, CI=1).
   zoom підтримують Chrome/Safari/Edge завжди, Firefox — з версії 126. */
html[lang="uk"] [style*="Permanent Marker"] {
  zoom: 1.18;
}

/* ---- Бічна рукописна нотатка секції «What we do» на головній ---- */

/* Горизонтальна позиція живе тут, а не в інлайні шаблону. Раніше стояв
   жорсткий left:1378px при контейнері 1320px — напис починався за 62px до
   правої межі viewport 1440, і жоден з трьох перекладів не вміщався
   (EN 203px, UA 211px, DE 255px — найдовший саме німецький, не український).
   Тепер прив'язка до ПРАВОЇ межі: відступ росте разом із гутером контейнера,
   тож на 1920 напис стоїть у полі праворуч від контенту, а на 1280–1440
   притискається до краю з гарантованим зазором 24px. Верхня межа 96px — щоб
   на дуже широких екранах він не відліпився від композиції.
   100%, а не 100vw: 100vw включає вертикальний скролбар і з'їдав би зазор.
   Не повертати фіксовані координати — на рукописному шарі це вже третій
   такий дефект (пор. прибраний «STRATEGY FIRST.», 08.08.2026). */
.gm-side-note {
  right: clamp(24px, calc((100% - 1320px) / 2 - 24px), 96px);
}

/* Нижче 1280px гутера вже нема: напис поїхав би на текст сервісних рядків
   (заміряно — на 1200px UA перекриває його на 44px, DE на 4px; на 1280px
   найтісніший зазор 36px у UA). Тому ховаємо — як і раніше, просто поріг
   тепер по реальній колізії, а не по 900px, за яким напис лишався в
   розмітці й просто висів за краєм екрана. */
@media (max-width: 1279px) {
  .gm-side-note {
    display: none !important;
  }
}

/* ВИНЯТОК: zoom масштабує не лише кегль, а ВСІ довжини всередині елемента —
   зокрема offset'и позиціонування. З попереднім left:1378px при zoom 1.18 він
   ставав 1626px, і напис виїжджав за viewport 1440, зникаючи для українських
   відвідувачів (scroll-reveal при цьому ніколи не спрацьовував, бо елемент
   поза екраном — лишався opacity:0). Виняток потрібен і після переїзду на
   right: clamp(...) — zoom так само спотворив би і відступ, і базу 1320px, з
   якої він рахується. Тому тут zoom скасовано, а кегль піднято напряму.
   Те саме правило треба застосувати до будь-якого рукописного напису,
   позиціонованого абсолютно. */
html[lang="uk"] .gm-side-note {
  zoom: 1;
  font-size: 22px !important;
}

/* На планшетній ширині About уже стає в одну колонку. Даємо нотатці
   окремий повітряний зазор після ілюстрації, щоб її нахил не торкався
   нижнього краю зображення навіть геометрично. */
@media (min-width: 721px) and (max-width: 1024px) {
  [data-screen-label="About"] .gm-about-note {
    margin-top: 24px !important;
  }
}

/* ---- Mobile QA hardening (real iPhone pass, 2026-07-09) ---- */
@media (max-width: 720px) {
  .gm-header {
    padding-left: 32px !important;
    padding-right: 32px !important;
  }

  .gm-burger-cb:checked ~ .gm-nav {
    top: 72px !important;
    bottom: 0 !important;
    height: calc(100dvh - 72px) !important;
    overflow-y: auto !important;
    overscroll-behavior: contain;
    background: #090909 !important;
    padding: 28px 32px max(40px, env(safe-area-inset-bottom)) !important;
    border-bottom: 0 !important;
  }

  .gm-burger-cb:checked ~ .gm-nav::after {
    content: none !important;
  }

  [data-screen-label="Hero"] .gm-hero-title,
  .gm-hero-h1,
  [data-screen-label$="hero"] h1,
  [data-screen-label="Services hero"] h1,
  [data-screen-label="Cases hero"] h1,
  [data-screen-label="Blog hero"] h1,
  [data-screen-label="Contact hero"] h1,
  [data-screen-label="About hero"] h1,
  [data-screen-label="Why us hero"] h1 {
    max-width: 100% !important;
    font-size: clamp(48px, 14.5vw, 64px) !important;
    line-height: .9 !important;
    overflow-wrap: anywhere;
    word-break: normal;
  }

  html[lang="uk"] [data-screen-label="Hero"] .gm-hero-title,
  html[lang="uk"] .gm-hero-h1,
  html[lang="uk"] [data-screen-label$="hero"] h1,
  html[lang="uk"] [data-screen-label="Services hero"] h1,
  html[lang="uk"] [data-screen-label="Contact hero"] h1,
  html[lang="uk"] [data-screen-label="About hero"] h1,
  html[lang="uk"] [data-screen-label="Why us hero"] h1 {
    font-size: clamp(44px, 12.8vw, 58px) !important;
    line-height: .94 !important;
  }

  .gm-hero-h1 span,
  [data-screen-label="Hero"] h1 span,
  [data-screen-label$="hero"] h1 span,
  [data-screen-label="Services hero"] h1 span,
  [data-screen-label="Contact hero"] h1 span,
  [data-screen-label="About hero"] h1 span,
  [data-screen-label="Why us hero"] h1 span,
  section h2 span {
    max-width: 100%;
    overflow-wrap: anywhere;
  }

  .reveal.rl {
    transform: translateY(22px) !important;
  }

  [data-screen-label="What we do"] {
    padding-top: 76px !important;
    padding-bottom: 76px !important;
  }

  [data-screen-label="About"] {
    padding-top: 78px !important;
    padding-bottom: 84px !important;
  }

  [data-screen-label="About"] > div {
    grid-template-columns: 1fr !important;
    gap: 30px !important;
    align-items: start !important;
  }

  [data-screen-label="About"] > div > div:first-child {
    order: 2;
    min-height: 0 !important;
    height: auto !important;
    overflow: hidden;
  }

  [data-screen-label="About"] > div > div:last-child {
    order: 1;
    min-width: 0;
  }

  [data-screen-label="About"] > div > div:first-child img {
    width: min(100%, 360px) !important;
    max-width: 100% !important;
    margin-top: 0 !important;
    margin-bottom: 0 !important;
  }

  [data-screen-label="About"] > div > div:first-child > div:first-child {
    width: min(118vw, 460px) !important;
    height: min(118vw, 460px) !important;
    left: 50% !important;
    top: 50% !important;
    transform: translate(-50%, -50%) !important;
  }

  [data-screen-label="About"] .gm-about-note {
    display: none !important;
  }

  [data-screen-label="About"] h2 {
    font-size: clamp(38px, 11.5vw, 50px) !important;
    line-height: .98 !important;
  }

  [data-screen-label="About"] p,
  [data-screen-label="About"] [style*="max-width:520px"] {
    max-width: 100% !important;
  }

  [data-screen-label="About"] [style*="grid-template-columns:1fr 1fr"] {
    grid-template-columns: 1fr !important;
    gap: 18px !important;
    margin-top: 32px !important;
  }

  [data-screen-label="About"] .gm-value {
    min-width: 0;
  }

  [data-screen-label="FAQ"] {
    padding-top: 78px !important;
    padding-bottom: 78px !important;
  }

  [data-screen-label="FAQ"] > div,
  [data-screen-label="FAQ"] .gm-faq-grid,
  [data-screen-label="FAQ"] .gm-why-ind-grid {
    display: grid !important;
    grid-template-columns: 1fr !important;
    gap: 26px !important;
    align-items: start !important;
  }

  [data-screen-label="FAQ"] h2 {
    font-size: clamp(38px, 11.5vw, 50px) !important;
    line-height: .98 !important;
    max-width: 100% !important;
  }

  [data-screen-label="FAQ"] h2 span {
    display: block !important;
    overflow-wrap: anywhere;
  }

  [data-screen-label="FAQ"] p {
    max-width: 100% !important;
  }

  [data-screen-label="What we do"] h2,
  [data-screen-label="Where to start"] h2,
  [data-screen-label="Problem"] h2,
  [data-screen-label="Case challenge"] h2,
  [data-screen-label="Our solution"] h2,
  [data-screen-label="Before vs after"] h2 {
    font-size: clamp(42px, 13.5vw, 58px) !important;
    line-height: .94 !important;
  }

  .gm-srow {
    display: grid !important;
    grid-template-columns: 34px minmax(0, 1fr) !important;
    align-items: start !important;
    gap: 10px 14px !important;
    padding: 20px 0 !important;
  }

  .gm-srow > span:first-child {
    width: auto !important;
  }

  .gm-srow .gm-stitle {
    width: auto !important;
    min-width: 0 !important;
  }

  .gm-srow > span:last-child {
    grid-column: 2 !important;
    width: 100% !important;
    max-width: 100% !important;
    font-size: 14px !important;
    line-height: 1.55 !important;
  }

  .gm-hero-grid,
  .gm-story-grid,
  .gm-team-grid,
  .gm-talk-grid,
  .gm-contact-grid,
  .gm-where-grid,
  .gm-cta-grid,
  [data-screen-label="Final CTA"] > div[style*="grid-template-columns"] {
    grid-template-columns: 1fr !important;
    gap: 36px !important;
  }

  [data-screen-label="Final CTA"] {
    padding: 80px 0 !important;
  }

  [data-screen-label="Final CTA"] > div[style*="grid-template-columns"] {
    align-items: start !important;
  }

  [data-screen-label="Final CTA"] > div[style*="grid-template-columns"] > div,
  [data-screen-label="CTA"] .gm-cta-grid > div,
  .gm-talk-grid > div,
  .gm-contact-grid > div {
    justify-self: stretch !important;
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    text-align: left !important;
  }

  [data-screen-label="Final CTA"] p,
  [data-screen-label="CTA"] p,
  [data-screen-label="Contact hero"] p,
  [data-screen-label="About hero"] p {
    max-width: 100% !important;
  }

  .gm-cta-btns,
  .gm-talk-btns {
    grid-template-columns: 1fr !important;
    width: 100% !important;
    max-width: 100% !important;
  }

  .gm-chan,
  .gm-msgcard,
  .gm-primary,
  .gm-outline {
    max-width: 100% !important;
    min-width: 0 !important;
  }

  .gm-chan span,
  .gm-msgcard span {
    min-width: 0 !important;
    overflow-wrap: anywhere;
  }

  .gm-hero-art,
  .gm-story-art,
  .gm-team-art {
    min-height: 0 !important;
    height: auto !important;
    max-width: 100% !important;
  }

  .gm-hero-art img {
    max-height: min(92vw, 430px);
    object-fit: contain !important;
  }

  [data-screen-label="About hero"] .gm-hero-art,
  [data-screen-label="Contact hero"] .gm-hero-art {
    order: 2 !important;
  }

  .gm-method {
    grid-template-columns: 1fr !important;
    gap: 28px !important;
  }

  .gm-method > div {
    border-left: 0 !important;
    padding-left: 0 !important;
  }

  .gm-gallery {
    max-width: 100% !important;
  }

  .gm-trust,
  .gm-hero-btns,
  [data-screen-label="Services hero"] [style*="margin-top:38px"] {
    flex-direction: column !important;
    align-items: stretch !important;
  }
}

@media (min-width: 721px) and (max-width: 900px) {
  /* .gm-side-note — див. централізоване правило @media (max-width: 1279px). */

  section[data-screen-label="Trusted by brands"] > div {
    height: auto !important;
    min-height: 104px;
    flex-direction: column !important;
    align-items: flex-start !important;
    justify-content: center !important;
    gap: 18px !important;
    overflow: hidden;
  }

  section[data-screen-label="Trusted by brands"] > div > div:last-child {
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    gap: 36px !important;
    padding-bottom: 8px;
  }
}

[data-gm-cookie-settings][hidden] {
  display: none !important;
}

/* Cookie-банер на вузьких екранах: три кнопки по minmax(140px) не влазять
   у 390px (3×140 + gaps = 440px), тому "ACCEPT ALL" зрізало правим краєм.
   Дві колонки + accept на всю ширину — головна дія лишається найпомітнішою. */
@media (max-width: 560px) {
  .gm-cookie-actions {
    grid-template-columns: 1fr 1fr !important;
    width: 100%;
  }
  .gm-cookie-actions [data-gm-cookie-action="accept"] {
    grid-column: 1 / -1;
  }
}

@media (max-width: 420px) {
  html[lang="uk"] [data-screen-label="Hero"] .gm-hero-title,
  html[lang="uk"] .gm-hero-h1,
  html[lang="uk"] [data-screen-label$="hero"] h1,
  html[lang="uk"] [data-screen-label="Services hero"] h1,
  html[lang="uk"] [data-screen-label="Contact hero"] h1,
  html[lang="uk"] [data-screen-label="About hero"] h1,
  html[lang="uk"] [data-screen-label="Why us hero"] h1 {
    font-size: clamp(40px, 11.8vw, 52px) !important;
  }

  [data-screen-label="Hero"] .gm-hero-title {
    font-size: clamp(54px, 16vw, 68px) !important;
  }
}

/* Case / services card metrics — never wrap "1 222" mid-number.
   F-02 fix (2026-08-08): each usage site now sizes its own column/font so a
   long value ("+373 %", "40,594") should always fit without hitting this
   limit. Kept only as a last-resort safety net — text-overflow:ellipsis
   (not the old `clip`) so if some future value still doesn't fit, it visibly
   truncates with "…" instead of silently losing a trailing digit or the "%"
   sign (which used to render "+373%" as the misleading "+3739"). */
.gm-metric-value {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---- Копіювання email (футер + email-картка /contact) + тост ---- */
.gm-email-copy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 6px;
  background: rgba(255,255,255,.06);
  color: rgba(245,245,245,.55);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background .18s ease, border-color .18s ease, color .18s ease, transform .1s ease;
}
.gm-email-copy svg { width: 15px; height: 15px; display: block; }
.gm-email-copy:hover { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.32); }
.gm-email-copy:active { transform: scale(0.92); }
.gm-email-copy:focus-visible { outline: 2px solid rgba(233,30,150, 0.8); outline-offset: 2px; }
.gm-email-copy.is-copied { color: #34D399; border-color: rgba(52, 211, 153, 0.55); background: rgba(52, 211, 153, 0.12); }

/* Світлий варіант — email-картка на світлому тлі /contact */
.gm-email-copy-light { border-color: rgba(180, 12, 134, 0.35); background: rgba(180, 12, 134, 0.07); color: #A8156A; }
.gm-email-copy-light:hover { background: rgba(180, 12, 134, 0.14); border-color: rgba(180, 12, 134, 0.6); }
.gm-email-copy-light.is-copied { color: #0F8A5F; border-color: rgba(15, 138, 95, 0.5); background: rgba(15, 138, 95, 0.1); }

.gm-toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%) translateY(12px);
  z-index: 9999;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 18px;
  background: #0a0207;
  border: 1px solid rgba(233,30,150, 0.5);
  border-radius: 6px;
  color: #F5F5F5;
  font-family: 'Outfit', sans-serif;
  font-weight: 600;
  font-size: 14px;
  line-height: 1;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s ease, transform .25s ease;
}
.gm-toast.is-visible { opacity: 1; transform: translateX(-50%) translateY(0); }
.gm-toast svg { flex: none; }
@media (prefers-reduced-motion: reduce) {
  .gm-toast { transition: opacity .12s ease; }
}

.gm-team-showcase {
  display: grid;
  grid-template-columns: minmax(360px, 1fr) minmax(250px, .72fr);
  gap: 34px;
  align-items: center;
  width: 100%;
}

.gm-team-photos {
  display: flex;
  gap: 10px;
  min-width: 0;
  overflow: visible;
}

.gm-team-photo-col {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.gm-team-photo-col-2 { padding-top: 58px; }
.gm-team-photo-col-3 { padding-top: 26px; }

.gm-team-photo,
.gm-team-row {
  -webkit-appearance: none;
  appearance: none;
  border: 0;
  padding: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.gm-team-photo {
  position: relative;
  display: block;
  flex: none;
  width: 132px;
  height: 150px;
  overflow: hidden;
  border-radius: 6px;
  background: #111;
  box-shadow: 0 0 0 1px rgba(255,255,255,.08);
  transition: opacity .25s ease, box-shadow .25s ease, transform .25s ease;
}

.gm-team-photo-col-2 .gm-team-photo {
  width: 150px;
  height: 170px;
}

.gm-team-photo-col-3 .gm-team-photo {
  width: 140px;
  height: 160px;
}

.gm-team-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) brightness(.72) contrast(1.04);
  transition: filter .3s ease, transform .35s ease;
}

.gm-team-list {
  display: flex;
  flex-direction: column;
  gap: 18px;
  min-width: 0;
}

.gm-team-row {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  gap: 11px;
  align-items: start;
  width: 100%;
  color: #F5F5F5;
  background: transparent;
  transition: opacity .22s ease, transform .22s ease;
}

.gm-team-mark {
  display: block;
  width: 16px;
  height: 11px;
  margin-top: 4px;
  border-radius: 5px;
  background: rgba(245,245,245,.22);
  transition: width .25s ease, background .25s ease;
}

.gm-team-copy {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.gm-team-name {
  font-family: 'Outfit', sans-serif;
  font-weight: 700;
  font-size: 18px;
  line-height: 1.05;
  letter-spacing: 0;
  color: rgba(245,245,245,.86);
  transition: color .22s ease;
}

.gm-team-role {
  margin-top: 7px;
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  line-height: 1.45;
  letter-spacing: 0;
  color: rgba(245,245,245,.42);
}

.gm-team-person:focus-visible {
  outline: 2px solid rgba(233,30,150,.85);
  outline-offset: 4px;
}

.gm-team-showcase[data-active-member] .gm-team-person { opacity: .42; }
.gm-team-showcase[data-active-member="strategy"] [data-gm-team-member="strategy"],
.gm-team-showcase[data-active-member="paid-media"] [data-gm-team-member="paid-media"],
.gm-team-showcase[data-active-member="seo-content"] [data-gm-team-member="seo-content"],
.gm-team-showcase[data-active-member="analytics"] [data-gm-team-member="analytics"],
.gm-team-showcase[data-active-member="creative"] [data-gm-team-member="creative"],
.gm-team-showcase[data-active-member="dev-automation"] [data-gm-team-member="dev-automation"] {
  opacity: 1;
}

.gm-team-showcase[data-active-member="strategy"] [data-gm-team-member="strategy"].gm-team-photo,
.gm-team-showcase[data-active-member="paid-media"] [data-gm-team-member="paid-media"].gm-team-photo,
.gm-team-showcase[data-active-member="seo-content"] [data-gm-team-member="seo-content"].gm-team-photo,
.gm-team-showcase[data-active-member="analytics"] [data-gm-team-member="analytics"].gm-team-photo,
.gm-team-showcase[data-active-member="creative"] [data-gm-team-member="creative"].gm-team-photo,
.gm-team-showcase[data-active-member="dev-automation"] [data-gm-team-member="dev-automation"].gm-team-photo {
  transform: translateY(-2px);
  box-shadow: 0 0 0 1px rgba(233,30,150,.5), 0 18px 34px rgba(0,0,0,.32);
}

.gm-team-showcase[data-active-member="strategy"] [data-gm-team-member="strategy"] img,
.gm-team-showcase[data-active-member="paid-media"] [data-gm-team-member="paid-media"] img,
.gm-team-showcase[data-active-member="seo-content"] [data-gm-team-member="seo-content"] img,
.gm-team-showcase[data-active-member="analytics"] [data-gm-team-member="analytics"] img,
.gm-team-showcase[data-active-member="creative"] [data-gm-team-member="creative"] img,
.gm-team-showcase[data-active-member="dev-automation"] [data-gm-team-member="dev-automation"] img,
.gm-team-photo:hover img,
.gm-team-photo:focus-visible img {
  filter: grayscale(.12) brightness(.98) contrast(1.02);
  transform: scale(1.035);
}

.gm-team-showcase[data-active-member="strategy"] [data-gm-team-member="strategy"] .gm-team-mark,
.gm-team-showcase[data-active-member="paid-media"] [data-gm-team-member="paid-media"] .gm-team-mark,
.gm-team-showcase[data-active-member="seo-content"] [data-gm-team-member="seo-content"] .gm-team-mark,
.gm-team-showcase[data-active-member="analytics"] [data-gm-team-member="analytics"] .gm-team-mark,
.gm-team-showcase[data-active-member="creative"] [data-gm-team-member="creative"] .gm-team-mark,
.gm-team-showcase[data-active-member="dev-automation"] [data-gm-team-member="dev-automation"] .gm-team-mark,
.gm-team-row:hover .gm-team-mark,
.gm-team-row:focus-visible .gm-team-mark {
  width: 22px;
  background: #E91E96;
}

.gm-team-showcase[data-active-member="strategy"] [data-gm-team-member="strategy"] .gm-team-name,
.gm-team-showcase[data-active-member="paid-media"] [data-gm-team-member="paid-media"] .gm-team-name,
.gm-team-showcase[data-active-member="seo-content"] [data-gm-team-member="seo-content"] .gm-team-name,
.gm-team-showcase[data-active-member="analytics"] [data-gm-team-member="analytics"] .gm-team-name,
.gm-team-showcase[data-active-member="creative"] [data-gm-team-member="creative"] .gm-team-name,
.gm-team-showcase[data-active-member="dev-automation"] [data-gm-team-member="dev-automation"] .gm-team-name,
.gm-team-row:hover .gm-team-name,
.gm-team-row:focus-visible .gm-team-name {
  color: #F5F5F5;
}

@media (max-width: 1180px) {
  .gm-team-showcase {
    grid-template-columns: 1fr;
    gap: 28px;
  }

  .gm-team-photos {
    justify-content: flex-start;
    overflow-x: auto;
    padding: 2px 2px 8px;
    scrollbar-width: thin;
  }
}

@media (max-width: 720px) {
  .gm-team-showcase {
    gap: 24px;
  }

  .gm-team-photos {
    gap: 8px;
    margin-right: -48px;
    padding-right: 48px;
  }

  .gm-team-photo-col {
    gap: 8px;
  }

  .gm-team-photo-col-2 { padding-top: 46px; }
  .gm-team-photo-col-3 { padding-top: 21px; }

  .gm-team-photo,
  .gm-team-photo-col-2 .gm-team-photo,
  .gm-team-photo-col-3 .gm-team-photo {
    width: 112px;
    height: 130px;
  }

  .gm-team-list {
    display: grid;
    grid-template-columns: 1fr;
    gap: 15px;
  }

  .gm-team-name {
    font-size: 17px;
  }

  .gm-team-role {
    font-size: 12px;
  }
}

/* Blog and case cards enter once, then hand transform control back to :hover.
   `both` kept the animation's final transform above the interaction state. */
.gm-card,
.gm-case {
  animation-fill-mode: backwards;
}

/* ============================================================
   Homepage light-theme pilot — header + bg drops + hero only
   ============================================================
   2026-08-21. `html[data-gm-theme="light"]` is set ONLY by the toggle script
   in templates/pages/home.html.j2 — no other template reads or writes it, so
   every rule below is inert on every page except the homepage. Everything
   here is an ADDITIVE override (!important against existing inline hex), not
   a rewrite: base.html.j2, header.html.j2 and macros.html.j2 are untouched,
   so this pilot carries zero risk to any other route.
   Paper values match the canon already live on contact/thank-you/blog
   (#F5F3EF / #14110E) and the paper-violet documented in
   docs/design/DS-SPLATTER-SPEC.md (#7B1FD1). Light splatter assets are a new
   "ink-blot" shape family (static/icons/blots-a.svg / blots-b.svg) — a
   rounded stain instead of the drip-with-bead anatomy, on purpose: the drip's
   trailing bead reads as a drop of blood, which is wrong on paper. */
:root {
  --gm-fg-rgb: 245 245 245;
  --gm-bg: #090909;
  --gm-accent: #E91E96;
  --gm-violet: #A736FF;
  --gm-note-shadow: 0 2px 10px rgba(0,0,0,.7);
  /* alpha for de-emphasised text. .58 measured 4.45:1 on paper — just under
     the 4.5 floor — so muted copy is one token, not a per-rule guess. */
  --gm-muted-a: .62;
}
html[data-gm-theme="light"] {
  --gm-fg-rgb: 20 17 14;
  --gm-bg: #F5F3EF;
  --gm-accent: #A8156A;
  --gm-violet: #7B1FD1;
  --gm-note-shadow: 0 2px 14px rgba(255,255,255,.6);
}

/* Almost everything on this site is inline-styled (style="color:#F5F5F5"),
   which always outranks an external stylesheet rule regardless of selector
   specificity. Every property below competes with an inline value, so
   !important is load-bearing here, not decorative — without it this whole
   block is a silent no-op. */
/* PAGE STRUCTURE IN LIGHT MODE — paper ground, dark islands
   ==========================================================
   The ground goes on `body`. An earlier revision painted it per-section with
   a full-bleed ::before, because at that point only the hero was themed and a
   body-wide colour leaked under unthemed sections. Now that the theme covers
   whole pages, body is the right place: it needs no per-section registry, it
   cannot leave dark bars on wide monitors, and it removes a pseudo-element
   whose z-index had to be negative to avoid covering in-flow content.

   What stays dark is then explicit rather than accidental: anything marked
   `.gm-dark` is an island that keeps the dark design inside it — the closing
   CTA slab, the footer, the cookie banner, and media cards that carry their
   own scrim (case posters, process comics). Two things matter for an island:
   it must set an OPAQUE background of its own, and the gm-t-* text classes
   inside it flip back to the dark palette (see the revert block below).
   Opacity matters because several islands paint a semi-transparent gradient
   and let the page show through — tuned for a dark body, that reads as depth;
   over paper it turns into washed mauve. */
html[data-gm-theme="light"] body { background: var(--gm-bg) !important; color: rgb(var(--gm-fg-rgb)) !important; }

/* Islands that must keep the dark design. Most already paint an opaque
   surface of their own (.gm-poster #0D0D0D, .gm-comic #0A0A0A, the cookie
   banner #0C0C0E, the newsletter card #14110E) and need nothing added. Two
   do not: the closing CTA paints a radial whose inner stops are translucent,
   and the footer paints a gradient that fades to transparent at both edges.
   Both were tuned to sit on a dark body; over paper they turn washed mauve,
   so they get an explicit opaque backing. */
html[data-gm-theme="light"] .gm-dark { background-color: #0A0A0C; }
html[data-gm-theme="light"] [data-screen-label="Final CTA"] { background-color: #0a0207 !important; }
html[data-gm-theme="light"] [data-screen-label="Footer"] { background-color: #070707 !important; }

/* Inside a dark island the semantic text classes mean the opposite, so they
   revert to the dark-design palette. This is what lets the annotation pass be
   blanket: mark the text once, and its location decides how it resolves.
   Nothing needs re-declaring per class: every gm-t-* rule below is written in
   terms of --gm-fg-rgb / --gm-accent, so redefining those two custom
   properties on the island makes each descendant resolve to the dark palette
   by inheritance. */
html[data-gm-theme="light"] :is(.gm-dark, .gm-poster, .gm-comic, .gm-tst-stage, .gm-nl-card, [data-gm-cookie], [data-screen-label="Final CTA"], [data-screen-label="Footer"]) {
  --gm-fg-rgb: 245 245 245;
  --gm-accent: #E91E96;
  --gm-violet: #A736FF;
}

/* ---- themed middle sections ----
   Driven by four semantic classes added to home.html.j2 (gm-t-ink /
   gm-t-body / gm-t-muted / gm-t-accent / gm-t-line) rather than by matching
   the inline style strings. Attribute matching looked tempting on a codebase
   that is 100% inline-styled, but gm-behaviors.js writes to element.style on
   every [data-reveal] node (the stagger sets transition-delay), and any
   CSSOM write makes the browser re-serialise the whole attribute in
   normalised form — "rgba(245,245,245,.5)" becomes "rgba(245, 245, 245,
   0.5)". Half the selectors silently stopped matching, which is exactly the
   class of bug that shipped white-on-white to production.
   The classes are applied only in the sections that go light; the Final CTA
   (white text on magenta) and the case/process cards (light text on their
   own dark surfaces) deliberately keep their dark-design colours. */
html[data-gm-theme="light"] .gm-t-ink,
html[data-gm-theme="light"] .gm-stitle,
html[data-gm-theme="light"] .gm-trusted-name { color: rgb(var(--gm-fg-rgb)) !important; }
html[data-gm-theme="light"] .gm-t-body { color: rgb(var(--gm-fg-rgb) / .74) !important; }
html[data-gm-theme="light"] .gm-t-muted { color: rgb(var(--gm-fg-rgb) / var(--gm-muted-a)) !important; }
html[data-gm-theme="light"] .gm-t-accent { color: var(--gm-accent) !important; }
html[data-gm-theme="light"] .gm-trusted-tagline,
html[data-gm-theme="light"] .gm-trusted-period { color: rgb(var(--gm-fg-rgb) / var(--gm-muted-a)) !important; }

/* keylines: the dark design draws them in white alpha, invisible on paper */
html[data-gm-theme="light"] .gm-t-line,
html[data-gm-theme="light"] [data-screen-label="Featured cases"] { border-color: rgb(var(--gm-fg-rgb) / .12) !important; }
html[data-gm-theme="light"] .gm-srow:hover { background: rgb(var(--gm-fg-rgb) / .04) !important; }
html[data-gm-theme="light"] .gm-srow:hover .gm-stitle { color: var(--gm-accent) !important; }

/* outline CTAs (What we do / Cases / About) */
html[data-gm-theme="light"] main .gm-cta { color: rgb(var(--gm-fg-rgb)) !important; border-color: var(--gm-accent) !important; }
html[data-gm-theme="light"] main .gm-cta:hover { background: var(--gm-accent) !important; color: #FFF !important; }
html[data-gm-theme="light"] .gm-carousel-btn { border-color: rgb(var(--gm-fg-rgb) / .22) !important; color: rgb(var(--gm-fg-rgb)) !important; }

/* About: handwritten note, value rings and their icons */
html[data-gm-theme="light"] .gm-about-note { color: rgb(var(--gm-fg-rgb) / .78) !important; }
html[data-gm-theme="light"] .gm-about-note span { color: var(--gm-accent) !important; }
html[data-gm-theme="light"] .gm-vring { border-color: rgb(var(--gm-fg-rgb) / .22) !important; }
html[data-gm-theme="light"] .gm-vring svg { stroke: rgb(var(--gm-fg-rgb) / .6); }
html[data-gm-theme="light"] .gm-value:hover .gm-vring { border-color: var(--gm-accent) !important; }
html[data-gm-theme="light"] .gm-side-note { color: rgb(var(--gm-fg-rgb) / .28) !important; }

/* Flow diagram: підписи каналів стоять на папері, а не на чорному диску —
   у dark-палітрі вони світлі й на світлому тлі зникали. Іконки всередині
   дисків лишаються світлими (див. .gm-flow-ico), диски навмисно чорні. */
html[data-gm-theme="light"] .gm-flow-label { fill: rgb(var(--gm-fg-rgb) / .7); }

/* violet decor deepens on paper (canon: DS-SPLATTER-SPEC.md §palette) */
html[data-gm-theme="light"] [data-screen-label="Process"] path[stroke="#A736FF"] { stroke: var(--gm-violet); }

/* ---- alpha that only works over a dark ground ----
   Two places de-emphasise or soften an element with partial opacity. Over
   #090909 the ground bleeding through is black, so it reads as "dimmed".
   Over paper the same alpha bleeds white through the element and reads as a
   milky haze — visible on the hero artwork and on the two non-active case
   cards (measured: the side cards jumped +25 and +94 mean brightness against
   +2 for the active one). Light mode keeps the intent but expresses it by
   darkening instead of by letting the background through. */
html[data-gm-theme="light"] [data-screen-label="Hero"] [data-gm-art] img { opacity: 1 !important; }
html[data-gm-theme="light"] .gm-case-slide:not(.is-active) { opacity: 1; filter: brightness(.93) saturate(.92); }

/* ============================================================
   Theme rocker — the CSS "rocker switch" pattern
   ============================================================
   Ported from the reference Max supplied (a React/Tailwind snippet wrapping
   the well-known `.rocker` / `.switch-left` / `.switch-right` CSS switch).
   This site is Jinja + plain CSS with no React, so the component is rebuilt
   in our stack: the markup keeps the reference's shape — a real
   `<input type="checkbox">` inside a `<label class="rocker rocker-small">`
   with two spans — and the geometry is the reference's, unchanged in kind:
   the idle half is lifted and tilted with rotate+skewX, the selected half
   sits flat and full-size, and each half's `::before` is the skewed side
   face that gives the switch its thickness. Yes/No become moon/sun.

   Sizing is driven entirely by the element's own font-size (everything below
   is in `em`), so `.rocker-small` is the only knob for fitting the header. */
.rocker {
  display: inline-block; position: relative; vertical-align: middle;
  font-size: 2em; text-align: center; text-transform: uppercase;
  width: 7em; height: 4em; overflow: hidden;
  border-bottom: 0.5em solid var(--gm-rk-frame);
  cursor: pointer;
  --gm-rk-frame: #2b2b31;   /* housing */
  --gm-rk-well: #17171a;    /* recess behind the halves */
  --gm-rk-idle: #33333b;    /* raised, unselected half */
  --gm-rk-edge: #23232a;    /* its side face */
  --gm-rk-idle-ink: rgba(245,245,245,.42);
}
html[data-gm-theme="light"] .rocker {
  --gm-rk-frame: #e2ddd3;
  --gm-rk-well: #cfc9be;
  --gm-rk-idle: #f4f1ea;
  --gm-rk-edge: #ddd7cb;
  --gm-rk-idle-ink: rgba(20,17,14,.45);
}
/* header fit: 11px base => 77 x 44px */
.rocker-small { font-size: 11px; margin: 0 2px 0 0; }

.rocker::before {
  content: ""; position: absolute; top: 0.5em; left: 0; right: 0; bottom: 0;
  background-color: var(--gm-rk-well);
  border: 0.5em solid var(--gm-rk-frame); border-bottom: 0;
}
.rocker input { opacity: 0; width: 0; height: 0; position: absolute; }

.switch-left,
.switch-right {
  cursor: pointer; position: absolute; display: flex;
  align-items: center; justify-content: center;
  height: 2.5em; width: 3em; transition: 0.2s; user-select: none;
}
.switch-left svg, .switch-right svg { width: 1.5em; height: 1.5em; display: block; }

/* default (unchecked) = dark theme: the moon is the pressed side */
.switch-left {
  left: 0.5em; bottom: 0; height: 2.5em; width: 3em;
  background-color: var(--gm-accent); color: #fff;
  transform: rotate(0deg) skewX(0deg);
}
.switch-right {
  right: 0.5em; bottom: 0.4em; height: 2.4em; width: 2.75em;
  background-color: var(--gm-rk-idle); color: var(--gm-rk-idle-ink);
  transform: rotate(-15deg) skewX(-15deg);
}
.switch-left::before,
.switch-right::before {
  content: ""; position: absolute; width: 0.4em; height: 2.45em; bottom: -0.45em;
  background-color: var(--gm-rk-edge);
}
.switch-left::before { left: -0.4em; background-color: transparent; transform: skewY(-65deg); }
.switch-right::before { right: -0.375em; transform: skewY(65deg); }

/* checked = light theme: the sun takes the pressed position, moon lifts */
.rocker input:checked + .switch-left {
  background-color: var(--gm-rk-idle); color: var(--gm-rk-idle-ink);
  bottom: 0.4em; left: 0.85em; height: 2.4em; width: 2.75em;
  transform: rotate(15deg) skewX(15deg);
}
.rocker input:checked + .switch-left::before { background-color: var(--gm-rk-edge); }
.rocker input:checked + .switch-left + .switch-right {
  background-color: var(--gm-accent); color: #fff;
  bottom: 0; right: 0.5em; height: 2.5em; width: 3em;
  transform: rotate(0deg) skewX(0deg);
}
.rocker input:checked + .switch-left + .switch-right::before {
  background-color: transparent; width: 3.0833em;
}

.rocker input:focus-visible + .switch-left { outline: 2px solid var(--gm-accent); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .switch-left, .switch-right { transition: none; } }
@media (max-width: 860px) { .rocker-small { font-size: 9.5px; } }

/* header (shared partial, untouched — pure attribute-scoped override).
   Needs its own opaque background: it's fixed, so once the page scrolls past
   the (now light) hero it would otherwise show dark-ink text over whatever
   dark section is currently underneath it. */
html[data-gm-theme="light"] .gm-header { background: var(--gm-bg) !important; border-bottom-color: rgba(0,0,0,.08) !important; }
html[data-gm-theme="light"] .gm-header,
html[data-gm-theme="light"] .gm-header .gm-nav a,
html[data-gm-theme="light"] .gm-logo,
html[data-gm-theme="light"] .gm-logo span { color: rgb(var(--gm-fg-rgb)) !important; }
html[data-gm-theme="light"] .gm-logo .gm-dot { color: var(--gm-accent) !important; }
html[data-gm-theme="light"] .gm-logo .gm-sub { color: rgb(var(--gm-fg-rgb) / var(--gm-muted-a)) !important; }
html[data-gm-theme="light"] .gm-header .gm-cta { border-color: var(--gm-accent) !important; color: rgb(var(--gm-fg-rgb)) !important; }
html[data-gm-theme="light"] .gm-header .gm-burger span { background: rgb(var(--gm-fg-rgb)) !important; }
html[data-gm-theme="light"] .gm-lang-dd > summary { color: var(--gm-accent) !important; }
html[data-gm-theme="light"] .gm-lang-dd > summary .caret { color: rgb(var(--gm-fg-rgb) / .6) !important; }

/* hero */
html[data-gm-theme="light"] .gm-hero-eyebrow { color: rgb(var(--gm-fg-rgb) / .85) !important; }
html[data-gm-theme="light"] .gm-hero-star { color: var(--gm-accent) !important; }
html[data-gm-theme="light"] .gm-hero-line-1 { color: rgb(var(--gm-fg-rgb)) !important; }
html[data-gm-theme="light"] .gm-hero-line-2 { color: var(--gm-accent) !important; }
html[data-gm-theme="light"] .gm-hero-sub { color: rgb(var(--gm-fg-rgb) / .72) !important; }
html[data-gm-theme="light"] .gm-hero-scroll-ring { border-color: rgb(var(--gm-fg-rgb) / .28) !important; }
html[data-gm-theme="light"] .gm-hero-scroll-arrow { color: rgb(var(--gm-fg-rgb) / .7) !important; }
html[data-gm-theme="light"] .gm-hero-scroll-label { color: rgb(var(--gm-fg-rgb) / var(--gm-muted-a)) !important; }
html[data-gm-theme="light"] .gm-hero-note { color: rgb(var(--gm-fg-rgb) / .76) !important; text-shadow: var(--gm-note-shadow) !important; }
html[data-gm-theme="light"] [data-screen-label="Hero"] .gm-secondary { border-color: rgb(var(--gm-fg-rgb) / .32) !important; color: rgb(var(--gm-fg-rgb)) !important; }

/* ---- shared components in light mode ----
   These live in site.css (generated) with hard-coded dark values, so every
   page inherits them. Overriding them once here covers all pages at once and
   keeps the per-template work to text annotation only. Rules that only apply
   inside a dark island are deliberately absent: the island redefines the
   colour tokens, so anything token-driven already resolves correctly there. */
html[data-gm-theme="light"] .gm-secondary { border-color: rgb(var(--gm-fg-rgb) / .3) !important; color: rgb(var(--gm-fg-rgb)) !important; }
html[data-gm-theme="light"] .gm-secondary:hover { background: rgb(var(--gm-fg-rgb) / .05) !important; border-color: rgb(var(--gm-fg-rgb) / .5) !important; }

html[data-gm-theme="light"] :is(.gm-timeline-control, .gm-spot-control, .gm-carousel-btn, .gm-tst-arrow) {
  border-color: rgb(var(--gm-fg-rgb) / .24) !important; color: rgb(var(--gm-fg-rgb)) !important;
}
html[data-gm-theme="light"] :is(.gm-timeline-control, .gm-spot-control):hover:not(:disabled),
html[data-gm-theme="light"] :is(.gm-timeline-control, .gm-spot-control):focus-visible {
  border-color: var(--gm-accent) !important; background: var(--gm-accent) !important; color: #fff !important;
}

html[data-gm-theme="light"] .gm-faq { border-color: rgb(var(--gm-fg-rgb) / .14) !important; }
html[data-gm-theme="light"] .gm-pill:hover { color: rgb(var(--gm-fg-rgb)) !important; }
html[data-gm-theme="light"] .gm-pill.is-active { background: var(--gm-accent) !important; border-color: var(--gm-accent) !important; color: #fff !important; }
html[data-gm-theme="light"] .gm-sel select { color: rgb(var(--gm-fg-rgb)) !important; }
html[data-gm-theme="light"] .gm-sel select option { background: #FFFFFF; color: #14110E; }

/* the compare table's scroll fade is a mask, not a colour — it survives the
   theme swap; only its column hover was tuned for a dark ground */
html[data-gm-theme="light"] .gm-cmp-col:hover { background: rgb(var(--gm-fg-rgb) / .04) !important; }

/* FAQ cards are body copy, so on paper they become light cards rather than
   staying dark islands (a dark block of Q&A reads as a foreign object in an
   otherwise light article). Surface only — the text is annotated. */
html[data-gm-theme="light"] .gm-faq { background: #FFFFFF !important; }
html[data-gm-theme="light"] .gm-faq[data-faq-open] { border-color: rgb(168 21 106 / .4) !important; }

/* Full-bleed content bands (.gm-band) — the dark design uses a horizontal
   gradient that fades to transparent at both edges to lift a section off the
   page. That device is about rhythm, not about being a dark object: the
   content inside is ordinary body copy. On paper it becomes a slightly deeper
   sheet instead of a black stripe, which keeps the alternation without
   turning a light page into a zebra. */
html[data-gm-theme="light"] .gm-band { --gm-bg: #EFEBE3; background: var(--gm-bg) !important; }

/* Handwritten decorative notes. In the dark design they are drawn in the
   violet decor layer or in soft magenta; both were picked to glow against
   near-black. On paper the same hues lose contrast, so they deepen to the
   documented paper values (DS-SPLATTER-SPEC.md: violet #7B1FD1, accent
   #A8156A). They stay decorative — no attempt to make them body-copy dark. */
html[data-gm-theme="light"] .gm-t-note { color: var(--gm-violet) !important; text-shadow: none !important; }

/* Empty rating stars are drawn in #3a3a3a — a dark grey that disappears into
   near-black and so reads as "unfilled". On paper that same grey is darker
   than the page and would read as FILLED, inverting the meaning of the row. */
/* Empty rating stars. The dark design draws them #3a3a3a on #080808 — about
   1.9:1, deliberately "unfilled". Paper keeps that intent but lands a little
   higher than the original, so the row is easier to read while the filled
   stars still carry the signal. A rating that leans on contrast alone is a
   pre-existing weakness of this table in BOTH themes, not something the light
   theme introduced; fixing it properly means changing the glyphs, not the
   colour, and that is a redesign. */
html[data-gm-theme="light"] .gm-t-faint { color: rgb(var(--gm-fg-rgb) / .42) !important; }

/* ---- content cards become light cards on paper ----
   These surfaces are defined by class in the generated site.css (a grouped
   `background:#080808 !important` block plus a few singles), not inline, so
   they survived the switch to a paper body and left ink text sitting on
   near-black. They are content containers — service cards, value and step
   cards, comparison columns, quiz options, timeline cards — not media
   objects, so on paper they become light cards rather than dark islands.
   Deliberately NOT in this list: .gm-poster / .gm-case / .gm-comic and the
   other photographic cards, which keep their scrim and stay dark islands.
   The !important is required to beat site.css's own !important. */
html[data-gm-theme="light"] :is(
  .gm-svc, .gm-quiz-opt, .gm-rec-card, .gm-cmp-scroll, .gm-combo, .gm-pcard,
  .gm-val, .gm-step, .gm-ind, .gm-chan-out, .gm-timeline-card, .gm-spotlight-card,
  .gm-featcase, .gm-tst-arrow
) {
  background: #FFFFFF !important;
  border-color: rgb(var(--gm-fg-rgb) / .12) !important;
}
html[data-gm-theme="light"] :is(.gm-svc, .gm-combo, .gm-cmp-col, .gm-timeline-card):hover {
  background: #FFFFFF !important; border-color: rgb(168 21 106 / .4) !important;
}
html[data-gm-theme="light"] .gm-timeline-image { background: #EFEBE3 !important; }

/* Blog and article carry their own opaque `background:#090909` on the hero and
   closing CTA — the body of both pages was already paper in the dark design,
   so these two bands were the contrast, not the ground. With the whole site on
   paper that inversion no longer holds: the bands would be the only dark thing
   on an otherwise light page, and their copy is annotated as ink. Both become
   ground-coloured, which also makes the blog read as one continuous sheet. */
html[data-gm-theme="light"] :is(
  [data-screen-label="Blog hero"],
  [data-screen-label="Article hero"],
  [data-screen-label="CTA"]
) { background: var(--gm-bg) !important; color: rgb(var(--gm-fg-rgb)) !important; }

/* ---- class-driven text colours (About timeline + team showcase) ----
   These two blocks style their text through CSS classes rather than inline
   attributes, so the per-element annotation pass could not reach them: the
   markup carries no `color:` to classify. They are mapped here by hand
   against the same token set, so they follow the theme like everything else.
   Anything whose colour lives in a stylesheet rather than in the markup needs
   an entry like this — worth remembering when a new component is added. */
html[data-gm-theme="light"] :is(.gm-timeline-title, .gm-timeline-count, .gm-timeline-statement, .gm-team-name) { color: rgb(var(--gm-fg-rgb)) !important; }
html[data-gm-theme="light"] :is(.gm-timeline-intro, .gm-timeline-description) { color: rgb(var(--gm-fg-rgb) / .74) !important; }
html[data-gm-theme="light"] :is(.gm-timeline-eyebrow, .gm-timeline-hint, .gm-timeline-meta, .gm-timeline-meta span:first-child, .gm-team-role) { color: rgb(var(--gm-fg-rgb) / var(--gm-muted-a)) !important; }
html[data-gm-theme="light"] :is(.gm-timeline-statement strong, .gm-team-mark) { color: var(--gm-accent) !important; }

/* Markdown-rendered longform: its headings, links and emphasis are styled by
   descendant rules (the HTML comes from the Markdown filter, so there is no
   markup to annotate). Same situation as the timeline and team blocks. */
html[data-gm-theme="light"] :is(.gm-seo-longform h2, .gm-seo-longform h3, .gm-seo-longform strong) { color: rgb(var(--gm-fg-rgb)) !important; }
html[data-gm-theme="light"] .gm-seo-longform a { color: var(--gm-accent) !important; }
html[data-gm-theme="light"] .gm-seo-longform a:hover { color: #7E0F4F !important; }

/* Pagination and filter pills: white-on-dark defaults that survive on paper */
html[data-gm-theme="light"] .gm-page { color: rgb(var(--gm-fg-rgb)) !important; border-color: rgb(var(--gm-fg-rgb) / .16) !important; }
html[data-gm-theme="light"] .gm-page.is-active { background: var(--gm-accent) !important; border-color: var(--gm-accent) !important; color: #fff !important; }
html[data-gm-theme="light"] .gm-page:hover { border-color: var(--gm-accent) !important; color: var(--gm-accent) !important; }
html[data-gm-theme="light"] .gm-fpill { color: rgb(var(--gm-fg-rgb)) !important; }
html[data-gm-theme="light"] .gm-fpill:hover { color: var(--gm-accent) !important; }
/* an active filter is a magenta chip — its label must stay white on that fill,
   not inherit the page's ink (measured 3.51:1 before this) */
html[data-gm-theme="light"] .gm-fpill[aria-pressed="true"],
html[data-gm-theme="light"] .gm-fpill.is-active {
  background: var(--gm-accent) !important; border-color: var(--gm-accent) !important; color: #fff !important;
}

/* ---- SVG icons ----
   Icons are coloured with SVG presentation attributes (stroke="rgba(245,…)"),
   not inline style, so the annotation pass skipped them and they stayed
   near-white — invisible on paper. Attribute selectors are safe here in a way
   they are not for style="": presentation attributes are plain attributes,
   never re-serialised by CSSOM, so the string matches exactly. Any CSS rule
   also outranks a presentation attribute, so no !important is needed.
   Inside a dark island --gm-fg-rgb flips back, so these resolve to light
   strokes there automatically. */
html[data-gm-theme="light"] [stroke="rgba(245,245,245,.55)"],
html[data-gm-theme="light"] [stroke="rgba(245,245,245,.5)"],
html[data-gm-theme="light"] [stroke="rgba(245,245,245,.72)"],
html[data-gm-theme="light"] [stroke="rgba(255,255,255,.18)"] { stroke: rgb(var(--gm-fg-rgb) / .66); }
html[data-gm-theme="light"] [fill="rgba(245,245,245,.55)"] { fill: rgb(var(--gm-fg-rgb) / .66); }

/* violet decor deepens on paper (canon: DS-SPLATTER-SPEC.md) */
html[data-gm-theme="light"] [stroke="#A736FF"] { stroke: var(--gm-violet); }
html[data-gm-theme="light"] [fill="#A736FF"] { fill: var(--gm-violet); }

/* chart dots are outlined in the dark page colour to punch them off the line */
html[data-gm-theme="light"] [stroke="#0A0A0A"] { stroke: var(--gm-bg); }

/* ---- pink glows off on paper ----
   Sixteen decorative radial washes (rgba(233,30,150,.22….34)) sit behind hero
   artwork and contact blocks. Over near-black they read as light spilling off
   the magenta; over paper the same wash is a pink smudge on white — the same
   family of problem as the opacity haze. Depth on paper comes from contrast
   and keylines, not from glow, so they are simply off. */
html[data-gm-theme="light"] .gm-glow { display: none !important; }

/* Sticky filter bar: a translucent scrim so cards stay readable while they
   scroll under it. It was a dark scrim; on paper that is a smoky band. */
html[data-gm-theme="light"] [data-screen-label="Filters"] {
  background: linear-gradient(90deg, rgba(245,243,239,0) 0%, rgba(245,243,239,.24) 16%, rgba(245,243,239,.9) 30%, rgba(245,243,239,.9) 70%, rgba(245,243,239,.24) 84%, rgba(245,243,239,0) 100%) !important;
}

/* ---- approval stamp ----
   The stamp fakes worn ink by overprinting near-black strokes (#080808) that
   match the dark page, so the violet looks eaten away. On paper those strokes
   stop being absence and become grey bars painted across the stamp. They must
   be the colour behind the stamp instead — hence --gm-bg, which .gm-band
   redefines for the section the stamp actually sits in. The violets are also
   dark-tuned and go to the canon paper violet. */
html[data-gm-theme="light"] .gm-approval-stamp-wear { stroke: var(--gm-bg); }
html[data-gm-theme="light"] .gm-approval-stamp-rings { stroke: var(--gm-violet); }
html[data-gm-theme="light"] .gm-approval-stamp-ring-text,
html[data-gm-theme="light"] .gm-approval-stamp-word { fill: var(--gm-violet); }
html[data-gm-theme="light"] .gm-approval-stamp {
  filter: drop-shadow(0 14px 26px rgba(20,17,14,.16));
  opacity: .92;
}

/* ---- splatter back in the footer ----
   The footer's own gradient fades to transparent at both edges, which in the
   dark design let the fixed drops layer show through — that is where the
   footer's paint splashes came from. Giving the footer an opaque backing for
   paper covered them up. Painting the same two drop clusters inside the
   footer restores them without reopening the edges to the page colour.
   z-index 0 keeps them under .gm-footer-grid, which is already z-index 1. */
html[data-gm-theme="light"] [data-screen-label="Footer"]::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: url('/static/icons/drops-a.svg'), url('/static/icons/drops-b.svg');
  background-repeat: no-repeat, no-repeat;
  background-position: -60px top, right -70px bottom;
  background-size: 250px auto, 300px auto;
  opacity: .42;
}

/* Stepper nodes colour their icon through `currentColor`, and that colour is
   set by a class in site.css rather than in the markup — so neither the
   annotation pass nor the stroke-attribute overrides reached them, and the
   icons stayed near-white. The beam line and its glow are violet decor. */
html[data-gm-theme="light"] .gm-beam-node { color: rgb(var(--gm-fg-rgb) / .55); }
html[data-gm-theme="light"] [data-drawn] .gm-beam-node { color: var(--gm-accent); border-color: rgb(168 21 106 / .45); }
html[data-gm-theme="light"] .gm-beam-node:hover { box-shadow: 0 0 26px rgb(168 21 106 / .22); border-color: rgb(168 21 106 / .6); }
html[data-gm-theme="light"] [stroke="rgba(167,54,255,.42)"] { stroke: rgb(123 31 209 / .45); }

/* language control on paper */
html[data-gm-theme="light"] .gm-lang-dd > summary {
  --gm-lang-ink: rgb(var(--gm-fg-rgb));
  --gm-lang-line: rgb(var(--gm-fg-rgb) / .2);
}
html[data-gm-theme="light"] .gm-lang-panel {
  background: #FFFFFF; border-color: rgb(var(--gm-fg-rgb) / .12);
  box-shadow: 0 18px 44px rgb(20 17 14 / .16);
}
html[data-gm-theme="light"] .gm-lang-item { color: rgb(var(--gm-fg-rgb)); }
html[data-gm-theme="light"] .gm-lang-item .name { color: rgb(var(--gm-fg-rgb) / var(--gm-muted-a)); }
html[data-gm-theme="light"] .gm-lang-item:hover { background: rgb(var(--gm-fg-rgb) / .05); color: var(--gm-accent); }
html[data-gm-theme="light"] .gm-lang-item[aria-current="true"],
html[data-gm-theme="light"] .gm-lang-item .check { color: var(--gm-accent); }
html[data-gm-theme="light"] .gm-lang-item[aria-current="true"] .name { color: rgb(168 21 106 / .8); }

/* ---- full-bleed article hero on paper ----
   31 of 43 articles put a photo behind the hero with a scrim that fades from
   near-opaque #090909 on the left, so light copy reads over it. Annotating the
   copy as ink turned that into dark-on-dark: measured, the title sat at
   rgb(20,17,14) on a scrim of mean brightness 13 — effectively invisible.
   The contrast gate cannot see this: it deliberately skips text over images
   and gradients, because contrast against arbitrary imagery is not computable.
   Found by sampling the rendered pixels instead. The scrim becomes paper, so
   the ink copy reads and the photo still fades in from the right. */
html[data-gm-theme="light"] .gm-editorial-hero-bg::after {
  background: linear-gradient(90deg, rgba(245,243,239,.97) 0%, rgba(245,243,239,.93) 34%, rgba(245,243,239,.34) 66%, rgba(245,243,239,.06) 100%) !important;
}
@media (max-width: 680px) {
  html[data-gm-theme="light"] .gm-editorial-hero-bg::after {
    background: linear-gradient(180deg, rgba(245,243,239,.9) 0%, rgba(245,243,239,.96) 58%, rgba(245,243,239,.76) 100%) !important;
  }
}

/* hero headline flip (prototype port) */
.gm-cycle-word { position: relative; display: inline-block; overflow: hidden; vertical-align: top; line-height: .9; cursor: pointer; }
.gm-flip-row { display: flex; }
.gm-flip-top { position: relative; z-index: 1; }
.gm-flip-bottom { position: absolute; inset: 0; z-index: 2; }
.gm-flip-row .gm-ltr { display: inline-block; transform: translateY(0); transition: transform .46s cubic-bezier(.65,0,.35,1); }
.gm-flip-bottom .gm-ltr { transform: translateY(110%); }
.gm-flip-top.is-out .gm-ltr { transform: translateY(-110%); }
.gm-flip-bottom.is-in .gm-ltr { transform: translateY(0); }
@media (prefers-reduced-motion: reduce) { .gm-flip-row .gm-ltr { transition: none; } }
