/* =========================================================
   ONNA Web Design — Site Stylesheet
   Colors/fonts pulled from global-fonts-colors.txt (real
   brand values from the current WordPress site).
   ========================================================= */

/* ---------- 0. Local fonts (self-hosted, no Google Fonts request) ---------- */
@font-face {
  font-family: 'Comfortaa';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/comfortaa-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Comfortaa';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/comfortaa-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/poppins-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/poppins-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../fonts/poppins-300-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../fonts/poppins-300-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/poppins-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/poppins-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- 1. Brand variables ---------- */
:root {
  /* Colors */
  --color-bg: #ffffff;
  --color-bg-alt: #F7F7F7;
  --color-text: #262424;
  --color-heading: #0C0B0B;
  --color-accent: #229486;      /* decorative accent only — fails AA as small text on white, see note below */
  --color-link: #12566D;
  --color-link-hover: #D46C4E;
  --color-yellow: #EFB000;
  --color-red: #D46C4E;
  --color-red-dark: #BB5438;
  --color-orange: #F9AD6A;

  --color-button: #053C36;      /* per global-fonts-colors.txt */
  --color-button-hover: #BB5438;
  --color-button-text: #ffffff;

  --color-menu-bg: rgba(20, 19, 19, 0.85);  /* #141313 — more visibly transparent per request (was 0.97) */
  --color-menu-bg-hover: #2A2828;            /* lighter than the bg now, so dropdown/mobile item hover still reads as a highlight */
  --color-dark-text: #f2f2f2;
  --color-border: #e2e2e2;

  --color-dark-overlay: rgba(12, 11, 11, 0.7); /* #0C0B0B @ 70% — used over the footer photo and page-hero banners */
  --color-copyright-bg: #262424;
  --color-footer-link: #69EEDF;

  /* Fonts */
  --font-body: 'Poppins', Arial, Helvetica, sans-serif;
  --font-heading: 'Comfortaa', Georgia, 'Times New Roman', serif;
  --fw-heading: 600;

  /* Type scale — rem-based and fluid (clamp) so it scales with the
     viewport instead of jumping at breakpoints. Sized smaller than the
     doc's original em values (h1 was 4em/64px, h2 3em/48px, h3 2em/32px,
     h4 1.5em/24px) per request. */
  --fs-base: 1rem;                                     /* 16px, matches doc's "P 16px" */
  --fs-h1: clamp(2.5rem, 1.8rem + 3vw, 3.75rem);       /* ~40px -> 60px */
  --fs-h2: clamp(1.625rem, 1.3rem + 1.4vw, 2.25rem);   /* ~26px -> 36px */
  --fs-h3: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);     /* ~20px -> 24px */
  --fs-h4: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);    /* ~16px -> 18px */

  /* Layout */
  --container-width: 80rem; /* 1280px */
  --gutter: 1.5rem;         /* 24px */
  --header-height: 5.75rem; /* estimate; js/main.js overwrites this with the
     header's real measured height on load/resize so the hero-overlap below
     lines up exactly even if the header's own sizing changes later */
}

/* ---------- 2. Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  font-weight: 300;
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.6;
}
strong, b { font-weight: 500; }
img { max-width: 100%; height: auto; display: block; }
/* height:auto here is important: images throughout the site carry HTML
   width/height attributes (to prevent layout shift while loading), and
   without an explicit height:auto, a browser renders the image at the
   fixed pixel height from that attribute regardless of how CSS shrinks
   its width — stretching/squishing the photo instead of scaling it. This
   was the real bug behind the Local SEO feature image looking wrong. */
a { color: var(--color-link); text-decoration: none; }
a:hover { color: var(--color-link-hover); }
/* Links inline within body copy (paragraphs and the numbered/bulleted
   .content-list items used on the legal pages, Resources posts, and
   hosting recommendations) need a non-color cue -- underline -- so
   they're distinguishable without relying on color alone (PageSpeed/
   Lighthouse "Links rely on color to be distinguishable" audit). Nav,
   footer, and .btn links are left alone -- they're not standalone
   text sitting inside a sentence, so they don't trigger this audit. */
p a,
.content-list a {
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
ul { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, h4 {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  color: var(--color-heading);
  margin: 0 0 1rem;
  line-height: 1.25;
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h4); }
/* Visually sized like an h3 while staying a real h2 in the markup —
   these three are parallel sections, not subsections, so the tag stays
   h2 for a correct heading outline; only the size changes. */
h2.h2-sm { font-size: var(--fs-h3); }
p { margin: 0 0 1rem; }

.container {
  width: 100%;
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* ---------- 3. Buttons ---------- */
.btn {
  display: inline-block;
  background: var(--color-button-text); /* white/near-white fill, outline style */
  color: var(--color-button);            /* dark green text */
  padding: 0.5rem 1.25rem; /* tightened from 0.75rem/1.75rem — felt clunky in the service cards */
  font-size: 0.9375rem;
  border-radius: 999px; /* pill shape, just to preview — was 0.25rem */
  font-weight: 400;
  border: 1px solid var(--color-button);
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.btn:hover,
.btn:focus-visible {
  background: var(--color-button-hover);
  border-color: var(--color-button-hover);
  color: var(--color-button-text); /* without this, the more specific global a:hover rule was winning and tinting button text */
}

/* ---------- 4. Header / Nav ---------- */
.site-header {
  background: var(--color-menu-bg);
  position: sticky;
  top: 0;
  z-index: 100;
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 0.75rem var(--gutter);
  transition: padding 0.25s ease;
}
.logo {
  flex-shrink: 0; /* without this, the nav crowding it in the flex row
     squished the logo's width while its explicit height held steady, distorting it */
  padding: 0.5rem 0;
  transition: padding 0.25s ease;
}
.logo img {
  height: 3.25rem;
  width: auto;
  transition: height 0.25s ease;
}

/* Shrinks once js/main.js adds this class after a bit of scroll */
.site-header.is-scrolled .header-inner { padding-top: 0.4rem; padding-bottom: 0.4rem; }
.site-header.is-scrolled .logo { padding: 0.2rem 0; }
.site-header.is-scrolled .logo img { height: 2.5rem; }
.main-nav {
  position: relative;
  top: 0.65rem; /* nudged down to visually balance the logo's tall "wings" above its text */
}
.main-nav ul { display: flex; align-items: center; gap: 1.75rem; }
.main-nav a {
  color: var(--color-dark-text);
  font-size: 0.9375rem;
  letter-spacing: 0.02em;
}
.main-nav a:hover { color: var(--color-orange); }
.main-nav a.active,
.main-nav a[aria-current="page"] { color: var(--color-orange); }
.main-nav .has-dropdown { position: relative; }
.main-nav .dropdown-row { display: flex; align-items: center; gap: 0.15rem; }
.main-nav .caret {
  width: 0;
  height: 0;
  border-left: 0.3em solid transparent;
  border-right: 0.3em solid transparent;
  border-top: 0.35em solid currentColor;
  display: inline-block;
}
/* Desktop: the toggle button is only needed for the mobile tap-to-expand
   pattern below — hovering the li already opens the dropdown here. */
.dropdown-toggle {
  /* Visible on desktop too now — it's the only element carrying the
     caret since the restructure, so hiding it by default was hiding the
     whole indicator there, not just the (desktop-unneeded) tap target. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: var(--color-dark-text);
  padding: 0.4rem;
  cursor: pointer;
}
.main-nav .dropdown {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  background: var(--color-menu-bg);
  min-width: 16rem;
  padding: 0.5rem 0;
}
/* :focus-within added so keyboard users (Tab) can reach the dropdown,
   not just mouse/:hover users — full keyboard menu behavior (Esc to
   close, arrow keys) still needs JS and is on the list for later.
   Wrapped in (hover: hover) so a touch device that simulates :hover on
   tap can't fight with the mobile tap-to-expand toggle below. */
@media (hover: hover) {
  .main-nav .has-dropdown:hover .dropdown { display: block; }
}
.main-nav .has-dropdown:focus-within .dropdown { display: block; }
.main-nav .dropdown li a {
  display: block;
  padding: 0.625rem 1.25rem;
  font-size: 0.875rem;
}
.main-nav .dropdown li a:hover,
.main-nav .dropdown li a:focus-visible {
  background: var(--color-menu-bg-hover);
}

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 0.3125rem;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  background: transparent;
  border: none;
  cursor: pointer;
}
.nav-toggle-bar {
  display: block;
  width: 1.5rem;
  height: 0.1875rem;
  background: var(--color-dark-text);
  border-radius: 0.125rem;
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) { transform: translateY(0.5rem) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) { transform: translateY(-0.5rem) rotate(-45deg); }

/* ---------- 5. Hero ---------- */
.hero {
  position: relative;
  overflow: hidden;
  height: clamp(22rem, 26vw + 10rem, 30rem); /* +160px over the previous 12rem-20rem range */
  /* Pulled up under the sticky header (z-index above this) so the header's
     transparent background shows the hero photo from the moment the page
     loads, not just once scrolling starts and something is "stuck" behind it. */
  margin-top: calc(-1 * var(--header-height));
}
.hero img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.hero-mobile { display: none; }

/* Inner-page title banner — same hero photo/crop as the homepage's plain
   .hero above (reuses .hero-desktop/.hero-mobile for the responsive image
   swap), plus a dark overlay and a centered page title on top.
   Unlike .hero, this band doesn't have a fixed height: the image sits
   behind the text as an absolutely-positioned layer, and .page-hero-content
   (in normal flow, with a min-height) is what actually sets the section's
   height. Short titles get exactly the same size as before via that
   min-height; a long title that wraps onto several lines (mobile
   especially) grows the whole band taller instead of getting clipped by
   the header or the image edge. */
.page-hero {
  position: relative;
  overflow: hidden;
  margin-top: calc(-1 * var(--header-height)); /* same reasoning as .hero above */
}
.page-hero img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.page-hero-overlay {
  position: absolute;
  inset: 0;
  background: var(--color-dark-overlay);
}
.page-hero-content {
  position: relative;
  min-height: clamp(15.75rem, 26vw + 3.75rem, 23.75rem); /* same curve as .hero, shifted down 6.25rem (~100px) */
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  /* Top padding equal to the header height shrinks the flex-centering box
     down to just the visible portion of the hero (below the transparent
     header that now overlaps it) — without this, the title centers on the
     full hero including the strip hidden behind the header, so it reads
     as sitting too high. */
  padding: var(--header-height) var(--gutter) 0;
}
/* Smaller than the sitewide --fs-h1 scale on purpose — a title sitting
   alone in a hero band reads oversized at the same size that works for
   a page's first on-page heading, especially once a long title wraps
   onto several lines. */
.page-hero-content h1 {
  color: var(--color-dark-text);
  margin: 0;
  font-size: clamp(2rem, 1.5rem + 2.4vw, 3rem); /* ~32px -> 48px, vs. --fs-h1's ~40px -> 60px */
}

/* Extra breathing room directly under the hero on every page — targets
   whatever section actually follows the hero (intro, feature, or a plain
   content-section), so it stays consistent no matter which one it is. */
.hero + section,
.page-hero + section {
  padding-top: 5rem;
}

/* ---------- 6. Intro ---------- */
.intro {
  text-align: center;
  padding: 3rem var(--gutter) 1.75rem;
  max-width: 65rem;
  margin: 0 auto;
}
.lede {
  font-size: clamp(1.25rem, 1.05rem + 0.8vw, 1.5rem); /* was inheriting the 1rem body size */
  line-height: 1.4; /* was inheriting the body's 1.6, too loose at this larger size */
}
/* A small, quieter aside under an .intro heading — e.g. the "rebus
   lovers" line on Web Design Services — not a second lede. */
.intro-note {
  font-size: 0.9375rem;
  color: #5c5959; /* lighter than body text, still passes AA at this size */
}

/* ---------- 7. Feature rows (image + text) ---------- */
.feature {
  display: flex;
  align-items: center;
  gap: 3rem;
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 3rem var(--gutter) 1.5rem;
}
/* ...and less top padding on whatever full-width section follows it,
   since the feature row and the next section usually continue the same
   thought (e.g. Local SEO's feature + services list). */
.feature + .content-section {
  padding-top: 1rem;
}
/* ...and the same going the other way — a short heading-only
   content-section (e.g. WordPress Security's intro) directly above a
   feature row shouldn't leave a big double-padding gap either. */
.content-section + .feature {
  padding-top: 1rem;
}
/* ...and the same when a plain .content-section (not a .feature row)
   follows the intro directly — e.g. Website Hosting's "So you have a
   shiny new website..." intro into its first content-section. Without
   this, .content-section's own 3rem top padding stacked on top of
   .intro's own bottom padding, reading as noticeably more white space
   than other pages get after their intro (e.g. Web Design Services,
   whose .services-grid-section is already tuned to 1rem here). Scoped to
   .content-section specifically (not a bare "+ section") so it doesn't
   also catch My Work's .portfolio-intro, which deliberately sits flush
   against its heading with no top padding of its own. */
.intro + .content-section {
  padding-top: 1rem;
}
/* ...and the same when two plain (non-alt) content-sections stack back
   to back with no background change between them to signal a break
   (e.g. WordPress Security's static-conversion pitch right after its
   $30/month explanation) -- without an alt background doing some of the
   work, the full 3rem+3rem gap reads as an unexplained gap rather than
   a new section. Scoped to plain-on-plain only, since a transition into
   or out of .content-section--alt already gets a visual break from the
   background color change and doesn't need the padding tightened too
   (see Website Hosting's alternating sections). */
.content-section:not(.content-section--alt) + .content-section:not(.content-section--alt) {
  padding-top: 0;
}
.feature--reverse { flex-direction: row-reverse; }
/* About Me: the media column (heading + 3 stacked photos) runs taller
   than the story text next to it — top-align both columns instead of
   the usual vertical centering, so they start flush together like the
   original. */
.feature--top { align-items: flex-start; }
.feature .feature-media,
.feature .feature-text { flex: 1 1 0; }
.feature .feature-media img { /* square corners, per site-wide image convention */ }
/* For a photo paired with a short paragraph, the image (at full column
   width) can end up much taller than the text next to it, since the two
   columns split the row evenly regardless of content length. Rather than
   inset the image within its column (which left visible gutters beside
   it), this gives the column itself less width — the image still fills
   its column edge-to-edge at its exact native ratio, just a smaller
   column, so the result is shorter without looking padded/narrowed. */
.feature .feature-media--narrow { flex: 0 1 40%; } /* matches .feature .feature-media's specificity so it actually wins */
/* A button paired with a feature image (e.g. Local SEO's right-hand
   column) sits centered below it, not stretched full width. */
.feature-media .btn {
  display: block;
  width: fit-content;
  margin: 1.25rem auto 0;
}
/* About Me: a heading plus three stacked photos in the media column,
   instead of the usual single image. */
.feature-media--stacked h4 {
  margin-bottom: 1.25rem;
}
.feature-media--stacked img {
  margin-bottom: 1.25rem;
}
.feature-media--stacked img:last-child {
  margin-bottom: 0;
}
/* Contact Me: a short centered caption below the photo (Ted's "what
   are you waiting for?" line). */
.feature-media-caption {
  margin-top: 1.25rem;
  text-align: center;
  font-size: 0.9375rem;
  color: var(--color-text);
  opacity: 0.75;
}
/* Scoped to just the one opening paragraph that's marked up with
   class="lead" — not every .feature-text paragraph. */
.feature-text p.lead {
  font-weight: 500;
  font-size: 1.125rem;
}
/* ---------- 8. Services grid ---------- */
.services-grid-section { padding: 1rem 0 5rem; }
.services-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5rem 2.5rem;
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.service-card {
  text-align: center;
  min-width: 0; /* stops a grid item from refusing to shrink below its
     image's intrinsic width, which was letting the image edge run past
     the card and look clipped by the column next to it */
}
.service-card img {
  /* Native 2:1 (800x400) ratio, no forced aspect-ratio/object-fit — width
     100% with height auto just follows the image's own intrinsic ratio
     (from its width/height attributes), so there's no cropping and no
     letterbox gap since the box and the photo always match exactly. */
  width: 100%;
  height: auto;
  margin-bottom: 0.75rem;
}

/* ---------- 9. Content sections (body copy: lists, etc.) ---------- */
.content-section {
  padding: 3rem 0; /* was 1rem/5rem, tuned for one centered section — too
     much cumulative whitespace once several of these stack in a row */
}
.content-section--alt { background: var(--color-bg-alt); } /* alternating
     stripe so several stacked content-sections (e.g. Domains/Hosting/...)
     read as distinct blocks without needing extra empty space */
.content-section .container { max-width: 65rem; } /* was 55rem — widened a bit so the gap next to the 80rem two-column .feature width doesn't read as jarring; matches .intro/.cta-banner's narrowed width */
.content-section > .container > h2 { text-align: center; margin-bottom: 2rem; }

/* 404 page */
.error-code {
  font-family: var(--font-heading);
  font-weight: var(--fw-heading);
  font-size: clamp(3.5rem, 2.5rem + 4vw, 6rem);
  line-height: 1;
  color: var(--color-heading);
  text-align: center;
  margin: 0 0 0.5rem;
}
.content-section > .container > .error-code + h2 { margin-top: 0; }
/* WordPress Security's heading-only intro sits directly above its
   feature row with nothing else in between, so it needs a good deal
   less bottom padding and heading margin than the default centered
   heading section (which usually has body copy following it). */
.content-section--tight-bottom {
  padding-bottom: 1.5rem;
}
.content-section--tight-bottom > .container > h2 {
  margin-bottom: 0;
}
/* Terms of Service: a long run of clause headings, not one centered
   section title, so they stay left-aligned like the body copy and get
   real spacing above each one to separate one clause from the next. */
.content-section--legal > .container > h2 {
  text-align: left;
  font-size: var(--fs-h3); /* visually an h3 — full h2 size read too large for
     a long run of clause headings this close together, but they stay real
     h2 markup since they're the top-level heading under the page's h1 */
  margin: 2rem 0 1rem;
}
/* Web Accessibility: a single, full-size h2 section title that the
   original (and its ada.gov source content) sets left-aligned rather
   than centered. */
.content-section--heading-left > .container > h2 {
  text-align: left;
}
/* Several h3 topic breaks stack in a row on this page (Examples of
   Barriers, When the ADA Requires..., How to Make Content Accessible,
   The bottom line) — give each one real separation from what's above it. */
.content-section > .container > h3 {
  margin-top: 2.5rem;
}
.content-section > .container > h4 {
  margin-top: 1.5rem;
}
/* ...except when the h3/h4 is the section's OPENING heading (its
   container's first child) rather than a sub-heading breaking up
   content further down -- the section's own top padding already
   provides that separation, so this top margin would just be extra,
   unaccounted-for space on top of it (e.g. WordPress Security's
   "Sign Up Today!" and its static-conversion pitch heading). */
.content-section > .container > h3:first-child,
.content-section > .container > h4:first-child {
  margin-top: 0;
}
/* A sub-list nested inside a .content-list item (e.g. the three form
   requirements under "Inaccessible online forms") — same square-bullet
   treatment, just indented an extra step and tightened up since it's a
   short list within a longer one. */
.content-list .content-list--nested {
  margin-top: 0.75rem;
}
.content-list--nested li {
  margin-bottom: 0.5rem;
}
.content-section > .container > h3,
.content-section > .container > h4 { margin-bottom: 1.25rem; }
.content-section > .container > .btn { display: block; width: fit-content; margin: 0 auto; }
/* WordPress Security's static-conversion CTA button needed a bit more
   room before the alt-background Sign Up section right after it. */
.content-section--conversion-offer > .container > .btn {
  margin-bottom: 2rem;
}

.content-list { margin: 0 0 2rem; padding: 0; }
.content-list li {
  position: relative;
  padding-left: 1.5rem;
  margin-bottom: 1.25rem;
}
/* Only unordered lists get the square in place of a bullet. An <ol>
   keeps its own numbers instead, so a numbered step never shows a
   number AND a square together. */
.content-list:not(ol) li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 0.5rem;
  height: 0.5rem;
  background: var(--color-accent);
}
/* Ordered lists: give the browser's own numbers a normal left gutter
   instead of the square's left:0 gutter reserved above. */
ol.content-list {
  padding-left: 1.5rem;
  list-style-position: outside;
}
ol.content-list > li {
  padding-left: 0.25rem;
}
.content-list strong { color: var(--color-heading); font-weight: 500; }

/* ---------- 10. CTA banner ---------- */
.cta-banner {
  background: var(--color-bg-alt);
  text-align: center;
  padding: 5rem var(--gutter) 3.5rem;
}
.cta-banner .container {
  /* narrowed for readability, same reasoning as .intro/.portfolio-intro —
     scoped to this section rather than the shared .container class, which
     the portfolio gallery grid also uses and needs to stay full width */
  max-width: 65rem;
}

/* Pricing: a row of 3 square example-site screenshots, each linking out
   to the live client site (no lightbox — unlike the My Work gallery,
   these exist to prove the price point, not to be browsed in place). */
.pricing-examples {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
  margin-top: 2rem;
}
.pricing-examples a {
  display: block;
  line-height: 0;
  transition: opacity 0.2s ease;
}
.pricing-examples a:hover,
.pricing-examples a:focus-visible {
  opacity: 0.85;
}
.pricing-examples img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}
@media (max-width: 700px) {
  .pricing-examples {
    grid-template-columns: 1fr;
    max-width: 26rem;
    margin-left: auto;
    margin-right: auto;
  }
}

/* Space the closing CTA button off the example grid above it. */
.content-section > .container > .pricing-examples + .btn {
  margin-top: 3rem;
}

/* Extra breathing room above the footer on every page — targets the
   last section in <main> directly (whatever type it happens to be),
   rather than the footer itself, so the added space sits with the
   content it's separating rather than inside the footer band. */
main > section:last-child {
  padding-bottom: 6rem;
}

/* ---------- 11. Footer ---------- */
.site-footer {
  color: var(--color-dark-text);
}
.footer-top {
  /* full-width image band above the copyright bar; background lives here
     (not on .footer-columns) so "center bottom" shows the true bottom of
     the photo right above .footer-bottom, instead of being covered by it */
  padding: 10rem 0; /* +80px top and bottom, same as before */
  background-image: linear-gradient(var(--color-dark-overlay), var(--color-dark-overlay)), url('../images/footer-ted-01.webp');
  background-size: cover;
  background-position: center bottom;
}
.footer-columns {
  display: flex;
  align-items: center;
  gap: 4rem;
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
.footer-columns h3 a { color: var(--color-orange); }
.footer-columns p a { color: var(--color-footer-link); }
.footer-columns a:hover { color: var(--color-orange); }
.footer-columns p { font-size: 0.9375rem; }
.footer-contact {
  flex-shrink: 0;
  min-width: 14rem; /* keeps "Email: address" from wrapping when About Me is wide */
}
.footer-contact p {
  margin: 0 0 0.375rem;
  white-space: nowrap;
}
.footer-contact p:last-child { margin-bottom: 0; }
.footer-bottom {
  background: var(--color-copyright-bg);
  padding: 1.25rem 0;
  font-size: 0.8125rem;
}
.footer-bottom-inner {
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 2rem; /* space between the copyright text and the links */
}
.footer-bottom p { margin: 0; } /* the global "p" rule adds a 1rem bottom margin, which was
   throwing off align-items: center against the nav links next to it */
.footer-bottom nav ul { display: flex; gap: 1rem; }
.footer-bottom a { color: var(--color-orange); }
.footer-bottom a:hover { color: var(--color-link-hover); }
/* ---------- 12. Portfolio gallery ---------- */
.portfolio-intro {
  text-align: center;
  padding: 0 var(--gutter) 2.5rem;
  max-width: 65rem;
  margin: 0 auto;
}
.portfolio-intro p:last-child { margin-bottom: 0; }

.portfolio-gallery { padding: 0 0 5rem; }

/* CSS grid "masonry" — a fine-grained row unit (grid-auto-rows) plus a
   small JS pass (see main.js) that gives each item a grid-row-end span
   sized to its own rendered height. Unlike CSS-columns (which fills one
   whole column top-to-bottom before starting the next, so the code order
   reads down each column instead of across), grid auto-placement fills
   left-to-right/top-to-bottom the same way normal reading order does —
   so the item order in the HTML matches the order they appear on the
   page, which matters a lot with 30+ portfolio pieces to reorder. */
.masonry {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 1px;
  column-gap: 1.25rem; /* 20px, matches the original gallery's spacing */
  row-gap: 1.25rem;
}
.portfolio-item {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  overflow: hidden;
  position: relative;
  cursor: zoom-in;
}
.portfolio-item img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform 0.3s ease;
}
.portfolio-item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(12, 11, 11, 0);
  transition: background 0.2s ease;
}
.portfolio-item:hover::after,
.portfolio-item:focus-visible::after { background: rgba(12, 11, 11, 0.25); }
.portfolio-item:hover img,
.portfolio-item:focus-visible img { transform: scale(1.04); }
.portfolio-item:focus-visible {
  outline: 3px solid var(--color-yellow);
  outline-offset: 2px;
}

/* ---------- 13. Lightbox ---------- */
.lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(12, 11, 11, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3.5rem var(--gutter) 2rem;
  z-index: 200;
}
.lightbox-overlay[hidden] { display: none; }
.lightbox-box {
  position: relative;
  width: 100%;
  max-width: 46rem;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.lightbox-img-wrap {
  width: 100%;
  max-height: 68vh;
  overflow: auto; /* full-page screenshots are taller than the viewport
     even scaled down, so the frame scrolls instead of squashing the image */
  background: var(--color-bg);
}
.lightbox-img-wrap img { width: 100%; height: auto; display: block; }
.lightbox-caption { text-align: center; margin-top: 1.25rem; }
.lightbox-visit {
  /* Pill button styled to match .lightbox-nav (the prev/next arrow
     buttons) — same translucent fill, border, and hover state — so
     the caption reads as one consistent set of on-image controls. */
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.75rem;
  border-radius: 999px;
  background: rgba(242, 242, 242, 0.12);
  border: 1px solid rgba(242, 242, 242, 0.4);
  color: var(--color-dark-text);
  font-weight: 500;
  transition: background 0.2s ease;
}
.lightbox-visit:hover, .lightbox-visit:focus-visible {
  background: rgba(242, 242, 242, 0.28);
  color: var(--color-dark-text); /* without this, the global a:hover rule wins and tints the text — same fix as .btn */
}
.lightbox-visit-arrow { color: var(--color-yellow); font-size: 1.15em; line-height: 1; }
.lightbox-close,
.lightbox-nav {
  position: absolute;
  background: rgba(242, 242, 242, 0.12);
  border: 1px solid rgba(242, 242, 242, 0.4);
  color: var(--color-dark-text);
  border-radius: 50%;
  width: 2.5rem;
  height: 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease;
}
.lightbox-close:hover, .lightbox-close:focus-visible,
.lightbox-nav:hover, .lightbox-nav:focus-visible { background: rgba(242, 242, 242, 0.28); }
.lightbox-close { top: -3.25rem; right: 0; }
/* .lightbox-prev/.lightbox-next are now direct children of .lightbox-overlay
   (not .lightbox-box), so these offsets sit relative to the viewport-wide
   overlay instead of hugging the image edge — clear of the photo at any
   image width, and never overlapping it. */
.lightbox-nav { top: 50%; transform: translateY(-50%); }
.lightbox-prev { left: 1rem; }
.lightbox-next { right: 1rem; }

/* ---------- 14. Responsive ----------
   Breakpoints use em on purpose (not rem/px): em in a media query tracks
   the browser's default font size regardless of any rem redefinition on
   the page, which is the more reliable unit for this specific spot. */
@media (max-width: 56.25em) { /* 900px */
  .feature, .feature--reverse { flex-direction: column; }
  .footer-columns { flex-direction: column; gap: 2rem; }
  .masonry { grid-template-columns: repeat(3, 1fr); }
  .services-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 40em) { /* 640px */
  .masonry { grid-template-columns: repeat(2, 1fr); }
  .services-grid { grid-template-columns: 1fr; }
}

@media (max-width: 56.25em) { /* 900px — matches the feature-row/footer breakpoint above */
  .nav-toggle { display: flex; }
  .main-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--color-menu-bg);
    padding: 0.5rem var(--gutter) 1rem;
  }
  .main-nav.is-open {
    display: block;
    /* In landscape on a phone (short viewport), the fully-expanded menu —
       especially with the Resources dropdown open — can be taller than
       the screen. Without a height cap the menu (an absolutely-positioned
       overlay) just grows past the viewport and the whole PAGE scrolls to
       reveal the rest of it. Capping its height and scrolling internally
       keeps the scroll gesture on the menu, where a thumb expects it. */
    max-height: calc(100vh - var(--header-height));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .main-nav ul {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }
  .main-nav li { width: 100%; }
  .main-nav > ul > li > a { display: block; padding: 0.75rem 0; }

  .main-nav .dropdown-row > a { flex: 1 1 auto; padding: 0.75rem 0; }
  .dropdown-toggle { display: flex; align-items: center; justify-content: center; }
  .dropdown-toggle .caret { transition: transform 0.2s ease; }
  .dropdown-toggle[aria-expanded="true"] .caret { transform: rotate(180deg); }

  /* Collapsed by default on mobile — the toggle button (not :hover, which
     doesn't exist on touch) reveals it via the .is-open class from JS. */
  .main-nav .has-dropdown .dropdown {
    display: none;
    position: static;
    min-width: auto;
    padding: 0 0 0.5rem 1rem;
  }
  .main-nav .has-dropdown .dropdown.is-open { display: block; }
  .main-nav .has-dropdown .dropdown li a { padding: 0.5rem 0; }

  .hero-desktop { display: none; }
  .hero-mobile { display: block; }
}

/* ---------- 15. Mobile spacing & footer stacking ----------
   Desktop section padding (3-10rem top/bottom) reads as excessive dead
   space once the page is this narrow, and the footer needs real block
   stacking here (not its desktop flex row) for both the About Me/Contact
   columns and the legal links to read cleanly on a phone. Same 900px
   breakpoint the nav/.footer-columns switch over at above, so "mobile"
   means the same thing everywhere in this file. */
@media (max-width: 56.25em) { /* 900px */
  .hero + section,
  .page-hero + section { padding-top: 3rem; }
  .intro { padding: 2rem var(--gutter) 1.25rem; }
  .feature, .feature--reverse { gap: 2rem; padding: 2rem var(--gutter) 1rem; }
  .content-section { padding: 2rem 0; }
  .content-section--tight-bottom { padding-bottom: 1rem; }
  .services-grid-section { padding-bottom: 3rem; }
  .cta-banner { padding: 3rem var(--gutter) 2rem; }
  .portfolio-gallery { padding-bottom: 3rem; }
  main > section:last-child { padding-bottom: 3rem; }

  /* About Me / Contact: full-width stacked blocks instead of narrow
     centered ones (the desktop row's align-items:center and
     .footer-contact's min-width just look off once .footer-columns
     is a single column). */
  .footer-top { padding: 3.5rem 0; }
  .footer-columns { align-items: stretch; text-align: left; }
  .footer-contact { min-width: 0; }
  .footer-contact p { white-space: normal; }

  /* Copyright text and the legal links each get their own centered
     row instead of squeezing onto one horizontal line. */
  .footer-bottom-inner { flex-direction: column; gap: 0.75rem; text-align: center; }
  .footer-bottom nav ul { flex-wrap: wrap; justify-content: center; gap: 0.5rem 1rem; }
}
