/* ABOUTME: Component styles for the Plumbline theme. */
/* ABOUTME: Buttons, UI primitives, and reusable visual patterns. */

@layer components {
  /* Buttons */
  .pl-button,
  .wp-block-button__link {
    display: inline-flex;
    align-items: center;
    gap: var(--pl-space-2);
    padding: var(--pl-space-3) var(--pl-space-5);
    font-family: var(--pl-font-body);
    font-size: var(--pl-text-base);
    font-weight: var(--pl-weight-semibold);
    line-height: var(--pl-leading-tight);
    text-decoration: none;
    border-radius: var(--pl-radius-md);
    border: var(--pl-border-medium) solid transparent;
    cursor: pointer;
    transition:
      background-color var(--pl-duration-fast) var(--pl-easing-default),
      border-color var(--pl-duration-fast) var(--pl-easing-default),
      color var(--pl-duration-fast) var(--pl-easing-default),
      box-shadow var(--pl-duration-fast) var(--pl-easing-default);
  }

  /* Primary button (default) */
  .pl-button,
  .wp-block-button:not(.is-style-secondary):not(.is-style-outline):not(.is-style-text-link) .wp-block-button__link,
  .wp-block-button.is-style-primary .wp-block-button__link {
    background-color: var(--pl-color-primary);
    color: var(--pl-color-text-inverse);
    border-color: var(--pl-color-primary);
  }

  .pl-button:hover,
  .wp-block-button:not(.is-style-secondary):not(.is-style-outline):not(.is-style-text-link) .wp-block-button__link:hover,
  .wp-block-button.is-style-primary .wp-block-button__link:hover {
    background-color: var(--pl-color-primary-dark);
    border-color: var(--pl-color-primary-dark);
    color: var(--pl-color-text-inverse);
  }

  /* Secondary button — neutral semantic, not brand amber */
  .wp-block-button.is-style-secondary .wp-block-button__link {
    background-color: var(--pl-color-button-secondary-bg);
    color: var(--pl-color-button-secondary-text);
    border-color: var(--pl-color-button-secondary-border);
    border-width: var(--pl-border-thin);
  }

  .wp-block-button.is-style-secondary .wp-block-button__link:hover {
    background-color: var(--pl-color-button-secondary-bg-hover);
    border-color: var(--pl-color-button-secondary-border);
    color: var(--pl-color-button-secondary-text);
  }

  /* Outline button */
  .wp-block-button.is-style-outline .wp-block-button__link {
    background-color: transparent;
    color: var(--pl-color-primary);
    border-color: var(--pl-color-primary);
  }

  .wp-block-button.is-style-outline .wp-block-button__link:hover {
    background-color: var(--pl-color-primary);
    color: var(--pl-color-text-inverse);
  }

  /* Text link button */
  .wp-block-button.is-style-text-link .wp-block-button__link {
    background-color: transparent;
    color: var(--pl-color-text-link);
    border-color: transparent;
    border-radius: 0;
    padding: 0;
    font-weight: var(--pl-weight-semibold);
    text-decoration-line: underline;
    text-decoration-color: var(--pl-link-underline-color);
    text-decoration-thickness: var(--pl-link-underline-thickness);
    text-underline-offset: var(--pl-link-underline-offset);
    text-decoration-skip-ink: auto;
    transition:
      color var(--pl-duration-fast) var(--pl-easing-default),
      text-decoration-color var(--pl-duration-fast) var(--pl-easing-default),
      text-decoration-thickness var(--pl-duration-fast) var(--pl-easing-default);
  }

  .wp-block-button.is-style-text-link .wp-block-button__link:hover {
    color: var(--pl-color-text-link-hover);
    text-decoration-color: var(--pl-link-underline-color-hover);
    text-decoration-thickness: var(--pl-link-underline-thickness-hover);
  }

  /* White / dark / white ring (base.css). Restated at component level so button
     rules that set their own outline or shadow can't drop part of it. */
  .pl-button:focus-visible,
  .wp-block-button__link:focus-visible,
  .wp-element-button:focus-visible {
    outline: var(--pl-focus-ring-width) solid var(--pl-focus-ring-dark);
    outline-offset: var(--pl-focus-ring-offset);
    box-shadow: 0 0 0 calc(var(--pl-focus-ring-offset) + var(--pl-focus-ring-width) + 2px) var(--pl-focus-ring-light);
  }

  /* ========================================
     New-tab link cue (WCAG 3.2.5 / G201)
     ======================================== */

  /*
   * Visible external-link glyph after text links that open a new tab. The spoken cue is
   * aria-describedby="pl-new-tab-hint" (inc/links/external-links.php). The glyph is a
   * mask on an empty ::after, so it adds nothing to the link's accessible name.
   * It is an inline box with padding rather than an inline-block: that leaves no line
   * break opportunity before it, so it never wraps onto a line by itself.
   * Scoped to links inside running text; skipped for buttons, menu parents (caret
   * ::after), and links wrapping media. Opt out with .pl-no-new-tab-icon on the link
   * or any ancestor.
   */
  :is(p, li, dd, dt, td, th, figcaption, blockquote, cite, address, h1, h2, h3, h4, h5, h6) a[target="_blank"]:not(.pl-no-new-tab-icon, .pl-no-new-tab-icon *, .wp-element-button, .wp-block-button__link, .menu-item-has-children > a, :has(img, svg, picture, video, iframe, canvas))::after {
    --pl-new-tab-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3Cpath d='M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z'/%3E%3C/svg%3E");

    content: "";
    padding-inline-start: 1em;
    background-color: currentColor;
    -webkit-mask: var(--pl-new-tab-glyph) right 55% / 0.72em 0.72em no-repeat;
    mask: var(--pl-new-tab-glyph) right 55% / 0.72em 0.72em no-repeat;
  }

  @media (forced-colors: active) {
    :is(p, li, dd, dt, td, th, figcaption, blockquote, cite, address, h1, h2, h3, h4, h5, h6) a[target="_blank"]:not(.pl-no-new-tab-icon, .pl-no-new-tab-icon *, .wp-element-button, .wp-block-button__link, .menu-item-has-children > a, :has(img, svg, picture, video, iframe, canvas))::after {
      forced-color-adjust: none;
      background-color: LinkText;
    }
  }

  /* Image styles */
  .wp-block-image.is-style-rounded img {
    border-radius: var(--pl-radius-lg);
  }

  .wp-block-image.is-style-shadow img {
    box-shadow: var(--pl-shadow-md);
  }

  /* Separator styles */
  .wp-block-separator.is-style-subtle {
    opacity: 0.5;
  }

  .wp-block-separator.is-style-accent {
    border-color: var(--pl-color-primary);
  }

  /* Quote accent-border style */
  .wp-block-quote.is-style-accent-border {
    border-left-color: var(--pl-color-secondary);
  }

  /* ========================================
     Back to Top
     ======================================== */

  .pl-back-to-top {
    position: fixed;
    bottom: var(--pl-space-6);
    right: var(--pl-space-6);
    z-index: var(--pl-z-sticky);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    border-radius: var(--pl-radius-full);
    background: var(--pl-color-surface-raised);
    border: 1px solid var(--pl-color-border);
    box-shadow: var(--pl-shadow-md);
    color: var(--pl-color-text-secondary);
    cursor: pointer;
    /* Hidden until the page has scrolled one viewport. visibility (not just opacity)
       keeps the invisible button out of the Tab order; the scroll-driven animation
       flips all three together. Without animation-timeline support the zero-length
       animation completes at once and the button simply stays visible. */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.2s ease, transform 0.15s var(--pl-spring), color 0.2s ease, box-shadow 0.2s ease;
    animation: pl-show-btt linear forwards;
    animation-timeline: scroll();
    animation-range: 100vh 100vh;
  }

  .pl-back-to-top:hover {
    transform: translateY(-2px);
    color: var(--pl-color-accent);
    box-shadow: var(--pl-shadow-lg);
  }

  .pl-back-to-top:active {
    transform: translateY(0) scale(0.95);
  }

  .pl-back-to-top:focus-visible {
    outline: var(--pl-focus-ring-width) solid var(--pl-focus-ring-dark);
    outline-offset: var(--pl-focus-ring-offset);
    box-shadow: 0 0 0 calc(var(--pl-focus-ring-offset) + var(--pl-focus-ring-width) + 2px) var(--pl-focus-ring-light);
  }

  @keyframes pl-show-btt {
    from {
      opacity: 0;
      visibility: hidden;
      pointer-events: none;
    }
    to {
      opacity: 1;
      visibility: visible;
      pointer-events: auto;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .pl-back-to-top {
      animation: none;
      opacity: 1;
      visibility: visible;
      pointer-events: auto;
    }

    .pl-back-to-top:hover,
    .pl-back-to-top:active {
      transform: none;
    }
  }

  /* Keep keyboard focus clear of the fixed button: when Tab brings an element into view near
     the bottom of the viewport, the browser scrolls it above this band instead of leaving it
     partly under the button (WCAG 2.4.11/2.4.12). */
  html:has(.pl-back-to-top) {
    scroll-padding-bottom: calc(2.5rem + var(--pl-space-6) + var(--pl-space-2));
  }

  /* ========================================
     Scroll Entrance Animations
     ======================================== */

  body.pl-animate-entrance [data-pl-section-style] {
    animation: pl-fade-in linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 35%;
  }

  body.pl-animate-entrance .wp-block-plumbline-hero {
    animation: none;
  }

  body.pl-animate-entrance [data-pl-no-entrance] {
    animation: none;
  }

  @keyframes pl-fade-in {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    body.pl-animate-entrance [data-pl-section-style] {
      animation: none;
    }
  }
}
