/* Reusable UI components */

/* --- Buttons --- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding: 0.85rem 1.5rem;
  border-radius: var(--radius-full);
  font-weight: var(--fw-semibold);
  font-size: var(--fs-sm);
  line-height: 1;
  white-space: nowrap;
  transition: transform var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out), background var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
  border: 1px solid transparent;
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  background: var(--color-gradient-brand);
  color: #ffffff;
  box-shadow: var(--shadow-md);
}

.btn-primary:hover {
  box-shadow: var(--shadow-lg);
  transform: translateY(-1px);
}

.btn-secondary {
  background: var(--color-bg-surface);
  color: var(--color-text);
  border-color: var(--color-border-strong);
}

.btn-secondary:hover {
  background: var(--color-bg-surface-hover);
  border-color: var(--color-accent-blue);
}

.btn-ghost {
  background: transparent;
  color: var(--color-text-muted);
  border-color: var(--color-border);
}

.btn-ghost:hover {
  color: var(--color-text);
  border-color: var(--color-border-strong);
}

.btn-sm {
  padding: 0.6rem 1.1rem;
  font-size: var(--fs-xs);
}

.btn-block {
  width: 100%;
}

.btn[disabled],
.btn[aria-disabled='true'] {
  opacity: 0.55;
  pointer-events: none;
}

/* --- Cards --- */

.card {
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
  transition: transform var(--duration-base) var(--ease-out), border-color var(--duration-base) var(--ease-out), box-shadow var(--duration-base) var(--ease-out);
}

.card--interactive:hover,
.card--interactive:focus-within {
  transform: translateY(-4px);
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-lg);
}

/* --- CTA band ---
   Used on 7+ pages (home, about, services, VULNKON, ENTERKON, BUSSKON) —
   belongs in this globally-loaded stylesheet, not home.css, which only the
   homepage itself loads via extra_css. It was previously defined there,
   which meant every OTHER page using it rendered plain unstyled text with
   no background at all. */
.cta-band {
  text-align: center;
  padding: var(--space-2xl) var(--space-xl);
  border-radius: var(--radius-lg);
  background: var(--color-gradient-brand);
  color: #ffffff;
}

.cta-band h2 {
  font-size: var(--fs-xl);
  margin-bottom: var(--space-sm);
}

.cta-band p {
  color: rgba(255, 255, 255, 0.85);
  max-width: 34rem;
  margin-inline: auto;
  margin-bottom: var(--space-lg);
}

.cta-band .btn-primary {
  /* Fixed dark text, not var(--color-bg): this button's background is
     always #fff regardless of theme, but --color-bg flips to #fff too in
     light mode, making the label invisible (white text on a white button). */
  background: #ffffff;
  color: #0a0f1a;
  box-shadow: none;
}

.cta-band .btn-ghost {
  border-color: rgba(255, 255, 255, 0.4);
  color: #ffffff;
}

/* --- Hero visual caption badge ---
   Same relocation reason as .cta-band above: used by the home hero AND the
   About page hero visual, so it needs to live where every page loads it. */
.hero__badge {
  position: absolute;
  bottom: var(--space-md);
  left: var(--space-md);
  right: var(--space-md);
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--color-bg-elevated) 82%, transparent);
  border: 1px solid var(--color-border);
  backdrop-filter: blur(6px);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
  z-index: 1;
}

.hero__badge .dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--color-accent-cyan);
  box-shadow: 0 0 0 4px rgba(99, 179, 237, 0.25);
}

.card__icon {
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-bg-elevated);
  color: var(--color-accent-cyan);
  margin-bottom: var(--space-sm);
}

.card__title {
  font-size: var(--fs-md);
  margin-bottom: var(--space-2xs);
}

.card__body {
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
}

.card__link {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  margin-top: var(--space-sm);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-accent-cyan);
}

.card__link .icon {
  transition: transform var(--duration-fast) var(--ease-out);
}

.card__link:hover .icon {
  transform: translateX(3px);
}

/* --- Badges --- */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  padding: 0.3rem 0.75rem;
  border-radius: var(--radius-full);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border-strong);
  color: var(--color-text-muted);
}

.badge--accent {
  background: rgba(49, 130, 206, 0.14);
  border-color: rgba(49, 130, 206, 0.4);
  color: var(--color-accent-blue-strong);
}

.badge--new { background: rgba(49, 130, 206, 0.14); color: var(--color-accent-blue-strong); border-color: rgba(49,130,206,.4); }
.badge--contacted { background: var(--color-warning-bg); color: var(--color-warning); border-color: rgba(198,146,20,.4); }
.badge--qualified,
.badge--approved,
.badge--published { background: var(--color-success-bg); color: var(--color-success); border-color: rgba(47,158,110,.4); }
.badge--archived,
.badge--declined { background: var(--color-danger-bg); color: var(--color-danger); border-color: rgba(224,82,92,.4); }
.badge--waitlisted,
.badge--under_review,
.badge--draft { background: var(--color-warning-bg); color: var(--color-warning); border-color: rgba(198,146,20,.4); }

/* --- Stat tiles --- */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
}

@media (min-width: 48rem) {
  .stat-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.stat-tile {
  text-align: center;
  padding: var(--space-lg) var(--space-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-surface);
}

.stat-tile__value {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  background: var(--color-gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.stat-tile__label {
  margin-top: var(--space-3xs);
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.stat-disclaimer {
  margin-top: var(--space-sm);
  font-size: var(--fs-xs);
  color: var(--color-text-faint);
}

/* --- Process / workflow steps --- */

.steps {
  display: grid;
  gap: var(--space-md);
}

@media (min-width: 48rem) {
  .steps {
    grid-template-columns: repeat(2, 1fr);
  }
}

.step {
  position: relative;
  padding: var(--space-lg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-surface);
}

.step__index {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  color: var(--color-accent-blue-strong);
  margin-bottom: var(--space-2xs);
}

.step__title {
  font-size: var(--fs-md);
  margin-bottom: var(--space-2xs);
}

.step__body {
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}

/* --- FAQ accordion (native details/summary) --- */

.faq-list {
  display: grid;
  gap: var(--space-sm);
}

.faq-item {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-surface);
  overflow: hidden;
}

.faq-item > summary {
  list-style: none;
  padding: var(--space-md) var(--space-lg);
  font-weight: var(--fw-semibold);
  font-family: var(--font-display);
  font-size: var(--fs-base);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  cursor: pointer;
}

.faq-item > summary::-webkit-details-marker {
  display: none;
}

.faq-item__icon {
  flex-shrink: 0;
  transition: transform var(--duration-base) var(--ease-out);
}

.faq-item[open] .faq-item__icon {
  transform: rotate(45deg);
}

.faq-item__body {
  padding: 0 var(--space-lg) var(--space-lg);
  color: var(--color-text-muted);
}

/* --- Service page hero: full-screen, matching the About page pattern ---
   (.about-statement's frame/tilt/glow/badge structure, renamed under
   .service-hero__* so it works here without loading about.css, which is
   scoped to the About page only). */

.service-hero-section {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
}

.service-hero {
  display: grid;
  gap: var(--space-xl);
  align-items: center;
  width: 100%;
}

@media (min-width: 60rem) {
  .service-hero {
    grid-template-columns: 1.1fr 0.9fr;
  }
}

.service-hero__text {
  max-width: none;
}

/* .section-head's h1 has no size of its own (falls back to the browser
   default), so this read noticeably smaller than the About/Home hero
   headings — matching their scale here for consistency. */
.service-hero__text h1 {
  font-size: var(--fs-3xl);
  margin-block: var(--space-sm) var(--space-md);
}

.service-hero__text .text-muted {
  font-size: var(--fs-lg);
  max-width: 38rem;
  margin-bottom: var(--space-lg);
}

.service-hero__visual {
  width: 100%;
  max-width: 26rem;
  margin-inline: auto;
}

.service-hero__frame {
  position: relative;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  perspective: 1200px;
}

.service-hero__glow {
  position: absolute;
  inset: -6%;
  background: radial-gradient(circle, color-mix(in srgb, var(--color-accent-blue) 14%, transparent), transparent 70%);
  animation: service-hero-glow-pulse 8s ease-in-out infinite;
  pointer-events: none;
}

@keyframes service-hero-glow-pulse {
  0%, 100% { opacity: 0.5; transform: scale(1); }
  50% { opacity: 0.75; transform: scale(1.04); }
}

/* Draggable 3D tilt — same plain-CSS-transform technique as monogram-tilt.js
   uses on the About page (that module's selector is generic, so reusing its
   data attribute here just works, no JS changes needed). */
.service-hero__tilt {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  touch-action: none;
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}

.service-hero__tilt:active {
  cursor: grabbing;
}

.service-hero__mark {
  width: 100%;
  height: auto;
  filter: drop-shadow(0 1rem 2rem rgba(49, 130, 206, 0.22)) saturate(0.9);
  animation: service-hero-mark-float 8s ease-in-out infinite;
}

@keyframes service-hero-mark-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-8px); }
}

@media (prefers-reduced-motion: reduce) {
  .service-hero__mark,
  .service-hero__glow {
    animation: none;
  }
}

/* --- Trust wall: animated client-logo grid ---
   Full-viewport section, background-less on purpose: cards used to be a
   solid white/dark fill, but that hid the site's own animated ambient
   background — now the cards are just layout/alignment (no fill, no
   shadow) and each logo gets its own adaptive glow (see .trust-wall__card
   img below) so arbitrary brand-logo colors stay legible over whatever's
   behind them in either theme, without needing a solid card underneath. */
.trust-wall {
  position: relative;
  overflow: hidden;
  min-height: 100vh;
  display: flex;
  align-items: center;
  padding-block: clamp(4rem, 8vw, var(--space-2xl));
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

/* A small label above each column, at a matched height on both sides, so
   the logo grid and the review carousel — two different-shaped things —
   still start at the same Y position instead of one sitting noticeably
   higher than the other. */
.trust-wall__col-head {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin-bottom: var(--space-md);
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}

.trust-wall__col-head-icon {
  display: inline-flex;
  color: var(--color-accent-blue);
}

.trust-wall__inner {
  width: 100%;
}

/* Shared heading, centered, full width — sits above BOTH columns rather
   than belonging to either one. */
.trust-wall__head {
  text-align: center;
  max-width: 40rem;
  margin-inline: auto;
  margin-bottom: var(--space-xl);
}

.trust-wall__head .eyebrow {
  justify-content: center;
}

.trust-wall__title {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: var(--fw-semibold);
  margin-top: var(--space-sm);
}

.trust-wall__body {
  margin-top: var(--space-sm);
  color: var(--color-text-muted);
}

/* The two-column split: client logos on the left, Google reviews on the
   right, each its own independently-scrolling carousel. */
.trust-wall__split {
  display: grid;
  gap: var(--space-xl);
}

@media (min-width: 64rem) {
  .trust-wall__split {
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }
}

.trust-wall__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-md);
  height: 22rem;
  /* Fades the top/bottom of each scrolling column into the section
     background instead of hard-cropping mid-card. */
  mask-image: linear-gradient(to bottom, transparent, black 14%, black 86%, transparent);
  -webkit-mask-image: linear-gradient(to bottom, transparent, black 14%, black 86%, transparent);
}

@media (min-width: 40rem) {
  .trust-wall__grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 64rem) {
  .trust-wall__grid {
    height: 32rem;
  }
}

.trust-wall__column {
  position: relative;
  overflow: hidden;
  height: 100%;
}

.trust-wall__track {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  width: 100%;
  will-change: transform;
  animation: trust-wall-scroll var(--trust-col-duration, 20s) linear infinite;
}

.trust-wall__column--reverse .trust-wall__track {
  animation-direction: reverse;
}

.trust-wall__column:hover .trust-wall__track {
  animation-play-state: paused;
}

@keyframes trust-wall-scroll {
  from { transform: translateY(0); }
  to { transform: translateY(-50%); }
}

/* Phones only: the 2/3-column vertical wall becomes cramped at this width,
   so it's swapped for a single horizontally-sliding row instead (see the
   sibling .trust-wall__mobile-strip markup in partials/trust-wall.php).
   Tablet and up keep the original vertical .trust-wall__grid untouched. */
.trust-wall__mobile-strip {
  display: none;
}

@media (max-width: 39.99rem) {
  .trust-wall__grid {
    display: none;
  }

  .trust-wall__mobile-strip {
    display: block;
    overflow: hidden;
    mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
    -webkit-mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
  }
}

.trust-wall__mobile-track {
  display: flex;
  flex-direction: row;
  gap: var(--space-md);
  width: max-content;
  will-change: transform;
  animation: trust-wall-scroll-x 26s linear infinite;
}

.trust-wall__mobile-strip:hover .trust-wall__mobile-track {
  animation-play-state: paused;
}

@keyframes trust-wall-scroll-x {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* Fixed white regardless of site theme (not translucent/theme-tinted): a
   translucent dark-tinted card was invisible for dark-colored logos in
   dark mode, since the tint and the logo were both dark. A plain, always-
   white card is the one background every logo here (colored or black
   wordmarks) reads against reliably in both themes. */
.trust-wall__card {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 6rem;
  padding: var(--space-md);
  border-radius: var(--radius-lg);
  background: #ffffff;
}

.trust-wall__card img {
  max-width: 100%;
  max-height: 3.25rem;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* The inverse case: logos that are themselves a light/white mark on a
   transparent background go invisible on the white card everything else
   uses, so they get a dark card instead (see the `dark` flag in
   config/client-logos.php). */
.trust-wall__card--dark {
  background: #12181f;
}

/* Left column: the logo wall (see .trust-wall__grid above). Right column:
   the Google reviews carousel — both live inside .trust-wall__split. */
.trust-wall__logos,
.trust-wall__reviews {
  min-width: 0;
}

.trust-wall__review-col {
  position: relative;
  overflow: hidden;
  height: 22rem;
  mask-image: linear-gradient(to bottom, transparent, black 8%, black 92%, transparent);
  -webkit-mask-image: linear-gradient(to bottom, transparent, black 8%, black 92%, transparent);
}

@media (min-width: 64rem) {
  .trust-wall__review-col {
    height: 26rem;
  }
}

.trust-wall__review-track {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  will-change: transform;
  animation: trust-wall-scroll 28s linear infinite;
}

.trust-wall__review-col:hover .trust-wall__review-track {
  animation-play-state: paused;
}

/* --- Google reviews (shared head/brand/score/card styles, reused inside
   .trust-wall__reviews above) --- */

.google-reviews__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg);
  /* Matches .trust-wall__col-head's margin-bottom exactly — the two column
     headers need to be the same height so the logo grid and the review
     carousel below them start at the same Y position. */
  margin-bottom: var(--space-md);
}

.google-reviews__brand {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}

.google-reviews__score {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.google-reviews__score-num {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  color: var(--color-text);
}

.google-reviews__score-stars {
  display: flex;
  gap: 2px;
}

.google-reviews__score-count {
  color: var(--color-text-faint);
  font-size: var(--fs-sm);
}

.google-reviews__star {
  fill: var(--color-border-strong);
}

.google-reviews__star.is-filled {
  fill: #fbbc05;
}

.google-reviews__card {
  flex-shrink: 0;
  padding: var(--space-lg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-bg-elevated);
  box-shadow: var(--shadow-sm);
  transition: transform var(--duration-base) var(--ease-out), box-shadow var(--duration-base) var(--ease-out);
}

.google-reviews__card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}

.google-reviews__card-head {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}

.google-reviews__avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--color-gradient-brand);
  color: #ffffff;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

.google-reviews__name {
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}

.google-reviews__see-all {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  margin-bottom: var(--space-md);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-accent-blue);
}

.google-reviews__see-all:hover {
  text-decoration: underline;
}

.google-reviews__stars {
  display: flex;
  gap: 2px;
  margin-bottom: var(--space-sm);
}

.google-reviews__stars .google-reviews__star {
  width: 15px;
  height: 15px;
}

.google-reviews__text {
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
}

@media (prefers-reduced-motion: reduce) {
  .trust-wall__track,
  .trust-wall__mobile-track,
  .trust-wall__review-track {
    animation: none;
  }
}

/* --- Forms --- */

.form-grid {
  display: grid;
  /* Without an explicit template, the single implicit column sizes to its
     widest child's max-content width instead of shrinking to fit the grid
     container — harmless on desktop (there's room to spare) but on narrow
     viewports it pushed inputs past the edge of the screen. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-md);
}

@media (min-width: 40rem) {
  .form-row--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    display: grid;
    gap: var(--space-md);
  }
}

.field {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2xs);
}

.field label,
.field legend {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--color-text);
}

.field .hint {
  font-size: var(--fs-xs);
  color: var(--color-text-faint);
}

.field input[type='text'],
.field input[type='email'],
.field input[type='tel'],
.field input[type='url'],
.field input[type='number'],
.field input[type='date'],
.field input[type='password'],
.field select,
.field textarea {
  width: 100%;
  padding: 0.8rem 1rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-strong);
  background: var(--color-bg-elevated);
  color: var(--color-text);
  font-size: var(--fs-sm);
  transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--color-accent-blue);
  box-shadow: var(--shadow-focus);
  outline: none;
}

.field textarea {
  min-height: 8rem;
  resize: vertical;
}

.field-error {
  font-size: var(--fs-xs);
  color: var(--color-danger);
}

.field.has-error input,
.field.has-error select,
.field.has-error textarea {
  border-color: var(--color-danger);
}

.checkbox-field,
.radio-field {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2xs);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}

.checkbox-field input,
.radio-field input {
  margin-top: 0.2rem;
  width: 1.1rem;
  height: 1.1rem;
  accent-color: var(--color-accent-blue);
}

.radio-group {
  display: flex;
  gap: var(--space-md);
  flex-wrap: wrap;
}

fieldset {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
}

.honeypot-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.file-drop {
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  text-align: center;
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
}

.file-drop.is-dragover {
  border-color: var(--color-accent-cyan);
  background: var(--color-bg-surface-hover);
}

/* --- Alerts / flash messages --- */

.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-strong);
  font-size: var(--fs-sm);
  margin-bottom: var(--space-md);
}

.alert--success {
  background: var(--color-success-bg);
  border-color: rgba(47,158,110,.4);
  color: var(--color-success);
}

.alert--error {
  background: var(--color-danger-bg);
  border-color: rgba(224,82,92,.4);
  color: var(--color-danger);
}

/* --- Pagination --- */

.pagination {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  justify-content: center;
  margin-top: var(--space-xl);
}

.pagination a,
.pagination span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.5rem;
  height: 2.5rem;
  padding-inline: var(--space-2xs);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
}

.pagination a:hover {
  border-color: var(--color-accent-blue);
  color: var(--color-text);
}

.pagination [aria-current='page'] {
  background: var(--color-gradient-brand);
  border-color: transparent;
  color: #fff;
  font-weight: var(--fw-semibold);
}

/* --- Empty states --- */

.empty-state {
  text-align: center;
  padding: var(--space-2xl) var(--space-lg);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-lg);
  color: var(--color-text-muted);
}

.empty-state h3 {
  color: var(--color-text);
  margin-bottom: var(--space-2xs);
}

/* --- Filter chips --- */

.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  margin-bottom: var(--space-lg);
}

.filter-chip {
  padding: 0.5rem 1rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  color: var(--color-text-muted);
}

.filter-chip[aria-pressed='true'] {
  background: var(--color-gradient-brand);
  color: #fff;
  border-color: transparent;
}

/* --- Cookie consent banner --- */

.cookie-banner {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: var(--z-toast);
  background: var(--color-bg-elevated);
  border-top: 1px solid var(--color-border-strong);
  box-shadow: var(--shadow-lg);
  padding: var(--space-md) var(--container-pad);
}

.cookie-banner[hidden] {
  display: none;
}

.cookie-banner__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
}

.cookie-banner p {
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
  max-width: 40rem;
}

.cookie-banner__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}

.cookie-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: grid;
  place-items: center;
  background: rgba(3, 8, 16, 0.7);
  padding: var(--space-md);
}

.cookie-modal[hidden] {
  display: none;
}

.cookie-modal__panel {
  width: 100%;
  max-width: 34rem;
  max-height: 85vh;
  overflow-y: auto;
  background: var(--color-bg-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
}

.cookie-modal__row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-md);
  padding-block: var(--space-sm);
  border-bottom: 1px solid var(--color-border);
}

.cookie-modal__row:last-of-type {
  border-bottom: none;
}

.switch {
  position: relative;
  display: inline-flex;
  width: 2.75rem;
  height: 1.6rem;
  flex-shrink: 0;
}

.switch input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}

.switch__track {
  position: absolute;
  inset: 0;
  background: var(--color-border-strong);
  border-radius: var(--radius-full);
  transition: background var(--duration-fast) var(--ease-out);
}

.switch__track::before {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 1.2rem;
  height: 1.2rem;
  border-radius: 50%;
  background: #fff;
  transition: transform var(--duration-fast) var(--ease-out);
}

.switch input:checked + .switch__track {
  background: var(--color-accent-blue);
}

.switch input:checked + .switch__track::before {
  transform: translateX(1.15rem);
}

.switch input:disabled + .switch__track {
  opacity: 0.5;
}

.switch input:focus-visible + .switch__track {
  outline: 3px solid var(--color-accent-blue-strong);
  outline-offset: 2px;
}

/* --- Reveal on scroll --- */

[data-reveal] {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out);
}

[data-reveal].is-visible {
  opacity: 1 !important;
  transform: translateY(0) !important;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* --- Contact page layout: form + a stack of info cards alongside it --- */

.detail-grid {
  display: grid;
  gap: var(--space-lg);
}

@media (min-width: 60rem) {
  .detail-grid {
    grid-template-columns: 1.4fr 1fr;
    align-items: start;
  }

  /* The form is shorter than the 4-card info list beside it — pin it in
     view while the cards scroll past, rather than letting it finish early
     and leave the rest of the taller column scrolling next to blank
     space. align-items:start above is what gives it room to travel: it
     keeps the form's own box at its natural (shorter) height instead of
     stretching it to match the cards column, so the grid row itself stays
     as tall as the cards list and the form can stick within that space. */
  .detail-grid > .surface {
    position: sticky;
    top: var(--space-xl);
  }
}

.contact-info-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.contact-info-card {
  padding: var(--space-lg);
}

.contact-info-card .card__icon {
  margin-bottom: var(--space-sm);
}

.contact-info-card .card__title {
  font-size: var(--fs-md);
  margin-bottom: var(--space-2xs);
}

.contact-info-card .card__body {
  font-size: var(--fs-sm);
}

.contact-info-card .footer-social {
  display: flex;
  gap: var(--space-md);
  margin-top: var(--space-2xs);
}
