/*
  RainTree Immigration — main stylesheet (GENERATED FILE).

  Do not edit this file directly — it's bundled from the modular source
  files in src/css/base/ and src/css/components/ by scripts/build_css.py.
  Edit those files, then run:
      python scripts/build_css.py
*/


/* ===== base/variables.css ===== */

/*
  Design tokens for RainTree Immigration.

  Brand colors were sampled directly from the approved mockups
  (assets/images/mockups/*.jpeg) via pixel-cluster analysis, not guessed:
    - Dark green sampled at ~#02302A across home/contact mockups.
    - Gold sampled at ~#D6931F-#D89626 across CTA buttons.

  --color-accent-text exists separately from --color-accent because the
  raw brand gold (#D89B2A) only contrasts ~2.4:1 against white, which
  fails WCAG AA (needs 4.5:1) for body text. It's fine for large
  decorative use, icons, and button fills, but never for small text on a
  light background — use --color-accent-text (~4.8:1) for that instead.
*/

:root {
  /* Brand colors */
  --color-primary: #0B3D2E;
  --color-primary-dark: #072A20;
  --color-primary-light: #12503C;

  --color-accent: #D89B2A;
  --color-accent-dark: #B97F1B;
  --color-accent-text: #9C6812;

  /* Neutrals */
  --color-text: #16241D;
  --color-text-muted: #52685F;
  --color-text-on-dark: #F3F6F4;
  --color-text-on-dark-muted: #B9CBC3;

  --color-bg: #FFFFFF;
  --color-bg-alt: #F6F8F6;
  --color-border: #E3E8E5;
  --color-white: #FFFFFF;

  --color-success: #1F8A55;
  --color-danger: #C0392B;

  /* Typography */
  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-body: "Poppins", "Segoe UI", system-ui, -apple-system, sans-serif;

  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-md: 1.125rem;
  --text-lg: 1.25rem;
  --text-xl: 1.5rem;
  --text-2xl: 1.875rem;
  --text-3xl: clamp(1.875rem, 1.6rem + 1.2vw, 2.5rem);
  --text-4xl: clamp(2.25rem, 1.8rem + 2vw, 3.25rem);

  --leading-tight: 1.2;
  --leading-normal: 1.5;
  --leading-relaxed: 1.7;

  /* Spacing scale (4px base) */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;

  /* Radius */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --radius-full: 999px;

  /* Shadows (green-tinted for a cohesive premium feel) */
  --shadow-sm: 0 1px 2px rgba(11, 61, 46, 0.06);
  --shadow-md: 0 8px 24px rgba(11, 61, 46, 0.10);
  --shadow-lg: 0 20px 48px rgba(11, 61, 46, 0.16);

  /* Motion */
  --transition-fast: 150ms ease;
  --transition-base: 250ms ease;

  /* Layout */
  --container-max: 1280px;
  --container-padding: clamp(1.25rem, 4vw, 2.5rem);

  /* Z-index scale */
  --z-header: 100;
  --z-dropdown: 200;
  --z-modal: 300;
  --z-toast: 400;
}

/*
  Breakpoint reference (no CSS var equivalent — media queries can't consume
  custom properties). Keep every @media rule in this codebase aligned to:
    sm:  480px
    md:  768px
    lg:  1024px
    xl:  1280px
*/


/* ===== base/reset.css ===== */

/* Modern, accessibility-conscious reset. */

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

* {
  margin: 0;
}

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

body {
  /* dvh has good modern support but isn't understood by Safari <15.4;
     an unsupported unit invalidates the whole declaration, so the 100vh
     line above it is what those browsers actually use — this is a
     progressive-enhancement fallback, not dead code. */
  min-height: 100vh;
  min-height: 100dvh;
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
}

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

img,
video {
  height: auto;
}

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

button {
  cursor: pointer;
  background: none;
  border: none;
}

a {
  color: inherit;
  text-decoration: none;
}

/* list-style: none removes list semantics in some assistive tech (VoiceOver
   in Safari); any <ul>/<ol> styled here in components must carry
   role="list" in the markup to keep screen readers announcing it as one. */
ul[class],
ol[class] {
  list-style: none;
  padding: 0;
}

ul[class]:not([role]),
ol[class]:not([role]) {
  list-style: none;
}

table {
  border-collapse: collapse;
  width: 100%;
}

#root,
#app {
  isolation: isolate;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}


/* ===== base/typography.css ===== */

body {
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--color-text);
  background-color: var(--color-bg);
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: var(--leading-tight);
  color: var(--color-text);
}

h1 {
  font-size: var(--text-4xl);
}

h2 {
  font-size: var(--text-3xl);
}

h3 {
  font-size: var(--text-xl);
}

h4 {
  font-size: var(--text-lg);
}

p {
  color: var(--color-text-muted);
  line-height: var(--leading-relaxed);
}

a {
  transition: color var(--transition-fast);
}

strong {
  font-weight: 600;
}

.text-lead {
  font-size: var(--text-md);
  color: var(--color-text-muted);
  line-height: var(--leading-relaxed);
}

/* Small uppercase label used above headings, e.g. "OUR SERVICES".
   Uses --color-accent-text (not --color-accent) so it stays WCAG AA
   compliant at small sizes on a white background. */
.eyebrow {
  display: inline-block;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent-text);
  margin-bottom: var(--space-2);
}

/* Accessible visually-hidden utility: content stays available to screen
   readers (skip links, form labels tied to icon-only fields) but is
   removed from the visual layout. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--space-4);
  z-index: var(--z-toast);
  background: var(--color-primary);
  color: var(--color-text-on-dark);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
  transition: top var(--transition-fast);
}

.skip-link:focus {
  top: var(--space-4);
}


/* ===== base/layout.css ===== */

/* ---------- Layout ---------- */

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

.section {
  padding-block: var(--space-20);
  /* Any section used as a #fragment jump target (e.g. services.html#work-permit)
     needs this so its heading clears the sticky header instead of hiding under it. */
  scroll-margin-top: 96px;
}

.section--alt {
  background-color: var(--color-bg-alt);
}

.section-header {
  max-width: 640px;
  margin-bottom: var(--space-10);
}

.section-header--center {
  margin-inline: auto;
  text-align: center;
}

/* Shared interior-page hero: eyebrow + title + lead text, centered, no
   media. Used by every page except Home (which has the real banner photo). */
.page-hero {
  padding-block: var(--space-16) var(--space-12);
  text-align: center;
}

.page-hero__content {
  max-width: 680px;
  margin-inline: auto;
}

.page-hero__title {
  margin-bottom: var(--space-5);
}

.page-hero__title .accent {
  color: var(--color-accent-text);
}

/* Shared media/content split row — alternating image-and-text blocks used
   by Services (detailed service sections) and About (Who We Are, etc.). */
.detail-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-12);
  align-items: center;
}

.detail-row + .detail-row {
  margin-top: var(--space-20);
}

.detail-row--reverse .detail-row__media {
  order: 2;
}

.detail-row__media {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-xl);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
}

/* Portrait-oriented photography (Services page: Visitor Visa, Work Permit)
   needs a taller image and a narrower image column so the row doesn't
   tower over its text. Scoped so About's team photo keeps the 4:3 default.
   Desktop-only (min-width matches the mobile collapse breakpoint below):
   .detail-row--portrait.detail-row--reverse has higher specificity (two
   classes) than the mobile ".detail-row { grid-template-columns: ... }"
   collapse rule (one class), so if this weren't scoped to desktop it would
   win the cascade at mobile widths too and keep the row split into two
   columns instead of collapsing to one — exactly the kind of "won't shrink
   below content width" overflow this file is otherwise built to avoid. */
@media (min-width: 1024px) {
  .detail-row--portrait {
    grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.25fr);
  }

  /* .detail-row--reverse flips visual order via `order`, not track order, so
     the asymmetric split above must flip too or the image ends up stretched
     into the wider text track. */
  .detail-row--portrait.detail-row--reverse {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
  }
}

.detail-row--portrait .detail-row__media {
  aspect-ratio: 4 / 5;
}

.detail-row__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.detail-row__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-md);
  background-color: var(--color-primary);
  color: var(--color-text-on-dark);
  margin-bottom: var(--space-5);
}

.detail-row__icon svg {
  width: 26px;
  height: 26px;
}

.detail-row__title {
  margin-bottom: var(--space-4);
}

.detail-row__desc {
  margin-bottom: var(--space-6);
}

.detail-row .checklist {
  margin-bottom: var(--space-8);
}

@media (max-width: 1023px) {
  .detail-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .detail-row--reverse .detail-row__media {
    order: 0;
  }

  .detail-row__media {
    max-width: 480px;
    margin-inline: auto;
  }

  .detail-row--portrait .detail-row__media {
    max-width: 400px;
  }
}

/* Mobile only: icon sits beside the title instead of above it — scoped to
   .detail-row__content (Services page's Visitor Visa / Work Permit detail
   sections) rather than the bare .detail-row content div, since About's
   "Who We Are" row uses that same div shape with no icon at all and must
   stay untouched. Description, checklist, and button still span full
   width on their own rows below. */
@media (max-width: 767px) {
  .detail-row__content {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    column-gap: var(--space-3);
  }

  .detail-row__content .detail-row__icon {
    margin-bottom: 0;
  }

  .detail-row__content .detail-row__title {
    margin-bottom: 0;
  }

  .detail-row__content > .detail-row__desc,
  .detail-row__content > .checklist,
  .detail-row__content > .btn {
    grid-column: 1 / -1;
  }

  .detail-row__content > .detail-row__desc {
    margin-top: var(--space-4);
  }
}

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

.grid--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.grid--4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.grid--5 {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}

.grid--6 {
  grid-template-columns: repeat(6, minmax(0, 1fr));
}

/* Collapses earlier than the generic .grid--2 so the internally split
   .service-card--media items (image column + text column) never have to
   share a cramped outer 2-column track on tablet widths. */
@media (max-width: 1023px) {
  .grid--services {
    grid-template-columns: minmax(0, 1fr);
  }
}

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

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

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

/* ---------- Global accessibility ---------- */

/* Dark green outline: ~12:1 against the white/off-white backgrounds most
   of the site uses. The brand gold (--color-accent) only manages ~2.4:1
   against white — well under the 3:1 minimum for a visible UI focus
   indicator — so it's reserved for the dark-background override below. */
:focus-visible {
  outline: 3px solid var(--color-primary);
  outline-offset: 2px;
}

/* Header, footer, and CTA banners are dark green themselves, so the
   default dark-green outline would be invisible against them. Element
   type is included in each selector so this reliably outranks
   same-specificity component rules like .btn:focus-visible regardless
   of source order. */
.site-header a:focus-visible,
.site-header button:focus-visible,
.site-footer a:focus-visible,
.site-footer button:focus-visible,
.cta-banner a:focus-visible,
.cta-banner button:focus-visible {
  outline-color: var(--color-text-on-dark);
}

/* Respect users who disable smooth scrolling at the OS level; reset.css
   also covers this, kept here so main.css is self-descriptive on its own. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}


/* ===== components/buttons.css ===== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  line-height: 1;
  padding: var(--space-4) var(--space-6);
  border-radius: var(--radius-md);
  border: 2px solid transparent;
  white-space: nowrap;
  transition: background-color var(--transition-fast),
    border-color var(--transition-fast), color var(--transition-fast),
    transform var(--transition-fast);
}

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

.btn:focus-visible {
  outline: 3px solid var(--color-primary);
  outline-offset: 2px;
}

.btn svg {
  width: 1.1em;
  height: 1.1em;
  flex-shrink: 0;
}

/* Dark text on gold, not white: the raw brand gold only contrasts ~2.4:1
   with white text, which fails WCAG AA. Dark green text on gold clears
   6:1+, so accent buttons flip the mockups' white-on-gold to stay compliant. */
.btn--accent {
  background-color: var(--color-accent);
  color: var(--color-primary-dark);
}

.btn--accent:hover {
  background-color: var(--color-accent-dark);
}

.btn--primary {
  background-color: var(--color-primary);
  color: var(--color-text-on-dark);
}

.btn--primary:hover {
  background-color: var(--color-primary-light);
}

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

.btn--outline:hover {
  background-color: var(--color-primary);
  color: var(--color-text-on-dark);
}

.btn--sm {
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
}

.btn--lg {
  padding: var(--space-5) var(--space-8);
  font-size: var(--text-md);
}

.btn--block {
  width: 100%;
}

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Text link with a trailing arrow that nudges forward on hover.
   Reused by service-card links, section "View all" links, etc. */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-primary);
}

.link-arrow svg {
  width: 1em;
  height: 1em;
  transition: transform var(--transition-fast);
}

.link-arrow:hover {
  color: var(--color-accent-text);
}

.link-arrow:hover svg {
  transform: translateX(3px);
}


/* ===== components/header.css ===== */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background-color: var(--color-primary);
  transition: box-shadow var(--transition-base);
}

.site-header.is-scrolled {
  box-shadow: var(--shadow-md);
}

.site-header__inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-padding);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  min-height: 76px;
}

.site-logo {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-display);
  color: var(--color-text-on-dark);
  flex-shrink: 0;
}

.site-logo__mark {
  width: auto;
  height: 32px;
  flex-shrink: 0;
}

.site-logo__name {
  font-size: var(--text-lg);
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
}

.site-logo__tagline {
  display: block;
  font-family: var(--font-body);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  color: var(--color-accent);
  margin-top: 2px;
}

.main-nav {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

.main-nav__list {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.main-nav__link {
  position: relative;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text-on-dark-muted);
  padding-block: var(--space-2);
}

.main-nav__link:hover,
.main-nav__link[aria-current="page"] {
  color: var(--color-text-on-dark);
}

.main-nav__link[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 2px;
  background-color: var(--color-accent);
  border-radius: var(--radius-full);
}

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.site-header__phone {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-on-dark);
}

.site-header__phone svg {
  width: 1.1em;
  height: 1.1em;
  color: var(--color-accent);
}

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
}

.nav-toggle__bar {
  display: block;
  width: 22px;
  height: 2px;
  background-color: var(--color-text-on-dark);
  transition: transform var(--transition-fast), opacity var(--transition-fast);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) {
  transform: translateY(7px) 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(-7px) rotate(-45deg);
}

@media (max-width: 1023px) {
  .nav-toggle {
    display: flex;
  }

  .main-nav {
    position: fixed;
    inset: 76px 0 0 0;
    background-color: var(--color-primary);
    flex-direction: column;
    align-items: stretch;
    padding: var(--space-6) var(--container-padding);
    gap: var(--space-6);
    overflow-y: auto;
    clip-path: inset(0 0 0 100%);
    transition: clip-path var(--transition-base);
  }

  .main-nav.is-open {
    clip-path: inset(0 0 0 0%);
  }

  .main-nav__list {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
  }

  .main-nav__link {
    display: block;
    width: 100%;
    padding: var(--space-3) 0;
    font-size: var(--text-md);
  }

  .site-header__phone {
    display: none;
  }
}

/* Below ~480px the logo + hamburger + "Book Consultation" button no longer
   fit on one row (the button's text can't wrap due to white-space:nowrap,
   and flex items won't shrink past their content's intrinsic width), which
   pushes the button past the viewport edge. The CTA stays reachable via the
   hero section and the Contact Us nav link, so it's safe to drop here. */
@media (max-width: 479px) {
  .site-header__actions {
    display: none;
  }
}


/* ===== components/footer.css ===== */

.site-footer {
  background-color: var(--color-primary-dark);
  color: var(--color-text-on-dark-muted);
}

.site-footer__main {
  max-width: var(--container-max);
  margin-inline: auto;
  padding: var(--space-16) var(--container-padding) var(--space-12);
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr) minmax(0, 1fr) minmax(0, 0.9fr) minmax(0, 1.2fr);
  gap: var(--space-10);
}

.footer-brand__desc {
  color: var(--color-text-on-dark-muted);
  font-size: var(--text-sm);
  margin-block: var(--space-4);
  max-width: 32ch;
}

.footer-brand__social {
  display: flex;
  gap: var(--space-3);
}

.footer-brand__social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-full);
  background-color: rgba(255, 255, 255, 0.08);
  transition: background-color var(--transition-fast);
}

.footer-brand__social a:hover,
.footer-brand__social a:focus-visible {
  background-color: var(--color-accent);
}

.footer-brand__social svg {
  width: 16px;
  height: 16px;
  color: var(--color-text-on-dark);
}

.footer-col__title {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-on-dark);
  margin-bottom: var(--space-4);
}

.footer-col__list {
  display: grid;
  gap: var(--space-3);
}

.footer-col__list a {
  font-size: var(--text-sm);
  color: var(--color-text-on-dark-muted);
}

.footer-col__list a:hover {
  color: var(--color-accent);
}

.footer-contact-item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-size: var(--text-sm);
}

/* Email addresses and phone numbers are single unbreakable "words" — inside
   a flex row their default min-width:auto equals the full string length,
   which can force this column (and the whole footer grid track) wider than
   its share of the page on narrow/tablet widths. */
.footer-contact-item span,
.footer-contact-item a {
  min-width: 0;
  overflow-wrap: anywhere;
}

.footer-contact-item svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--color-accent);
}

.site-footer__bottom {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.site-footer__bottom-inner {
  max-width: var(--container-max);
  margin-inline: auto;
  padding: var(--space-5) var(--container-padding);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  font-size: var(--text-xs);
}

.site-footer__legal {
  display: flex;
  gap: var(--space-5);
}

.site-footer__legal a:hover {
  color: var(--color-accent);
}

@media (max-width: 1023px) {
  .site-footer__main {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
}

@media (max-width: 599px) {
  .site-footer__main {
    grid-template-columns: minmax(0, 1fr);
  }
}


/* ===== components/media-placeholder.css ===== */

/*
  Stand-in visual for destination photos we don't have yet — a flag on a
  brand-green gradient. Purely decorative, paired with aria-hidden="true"
  in markup since the adjacent country name already conveys the content.
  Swap for a real <img> (see destinationMediaMarkup in
  src/js/modules/destination-card.js) once a photo is sourced and run
  through scripts/process_content_images.py.
*/

.media-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-light) 100%);
  color: var(--color-text-on-dark);
}

.media-placeholder__flag {
  font-size: 3rem;
  line-height: 1;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.25));
}


/* ===== components/cards.css ===== */

.card {
  background-color: var(--color-bg);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-base), transform var(--transition-base);
}

.card--hoverable:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-4px);
}

@media (prefers-reduced-motion: reduce) {
  .card--hoverable:hover {
    transform: none;
  }
}

/* Service card: icon + image + title + description + link */
.service-card {
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.service-card__media {
  aspect-ratio: 4 / 5;
  overflow: hidden;
}

.service-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.service-card__body {
  padding: var(--space-6);
}

/* Split layout for image-bearing service cards (Home, About). The bare
   .service-card class is also used for icon-only overview cards on the
   Services page with no media element, so this stays a separate modifier
   rather than a change to the base class. */
.service-card--media {
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  align-items: stretch;
}

.service-card--media .service-card__media {
  aspect-ratio: auto;
}

.service-card--media .service-card__body {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

@media (max-width: 599px) {
  .service-card--media {
    grid-template-columns: minmax(0, 1fr);
  }

  .service-card--media .service-card__media {
    aspect-ratio: 4 / 5;
  }
}

.service-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-md);
  background-color: var(--color-primary);
  color: var(--color-text-on-dark);
  margin-bottom: var(--space-4);
}

.service-card__icon svg {
  width: 22px;
  height: 22px;
}

.service-card__title {
  margin-bottom: var(--space-2);
}

/* Mobile only: icon sits beside the title instead of above it. Covers both
   the plain .service-card__body (Services page overview cards) and the
   image-bearing .service-card--media variant (Home/About), so Visitor
   Visa / Work Permit read the same horizontal way everywhere they appear —
   the description paragraph and link still span full width below. */
@media (max-width: 767px) {
  .service-card__body,
  .service-card--media .service-card__body {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    column-gap: var(--space-3);
  }

  .service-card__icon {
    margin-bottom: 0;
  }

  .service-card__title {
    margin-bottom: 0;
  }

  .service-card__body > p {
    grid-column: 1 / -1;
    margin-top: var(--space-2);
  }

  .service-card__link {
    grid-column: 1 / -1;
  }
}

/* Spacing only — color/gap/hover behavior comes from the shared
   .link-arrow class this is always paired with in markup. */
.service-card__link {
  margin-top: var(--space-4);
}

/* Destination card: flag + photo + name + label + arrow link */
.destination-card {
  display: block;
  overflow: hidden;
  position: relative;
}

.destination-card__media {
  aspect-ratio: 4 / 3;
  overflow: hidden;
  position: relative;
}

.destination-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--transition-base);
}

.destination-card:hover .destination-card__media img {
  transform: scale(1.06);
}

.destination-card__body {
  padding: var(--space-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.destination-card__name {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-text);
}

.destination-card__label {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin-top: 2px;
}

.destination-card__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--radius-full);
  background-color: var(--color-bg-alt);
  color: var(--color-primary);
  transition: background-color var(--transition-fast);
  flex-shrink: 0;
}

.destination-card__arrow svg {
  width: 16px;
  height: 16px;
}

.destination-card:hover .destination-card__arrow {
  background-color: var(--color-accent);
  color: var(--color-primary-dark);
}

/* Closed work-permit destination (e.g. a temporarily paused opportunity):
   the card and its detail page stay live for when it reopens, but the
   photo is desaturated and a badge makes unavailability obvious at a
   glance rather than only on click-through. */
.destination-card__status-badge {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  z-index: 1;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background-color: var(--color-danger);
  color: var(--color-text-on-dark);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.destination-card--closed .destination-card__media img {
  filter: grayscale(70%);
  opacity: 0.7;
}

.destination-card--closed .destination-card__label {
  color: var(--color-danger);
  font-weight: 600;
}

/* Feature card: icon + title + description (Why Choose Us / Core Values) */
.feature-card {
  padding: var(--space-6);
  text-align: center;
}

.feature-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-full);
  background-color: var(--color-bg-alt);
  color: var(--color-primary);
  margin-bottom: var(--space-4);
}

.feature-card__icon svg {
  width: 26px;
  height: 26px;
}

.feature-card__title {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  margin-bottom: var(--space-2);
}

.feature-card__desc {
  font-size: var(--text-sm);
}

/* Mobile only: icon sits beside the title instead of above it, for every
   .feature-card (Core Values, Mission/Vision, and any other Why-Choose-Us
   style list) — description still spans full width below, left-aligned to
   match the new icon+title row instead of the desktop's centered layout. */
@media (max-width: 767px) {
  .feature-card {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    column-gap: var(--space-3);
    text-align: left;
  }

  .feature-card__icon {
    margin-bottom: 0;
  }

  .feature-card__title {
    margin-bottom: 0;
  }

  .feature-card__desc {
    grid-column: 1 / -1;
    margin-top: var(--space-2);
  }
}

/* Testimonial card */
.testimonial-card {
  padding: var(--space-6);
}

.testimonial-card__stars {
  display: flex;
  gap: 2px;
  color: var(--color-accent);
  margin-bottom: var(--space-4);
}

/* The 5 stars are wrapped in a single aria-hidden span (so screen readers
   get one "Rated 5 out of 5 stars" label instead of 5 unlabeled icons).
   The global reset makes <svg> display:block, so without this the span
   stacks its block-level star children vertically instead of in a row. */
.testimonial-card__stars span[aria-hidden] {
  display: inline-flex;
  gap: 2px;
}

.testimonial-card__stars svg {
  width: 16px;
  height: 16px;
}

.testimonial-card__quote {
  font-style: italic;
  color: var(--color-text);
  margin-bottom: var(--space-5);
}

.testimonial-card__author {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.testimonial-card__avatar {
  width: 64px;
  height: 64px;
  border-radius: var(--radius-full);
  object-fit: cover;
  flex-shrink: 0;
  box-shadow: var(--shadow-sm);
}

/* Used until real client photos are available: initials on a brand-gold
   gradient instead of a broken/missing <img>. Decorative — the visible
   name text next to it already identifies the person. */
.testimonial-card__avatar--initials {
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--color-accent) 0%, var(--color-accent-dark) 100%);
  color: var(--color-primary-dark);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-sm);
}

.testimonial-card__name {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
}

.testimonial-card__origin {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

/* Info card: icon + label + value (country detail grid, contact methods) */
.info-card {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5);
}

.info-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-full);
  background-color: var(--color-bg-alt);
  color: var(--color-primary);
  flex-shrink: 0;
}

.info-card__icon svg {
  width: 20px;
  height: 20px;
}

.info-card__label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: 2px;
}

.info-card__value {
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}


/* ===== components/cta-banner.css ===== */

.cta-banner {
  background-color: var(--color-primary);
  border-radius: var(--radius-xl);
  padding: var(--space-8) var(--space-10);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  flex-wrap: wrap;
  overflow: hidden;
  position: relative;
}

.cta-banner__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: var(--radius-full);
  background-color: rgba(255, 255, 255, 0.1);
  color: var(--color-text-on-dark);
  flex-shrink: 0;
}

.cta-banner__icon svg {
  width: 24px;
  height: 24px;
}

.cta-banner__content {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  flex: 1 1 320px;
}

.cta-banner__title {
  color: var(--color-text-on-dark);
  font-size: var(--text-xl);
  margin-bottom: var(--space-1);
}

.cta-banner__text {
  color: var(--color-text-on-dark-muted);
  font-size: var(--text-sm);
}

.cta-banner__actions {
  flex-shrink: 0;
}

@media (max-width: 767px) {
  .cta-banner {
    flex-direction: column;
    align-items: stretch;
    /* justify-content:space-between is meant for the desktop row (icon+text
       on the left, button on the right) — left as-is in a column layout it
       would stretch any extra vertical space into the gap between them. */
    justify-content: flex-start;
    text-align: center;
    padding: var(--space-6);
  }

  .cta-banner__content {
    flex-direction: column;
    /* The desktop "flex: 1 1 320px" sets flex-basis:320px meant as a
       minimum *width* for the row layout — in this column layout the same
       basis becomes a *height* instead, forcing a 320px-tall box regardless
       of actual content height. flex:none resets grow/shrink/basis so this
       sizes to its content like a normal block. */
    flex: none;
    text-align: center;
  }

  .cta-banner__actions {
    width: 100%;
  }

  .cta-banner__actions .btn {
    width: 100%;
  }
}


/* ===== components/badges.css ===== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  font-weight: 500;
  background-color: var(--color-bg-alt);
  color: var(--color-text);
}

/* Filter pill (Countries page: All / Asia / Europe / ...) */
.filter-pill {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text);
  background-color: var(--color-bg);
  transition: background-color var(--transition-fast), color var(--transition-fast),
    border-color var(--transition-fast);
}

.filter-pill:hover {
  border-color: var(--color-primary);
}

.filter-pill[aria-pressed="true"] {
  background-color: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-text-on-dark);
}

.filter-pill:focus-visible {
  outline: 3px solid var(--color-primary);
  outline-offset: 2px;
}


/* ===== components/forms.css ===== */

.form-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}

.form-field__label {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
}

.form-field__label .required {
  color: var(--color-danger);
}

.form-field input,
.form-field textarea,
.form-field select {
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background-color: var(--color-bg);
  color: var(--color-text);
  font-size: var(--text-sm);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.form-field textarea {
  min-height: 140px;
  resize: vertical;
}

.form-field input:focus-visible,
.form-field textarea:focus-visible,
.form-field select:focus-visible {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(11, 61, 46, 0.15);
}

.form-field input:invalid[data-touched="true"],
.form-field textarea:invalid[data-touched="true"] {
  border-color: var(--color-danger);
}

.form-field__error {
  font-size: var(--text-xs);
  color: var(--color-danger);
}

.form-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-5);
}

@media (max-width: 599px) {
  .form-row {
    grid-template-columns: minmax(0, 1fr);
  }
}

.form-note {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}

.form-note svg {
  width: 16px;
  height: 16px;
  color: var(--color-success);
  flex-shrink: 0;
}


/* ===== components/breadcrumb.css ===== */

.breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.breadcrumb a:hover {
  color: var(--color-primary);
}

.breadcrumb__current {
  color: var(--color-text);
  font-weight: 500;
}

.breadcrumb__separator {
  color: var(--color-border);
}


/* ===== components/process-steps.css ===== */

.process-steps {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--space-6);
  position: relative;
}

.process-steps::before {
  content: "";
  position: absolute;
  top: 22px;
  left: 10%;
  right: 10%;
  height: 1px;
  background-image: linear-gradient(
    to right,
    var(--color-border) 0,
    var(--color-border) 6px,
    transparent 6px,
    transparent 14px
  );
  background-size: 14px 1px;
  z-index: 0;
}

.process-step {
  position: relative;
  z-index: 1;
  text-align: center;
}

.process-step__number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-full);
  background-color: var(--color-accent);
  color: var(--color-primary-dark);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-sm);
  margin-bottom: var(--space-4);
}

.process-step__title {
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 600;
  margin-bottom: var(--space-1);
}

.process-step__desc {
  font-size: var(--text-sm);
}

@media (max-width: 1023px) {
  .process-steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .process-steps::before {
    display: none;
  }
}

@media (max-width: 479px) {
  .process-steps {
    grid-template-columns: minmax(0, 1fr);
  }
}


/* ===== components/checklist.css ===== */

.checklist {
  display: grid;
  gap: var(--space-3);
}

.checklist__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text);
}

/* Flex items default to min-width:auto (their own content's min-content
   size), which can force this row — and the grid track containing it —
   wider than its share of the page if the label text can't shrink enough. */
.checklist__item > span {
  min-width: 0;
}

.checklist__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-full);
  background-color: rgba(31, 138, 85, 0.12);
  color: var(--color-success);
  flex-shrink: 0;
  margin-top: 1px;
}

.checklist__icon svg {
  width: 12px;
  height: 12px;
}

@media (min-width: 768px) {
  .checklist--columns {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--space-6);
  }
}
