/* =========================================================================
   Angel Cea — Systems Strategist Portfolio
   Stylesheet map:
   1. Custom properties
   2. Reset / base
   3. Typography
   4. Layout primitives
   5. Utilities
   6. Components — header / nav
   7. Components — footer
   8. Components — buttons
   9. Components — cards & tags
   10. Components — sections (hero, problem, services, how-it-works, cta)
   11. Components — testimonial carousel
   12. Components — case studies gallery
   13. Components — case study modal
   14. Components — about section
   ========================================================================= */

/* ---------- 1. Custom properties ---------- */
:root {
  /* Brand colors — the only hues used anywhere on the site */
  --color-yellow: #F2C84B;
  --color-yellow-hover: #E6B93A;
  --color-ivory: #FAF8F3;
  --color-charcoal: #282723;
  --color-stone: #E9E5DD;

  /* Semantic aliases */
  --color-bg: var(--color-ivory);
  --color-surface: var(--color-stone);
  --color-surface-alt: #FFFFFF;
  --color-text: var(--color-charcoal);
  --color-text-muted: rgba(40, 39, 35, 0.65);
  --color-accent: var(--color-yellow);
  --color-accent-hover: var(--color-yellow-hover);
  --color-border: rgba(40, 39, 35, 0.12);
  --color-focus-ring: var(--color-charcoal);
  --color-node-muted: rgba(40, 39, 35, 0.32);
  --color-accent-bright: color-mix(in srgb, var(--color-yellow) 82%, white 18%);

  /* Typography */
  --font-display: "Fraunces", Georgia, serif;
  --font-body: "DM Sans", -apple-system, BlinkMacSystemFont, sans-serif;

  --fs-eyebrow: 0.75rem;
  --fs-small: 0.875rem;
  --fs-body: 1rem;
  --fs-body-lg: 1.125rem;
  --fs-h4: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
  --fs-h3: clamp(1.375rem, 1.1rem + 1vw, 1.875rem);
  --fs-h2: clamp(1.75rem, 1.3rem + 2vw, 2.5rem);
  --fs-h1: clamp(2.25rem, 1.5rem + 3.5vw, 3.5rem);

  --lh-tight: 1.1;
  --lh-heading: 1.2;
  --lh-body: 1.65;

  --tracking-eyebrow: 0.08em;

  /* Spacing (8px base) */
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2rem;
  --space-5: 3rem;
  --space-6: 4rem;
  --space-7: 6rem;
  --space-8: 8rem;

  /* Radius */
  --radius-card: 12px;
  --radius-button: 8px;
  --radius-tag: 999px;

  /* Shadow */
  --shadow-card: 0 2px 10px rgba(40, 39, 35, 0.06);
  --shadow-card-hover: 0 10px 24px rgba(40, 39, 35, 0.10);

  /* Layout */
  --container-max: 1200px;
  --container-pad: 1.25rem;

  /* Motion */
  --transition-base: 180ms ease;
  /* Shared hover language for process/service/case-study cards — a slightly
     slower, more deliberate transition than --transition-base's UI-chrome
     timing (buttons, tags, nav), since these are full-card background
     fills rather than small controls. */
  --transition-hover: 220ms ease-out;
}

/* ---------- 2. Reset / base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; transition-delay: 0s !important; scroll-behavior: auto !important; }
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--lh-heading);
  margin: 0 0 var(--space-2);
  text-wrap: balance;
}

h1 { font-size: var(--fs-h1); line-height: var(--lh-tight); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h4); }

p { margin: 0 0 var(--space-2); }
p:last-child { margin-bottom: 0; }

ul { margin: 0; padding: 0; }

a {
  color: inherit;
  text-decoration-color: rgba(40, 39, 35, 0.35);
}

button { font-family: inherit; }

/* Consistent, visible focus state everywhere */
a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--color-focus-ring);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ---------- 3. Typography helpers ---------- */
.eyebrow {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}

.prose {
  max-width: 65ch;
}
.prose p { margin-bottom: var(--space-3); }

/* ---------- 4. Layout primitives ---------- */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.section { padding-block: var(--space-6); }
.section--muted { background: var(--color-surface); }
.section--tight { padding-block: var(--space-4); }

@media (min-width: 1024px) {
  .section { padding-block: var(--space-7); }
}

.stack { display: flex; flex-direction: column; }
.stack--sm { gap: var(--space-2); }
.stack--md { gap: var(--space-3); }
.stack--lg { gap: var(--space-5); }

.grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;
}
.grid--2 { grid-template-columns: 1fr; }
.grid--3 { grid-template-columns: 1fr; }

@media (min-width: 768px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
}

.section-head {
  max-width: 720px;
  margin-bottom: var(--space-5);
}
.section-head--center {
  margin-inline: auto;
  text-align: center;
}
.section-head--accent::after {
  content: "";
  display: block;
  width: 36px;
  height: 3px;
  border-radius: 2px;
  background: var(--color-accent);
  margin: var(--space-2) auto 0;
}

/* ---------- 5. Utilities ---------- */
/* Centers a block on the page while keeping its own text left-aligned —
   matches .problem__content's width so sections using it read as part of
   the same visual sequence as the Problem section. */
.narrow-column {
  max-width: 620px;
  margin-inline: auto;
  text-align: left;
}

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

.skip-link {
  position: absolute;
  top: -999px;
  left: var(--space-2);
  background: var(--color-charcoal);
  color: var(--color-ivory);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-button);
  z-index: 1000;
}
.skip-link:focus {
  top: var(--space-2);
}

/* ---------- 6. Header / nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
}

.nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  padding-block: var(--space-2);
  gap: var(--space-3);
}

.nav__brand {
  text-decoration: none;
  line-height: 1.2;
}
.nav__brand-name {
  display: block;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--fs-body-lg);
  letter-spacing: 0.06em;
  color: var(--color-text);
}
.nav__brand-tag {
  display: block;
  font-size: 0.6875rem;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-top: 2px;
}

.nav__toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-button);
  cursor: pointer;
  order: 3;
}
.nav__toggle-icon,
.nav__toggle-icon::before,
.nav__toggle-icon::after {
  display: block;
  width: 20px;
  height: 2px;
  background: var(--color-charcoal);
  border-radius: 2px;
  transition: transform var(--transition-base), opacity var(--transition-base);
}
.nav__toggle-icon { position: relative; }
.nav__toggle-icon::before,
.nav__toggle-icon::after {
  content: "";
  position: absolute;
  left: 0;
}
.nav__toggle-icon::before { top: -6px; }
.nav__toggle-icon::after { top: 6px; }
.nav__toggle[aria-expanded="true"] .nav__toggle-icon { background: transparent; }
.nav__toggle[aria-expanded="true"] .nav__toggle-icon::before { transform: translateY(6px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] .nav__toggle-icon::after { transform: translateY(-6px) rotate(-45deg); }

.nav__panel {
  order: 4;
  flex-basis: 100%;
  display: none;
  flex-direction: column;
  gap: var(--space-1);
  padding-block: var(--space-2) var(--space-3);
  border-top: 1px solid var(--color-border);
  margin-top: var(--space-2);
}
.nav__panel.is-open { display: flex; }

.nav__links {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.nav__link {
  display: block;
  padding: var(--space-2) 0;
  text-decoration: none;
  font-weight: 500;
  color: var(--color-text);
  border-bottom: 2px solid transparent;
}
.nav__link.is-active {
  border-bottom-color: var(--color-accent);
}

.nav__cta-wrap {
  margin-top: var(--space-2);
}
.nav__cta-wrap .btn { width: 100%; justify-content: center; }

@media (min-width: 768px) {
  .nav__toggle { display: none; }
  .nav__panel {
    display: flex;
    flex-direction: row;
    align-items: center;
    order: 2;
    flex-basis: auto;
    border-top: none;
    margin-top: 0;
    padding-block: 0;
    gap: var(--space-4);
  }
  .nav__links {
    flex-direction: row;
    gap: var(--space-4);
  }
  .nav__link { padding: var(--space-1) 0; }
  .nav__cta-wrap { margin-top: 0; }
  .nav__cta-wrap .btn { width: auto; }
}

/* ---------- 7. Footer ---------- */
/* Deliberately just a utility strip: identity already lives in the sticky
   nav and the primary action already lives in the CTA directly above, so
   this only needs to carry copyright + contact icons. */
.site-footer {
  background: var(--color-charcoal);
  color: var(--color-ivory);
  padding-block: var(--space-3);
  /* Same charcoal as .section--cta directly above — this hairline is the
     only seam between them, so the two read as one closing dark block. */
  border-top: 1px solid rgba(250, 248, 243, 0.1);
}
.footer__row {
  display: flex;
  /* Mobile: icons above copyright (per spec), achieved via column-reverse
     rather than reordering the markup — copyright stays first in reading/DOM
     order since it's the more fundamental line of the two. */
  flex-direction: column-reverse;
  align-items: center;
  gap: var(--space-2);
  text-align: center;
}
.footer__copyright {
  margin: 0;
  color: rgba(250, 248, 243, 0.55);
  font-size: var(--fs-small);
}
.footer__contact {
  display: flex;
  gap: var(--space-2);
}
.footer__icon-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid rgba(250, 248, 243, 0.2);
  color: rgba(250, 248, 243, 0.65);
  transition: border-color var(--transition-hover), color var(--transition-hover), transform var(--transition-hover);
}
.footer__icon-link:hover,
.footer__icon-link:focus-visible {
  border-color: var(--color-accent);
  color: var(--color-accent);
  transform: translateY(-2px);
}

@media (min-width: 768px) {
  .footer__row {
    flex-direction: row;
    justify-content: space-between;
    text-align: left;
  }
}

/* ---------- 8. Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--fs-body);
  text-decoration: none;
  border-radius: var(--radius-button);
  padding: 0.8125rem 1.375rem;
  letter-spacing: 0.01em;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color var(--transition-base), transform var(--transition-base), border-color var(--transition-base);
}
.btn--primary {
  background: var(--color-accent);
  color: var(--color-charcoal);
}
.btn--primary:hover {
  background: var(--color-accent-hover);
}
.btn--secondary {
  background: transparent;
  color: var(--color-charcoal);
  border-color: var(--color-charcoal);
}
.btn--secondary:hover {
  background: var(--color-charcoal);
  color: var(--color-ivory);
}
.btn--sm {
  padding: 0.6rem 1.1rem;
  font-size: var(--fs-small);
}
.btn__arrow {
  transition: transform var(--transition-base);
}
.btn:hover .btn__arrow {
  transform: translateX(3px);
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2);
}

/* ---------- 9. Cards & tags ---------- */
/* Shared hover pattern — reused by every card-like component on the site
   (work cards, service cards, step cards, testimonial cards): a small lift,
   a soft shadow bump, and a hint of the accent color at the border. Kept
   deliberately restrained — no scale, no glow. */
.card {
  background: var(--color-surface);
  border-radius: var(--radius-card);
  padding: var(--space-3);
  border: 1px solid transparent;
  box-shadow: var(--shadow-card);
  transition: transform var(--transition-base), box-shadow var(--transition-base), border-color var(--transition-base);
}
.card:hover,
.card:focus-visible {
  /* !important: [data-reveal].is-revealed also sets transform at equal
     specificity — without this, the reveal system's resting transform
     silently cancels the hover lift on any card used inside a reveal group. */
  transform: translateY(-4px) !important;
  box-shadow: var(--shadow-card-hover);
  border-color: var(--color-accent);
}

.card--work {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  text-decoration: none;
  color: var(--color-text);
  height: 100%;
}
.card--work__title { margin-bottom: 0; }
.card--work__hook {
  font-weight: 500;
  color: var(--color-text);
}
.card--work__blurb {
  color: var(--color-text-muted);
}
.card--work__link {
  margin-top: auto;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
}

/* Services grid — five cards: a 3-up row, then 2 centered beneath it.
   Built on a 6-column sub-grid (desktop) / 4-column sub-grid (tablet) so the
   shorter final row can be centered without stretching cards or leaving a
   visibly empty slot. See responsive overrides below. */
.services-grid {
  grid-template-columns: 1fr;
}
@media (min-width: 768px) and (max-width: 1023px) {
  .services-grid { grid-template-columns: repeat(4, 1fr); }
  .services-grid > *:nth-child(-n+4) { grid-column: span 2; }
  .services-grid > *:nth-child(5) { grid-column: 2 / span 2; }
}
@media (min-width: 1024px) {
  .services-grid { grid-template-columns: repeat(6, 1fr); }
  .services-grid > *:nth-child(-n+3) { grid-column: span 2; }
  .services-grid > *:nth-child(4) { grid-column: 2 / span 2; }
  .services-grid > *:nth-child(5) { grid-column: 4 / span 2; }
}

.card--service {
  text-align: left;
}
.card--service__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--color-ivory);
  color: var(--color-accent);
  margin-bottom: var(--space-2);
  transition: background-color var(--transition-hover), color var(--transition-hover);
}
.card--service__title {
  font-size: var(--fs-h4);
  margin-bottom: 10px;
}
.card--service__divider {
  display: block;
  width: 48px;
  height: 2px;
  border-radius: 1px;
  background: var(--color-accent);
  margin-bottom: 16px;
  transition: background-color var(--transition-hover);
}
.card--service:hover,
.card--service:focus-visible {
  /* Redeclaring `transition` here (not just on the base class) matters:
     this element also carries data-reveal, whose own `transition` shorthand
     would otherwise fully replace ours (equal specificity, later in source
     wins for the whole property, not just the sub-properties it lists) —
     a plain hover/focus-visible compound selector has higher specificity
     than either, so it reliably wins regardless of source order. */
  transition: background-color var(--transition-hover), transform var(--transition-hover), box-shadow var(--transition-hover), border-color var(--transition-hover);
  /* Whole-card highlight, matching the process-card language — a fill, not
     a border accent, so the two treatments don't compete. */
  background: var(--color-accent);
  border-color: transparent;
  transform: translateY(-4px) !important;
  box-shadow: var(--shadow-card-hover);
}
.card--service:hover .card--service__icon,
.card--service:focus-visible .card--service__icon {
  background: var(--color-charcoal);
  color: var(--color-accent);
}
.card--service:hover .card--service__divider,
.card--service:focus-visible .card--service__divider {
  background: var(--color-charcoal);
}
.card--service__desc {
  color: var(--color-text-muted);
  margin: 0;
}
/* Wide enough that the first sentence doesn't wrap on its own at tablet/
   desktop widths, so the <br> below produces a clean two-line note instead
   of three. */
.services-note {
  max-width: 760px;
  margin: var(--space-5) auto 0;
  text-align: center;
}
.services-note__emphasis {
  font-weight: 600;
}
.tools-note {
  margin-top: var(--space-5);
  text-align: center;
}
.tools-note__emphasis {
  font-weight: 600;
}
/* Mobile-only forced break: tablet/desktop keep this note on one line
   (there's room), so the break only shows below 768px. */
.tools-note__break {
  display: none;
}
@media (max-width: 767px) {
  .tools-note__break {
    display: inline;
  }
}

.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.tag {
  font-size: var(--fs-small);
  font-weight: 500;
  padding: 0.3rem 0.75rem;
  border-radius: var(--radius-tag);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  color: var(--color-text);
  transition: border-color var(--transition-base);
}
.card--work .tag,
.card.section--muted .tag {
  background: var(--color-ivory);
}
.tag--tool {
  /* Compact, consistent-height pill — the icon circle (not the pill itself)
     normalizes each logo's slot; the logo keeps its own native aspect ratio
     inside that circle. See .tag__icon-circle / .tag__logo. */
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 9px 16px;
  background: var(--color-ivory);
  transition: border-color 200ms ease-out, transform 200ms ease-out;
}
.tag--tool:hover {
  border-color: var(--color-accent);
  transform: translateY(-1.5px);
}
.tag__icon-circle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--color-surface-alt);
  border: 1.5px solid transparent;
  overflow: hidden;
  flex-shrink: 0;
  transition: border-color 200ms ease-out;
}
.tag--tool:hover .tag__icon-circle {
  border-color: var(--color-accent);
}
.tag__logo {
  display: block;
  width: 14px;
  height: 14px;
  object-fit: contain;
}
/* Applied by js/main.js if a logo file fails to load — the tag still shows
   its plain text label rather than a broken image or an invented icon. */
.tag--tool-fallback {
  padding-left: 16px;
}

/* Reveal-on-scroll — reusable fade + slight rise, used by any grid of items
   wrapped in [data-reveal-group] with [data-reveal] children. No typewriter,
   no bounce — just a quiet entrance, staggered a few items at a time. */
[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 450ms ease-out, transform 450ms ease-out;
}
[data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}
[data-reveal]:nth-child(1) { transition-delay: 0ms; }
[data-reveal]:nth-child(2) { transition-delay: 70ms; }
[data-reveal]:nth-child(3) { transition-delay: 140ms; }
[data-reveal]:nth-child(4) { transition-delay: 210ms; }
[data-reveal]:nth-child(5) { transition-delay: 280ms; }
[data-reveal]:nth-child(6) { transition-delay: 350ms; }

/* ---------- 10. Section-specific blocks ---------- */
/* Hero — centered composition. .hero-section holds the full-bleed floating
   logo layer (positioned across the section's whole padding+content box, so
   icons can sit in the top/bottom padding bands on mobile and the side
   margins on wider screens); .hero__content is the centered focal column. */
.hero-section {
  position: relative;
  overflow: hidden; /* safety clip — a mispositioned icon clips instead of causing page-wide horizontal scroll */
}
.hero {
  position: relative;
  z-index: 1;
}
.hero__content {
  margin-inline: auto;
  text-align: center;
}
@media (min-width: 768px) {
  .hero__content { max-width: 560px; }
}
@media (min-width: 1024px) {
  .hero__content { max-width: 720px; }
}
.hero__headline { margin-bottom: var(--space-3); font-size: var(--fs-h2); }
.hero__highlight {
  background-image: linear-gradient(var(--color-accent), var(--color-accent));
  background-repeat: no-repeat;
  background-size: 100% 0.3em;
  background-position: 0 92%;
}
.hero__subhead {
  font-size: var(--fs-body);
  color: var(--color-text-muted);
  max-width: 56ch;
  margin-inline: auto;
  margin-bottom: var(--space-2);
}
.hero__subhead + .hero__subhead {
  margin-bottom: var(--space-3);
}
.hero__stats {
  font-size: var(--fs-small);
  font-weight: 500;
  color: var(--color-text-muted);
  margin-bottom: var(--space-3);
}

/* Floating tool logos — decorative, aria-hidden. Positioned relative to
   .hero-section (not .hero__content) so mobile can anchor icons within the
   section's own top/bottom padding bands, clear of the text regardless of
   how many lines the headline wraps to. */
.hero__floating {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}
.hero__float-icon {
  position: absolute;
  opacity: 0;
  transition: opacity 600ms ease-out;
}
.hero__float-icon.is-revealed { opacity: 1; }
.hero__float-icon--1 { transition-delay: 0ms; }
.hero__float-icon--2 { transition-delay: 80ms; }
.hero__float-icon--3 { transition-delay: 160ms; }
.hero__float-icon--4 { transition-delay: 240ms; }
.hero__float-icon--5 { transition-delay: 320ms; }
.hero__float-icon--6 { transition-delay: 400ms; }
.hero__float-icon--7 { transition-delay: 480ms; }
.hero__float-icon--8 { transition-delay: 560ms; }
.hero__float-icon--9 { transition-delay: 640ms; }
.hero__float-icon--10 { transition-delay: 720ms; }
.hero__float-icon--11 { transition-delay: 800ms; }
.hero__float-icon--12 { transition-delay: 880ms; }

.hero__float-card {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 8px;
  border-radius: 12px;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-card);
  animation: hero-float var(--float-duration, 8s) ease-in-out infinite;
  animation-delay: var(--float-delay, 0s);
}
.hero__float-logo {
  display: block;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}
@keyframes hero-float {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(var(--float-x, 6px), var(--float-y, -8px)); }
}

/* Mobile — only 6 icons (top/bottom padding bands, a few px in from the
   edge so they never reach into the text); the other 6 return at tablet+
   where there's room in the side margins instead. */
.hero__float-icon--7,
.hero__float-icon--8,
.hero__float-icon--9,
.hero__float-icon--10,
.hero__float-icon--11,
.hero__float-icon--12 {
  display: none;
}
.hero__float-icon--1 { top: 10px; left: 6%; }
.hero__float-icon--2 { top: 14px; right: 8%; }
.hero__float-icon--3 { top: 10px; left: 42%; }
.hero__float-icon--4 { bottom: 10px; left: 8%; }
.hero__float-icon--5 { bottom: 12px; right: 6%; }
.hero__float-icon--6 { bottom: 14px; left: 42%; }

/* Tablet — all 12 icons, spread across six vertical bands in the (now
   narrower) side margins, alternating left/right. */
@media (min-width: 768px) and (max-width: 1023px) {
  .hero__float-icon--7,
  .hero__float-icon--8,
  .hero__float-icon--9,
  .hero__float-icon--10,
  .hero__float-icon--11,
  .hero__float-icon--12 {
    display: block;
  }
  .hero__float-card { width: 44px; height: 44px; }
  .hero__float-icon--1 { top: 4%; left: 2%; bottom: auto; right: auto; }
  .hero__float-icon--2 { top: 6%; right: 3%; bottom: auto; left: auto; }
  .hero__float-icon--3 { top: 21%; left: 0.5%; bottom: auto; right: auto; }
  .hero__float-icon--4 { top: 24%; right: 1%; bottom: auto; left: auto; }
  .hero__float-icon--5 { top: 41%; left: 2%; bottom: auto; right: auto; }
  .hero__float-icon--6 { top: 38%; right: 2%; bottom: auto; left: auto; }
  .hero__float-icon--7 { top: 55%; left: 1%; }
  .hero__float-icon--8 { top: 58%; right: 1.5%; }
  .hero__float-icon--9 { top: 75%; left: 2%; }
  .hero__float-icon--10 { top: 72%; right: 2%; }
  .hero__float-icon--11 { top: 84%; left: 5%; }
  .hero__float-icon--12 { top: 87%; right: 5%; }
}

/* Desktop — larger cards, wider side margins around the focal content */
@media (min-width: 1024px) {
  .hero__float-icon--7,
  .hero__float-icon--8,
  .hero__float-icon--9,
  .hero__float-icon--10,
  .hero__float-icon--11,
  .hero__float-icon--12 {
    display: block;
  }
  .hero__float-card { width: 56px; height: 56px; padding: 10px; border-radius: 14px; }
  .hero__float-icon--1 { top: 4%; left: 4%; bottom: auto; right: auto; }
  .hero__float-icon--2 { top: 7%; right: 4%; bottom: auto; left: auto; }
  .hero__float-icon--3 { top: 21%; left: 1%; bottom: auto; right: auto; }
  .hero__float-icon--4 { top: 24%; right: 1%; bottom: auto; left: auto; }
  .hero__float-icon--5 { top: 41%; left: 3%; bottom: auto; right: auto; }
  .hero__float-icon--6 { top: 38%; right: 3%; bottom: auto; left: auto; }
  .hero__float-icon--7 { top: 55%; left: 1%; }
  .hero__float-icon--8 { top: 58%; right: 1%; }
  .hero__float-icon--9 { top: 75%; left: 3%; }
  .hero__float-icon--10 { top: 72%; right: 3%; }
  .hero__float-icon--11 { top: 84%; left: 8%; }
  .hero__float-icon--12 { top: 87%; right: 7%; }
}

@media (prefers-reduced-motion: reduce) {
  .hero__float-card { animation: none; }
}

.list-check {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.list-check li {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
}
.list-check li svg { flex-shrink: 0; margin-top: 0.2em; color: var(--color-accent); }
/* Same weight as .problem__emphasis, so the two sections' bold treatment
   reads as identical rather than merely similar. */
.list-check__emphasis {
  font-weight: 600;
}

/* Problem section — independent operational signals (not sequential) */
.problem .section-head--center { margin-inline: auto; }
.problem__content {
  max-width: 620px;
  margin-inline: auto;
  text-align: left;
}
.problem__list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1.15rem;
}
.problem__item {
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* Irregular, non-sequential stagger — deliberately not top-to-bottom order */
.problem__item:nth-child(1) { --stagger-delay: 60ms; }
.problem__item:nth-child(2) { --stagger-delay: 150ms; }
.problem__item:nth-child(3) { --stagger-delay: 0ms; }
.problem__item:nth-child(4) { --stagger-delay: 190ms; }
.problem__item:nth-child(5) { --stagger-delay: 100ms; }
.problem__item:nth-child(6) { --stagger-delay: 130ms; }

.problem__node {
  flex-shrink: 0;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid var(--color-node-muted);
  background: var(--color-surface);
  transition: transform 200ms ease-out;
}
@keyframes problem-node-activate {
  0% { border-color: var(--color-node-muted); background-color: var(--color-surface); }
  50% { border-color: var(--color-accent); background-color: var(--color-surface); }
  100% { border-color: var(--color-accent); background-color: var(--color-accent); }
}
.problem__list.is-visible .problem__item .problem__node {
  animation: problem-node-activate 420ms ease-out both;
  animation-delay: var(--stagger-delay, 0ms);
}
.problem__item:hover .problem__node {
  transform: scale(1.08);
}
.problem__body {
  opacity: 0;
  transform: translateY(5px);
  transition: opacity 200ms ease-out, transform 200ms ease-out;
  transition-delay: var(--stagger-delay, 0ms);
}
.problem__list.is-visible .problem__item .problem__body {
  opacity: 1;
  transform: none;
}
.problem__emphasis {
  font-weight: 600;
}
/* Higher-specificity override so hover response is instant, not delayed by the entrance stagger */
.problem__list.is-visible .problem__item:hover .problem__body {
  transform: translateX(2px);
  transition-delay: 0ms;
}

.problem__payoff {
  /* Same width as the section heading so it reads as centered on the page
     rather than cramped into the narrower signal-list column. */
  max-width: 720px;
  margin-inline: auto;
  margin-top: var(--space-5);
  text-align: left;
}
.problem__transition {
  margin: 0;
}
.problem__transition + .problem__transition {
  margin-top: var(--space-2);
}
.problem__closing {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-h3);
  margin: var(--space-4) 0 0;
  text-align: center;
}

.tools-block {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}
.tools-block .section-head--center {
  margin-bottom: 0;
}

/* Mobile — single column, categories stacked with generous but compact gaps */
.tools-columns {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 36px;
  margin-top: var(--space-4);
}
.tools-column {
  width: 100%;
  text-align: center;
}
.tools-group__label {
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}
.tag-row--center {
  justify-content: center;
  gap: 10px;
}

/* Tablet — 2-column grid; the third (odd) category centers on its own row,
   reusing the same sub-grid centering technique as .services-grid. */
@media (min-width: 768px) and (max-width: 1023px) {
  .tools-columns {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    column-gap: 32px;
    row-gap: var(--space-4);
    align-items: start;
  }
  .tools-column { width: auto; }
  .tools-column:nth-child(1) { grid-column: span 2; }
  .tools-column:nth-child(2) { grid-column: span 2; }
  .tools-column:nth-child(3) { grid-column: 2 / span 2; }
}

/* Desktop — one horizontal row, three equal columns, thin dividers sized to
   each column's own content height (not stretched to match a taller sibling). */
@media (min-width: 1024px) {
  .tools-columns {
    flex-direction: row;
    justify-content: center;
    align-items: flex-start;
    gap: 0;
  }
  .tools-column {
    flex: 1 1 0;
    max-width: 320px;
    padding-inline: 22px;
  }
  .tools-column:first-child { padding-left: 0; }
  .tools-column:last-child { padding-right: 0; }
  .tools-column:not(:first-child) {
    border-left: 1px solid var(--color-border);
  }
}

/* How it works — same editorial card language as Services/Client Success
   Stories: plain 1→3 column grid, left-aligned card content, no connector
   line/floating icon/pill — those read as SaaS-onboarding-widget furniture
   rather than part of this site. Single column through tablet (a 3-item
   row squeezed into a narrow tablet width, or an awkward 2+1 split, both
   read worse than staying stacked until there's genuinely enough room). */
.steps-grid {
  grid-template-columns: 1fr;
}
@media (min-width: 1024px) {
  .steps-grid { grid-template-columns: repeat(3, 1fr); }
}

.step-card {
  text-align: left;
}
.step-card__num {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-h4);
  color: var(--color-accent);
  margin-bottom: var(--space-2);
}
.step-card__title {
  margin-bottom: var(--space-1);
}
.step-card__desc {
  color: var(--color-text-muted);
  margin: 0;
}
.step-card:hover,
.step-card:focus-visible {
  /* See .card--service:hover for why `transition` is redeclared here rather
     than on the base class — same data-reveal specificity conflict. */
  transition: background-color var(--transition-hover), transform var(--transition-hover), box-shadow var(--transition-hover), border-color var(--transition-hover);
  background: var(--color-accent);
  border-color: transparent;
  transform: translateY(-4px) !important;
  box-shadow: var(--shadow-card-hover);
}
.step-card:hover .step-card__num,
.step-card:focus-visible .step-card__num {
  /* The number's resting color is the accent yellow — invisible against
     its own hover fill without this. */
  color: var(--color-charcoal);
}

.steps-note {
  max-width: 640px;
  margin: var(--space-5) auto 0;
  text-align: center;
  color: var(--color-text-muted);
  font-size: var(--fs-small);
}
.steps-note__emphasis {
  font-weight: 600;
  color: var(--color-text);
}

.section--cta {
  background: var(--color-charcoal);
  color: var(--color-ivory);
}
.section--cta h2 { color: var(--color-ivory); }
.cta-block {
  text-align: center;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}
/* Deliberately wider than the body below — narrowing this to match would
   force "Your systems should support the way you work" to wrap before the
   intended break, per .cta-headline__break--wide. */
.cta-headline {
  max-width: 900px;
}
/* Plain color emphasis (not the hero's underline treatment) — on the dark
   CTA background, a solid accent-yellow underline bar would read as
   heavier decoration than intended here; recoloring the phrase itself
   keeps the same serif weight/size and stays restrained. */
.cta-headline__emphasis {
  color: var(--color-accent);
}
/* Narrower than the headline so the body reads as a settled, balanced
   two-line block underneath it rather than stretching edge-to-edge. */
.section--cta p {
  max-width: 800px;
  color: rgba(250, 248, 243, 0.75);
}

/* Forced line breaks, shown/hidden per breakpoint instead of left to
   natural wrap — see the two <br> elements in the markup.
   - Mobile (<768px): both breaks show → 3 lines.
   - Tablet (768–1023px): neither shows → natural wrap, 2–3 lines depending
     on width, breaking at whatever phrase boundary fits.
   - Desktop (1024px+): only --wide shows → 2 lines. */
.cta-headline__break {
  display: none;
}
@media (max-width: 767px) {
  .cta-headline__break--mobile {
    display: inline;
  }
  /* The h2/.cta-block are shrink-to-fit (flex align-items:center), so text
     wraps against the true available width, not the max-width above — at
     narrow phone widths, "support the way you work" needs the full width
     with essentially zero margin at the default clamp() size, which isn't
     reliable across rendering engines. Trimmed slightly so it fits with
     real margin to spare. */
  .cta-headline {
    font-size: 1.6rem;
  }
}
@media (max-width: 767px), (min-width: 1024px) {
  .cta-headline__break--wide {
    display: inline;
  }
}

/* ---------- 11. Testimonials ---------- */
#testimonials {
  /* Offsets the anchor-scroll target so the sticky header never covers the
     section heading. Matches the header's own rendered height. */
  scroll-margin-top: 88px;
}
/* Sub-groups (video/screenshot/written) are no longer separated by text
   labels — the formats are visually self-evident — so each group after the
   first carries its own top margin to keep clear separation. */
.testimonials-screens,
.testimonials-written {
  margin-top: var(--space-6);
}
/* Tablet only: both groups have exactly 3 cards, which the shared 2-column
   .grid--3 breakpoint leaves as an orphaned lone card in column 1 with an
   empty gap beside it. Desktop's 3-column row and mobile's 1-column stack
   never hit this case, so the fix is scoped to the tablet range only. */
@media (min-width: 768px) and (max-width: 1023px) {
  .testimonials-written > :nth-child(3),
  .testimonials-screens > :nth-child(3) {
    grid-column: 1 / -1;
    max-width: calc(50% - var(--space-4) / 2);
    margin-inline: auto;
  }
}

#work {
  /* Offsets the anchor-scroll target so the sticky header never covers the
     section heading — same fixed value as #testimonials. */
  scroll-margin-top: 88px;
}

.testimonial-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
/* The card itself carries [data-reveal]'s nth-child transition-delay (for
   the entrance stagger) — without resetting it on hover, hover would
   inherit that same delay and feel sluggish instead of an immediate ~200ms
   response. */
.testimonials-section .testimonial-card:hover {
  /* [data-reveal]'s own `transition: opacity 450ms, transform 450ms` fully
     replaces (not merges with) the base .card transition — since the card
     carries data-reveal directly, its hover would otherwise inherit that
     450ms entrance speed instead of a quick ~200ms response. Redeclaring
     the transition here (a CSS transition uses whichever `transition`
     value is in effect for the state being entered) restores the fast
     hover feel; the slightly slower 450ms return-to-rest on mouse-leave
     is a deliberate, unnoticeable trade-off vs. restructuring the markup. */
  transition: transform 200ms ease-out, border-color 200ms ease-out, box-shadow 200ms ease-out;
}
/* Section uses a slightly smaller entrance rise (7px) than the generic
   [data-reveal] default (14px) — a subtler motion for a denser grid. */
.testimonials-section [data-reveal] {
  transform: translateY(7px);
}

/* Video testimonials */
.video-embed {
  aspect-ratio: 16 / 9;
  border-radius: calc(var(--radius-card) - 4px);
  overflow: hidden;
  background: var(--color-charcoal);
}
.video-embed iframe { width: 100%; height: 100%; border: 0; display: block; }
/* Ryan Johnson's YouTube Short is vertical — capped to a modest width so it
   reads as an intentional "phone preview" rather than dominating the grid. */
.video-embed--vertical {
  aspect-ratio: 9 / 16;
  max-width: 220px;
  margin-inline: auto;
}

/* Written testimonials — dark editorial quote cards, styled after the
   case-study modal's own "Client Feedback" treatment (see
   .case-modal__feedback) but as standalone cards rather than a block inside
   a light modal. */
.testimonial-card--written {
  background: var(--color-charcoal);
}
.testimonial-card--written p {
  color: rgba(250, 248, 243, 0.78);
  margin: 0;
}
.testimonial-card--written .testimonial-person__name {
  color: var(--color-ivory);
}
.testimonial-card--written .testimonial-person__role {
  color: rgba(250, 248, 243, 0.6);
}
.testimonial-card__mark {
  font-family: var(--font-display);
  font-size: 2rem;
  line-height: 1;
  color: var(--color-accent);
  display: block;
}
.testimonial-card--written:hover,
.testimonial-card--written:focus-within {
  /* Redeclared here — see .case-card:hover for why (data-reveal transition
     conflict). Slight lift/shadow bump from the base .card:hover, but the
     border stays a soft translucent yellow rather than the sitewide solid
     accent — a bright 1px yellow line reads as too strong against charcoal. */
  transition: transform 200ms ease-out, box-shadow 200ms ease-out, border-color 200ms ease-out;
  border-color: rgba(242, 200, 75, 0.45);
}
/* Screenshot testimonials — light, image-led cards. The image bleeds to
   the card's own edges (no card padding around it) so it gets as much of
   the card's area as possible; padding is reserved for the byline only. */
.testimonial-card--screenshot {
  padding: 0;
  gap: 0;
  overflow: hidden;
}
.testimonial-card__image-trigger {
  /* Button reset — see .case-card for the same pattern/rationale. */
  appearance: none;
  -webkit-appearance: none;
  display: block;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.testimonial-card__image-wrap {
  display: block;
  /* A square-ish frame is the best compromise across this set's mixed
     aspect ratios (landscape LinkedIn posts vs. a taller WhatsApp thread) —
     it minimizes worst-case letterboxing on either shape better than a
     wide 4:3 frame does for the tall one. */
  aspect-ratio: 1 / 1;
  background: var(--color-ivory);
}
.testimonial-card__image-wrap img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  transition: transform 200ms ease-out;
}
.testimonial-card--screenshot .testimonial-person {
  padding: var(--space-3);
  margin-top: 0;
}
.testimonial-card--screenshot:hover,
.testimonial-card--screenshot:focus-within {
  /* Redeclared here — see .case-card:hover for why (data-reveal transition
     conflict). No background/border-accent shift — with the image now
     flush to the card edges, the click affordance is just the lift/shadow
     plus a barely-there zoom on the image itself, not a color change. */
  transition: transform 200ms ease-out, box-shadow 200ms ease-out, border-color 200ms ease-out;
}
.testimonial-card--screenshot:hover .testimonial-card__image-wrap img,
.testimonial-card--screenshot:focus-within .testimonial-card__image-wrap img {
  transform: scale(1.015);
}

/* Shared byline across all three testimonial types */
.testimonial-person {
  margin-top: auto;
  padding-top: var(--space-1);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.testimonial-person__name {
  font-weight: 500;
  color: var(--color-text);
}
.testimonial-person__role {
  font-size: var(--fs-small);
  color: var(--color-text-muted);
}

/* Screenshot lightbox — reuses .case-modal-overlay for the dim backdrop +
   fade transition; .lightbox replaces .case-modal since sizing here is
   image-driven rather than a fixed-max-width text card. Width-first sizing
   (not height-capped) so a tall screenshot scrolls instead of shrinking
   until its text becomes unreadable. */
.lightbox {
  position: relative;
  max-width: min(92vw, 850px);
  max-height: 92vh;
  /* Same open transition as .case-modal, so the lightbox doesn't just pop
     in while every other modal on the site fades + scales. */
  transform: translateY(12px) scale(0.98);
  transition: transform 200ms ease-out;
}
.case-modal-overlay.is-open .lightbox {
  transform: none;
}
.lightbox__scroll {
  max-height: 92vh;
  overflow-y: auto;
  border-radius: var(--radius-card);
  background: var(--color-ivory);
  padding: var(--space-2);
  box-shadow: var(--shadow-card-hover);
}
.lightbox__img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: calc(var(--radius-card) - 4px);
}
@media (max-width: 639px) {
  .lightbox { max-width: 96vw; max-height: 94vh; }
  .lightbox__scroll { max-height: 94vh; }
}

/* ---------- 12. Case studies gallery ---------- */
/* Mobile/tablet: natural per-card height (stacked or 2-up, content-sized —
   no fixed height, so nothing clips and nothing gets an awkward forced gap).
   Desktop (1024px+, the 3-column layout) switches to a uniform card height
   below, so all six cards read as one consistent set. */
.case-studies-grid {
  align-items: start;
}
@media (min-width: 1024px) {
  .case-studies-grid {
    align-items: stretch;
  }
}

.case-card {
  appearance: none;
  -webkit-appearance: none;
  display: flex;
  flex-direction: column;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  /* Positions + clips .case-card::before to this card's own rounded box. */
  position: relative;
  overflow: hidden;
}
/* Subtle warm depth, concentrated near the logo — a directional gradient
   layer (not a background-color/background-image transition, which isn't
   reliably animatable) so it can fade and grow smoothly on hover. Kept as a
   soft tint, never a flat fill: these cards carry more information than the
   service/process cards and should read calmer. */
.case-card::before {
  content: "";
  position: absolute;
  inset: -12%;
  z-index: -1;
  background: radial-gradient(55% 55% at 26% 12%, rgba(242, 200, 75, 0.5), transparent 70%);
  opacity: 0.32;
  transform: scale(0.85);
  transition: opacity var(--transition-hover), transform var(--transition-hover);
  pointer-events: none;
}
.case-card:hover::before,
.case-card:focus-visible::before {
  opacity: 1;
  transform: scale(1.15);
}
.case-card:hover,
.case-card:focus-visible {
  /* Redeclared for the same reason as .card--service/.step-card above: this
     element carries data-reveal, whose transition would otherwise fully
     replace the base .card:hover's (equal specificity, later in source),
     leaving the lift/shadow to run at data-reveal's 450ms instead of this
     card language's 220ms. */
  transition: transform var(--transition-hover), box-shadow var(--transition-hover), border-color var(--transition-hover);
}
.case-card__logo-wrap {
  /* Client logos range from square icon badges to wide wordmarks (up to
     ~4.4:1) — sizing by height and letting width follow the logo's own
     aspect ratio keeps wordmarks legible instead of squeezing them into a
     forced square. No background/border box — logos sit directly on the
     card. */
  height: 40px;
  max-width: 100%;
  width: fit-content;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-2);
}
.case-card__logo {
  height: 100%;
  width: auto;
  max-width: 220px;
  object-fit: contain;
}
.case-card__name {
  margin-bottom: 2px;
  overflow-wrap: break-word;
  line-height: 1.15;
  /* Allows up to 2 lines for a long business name without the browser's
     default (unlimited) wrap pushing the card taller than necessary. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
/* Opt-in for names long enough to otherwise wrap to 2 lines at the default
   size (e.g. "Healthy Home Pediatrics") — one step down from the default h3
   size, same weight/family, so it fits more comfortably without inflating
   the card. Reusable for any future long name; not applied globally. */
.case-card__name--compact {
  font-size: var(--fs-h4);
}
.case-card__type {
  font-size: var(--fs-small);
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}
.case-card__headline {
  font-weight: 500;
  margin-bottom: var(--space-2);
}
.case-card__results {
  font-size: var(--fs-small);
  margin-bottom: var(--space-2);
}
.case-card__link {
  margin-top: auto;
  padding-top: var(--space-1);
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
}

/* Shared checkmark list — compact on gallery cards (title only), fuller in
   the modal (title + one-line description). */
.check-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.check-list li {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
}
.check-list li::before {
  content: "\2713";
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  margin-top: 0.15em;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-charcoal);
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 1;
}
.check-list__title { margin: 0; font-weight: 500; }
.check-list__desc { margin: 0; color: var(--color-text-muted); }

/* ---------- 13. Case study modal ---------- */
.case-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-3);
  background: rgba(40, 39, 35, 0.55);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 200ms ease-out;
}
.case-modal-overlay.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

body.has-modal-open { overflow: hidden; }

.case-modal {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  border-radius: var(--radius-card);
  width: 100%;
  max-width: 720px;
  max-height: 85vh;
  overflow: hidden;
  box-shadow: var(--shadow-card-hover);
  transform: translateY(12px) scale(0.98);
  transition: transform 200ms ease-out;
}
.case-modal-overlay.is-open .case-modal {
  transform: none;
}

.case-modal__close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  z-index: 1;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  color: var(--color-text);
  cursor: pointer;
  font-size: 1.25rem;
  line-height: 1;
  transition: border-color var(--transition-base), transform var(--transition-base);
}
.case-modal__close:hover,
.case-modal__close:focus-visible {
  border-color: var(--color-accent);
  transform: scale(1.06);
}

.case-modal__body {
  overflow-y: auto;
  padding: var(--space-4);
}

.case-modal__header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  padding-right: var(--space-5);
}
.case-modal__header-text {
  /* Flex items default to min-width:auto, which stops the name/type text
     from shrinking to fit — without this, a long name overflows past the
     header instead of wrapping, colliding with the close button. */
  min-width: 0;
}
.case-modal__logo-wrap {
  /* Same height-fixed / width-auto sizing as .case-card__logo-wrap, scaled
     up slightly for the modal header. No background/border box — logos
     sit directly on the modal. */
  height: 52px;
  max-width: 100%;
  width: fit-content;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.case-modal__logo {
  height: 100%;
  width: auto;
  max-width: 260px;
  object-fit: contain;
}
.case-modal__name {
  margin: 0;
  /* DiverseJobsMatter/Brainiact are single unbroken words — without this,
     browsers have no space to wrap at and just let the name overflow past
     the header instead of breaking it onto a second line. */
  overflow-wrap: break-word;
}
.case-modal__type {
  margin: 0;
  font-size: var(--fs-small);
  color: var(--color-text-muted);
}
.case-modal__headline {
  margin-bottom: var(--space-3);
}
.case-modal__context p {
  color: var(--color-text-muted);
}
.case-modal__section {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}
.case-modal__section h4 {
  margin-bottom: var(--space-2);
}
.case-modal__feedback {
  /* Dark charcoal card, breaking from the rest of the modal's ivory
     sections so the client's own words visually pop instead of reading
     as just another paragraph block. */
  border-top: none;
  padding: var(--space-3);
  border-radius: var(--radius-card);
  background: var(--color-charcoal);
  color: var(--color-ivory);
}
.case-modal__feedback h4 {
  color: var(--color-ivory);
}
.case-modal__feedback .testimonial-card__mark {
  color: var(--color-accent);
  margin-bottom: 4px;
}
.case-modal__feedback p:not(.testimonial-person__name):not(.testimonial-person__role) {
  color: rgba(250, 248, 243, 0.78);
}
.case-modal__feedback .testimonial-person__name {
  color: var(--color-ivory);
}
.case-modal__feedback .testimonial-person__role {
  color: rgba(250, 248, 243, 0.6);
}

@media (max-width: 639px) {
  .case-modal-overlay {
    padding: 0;
    align-items: flex-end;
  }
  .case-modal {
    max-width: none;
    max-height: 92vh;
    border-radius: var(--radius-card) var(--radius-card) 0 0;
    transform: translateY(100%);
  }
  .case-modal-overlay.is-open .case-modal {
    transform: translateY(0);
  }
  .case-modal__name {
    /* At the default --fs-h2 size, the text column beside the logo is too
       narrow for a longer name's second word to fit on its own line — it
       force-breaks mid-word onto a 3rd line with a few hanging letters.
       Sizing down to --fs-h3 keeps names wrapping at word boundaries. */
    font-size: var(--fs-h3);
  }
}

/* ---------- 14. About section ---------- */
#about {
  /* Offsets the anchor-scroll target so the sticky header never covers the
     section heading — same fixed value as #work/#testimonials. */
  scroll-margin-top: 88px;
}

.about-copy h2 { margin-bottom: var(--space-3); }

/* Mobile/tablet: the portrait floats right so paragraph text wraps
   cleanly beside it (with real margin, so text doesn't hug the frame)
   instead of sitting as its own full-width block above or below the copy. */
.about-portrait {
  float: right;
  width: 44%;
  max-width: 260px;
  margin: 0 0 var(--space-3) var(--space-3);
  border-radius: var(--radius-card);
  overflow: hidden;
  aspect-ratio: 3 / 4;
}
.about-portrait__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Biases the crop toward the face/upper body (roughly the upper-middle
     of the source photo) rather than splitting the crop evenly top/bottom. */
  object-position: center 20%;
}

@media (min-width: 1024px) {
  .about-layout {
    display: grid;
    /* ~38% of the row to the portrait column — within the requested
       35-40% range — with the copy column kept comfortably readable. */
    grid-template-columns: 1.6fr 1fr;
    align-items: center;
    gap: var(--space-6);
  }
  /* Portrait is first in source (so the float works below 1024px); `order`
     restores the intended copy-left/portrait-right reading order here. */
  .about-copy { order: 1; }
  .about-portrait {
    order: 2;
    float: none;
    width: auto;
    max-width: none;
    margin: 0;
    aspect-ratio: 4 / 5;
  }
  .about-portrait__img {
    object-position: center top;
  }
}
