/* ==========================================================================
   Components — buttons, cards, forms, section headers.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Buttons
   Note the teal used for fills: --tr-teal-700, not --tr-teal. White on
   #00B39A measures 2.65:1 and fails WCAG AA. See tokens.css.
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  padding: 0.85rem 1.6rem;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-family: var(--font-body);
  font-size: 0.9375rem;
  font-weight: var(--fw-semibold);
  line-height: 1.2;
  text-decoration: none;
  transition:
    background var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

.btn--primary {
  background: var(--tr-teal-700);
  color: #fff;
}

.btn--primary:hover,
.btn--primary:focus-visible {
  background: var(--tr-teal-800);
  color: #fff;
}

.btn--secondary {
  background: var(--tr-white);
  color: var(--tr-teal-700);
  border-color: var(--tr-teal-700);
}

.btn--secondary:hover,
.btn--secondary:focus-visible {
  background: var(--tr-teal-soft);
  color: var(--tr-teal-800);
}

/* On charcoal, the secondary button inverts rather than punching a white hole. */
.is-dark .btn--secondary {
  background: transparent;
  color: var(--tr-teal);
  border-color: var(--tr-teal);
}

.is-dark .btn--secondary:hover {
  background: var(--tr-teal-soft);
  color: #fff;
}

.btn--ghost {
  background: none;
  color: var(--color-accent-text);
  padding-inline: 0;
}

.btn--ghost:hover {
  text-decoration: underline;
}

/* Arrow glyphs must flip in RTL — the arrow points "forward", not "right". */
.btn__arrow {
  transition: transform var(--dur-base) var(--ease-out);
}

.btn:hover .btn__arrow {
  transform: translateX(3px);
}

[dir="rtl"] .btn__arrow {
  transform: scaleX(-1);
}
[dir="rtl"] .btn:hover .btn__arrow {
  transform: scaleX(-1) translateX(3px);
}

/* --------------------------------------------------------------------------
   Section header
   -------------------------------------------------------------------------- */

.sec-head {
  margin-block-end: clamp(2.5rem, 5vw, 4rem);
  max-inline-size: 62ch;
}

.sec-head .readout {
  display: block;
  margin-block-end: 0.9rem;
  color: var(--color-accent-text);
}

.sec-head h2 {
  margin-block-end: var(--space-md);
}

.sec-head p {
  font-size: var(--fs-lead);
}

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */

/*
 * A card is a dimensioned panel, not a floating thumbnail. It carries a hairline
 * frame so it reads as contained, the media sits flush with a divider below it,
 * and the whole thing is a flex column so a grid row keeps one baseline no
 * matter how much copy each card holds. Corner brackets (.brk, on product and
 * project cards) energize on hover; the editorial post card omits them.
 */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  block-size: 100%;
  background: var(--color-bg);
  border: 1px solid var(--bp-line-strong);
  text-decoration: none;
  color: inherit;
  transition:
    border-color var(--dur-base) var(--ease-out),
    background var(--dur-base) var(--ease-out);
}

.card:hover {
  border-color: var(--tr-charcoal);
}

.card__link {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  color: inherit;
  text-decoration: none;
}

.card__media {
  position: relative;
  aspect-ratio: 3 / 2;
  background: var(--color-bg-alt);
  border-block-end: 1px solid var(--bp-line-strong);
  overflow: hidden;
  flex-shrink: 0;
}

/*
 * base.css sets `img[width][height] { block-size: auto }` so post images don't
 * reflow while loading — every WordPress thumbnail carries those attributes,
 * and that selector's specificity (0,2,1) beats a plain `.card__media img`
 * (0,1,1). Without matching it here, block-size falls back to "auto": the img
 * takes its own intrinsic ratio instead of filling the media box, object-fit
 * has no size mismatch left to resolve, and overflow:hidden silently clips
 * whatever doesn't fit — a portrait photo lost its bottom third with neither
 * contain's letterboxing nor cover's even crop actually engaging. Repeating
 * [width][height] beats the trap the same way layout.css already does for the
 * brand logo.
 */
.card__media img[width][height] {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/*
 * Every product photograph in the library is shot square on a plain ground
 * (see tr-product in inc/setup.php) — a 3:2 box under a 1:1 photo was exactly
 * the mismatch that made panels look small and adrift in a sea of white. The
 * box now matches the source ratio, so the image fills it edge to edge; the
 * padding is a deliberate mat around a full-resolution product shot, not
 * compensation for a shape that doesn't fit.
 */
.card--product .card__media {
  aspect-ratio: 1 / 1;
}

.card--product .card__media img[width][height] {
  object-fit: contain;
  padding: clamp(0.75rem, 4%, 1.5rem);
}

.card__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  gap: 0.35rem;
  padding: var(--space-lg) 1.35rem;
}

.card__eyebrow {
  display: block;
  color: var(--tr-gray);
}

.card__title {
  font-size: 1rem;
  line-height: 1.4;
  color: var(--color-heading);
  transition: color var(--dur-base) var(--ease-out);
}

.card:hover .card__title {
  color: var(--tr-teal-700);
}

/* The rating / meta line sits directly under the title — it belongs to it. */
.card__spec {
  color: var(--tr-gray);
}

/*
 * Leader arrow — pinned to the foot so it anchors the panel and stays put
 * however short the copy is. Parks muted, slides toward the spec sheet on
 * hover. It is the only element that claims the free space.
 */
.card__go {
  align-self: flex-end;
  margin-block-start: auto;
  padding-block-start: var(--space-md);
  color: var(--bp-line-strong);
  transition:
    color var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

.card:hover .card__go {
  color: var(--tr-teal-700);
  transform: translateX(3px);
}

[dir="rtl"] .card__go {
  transform: scaleX(-1);
}
[dir="rtl"] .card:hover .card__go {
  transform: scaleX(-1) translateX(3px);
}

.card__meta {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-block-start: auto;
  padding-block-start: var(--space-sm);
  color: var(--tr-gray);
}

.card__meta-sep {
  opacity: 0.6;
}

/* Editorial post card — a summary the reader can decide on. */
.card__excerpt {
  font-size: var(--fs-small);
  line-height: 1.6;
  color: var(--color-text);
}

.card--post .card__title {
  font-size: 1.0625rem;
}

/*
 * Missing thumbnail: a hairline blueprint panel rather than a blank box, so a
 * post without a photo still holds its place in the grid instead of floating.
 */
.card__media--empty {
  position: absolute;
  inset: 0;
  background-color: var(--color-bg-alt);
  background-image:
    repeating-linear-gradient(to right, var(--bp-line) 0 1px, transparent 1px 2rem),
    repeating-linear-gradient(to bottom, var(--bp-line) 0 1px, transparent 1px 2rem);
}

/* --------------------------------------------------------------------------
   Grids
   -------------------------------------------------------------------------- */

.grid {
  display: grid;
  gap: 1.25rem;
}
.grid--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.grid--4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.grid--5 {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}

@media (max-width: 1080px) {
  .grid--4,
  .grid--5 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .grid--3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  .grid--2,
  .grid--3,
  .grid--4,
  .grid--5 {
    grid-template-columns: 1fr;
  }
}

/* --------------------------------------------------------------------------
   Spec table — the core of a product page
   -------------------------------------------------------------------------- */

.spec-table {
  inline-size: 100%;
  border-collapse: collapse;
}

.spec-table th,
.spec-table td {
  padding: 0.7rem 0;
  border-block-end: 1px solid var(--bp-line);
  vertical-align: baseline;
}

.spec-table th {
  inline-size: 40%;
  font-weight: var(--fw-regular);
  color: var(--color-text);
  font-size: var(--fs-small);
}

.spec-table td {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.05em;
  color: var(--color-heading);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */

.field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

/* CF7 emits one <p> per row with no wrapping container; base.css also zeroes
   default <p> margins, so without this every row sat flush against the next
   with no gap at all. Row-to-row rhythm is this container's job — the
   label-to-control gap inside a row stays on .field above. */
.wpcf7 form {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.field label {
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  color: var(--color-heading);
}

.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="number"],
.field select,
.field textarea,
.wpcf7 input[type="text"],
.wpcf7 input[type="email"],
.wpcf7 input[type="tel"],
.wpcf7 input[type="number"],
.wpcf7 select,
.wpcf7 textarea {
  inline-size: 100%;
  padding: 0.75rem 0.9rem;
  background: var(--tr-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-heading);
  transition: border-color var(--dur-fast) var(--ease-out);
}

.field input:focus,
.field textarea:focus,
.field select:focus,
.wpcf7 input:focus,
.wpcf7 textarea:focus,
.wpcf7 select:focus {
  border-color: var(--tr-teal-700);
  outline: 2px solid var(--tr-teal-soft);
  outline-offset: 0;
}

.field textarea,
.wpcf7 textarea {
  min-block-size: 8rem;
  resize: vertical;
}

/* CF7's own stylesheet has already run by this point (it is enqueued
   independently of the theme's dependency chain), so these selectors are
   written at least as specific as its equivalents to win the cascade
   regardless of load order. */

.wpcf7 input[type="checkbox"] {
  accent-color: var(--tr-teal-700);
  inline-size: 1.05rem;
  block-size: 1.05rem;
  vertical-align: middle;
  cursor: pointer;
}

.wpcf7-acceptance .wpcf7-list-item {
  display: block;
  margin: 0;
}

.wpcf7-acceptance .wpcf7-list-item-label {
  margin-inline-start: 0.5rem;
  font-size: var(--fs-small);
  color: var(--color-text);
  cursor: pointer;
}

.wpcf7 input[type="file"].wpcf7-form-control {
  inline-size: 100%;
  padding: 0.6rem 0.75rem;
  background: var(--tr-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--fs-small);
  color: var(--color-text);
}

.wpcf7 input[type="file"]::file-selector-button {
  margin-inline-end: 0.75rem;
  padding: 0.45rem 0.9rem;
  border: 1px solid var(--tr-teal-700);
  border-radius: var(--radius-sm);
  background: var(--tr-white);
  color: var(--tr-teal-700);
  font-weight: var(--fw-medium);
  font-size: var(--fs-small);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}

.wpcf7 input[type="file"]::file-selector-button:hover {
  background: var(--tr-teal-soft);
}

/* The [submit] tag carries class:btn class:btn--primary (see
   tools/setup-07-forms.php), so it already has the site's button look. This
   only covers what the .btn component doesn't know about: CF7's own
   disabled-during-submit state and its spinner, which shipped with a
   hardcoded 24px physical margin on both sides. */
.wpcf7 .wpcf7-submit:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.wpcf7 .wpcf7-spinner {
  margin: 0;
  margin-inline-start: 0.75rem;
  vertical-align: middle;
}

.wpcf7 form .wpcf7-response-output {
  margin: 0;
  padding: 0.85rem 1.1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--fs-small);
  color: var(--color-heading);
  background: var(--color-bg-alt);
}

.wpcf7 form.sent .wpcf7-response-output {
  border-color: var(--tr-teal-700);
  color: var(--tr-teal-700);
  background: var(--tr-teal-soft);
}

.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output,
.wpcf7 form.failed .wpcf7-response-output,
.wpcf7 form.aborted .wpcf7-response-output,
.wpcf7 form.spam .wpcf7-response-output,
.wpcf7 form.payment-required .wpcf7-response-output {
  border-color: var(--tr-charcoal);
  color: var(--tr-charcoal);
  background: rgba(31, 41, 51, 0.06);
}

.wpcf7-not-valid-tip {
  font-family: var(--font-body);
  font-size: var(--fs-small);
  margin-block-start: 0.3rem;
}

/* --------------------------------------------------------------------------
   Pagination
   -------------------------------------------------------------------------- */

.pagination {
  margin-block-start: var(--space-2xl);
}

/*
 * WordPress wraps the links in their own .nav-links div, so .pagination (the
 * outer <nav>) only ever has that one child — flex+gap here had nothing to
 * lay out and the numbers fell back to source-order whitespace for spacing.
 * The real row is .nav-links.
 */
.pagination .nav-links {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  justify-content: center;
  flex-wrap: wrap;
}

.pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 2.5rem;
  block-size: 2.5rem;
  padding-inline: 0.5rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  text-decoration: none;
  color: var(--color-heading);
  font-variant-numeric: tabular-nums;
  transition:
    border-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

.pagination .page-numbers:hover {
  border-color: var(--tr-teal);
  color: var(--tr-teal-700);
}

.pagination .page-numbers.current {
  background: var(--tr-charcoal);
  border-color: var(--tr-charcoal);
  color: #fff;
}

/*
 * Prev/next are a way OUT of the numbered set, not one more stop in it, so
 * they drop the boxed-pill treatment and read as a quiet text link with a
 * directional arrow — the same voice as .fam__link / .card__go elsewhere.
 */
.pagination .prev,
.pagination .next {
  gap: 0.4rem;
  min-inline-size: 0;
  padding-inline: 0.3rem;
  border-color: transparent;
  color: var(--tr-teal-700);
  font-family: var(--font-body);
  font-weight: var(--fw-medium);
  letter-spacing: normal;
  text-transform: none;
}

.pagination .prev:hover,
.pagination .next:hover {
  border-color: transparent;
  background: var(--tr-teal-soft);
}

/*
 * The arrow icon is authored once, pointing "next" (right). Four explicit
 * rules cover the truth table rather than composing transforms across the
 * cascade — transform is a single winning value per element, not something
 * two separate rules add together, so each of the four prev/next × LTR/RTL
 * states needs its own explicit answer:
 *
 *          LTR              RTL
 *   next   →  (default)     ←  (flipped)
 *   prev   ←  (flipped)     →  (flipped, cancels the LTR flip above)
 */
.pagination .prev .tr-icon {
  transform: scaleX(-1);
}

[dir="rtl"] .pagination .next .tr-icon {
  transform: scaleX(-1);
}

[dir="rtl"] .pagination .prev .tr-icon {
  transform: none;
}

/* --------------------------------------------------------------------------
   Honeypot

   Moved out of view rather than display:none. A hidden-by-display field is
   trivially detectable, and it would also be dropped from the accessibility
   tree — the aria-hidden on the wrapper is what keeps screen readers away,
   deliberately, rather than the layout doing it by accident.
   -------------------------------------------------------------------------- */

.tr-hp {
  position: absolute !important;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Arithmetic check

   Cheaper and more reliable than reCAPTCHA for this audience: no third-party
   request, nothing to load, and it works on a slow or filtered connection.
   -------------------------------------------------------------------------- */

.tr-quiz label {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  max-inline-size: 16rem;
}

.tr-quiz input {
  max-inline-size: 8rem;
}
