/* ==========================================================================
   Income Outsource — Base Styles
   Minimal hand-written reset + typography wired to variables.css
   ========================================================================== */

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

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

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--color-text);
  background: var(--color-bg);
  font-weight: var(--fw-regular);
  letter-spacing: var(--ls-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img,
picture,
video,
svg {
  display: block;
  max-width: 100%;
  height: auto;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
  color: var(--color-primary);
  margin: 0 0 var(--space-4);
}

h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); }
h4 { font-size: var(--fs-h4); }
h5 { font-size: var(--fs-h5); }
h6 { font-size: var(--fs-h6); }

p {
  margin: 0 0 var(--space-4);
}

small {
  font-size: var(--fs-small);
}

a {
  color: var(--color-link);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease-standard);
}

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

ul, ol {
  margin: 0 0 var(--space-4);
  padding-left: var(--space-5);
}

button, input, select, textarea {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

button {
  cursor: pointer;
  /* Without an explicit appearance/background, browsers can auto-paint
     native dark-mode chrome (OS accent color) onto unstyled buttons.
     Resetting to plain + none lets every component's own background win. */
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: none;
}

/* ---------------------------------------------------------------------
   Shared button component — used on both <a> (pages.css: Write For Us,
   Contact CTAs) and real <button> elements (single.css: sidebar toggle).
   Lives here, not in a page-specific stylesheet, since base.css is the
   one file enqueued on every template. :focus/:active are covered
   explicitly alongside :hover/:focus-visible — Astra's parent stylesheet
   paints its own accent-blue on a real <button>'s plain :focus/:active
   (mouse clicks trigger :focus, not :focus-visible), a conflict already
   documented in CLAUDE.md for the theme toggle and mobile hamburger.
   --------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-6);
  font-family: var(--font-heading);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    border-color var(--duration-fast) var(--ease-standard),
    color var(--duration-fast) var(--ease-standard);
}

.btn--accent {
  color: var(--color-text-inverse);
  background: var(--color-accent);
}

.btn--accent:hover,
.btn--accent:focus-visible,
.btn--accent:focus,
.btn--accent:active {
  color: var(--color-text-inverse);
  background: var(--color-accent-hover);
}

.btn--ghost {
  color: var(--color-primary);
  background: transparent;
  border-color: var(--color-border-strong);
}

.btn--ghost:hover,
.btn--ghost:focus-visible,
.btn--ghost:focus,
.btn--ghost:active {
  color: var(--color-accent-hover);
  /* Explicit background, not just inherited from the base rule above:
     Astra's parent stylesheet has its own button:hover rule that sets
     background-color to var(--ast-global-color-1), which resolves to a
     blue (#045cb4) — an element+pseudo-class selector that outranks our
     unqualified .btn--ghost base rule (which never redeclares background
     at :hover) for that one property, even though our class-based :hover
     rule otherwise wins on color/border-color. Only bites real <button>
     elements (the anchor-based .btn usages elsewhere never triggered
     this, since Astra's rule doesn't match <a>). Redeclaring background
     here pins it regardless. */
  background: transparent;
  border-color: var(--color-accent);
}

.btn--ink {
  color: var(--color-on-ink);
  background: var(--color-ink);
}

.btn--ink:hover,
.btn--ink:focus-visible,
.btn--ink:focus,
.btn--ink:active {
  background: var(--color-ink-light);
}

.btn--ghost-inverse {
  color: var(--color-on-ink);
  background: transparent;
  border-color: var(--color-ink-light);
}

.btn--ghost-inverse:hover,
.btn--ghost-inverse:focus-visible,
.btn--ghost-inverse:focus,
.btn--ghost-inverse:active {
  /* Same reasoning as .btn--ghost above — explicit background needed to
     beat Astra's button:hover background-color rule on real <button>s. */
  background: transparent;
  border-color: var(--color-on-ink);
}

::selection {
  background: var(--color-accent);
  color: var(--color-text-inverse);
}

/* ---------------------------------------------------------------------
   Shared search form component — used by searchform.php (get_search_form())
   everywhere: the header search panel, the footer, and search.php/404.php's
   own hero. Lives here rather than a page-specific stylesheet, same
   reasoning as .btn above — it needs to be available on every template,
   not just the archive/search/404 ones.
   --------------------------------------------------------------------- */
.search-form-custom {
  display: flex;
  align-items: stretch;
  gap: var(--space-2);
}

/* input[type="search"] in the selector, not just the class, is required
   here — Astra prints a dynamic inline <style> block (Customizer CSS,
   same pattern documented in CLAUDE.md's Astra conflicts) with its own
   `input[type="search"]{padding:12px 16px}` rule. That's a type+attribute
   selector, higher specificity than a plain class alone, so it silently
   overrode our height/padding below regardless of our stylesheet's load
   order. Matching its specificity is what actually wins. */
input[type="search"].search-form-custom__input {
  flex: 1;
  min-width: 0;
  /* Explicit height, not just padding + align-items:stretch on the parent
     — form controls don't reliably stretch to fill a flex container's
     cross size the way plain block elements do, so the input rendered a
     few px shorter than the 48px submit button next to it. Matching the
     button's height directly guarantees they're equal regardless of that
     quirk. */
  height: 48px;
  padding-inline: var(--space-4);
  padding-block: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  color: var(--color-text);
  background: var(--color-surface-1);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  transition: border-color var(--duration-fast) var(--ease-standard);
}

input[type="search"].search-form-custom__input:hover {
  border-color: var(--color-border-strong);
}

input[type="search"].search-form-custom__input:focus-visible {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: var(--shadow-focus);
  /* Astra's inline Customizer CSS also sets background-color on
     input[type="search"]:focus — same specificity conflict as the base
     rule above, redeclared explicitly here to keep it consistent through
     focus, not just at rest. */
  background: var(--color-surface-1);
}

.search-form-custom__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  padding: 0;
  color: var(--color-text-inverse);
  background: var(--color-accent);
  border-radius: var(--radius-md);
  transition: background-color var(--duration-fast) var(--ease-standard);
}

.search-form-custom__submit:hover,
.search-form-custom__submit:focus-visible,
.search-form-custom__submit:focus,
.search-form-custom__submit:active {
  background: var(--color-accent-hover);
}

.search-form-custom__submit svg {
  width: 20px;
  height: 20px;
}

/* Accessible focus rings — never remove outline without a replacement */
:focus {
  outline: none;
}

:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
  border-radius: var(--radius-sm);
}

/* ---------------------------------------------------------------------
   Neutralize Astra's "Separate Containers" layout backgrounds.
   Astra's core CSS paints these wrapper elements directly
   (.ast-separate-container / .ast-article-post / .ast-article-single),
   at a specificity that beats a plain `body` rule — without this they
   show through as a fixed light gray/white regardless of theme. Matching
   selectors here (loaded after Astra's stylesheet) lets our page
   background win in both themes; !important guards the one selector
   Astra scopes with :not(), which we can't specificity-match safely.
   --------------------------------------------------------------------- */
.ast-separate-container,
.ast-separate-container .ast-article-post,
.ast-separate-container .ast-article-single,
.ast-separate-container .error-404,
.ast-separate-container .no-results {
  background-color: var(--color-bg) !important;
}

/* Same problem, different selector: Astra colors the comments module with
   its own global color swatch (fixed white), independent of the article
   background rule above. Card-tinted here (matches the TOC/blockquote
   treatment) rather than flat, so the module reads as a deliberate block. */
.ast-separate-container .comments-area,
.ast-separate-container .comments-count-wrapper {
  background-color: var(--color-card-bg) !important;
}

/* Third variant of the same conflict, found on static pages (plan 09):
   Astra's "Plain Container" layout — used by page.php and the
   page-templates/* templates, body class `ast-plain-container` instead of
   `ast-separate-container` — paints its own fixed-white background via
   Astra's *dynamic* Customizer CSS (`--ast-global-color-4`, generated
   per-request and printed inline in <head>, so it never shows up in the
   static compiled stylesheet — check the rendered page's inline
   `#astra-theme-css-inline-css` block, not just main.min.css, when hunting
   this pattern down again). That rule targets `.ast-plain-container`
   directly on <body> plus `.ast-plain-container .site-content`, both class
   selectors that beat our plain `body` rule in base.css regardless of load
   order. Same fix as above: match the selector, load after Astra's inline
   block (enqueue order already guarantees this), let our variable win. */
.ast-plain-container,
.ast-plain-container .site-content {
  background-color: var(--color-bg) !important;
}

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

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

/* Skip-to-content link — reuses .screen-reader-text's off-screen clip, but
   overrides it back into view on focus so keyboard users can see and use it
   before tabbing through the whole header. */
.skip-link:focus {
  position: fixed;
  top: var(--space-3);
  left: var(--space-3);
  z-index: var(--z-skip-link);
  width: auto;
  height: auto;
  padding: var(--space-3) var(--space-5);
  margin: 0;
  overflow: visible;
  clip: auto;
  white-space: normal;
  font-family: var(--font-heading);
  font-weight: var(--fw-semibold);
  color: var(--color-text-inverse);
  background: var(--color-accent);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}

/* Respect reduced-motion preference — neutralize animation/transition */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
