/* ==========================================================================
   Nexflow — bilingual (EN/TH) marketing site
   Design system: Mobbin — monochrome, shadow-free, stadium pills.
   Rules honoured: zero letter-spacing, no drop shadows (the segmented-control
   thumb is the sanctioned exception), tint-ladder elevation, 2px ink focus.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Surfaces */
  --canvas: #ffffff;
  --canvas-soft: #f3f3f3;
  --field: #f0f0f0;
  --hairline-soft: #f0f0f0;
  --hairline: #e0e0e0;

  /* Ink */
  --ink: #141414;
  --ink-soft: #262626;
  --text-muted: #707070;
  --text-faint: #adadad;
  --on-primary: #ffffff;

  /* The single chromatic accent — commercial signals only */
  --accent: #0066ff;

  /* Saans is commercial; this is the design doc's sanctioned system stack.
     Thai glyphs fall through to the platform's Thai face automatically. */
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI",
    Inter, "Helvetica Neue", Arial, "Noto Sans Thai", "Leelawadee UI",
    "Sukhumvit Set", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Geometry */
  --round-sm: 16px;
  --round-md: 24px;
  --round-full: 9999px;

  /* Spacing */
  --xxs: 4px;
  --xs: 8px;
  --sm: 12px;
  --md: 16px;
  --lg: 24px;
  --xl: 32px;
  --xxl: 48px;
  --section: 80px;
  --section-lg: 120px;

  /* Type */
  --w-display: clamp(44px, 7.4vw, 80px);
  --w-h1: clamp(36px, 5.6vw, 56px);
  --w-h2: clamp(28px, 3.9vw, 44px);
  --w-h3: clamp(21px, 2.1vw, 30px);
  --w-h4: 24px;
  --w-title: 20px;
  --w-body-lg: clamp(17px, 1.5vw, 20px);
  --w-body: 16px;
  --w-body-sm: 14px;
  --w-link: 16px;
  --w-label: 12px;
  --w-caption: 12px;

  /* Signature variable weights */
  --fw-heading: 652;
  --fw-body: 456;
  --fw-light: 300;

  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  /* Spring easings — the kinetics borrow: overshoot on entrance and hover
     instead of fixed-duration easing. Transform-only, so they composite
     cheaply. */
  --spring: cubic-bezier(0.34, 1.45, 0.5, 1);
  --spring-soft: cubic-bezier(0.22, 0.85, 0.25, 1.06);
  --shell: 1200px;
  --gutter: clamp(16px, 4vw, 32px);
  --nav-gap: 12px;
}

/* --------------------------------------------------------------------------
   2. Reset & base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

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

body {
  margin: 0;
  font-family: var(--sans);
  font-size: var(--w-body);
  font-weight: var(--fw-body);
  line-height: 1.38;
  color: var(--ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: var(--fw-heading);
  letter-spacing: 0;
  line-height: 1.13;
  text-wrap: balance;
}

h1,
h2 {
  line-height: 1;
}

p {
  margin: 0;
}

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

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

svg {
  display: block;
}

::selection {
  background: var(--ink);
  color: var(--on-primary);
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
  border-radius: var(--round-full);
}

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--on-primary);
  padding: var(--sm) var(--md);
  border-radius: var(--round-full);
}

.skip-link:focus {
  left: var(--md);
  top: var(--md);
}

/* --------------------------------------------------------------------------
   3. Floating nav pill
   -------------------------------------------------------------------------- */
/* Marks the moment the sticky nav has content sliding beneath it. The 8px
   sentinel sits at the document top; app.js toggles .is-stuck from an
   IntersectionObserver, so no scroll listener ever runs. */
.nav-sentinel {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 8px;
  pointer-events: none;
}

.site-nav {
  position: sticky;
  top: var(--nav-gap);
  z-index: 50;
  padding-inline: var(--gutter);
  pointer-events: none;
}

.nav-pill {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--sm);
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  height: 64px;
  padding: 6px 6px 6px var(--lg);
  background: var(--canvas-soft);
  border: 1px solid transparent;
  border-radius: var(--round-full);
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease),
    box-shadow 0.25s var(--ease);
}

/* Legibility once content slides beneath the pill */
.site-nav.is-stuck .nav-pill {
  background: rgba(243, 243, 243, 0.82);
  border-color: rgba(0, 0, 0, 0.05);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  backdrop-filter: saturate(180%) blur(16px);
}

.brand {
  display: flex;
  align-items: center;
  flex: none;
  margin-right: auto;
  border-radius: var(--round-sm);
}

.brand img {
  width: auto;
  height: 34px;
  transition: height 0.25s var(--ease);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 2px;
}

.nav-links a {
  position: relative;
  padding: 0 var(--sm);
  height: 36px;
  display: inline-flex;
  align-items: center;
  border-radius: var(--round-full);
  font-size: var(--w-link);
  font-weight: 600;
  white-space: nowrap;
  transition: background 0.2s var(--ease), color 0.2s var(--ease);
}

/* Ink underline grows from the left on hover — springs, doesn't fade */
.nav-links a::after {
  content: "";
  position: absolute;
  left: var(--sm);
  right: var(--sm);
  bottom: 5px;
  height: 2px;
  border-radius: 2px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.3s var(--spring-soft);
}

.nav-links a:hover::after {
  transform: scaleX(1);
}

.nav-links a:hover {
  background: var(--field);
}

.nav-actions {
  display: flex;
  align-items: center;
  gap: var(--xs);
  flex: none;
}

/* Segmented language control */
.lang-toggle {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  background: var(--field);
  border-radius: var(--round-full);
}

.lang-toggle button {
  min-width: 42px;
  height: 30px;
  padding: 0 var(--sm);
  border-radius: var(--round-full);
  font-size: var(--w-label);
  font-weight: 600;
  color: var(--text-muted);
  transition: background 0.2s var(--ease), color 0.2s var(--ease),
    box-shadow 0.2s var(--ease), transform 0.3s var(--spring);
}

.lang-toggle button:hover {
  color: var(--ink);
}

.lang-toggle button[aria-pressed="true"] {
  background: var(--canvas);
  color: var(--ink);
  transform: scale(1.04);
  /* Sanctioned exception: the active segment lifts off its track */
  box-shadow: 0 1px 2px rgba(20, 20, 20, 0.12);
}

/* Hamburger — mobile only */
.nav-burger {
  display: none;
  width: 40px;
  height: 40px;
  border-radius: var(--round-full);
  place-items: center;
  transition: background 0.2s var(--ease);
}

.nav-burger:hover {
  background: var(--field);
}

.nav-burger span {
  display: block;
  width: 16px;
  height: 1.5px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform 0.25s var(--ease);
}

.nav-burger span + span {
  margin-top: 5px;
}

.nav-burger[aria-expanded="true"] span:first-child {
  transform: translateY(3.25px) rotate(45deg);
}

.nav-burger[aria-expanded="true"] span:last-child {
  transform: translateY(-3.25px) rotate(-45deg);
}

/* Mobile disclosure panel */
.nav-panel {
  pointer-events: auto;
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  top: calc(100% + var(--xs));
  max-width: var(--shell);
  margin-inline: auto;
  padding: var(--xs);
  background: var(--canvas-soft);
  border-radius: var(--round-md);
  display: grid;
  gap: 2px;
  animation: panel-in 0.28s var(--spring);
}

.nav-panel[hidden] {
  display: none;
}

.nav-panel a {
  padding: var(--sm) var(--md);
  border-radius: var(--round-full);
  font-size: var(--w-link);
  font-weight: 600;
}

.nav-panel a:hover {
  background: var(--field);
}

.nav-panel .btn-pill {
  margin-top: var(--xxs);
  width: 100%;
}

@keyframes panel-in {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--xs);
  height: 44px;
  padding: 0 var(--lg);
  border-radius: var(--round-full);
  font-size: var(--w-link);
  font-weight: 600;
  white-space: nowrap;
  text-align: center;
  transition: background 0.2s var(--ease), color 0.2s var(--ease),
    border-color 0.2s var(--ease), transform 0.12s ease-out;
}

.btn-pill:active {
  transform: scale(0.97);
}

.btn-primary {
  position: relative;
  overflow: hidden;
  background: var(--ink);
  color: var(--on-primary);
}

/* Shine sweep — a flat, light-only pass across the ink surface */
.btn-primary::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    110deg,
    transparent 30%,
    rgba(255, 255, 255, 0.22) 50%,
    transparent 70%
  );
  transform: translateX(-130%);
  transition: transform 0.7s var(--ease);
  pointer-events: none;
}

.btn-primary:hover {
  background: var(--ink-soft);
  transform: translateY(-1px);
}

.btn-primary:hover::before {
  transform: translateX(130%);
}

.btn-outline {
  background: var(--canvas);
  color: var(--ink);
  border: 1px solid var(--hairline);
}

.btn-outline:hover {
  border-color: var(--ink);
  background: var(--field);
  transform: translateY(-1px);
}

.nav-cta {
  height: 40px;
  padding: 0 var(--md);
}

/* --------------------------------------------------------------------------
   5. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(48px, 6.5vw, 96px) clamp(48px, 6vw, 88px);
}

/* Aurora — two soft gradient blobs drift slowly behind the headline.
   Painted with radial-gradients (no filter), so the drift is transform-only
   and stays cheap to composite. */
.hero::before,
.hero::after {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
  border-radius: 50%;
}

.hero::before {
  width: min(680px, 80vw);
  height: min(680px, 80vw);
  top: -18%;
  right: -8%;
  background: radial-gradient(
    closest-side,
    rgba(0, 102, 255, 0.14),
    transparent 72%
  );
  animation: aurora-a 22s ease-in-out infinite alternate;
}

.hero::after {
  width: min(560px, 70vw);
  height: min(560px, 70vw);
  bottom: -24%;
  left: -10%;
  background: radial-gradient(
    closest-side,
    rgba(0, 40, 90, 0.1),
    transparent 72%
  );
  animation: aurora-b 26s ease-in-out infinite alternate;
}

.hero-inner {
  max-width: 880px;
}

.eyebrow {
  display: inline-block;
  font-size: var(--w-caption);
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: var(--sm);
}

/* The measure is governed by .hero-inner so the headline breaks into two
   generous lines on desktop and wraps naturally on phones. */
.hero h1 {
  font-size: var(--w-h1);
}

.lead {
  font-size: var(--w-body-lg);
  font-weight: var(--fw-light);
  line-height: 1.38;
  color: var(--ink-soft);
  max-width: 62ch;
}

.hero .lead {
  margin-top: var(--lg);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sm);
  margin-top: var(--lg);
}

/* --------------------------------------------------------------------------
   6. Sections
   -------------------------------------------------------------------------- */
.section {
  padding-block: var(--section);
}

.section-head {
  max-width: 720px;
  margin-bottom: var(--xl);
}

.section-head h2 {
  font-size: var(--w-h2);
}

.section-head p {
  margin-top: var(--sm);
  font-size: var(--w-body-lg);
  font-weight: var(--fw-light);
  color: var(--ink-soft);
}

.band {
  background: var(--canvas-soft);
  border-top: 1px solid var(--hairline-soft);
  border-bottom: 1px solid var(--hairline-soft);
}

[id] {
  scroll-margin-top: 96px;
}

/* --------------------------------------------------------------------------
   7. Marquee (full-bleed)
   -------------------------------------------------------------------------- */
.marquee {
  overflow: hidden;
  background: var(--ink);
  color: var(--on-primary);
}

.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee 38s linear infinite;
  will-change: transform;
}

.marquee:hover .marquee-track,
.marquee:focus-within .marquee-track {
  animation-play-state: paused;
}

@keyframes marquee {
  from {
    transform: translate3d(0, 0, 0);
  }
  to {
    transform: translate3d(-50%, 0, 0);
  }
}

.brand-chip {
  display: flex;
  align-items: center;
  gap: var(--sm);
  height: 72px;
  padding-inline: var(--xl);
  white-space: nowrap;
  border-right: 1px solid rgba(255, 255, 255, 0.14);
  transition: transform 0.3s var(--spring-soft);
}

.marquee:hover .brand-chip:hover {
  transform: translateY(-2px);
}

.brand-chip .ic {
  width: 32px;
  height: 32px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 30%;
  background: var(--canvas-soft);
  color: var(--ink);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}

.brand-chip .nm {
  font-size: var(--w-h4);
  font-weight: var(--fw-heading);
}

/* --------------------------------------------------------------------------
   8. Catalog
   -------------------------------------------------------------------------- */
.catalog {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--lg);
}

.card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: var(--lg);
  background: var(--canvas);
  border: 1px solid var(--hairline-soft);
  border-radius: var(--round-md);
  transition: border-color 0.3s var(--spring-soft),
    transform 0.35s var(--spring-soft);
}

.card:hover {
  border-color: var(--hairline);
  transform: translateY(-4px);
}

/* Cursor spotlight — follows the pointer inside the card (--mx/--my set by
   app.js), painted as a soft ink wash so the accent blue stays scarce. */
.card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(
    320px circle at var(--mx, 50%) var(--my, 50%),
    rgba(20, 20, 20, 0.05),
    transparent 68%
  );
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}

.card:hover::after {
  opacity: 1;
}

.card .num {
  font-size: var(--w-caption);
  font-weight: 600;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.card h3 {
  margin-top: var(--xs);
  font-size: var(--w-h3);
  line-height: 1.13;
}

.card .desc {
  margin-top: var(--sm);
  font-size: var(--w-body);
  line-height: 1.43;
  color: var(--text-muted);
}

.card .tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--xs);
  margin-top: var(--md);
  margin-bottom: var(--md);
}

.pill {
  padding: var(--xxs) var(--sm);
  border-radius: var(--round-full);
  background: var(--canvas-soft);
  color: var(--ink);
  font-size: var(--w-caption);
  font-weight: 600;
}

/* margin-top: auto pins the note to the card floor, so the nine cards keep
   a shared baseline for the hairline regardless of copy length. */
.card .note {
  margin-top: auto;
  padding-top: var(--md);
  border-top: 1px solid var(--hairline-soft);
  font-size: var(--w-body-sm);
  line-height: 1.5;
  color: var(--ink-soft);
}

.work-group-head {
  max-width: 800px;
  margin-bottom: var(--lg);
}

.work-group-head h3 {
  font-size: var(--w-h3);
}

.work-group-head p {
  margin-top: var(--sm);
  color: var(--text-muted);
}

.work-group-head--research {
  margin-top: var(--xxl);
}

/* --------------------------------------------------------------------------
   9. Offerings
   -------------------------------------------------------------------------- */
.offerings {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--lg);
}

.offering {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: var(--lg);
  background: var(--canvas);
  border: 1px solid var(--hairline-soft);
  border-radius: var(--round-md);
  transition: border-color 0.3s var(--spring-soft),
    transform 0.35s var(--spring-soft);
}

.offering:hover {
  border-color: var(--hairline);
  transform: translateY(-3px);
}

.offering::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(
    340px circle at var(--mx, 50%) var(--my, 50%),
    rgba(20, 20, 20, 0.04),
    transparent 68%
  );
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}

.offering:hover::after {
  opacity: 1;
}

.offering .tag {
  font-size: var(--w-caption);
  font-weight: 600;
  color: var(--text-muted);
}

.offering h3,
.offering h4 {
  margin-top: var(--xs);
  font-size: var(--w-h3);
  line-height: 1.13;
}

.offering .verdict {
  margin-top: var(--sm);
  font-size: var(--w-body-lg);
  font-weight: var(--fw-light);
  line-height: 1.38;
  color: var(--ink-soft);
}

.offering .stack {
  margin-top: var(--md);
  padding: var(--sm) var(--md);
  border-radius: var(--round-sm);
  background: var(--field);
  font-size: var(--w-body-sm);
  line-height: 1.5;
  color: var(--text-muted);
}

.badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--xs);
  margin-top: var(--md);
}

.badge {
  padding: var(--xxs) var(--sm);
  border-radius: var(--round-full);
  background: var(--canvas-soft);
  color: var(--ink);
  font-size: var(--w-caption);
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   9b. Track record rows
   Editorial index rows instead of a third card grid: tag + title on the
   left, body on the right, hairline rules between entries.
   -------------------------------------------------------------------------- */
.work-list {
  display: grid;
}

.work-item {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--md) var(--xl);
  align-items: start;
  padding-block: var(--xl);
  border-top: 1px solid var(--hairline-soft);
}

.work-item:first-child {
  border-top: 0;
  padding-top: 0;
}

.work-item .tag {
  font-size: var(--w-caption);
  font-weight: 600;
  color: var(--text-muted);
}

.work-item h4 {
  margin-top: var(--xs);
  font-size: var(--w-h4);
  line-height: 1.25;
}

/* Denser prose than the offering cards: these are longer paragraphs. */
.work-item .verdict {
  margin-top: 0;
  font-size: var(--w-body);
  line-height: 1.5;
  color: var(--ink-soft);
}

.work-stack {
  margin-top: var(--md);
  font-size: var(--w-body-sm);
  line-height: 1.5;
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   10. About
   -------------------------------------------------------------------------- */
.about-grid {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: var(--xl);
  align-items: start;
}

.about-heading {
  font-size: var(--w-h3);
  line-height: 1.13;
}

.about-body {
  margin-top: var(--sm);
  font-size: var(--w-body);
  line-height: 1.5;
  color: var(--ink-soft);
}

.about-body + .about-heading {
  margin-top: var(--xl);
}

.about-panel {
  padding: var(--lg);
  border-radius: var(--round-md);
  background: var(--canvas-soft);
}

.steps {
  margin-top: var(--md);
}

.steps li {
  display: flex;
  gap: var(--md);
  padding: var(--sm) 0;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  font-size: var(--w-body);
  line-height: 1.45;
  color: var(--ink-soft);
}

.steps li:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.steps .idx {
  flex: none;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--ink);
  color: var(--on-primary);
  font-size: var(--w-label);
  font-weight: 600;
}

.steps strong {
  font-weight: var(--fw-heading);
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   11. Form
   -------------------------------------------------------------------------- */
.form-wrap {
  max-width: 680px;
}

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

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--md);
}

/* Honeypot — visually removed, still focusable by bots only */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.field {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.field label {
  font-size: var(--w-body-sm);
  font-weight: 600;
  color: var(--ink-soft);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  font: inherit;
  font-weight: var(--fw-body);
  color: var(--ink);
  background: var(--field);
  border: 2px solid transparent;
  border-radius: var(--round-sm);
  padding: var(--sm) var(--md);
  transition: border-color 0.18s var(--ease), background 0.18s var(--ease);
}

.field textarea {
  resize: vertical;
  min-height: 132px;
  line-height: 1.45;
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--text-faint);
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--ink);
  background: var(--canvas);
}

/* Native select needs a visible affordance */
.select-wrap {
  position: relative;
}

.select-wrap select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--xxl);
  cursor: pointer;
}

.select-wrap::after {
  content: "";
  position: absolute;
  right: var(--md);
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -6px;
  border-right: 1.5px solid var(--ink);
  border-bottom: 1.5px solid var(--ink);
  transform: rotate(45deg);
  pointer-events: none;
}

.form .btn-pill {
  justify-self: start;
  margin-top: var(--xxs);
}

.form-feedback {
  margin-top: var(--md);
  min-height: 1.4em;
  font-size: var(--w-body-sm);
  color: var(--text-muted);
}

.form-feedback[data-state="error"] {
  color: var(--ink);
  font-weight: 600;
}

/* Invalidate only after a submit attempt — never on first paint */
.form.was-submitted input:invalid,
.form.was-submitted textarea:invalid {
  border-color: var(--ink);
}

/* --------------------------------------------------------------------------
   12. Footer
   -------------------------------------------------------------------------- */
.footer {
  margin-top: var(--xxl);
  padding-block: var(--section-lg) var(--section);
  background: var(--ink);
  color: var(--on-primary);
  border-radius: var(--round-md) var(--round-md) 0 0;
}

.footer-wordmark {
  font-size: var(--w-display);
  font-weight: var(--fw-heading);
  line-height: 1;
}

.footer-tagline {
  margin-top: var(--sm);
  max-width: 52ch;
  font-size: var(--w-body);
  color: var(--text-faint);
}

.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: var(--xl);
  margin-top: var(--xl);
  padding-top: var(--xl);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}

.footer-col h4 {
  margin-bottom: var(--md);
  font-size: var(--w-caption);
  font-weight: 600;
  color: var(--text-faint);
}

.footer-col a {
  position: relative;
  display: block;
  padding: var(--xs) 0;
  font-size: var(--w-body-sm);
  color: rgba(255, 255, 255, 0.82);
  transition: color 0.18s var(--ease);
}

.footer-col a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4px;
  height: 1px;
  background: var(--on-primary);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.3s var(--spring-soft);
}

.footer-col a:hover {
  color: var(--on-primary);
}

.footer-col a:hover::after {
  transform: scaleX(1);
}

.footer-lang {
  position: relative;
  display: block;
  padding: var(--xs) 0;
  font-size: var(--w-body-sm);
  color: rgba(255, 255, 255, 0.82);
  text-align: left;
  transition: color 0.18s var(--ease);
}

.footer-lang::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4px;
  height: 1px;
  background: var(--on-primary);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.3s var(--spring-soft);
}

.footer-lang:hover::after {
  transform: scaleX(1);
}

.footer-lang:hover {
  color: var(--on-primary);
}

.footer-lang[aria-pressed="true"] {
  color: var(--on-primary);
  font-weight: 600;
}

.footer-base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--md);
  margin-top: var(--section);
  padding-top: var(--md);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  font-size: var(--w-caption);
  color: var(--text-faint);
}

/* --------------------------------------------------------------------------
   13. Entrance / scroll reveal
   -------------------------------------------------------------------------- */
[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 24px, 0);
}

/* Cards also settle in with a whisper of scale for depth */
.catalog [data-reveal],
.offerings [data-reveal] {
  transform: translate3d(0, 24px, 0) scale(0.985);
}

/* Row-aware stagger: cards in the same visual row arrive together, and each
   subsequent row follows. Uses nth-child so the markup stays style-free. */
.catalog .card:nth-child(3n + 2),
.offerings .offering:nth-child(2n) {
  --reveal-delay: 80ms;
}

.catalog .card:nth-child(3n + 3) {
  --reveal-delay: 160ms;
}

@media (max-width: 1080px) {
  .catalog .card:nth-child(n) {
    --reveal-delay: 0ms;
  }

  .catalog .card:nth-child(2n) {
    --reveal-delay: 80ms;
  }
}

@media (max-width: 768px) {
  .catalog .card:nth-child(n),
  .offerings .offering:nth-child(n) {
    --reveal-delay: 0ms;
  }
}

[data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition: opacity 0.8s var(--spring-soft), transform 0.8s var(--spring-soft);
  transition-delay: var(--reveal-delay, 0ms);
}

/* Hero plays immediately on load rather than on scroll */
.hero [data-reveal] {
  animation: rise 0.9s var(--spring) both;
  animation-delay: var(--reveal-delay, 0ms);
  opacity: 1;
  transform: none;
}

/* The eyebrow springs in with a pop of its own */
.hero .eyebrow {
  animation: pop 0.7s var(--spring) both;
  animation-delay: var(--reveal-delay, 0ms);
}

@keyframes pop {
  from {
    opacity: 0;
    transform: translateY(-8px) scale(0.9);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes aurora-a {
  from {
    transform: translate3d(0, 0, 0) scale(1);
  }
  to {
    transform: translate3d(-40px, 34px, 0) scale(1.14);
  }
}

@keyframes aurora-b {
  from {
    transform: translate3d(0, 0, 0) scale(1);
  }
  to {
    transform: translate3d(46px, -30px, 0) scale(1.18);
  }
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translate3d(0, 18px, 0);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   14. Thai typography
   Thai stacks vowels and tone marks above and below the baseline, so it needs
   materially more leading than Latin at the same size. Without this the marks
   collide and the copy reads as cramped.
   -------------------------------------------------------------------------- */
html[lang="th"] body {
  line-height: 1.62;
}

/* Thai stacks tone marks above and vowel marks below the baseline, so its
   glyphs claim far more vertical space than Latin. These values sit
   deliberately above the Latin spec: at 1.0–1.25 leading, one line's marks
   land inside the next line's glyph box. Leading this loose is a requirement
   of the script, not a style preference. */
html[lang="th"] h1,
html[lang="th"] h2 {
  line-height: 1.34;
}

html[lang="th"] h3,
html[lang="th"] h4 {
  line-height: 1.42;
}

html[lang="th"] .lead,
html[lang="th"] .offering .verdict {
  line-height: 1.68;
}

html[lang="th"] .card .desc,
html[lang="th"] .card .note,
html[lang="th"] .offering .stack,
html[lang="th"] .work-item .verdict,
html[lang="th"] .work-stack,
html[lang="th"] .steps li,
html[lang="th"] .about-body,
html[lang="th"] .footer-col a,
html[lang="th"] .field input,
html[lang="th"] .field select,
html[lang="th"] .field textarea,
html[lang="th"] .brand-chip .nm {
  line-height: 1.62;
}

/* Thai glyphs read smaller than Latin at the same point size, so the reading
   tokens are nudged up. Overriding the tokens keeps every component in step,
   rather than patching selectors one at a time. Nav and button labels keep
   their Latin sizes so both languages occupy the same header space. */
html[lang="th"] {
  --w-body: 17px;
  --w-body-sm: 15px;
  --w-label: 13px;
  --w-caption: 13px;
  line-break: loose;
  overflow-wrap: break-word;
}

/* Thai runs longer than English, so section intros get a wider measure to keep
   the line count comparable. */
html[lang="th"] .section-head {
  max-width: 800px;
}

/* --------------------------------------------------------------------------
   15. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1280px) {
  :root {
    --section: 72px;
    --section-lg: 104px;
  }
}

/* Grids shed a column each */
@media (max-width: 1080px) {
  .catalog {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .offerings,
  .about-grid {
    grid-template-columns: 1fr;
  }

  .work-item {
    grid-template-columns: 1fr;
    gap: var(--sm);
  }

  .footer-grid {
    grid-template-columns: 1fr 1fr;
  }
}

/* Five inline links need room alongside the brand, language control and CTA. */
@media (max-width: 1080px) {
  .nav-links {
    display: none;
  }

  .nav-burger {
    display: grid;
  }

  .nav-pill {
    padding-left: var(--md);
  }
}

@media (max-width: 768px) {
  :root {
    --section: 56px;
    --section-lg: 80px;
    --nav-gap: 8px;
  }

  .nav-pill {
    height: 56px;
    padding: 5px 5px 5px var(--md);
  }

  .brand img {
    height: 28px;
  }

  .nav-cta {
    height: 36px;
    padding: 0 var(--sm);
  }

  .catalog {
    grid-template-columns: 1fr;
  }

  .form-row {
    grid-template-columns: 1fr;
  }

  .brand-chip {
    height: 64px;
    padding-inline: var(--lg);
  }

  .brand-chip .nm {
    font-size: var(--w-title);
  }

  .footer-grid {
    grid-template-columns: 1fr;
    gap: var(--lg);
  }

  .footer {
    border-radius: var(--round-sm) var(--round-sm) 0 0;
  }

  [id] {
    scroll-margin-top: 80px;
  }
}

@media (max-width: 420px) {
  .brand img {
    height: 24px;
  }

  .lang-toggle button {
    min-width: 34px;
    padding: 0 var(--xs);
  }

  .nav-cta {
    display: none;
  }

  .hero-actions .btn-pill {
    width: 100%;
  }
}

/* --------------------------------------------------------------------------
   16. Motion preferences
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  .marquee-track {
    animation: none;
    transform: none;
  }

  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
}

@media print {
  .site-nav,
  .marquee,
  .hero-actions {
    display: none;
  }
}
