/* ==========================================================================
   Viễn Minh — maintenance screen

   The Tailwind / tw-animate-css / shadcn imports that used to head this file
   were removed: nothing on this route uses a utility class, and they cost
   ~173 KB of decoded CSS (27 KB over the wire) on a one-screen page. Restore
   them if another route is ever added that needs them.
   ========================================================================== */

/* Layout contract: one viewport, two columns on desktop, stacked below.
   The artwork and the message live in separate grid cells, so the panel can
   never cover the engineer at any size.
   ========================================================================== */

:root {
  /* Neutrals — cool graphite, tuned to sit under the illustration's periwinkle */
  --ink-900: #0c211e;
  --ink-800: #10322d;
  --ink-700: #1a413b;
  --ink-500: #48605c;
  --ink-400: #5b706c;  /* 4.9:1 on the panel — #647a76 measured 4.33 and failed AA */
  --ink-300: #8b9c99;

  /* Brand viridian, taken from the company mark */
  --brand-900: #0c3a34;
  --brand-800: #0f473f;
  --brand-700: #12564d;
  --brand-600: #17685d;
  --brand-200: #b9d5ce;

  /* Warm signal accent, taken from the mark's dot */
  --amber: #c8804a;
  --error: #b04a2f;

  /* Periwinkle bridge to the illustration */
  --peri-100: #eff3fc;
  --peri-200: #dfe8f8;
  --peri-400: #a8c0e6;

  --canvas: #f5f7f5;
  --white: #ffffff;

  --hairline: rgba(14, 48, 43, .10);
  --hairline-strong: rgba(14, 48, 43, .16);

  /* One easing token for the whole entrance choreography */
  --e: cubic-bezier(.22, 1, .36, 1);
  --e-out: cubic-bezier(.33, 1, .68, 1);

  /* Pointer parallax, written by JS; 0 when idle or unsupported */
  --px: 0;
  --py: 0;

  --gutter: clamp(20px, 4.4vw, 76px);
  /* Message column. Wide enough that the one-line headline keeps a usable size
     at every viewport; every other measurement below is derived from it. */
  --panel: clamp(330px, 28vw, 460px);
  --panel-gap: clamp(13px, 1.15vw, 17px);

  /* Width of the centred content block. The artwork is contain-fitted, so on a
     tall screen a fixed width leaves a band of empty space above it. Growing
     the shell with viewport height keeps the group filling the screen instead:
     1.56 is the artwork's aspect ratio, the offset covers the panel column,
     the gap and the gutters. */
  --shell: min(96vw, max(1200px, calc(100svh * 1.56 + var(--panel) + 170px)));
}

* { box-sizing: border-box; }

html { height: 100%; -webkit-text-size-adjust: 100%; }

body {
  min-height: 100%;
  margin: 0;
  background: var(--canvas);
  color: var(--ink-800);
  font-family: Geist, 'Geist Fallback', ui-sans-serif, system-ui, 'Segoe UI', Roboto, Arial, sans-serif;
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Deliberately NOT overflow:hidden — on a short landscape phone the CTA must
     stay reachable rather than being clipped out of an unscrollable page. */
  overscroll-behavior: none;
}

a { color: inherit; text-decoration: none; }
button, a { -webkit-tap-highlight-color: transparent; }
::selection { background: var(--brand-200); color: var(--brand-900); }

.page {
  position: relative;
  min-height: 100svh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  overflow: clip;
  isolation: isolate;
}

/* --------------------------------------------------------------------------
   Ambient background: a slow aurora mesh plus a fine grain.
   Radial gradients rather than filter:blur() — same softness, no GPU blur cost.
   -------------------------------------------------------------------------- */

.aurora {
  position: absolute;
  z-index: 0;
  inset: -12%;
  pointer-events: none;
}
.aurora i {
  position: absolute;
  display: block;
  border-radius: 50%;
  will-change: transform;
}
.aurora-a {
  top: 2%; left: -4%;
  width: 62%; height: 76%;
  background: radial-gradient(circle at 50% 50%, rgba(163, 189, 230, .60), rgba(168, 192, 230, 0) 68%);
  animation: drift-a 19s var(--e-out) infinite;
}
.aurora-b {
  right: -6%; bottom: -12%;
  width: 58%; height: 70%;
  background: radial-gradient(circle at 50% 50%, rgba(228, 197, 169, .46), rgba(226, 199, 174, 0) 68%);
  animation: drift-b 25s var(--e-out) infinite;
}
.aurora-c {
  top: 34%; left: 42%;
  width: 46%; height: 52%;
  background: radial-gradient(circle at 50% 50%, rgba(146, 196, 183, .30), rgba(150, 197, 185, 0) 70%);
  animation: drift-c 16s var(--e-out) infinite;
}

@keyframes drift-a {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(11%, -8%, 0) scale(1.16); }
}
@keyframes drift-b {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1.04); }
  50%      { transform: translate3d(-13%, 7%, 0) scale(.88); }
}
@keyframes drift-c {
  0%, 100% { transform: translate3d(0, 0, 0) scale(.96); }
  50%      { transform: translate3d(8%, 11%, 0) scale(1.18); }
}

.grain {
  position: absolute;
  z-index: 1;
  inset: 0;
  pointer-events: none;
  opacity: .42;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

/* --------------------------------------------------------------------------
   Top bar
   -------------------------------------------------------------------------- */

.topbar {
  position: relative;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding: clamp(18px, 2.6vw, 34px) var(--gutter);
  animation: fade-down .7s var(--e) both;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  border-radius: 14px;
}
.brand-mark {
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 13px;
  background: linear-gradient(155deg, var(--brand-600), var(--brand-900));
  color: #eaf5f1;
  box-shadow:
    0 1px 1px rgba(12, 58, 52, .18),
    0 8px 20px -6px rgba(12, 58, 52, .34),
    inset 0 1px 0 rgba(255, 255, 255, .22);
}
.brand-copy strong {
  display: block;
  color: var(--ink-800);
  font-size: 13px;
  font-weight: 640;
  letter-spacing: .17em;
  line-height: 1;
}
.brand-copy small {
  display: block;
  margin-top: 6px;
  color: var(--ink-400);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: .05em;
  line-height: 1;
}

/* Segmented language control with a sliding thumb */
.lang {
  position: relative;
  display: flex;
  align-items: center;
  padding: 4px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: rgba(255, 255, 255, .5);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .7);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.lang-thumb {
  position: absolute;
  z-index: 0;
  top: 4px;
  left: 4px;
  width: calc((100% - 8px) / 2);
  height: calc(100% - 8px);
  border-radius: 999px;
  background: var(--white);
  box-shadow:
    0 1px 2px rgba(14, 48, 43, .10),
    0 4px 12px -4px rgba(14, 48, 43, .16);
  transition: transform .42s var(--e);
}
:root[data-lang='en'] .lang-thumb { transform: translateX(100%); }

.lang-btn {
  position: relative;
  z-index: 1;
  min-width: 66px;
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 12px;
  border-radius: 999px;
  color: var(--ink-400);
  cursor: pointer;
  font-size: 11px;
  font-weight: 650;
  letter-spacing: .08em;
  transition: color .28s var(--e);
}
:root[data-lang='vi'] .lang-btn[data-lang-value='vi'],
:root[data-lang='en'] .lang-btn[data-lang-value='en'] { color: var(--ink-800); }
.lang-btn .flag {
  display: block;
  flex: 0 0 auto;
  border-radius: 2.5px;
  box-shadow: 0 0 0 1px rgba(14, 48, 43, .14);
  opacity: .55;
  transition: opacity .28s var(--e);
}
:root[data-lang='vi'] .lang-btn[data-lang-value='vi'] .flag,
:root[data-lang='en'] .lang-btn[data-lang-value='en'] .flag { opacity: 1; }

/* --------------------------------------------------------------------------
   Stage — the two-column contract
   -------------------------------------------------------------------------- */

.stage {
  position: relative;
  z-index: 5;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--panel);
  /* An explicit, shrinkable row: without it the implicit `auto` row is sized by
     the artwork's intrinsic height, which pushes the page past the viewport on
     short landscape screens. */
  grid-template-rows: minmax(0, 1fr);
  align-items: center;
  gap: clamp(12px, 2.2vw, 40px);
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding: 0 var(--gutter) 0;
}

.art {
  position: relative;
  min-height: 0;
  height: 100%;
  /* Bleed past the page gutter so the group reads generous rather than boxed */
  margin: 0 0 0 calc(var(--gutter) * -1 - 2.4vw);
  display: grid;
  place-items: end center;
  animation: art-arrive 1.05s .06s var(--e) both;
}
/* Soft contact shadow so the cut-out group sits on a surface instead of floating */
.art::after {
  content: '';
  position: absolute;
  z-index: -1;
  top: 50%;
  left: 46%;
  width: 74%;
  translate: 0 calc(50% - 4px);
  height: 9%;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 50%, rgba(38, 66, 92, .16), rgba(38, 66, 92, 0) 70%);
}
.art picture { display: contents; }
/* Out of flow on purpose: an in-flow image contributes its intrinsic height to
   the grid's min-content size, which grew the page past the viewport on short
   screens. Absolute positioning lets the row shrink, so the artwork scales to
   whatever space is left and the page only ever grows if the message itself
   does not fit. */
.art img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: right center;
  transform: translate3d(calc(var(--px) * -14px), calc(var(--py) * -10px), 0);
  animation: art-float 7.5s 1.1s ease-in-out infinite;
}
@keyframes art-float {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -10px; }
}

/* --------------------------------------------------------------------------
   Message panel — light glass, not a heavy card
   -------------------------------------------------------------------------- */

.panel {
  position: relative;
  /* Lets the headline size itself against the panel rather than the viewport,
     so a single line always fits whatever width the column ends up. */
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  gap: var(--panel-gap);
  padding: clamp(26px, 2.1vw, 36px) clamp(26px, 2.1vw, 34px) clamp(24px, 1.9vw, 32px);
  border: 1px solid rgba(255, 255, 255, .8);
  border-radius: 24px;
  background: linear-gradient(168deg, rgba(255, 255, 255, .74), rgba(255, 255, 255, .52));
  box-shadow:
    0 0 0 1px rgba(14, 48, 43, .045),
    0 2px 4px rgba(16, 45, 41, .03),
    0 14px 30px -14px rgba(16, 45, 41, .14),
    0 46px 84px -44px rgba(16, 45, 41, .30);
  backdrop-filter: blur(18px) saturate(112%);
  -webkit-backdrop-filter: blur(18px) saturate(112%);
  margin-bottom: clamp(18px, 3.5vh, 46px);
  transform: translate3d(calc(var(--px) * 6px), calc(var(--py) * 5px), 0);
  animation: panel-arrive .85s .12s var(--e) both;
}
/* A slow pass of light across the glass, then a long rest. */
.panel::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(104deg, transparent 40%, rgba(255, 255, 255, .5) 50%, transparent 60%);
  transform: translateX(-135%);
  animation: panel-sheen 11s 2.6s ease-in-out infinite both;
}
.panel > * { position: relative; z-index: 1; }
@keyframes panel-sheen {
  0%        { transform: translateX(-135%); }
  16%, 100% { transform: translateX(135%); }
}

/* Hairline of light along the top edge */
.panel::before {
  content: '';
  position: absolute;
  top: 0;
  right: 22%;
  left: 22%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .95), transparent);
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--ink-500);
  font-size: 10px;
  font-weight: 680;
  letter-spacing: .17em;
  line-height: 1.4;
  text-transform: uppercase;
  animation: fade-up .7s .18s var(--e) both;
}
.eyebrow::after {
  content: '';
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--hairline-strong), transparent);
}
.dot {
  position: relative;
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--amber);
}
.dot::before,
.dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--amber);
  animation: ping 2.8s var(--e-out) infinite;
}
.dot::after { animation-delay: 1.4s; }

@keyframes ping {
  0%   { transform: scale(1);   opacity: .55; }
  70%  { transform: scale(3.4); opacity: 0; }
  100% { transform: scale(3.4); opacity: 0; }
}

.headline {
  margin: 0;
  color: var(--brand-900);
  font-size: min(34px, 7.2cqi);
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -.04em;
  white-space: nowrap;
}
/* Masked line reveal. The generous block padding keeps Vietnamese diacritics
   (ẽ, ớ, ố) from being clipped by the mask; the negative margin removes the
   extra space again so the optical rhythm is unchanged. */
.hl-line {
  display: block;
  overflow: hidden;
  padding-block: .22em;
  margin-block: -.16em;
}
.hl-line > span {
  display: block;
  transform: translateY(112%);
  animation: line-rise .95s var(--d, 0s) var(--e) both;
}

.lede {
  margin: 0;
  color: var(--ink-500);
  font-size: 13.5px;
  font-weight: 420;
  line-height: 1.66;
  text-wrap: pretty;
  animation: fade-up .8s .40s var(--e) both;
}

/* Primary call to action */
.cta {
  position: relative;
  min-height: 56px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 12px;
  overflow: hidden;
  padding: 8px 14px 8px 8px;
  border-radius: 15px;
  background: linear-gradient(168deg, var(--brand-600), var(--brand-800));
  color: #f4fbf8;
  font-size: 13px;
  font-weight: 640;
  letter-spacing: -.005em;
  /* A coloured shadow rather than a grey one — the detail that reads expensive */
  box-shadow:
    0 1px 1px rgba(9, 44, 39, .22),
    0 10px 22px -10px rgba(15, 71, 63, .55),
    0 26px 44px -26px rgba(15, 71, 63, .50),
    inset 0 1px 0 rgba(255, 255, 255, .16);
  transition: transform .3s var(--e), box-shadow .3s var(--e), filter .3s var(--e);
  animation: fade-up .8s .50s var(--e) both;
}
/* Specular sweep, running continuously so the button reads as live without
   needing a pointer. Long rest between passes keeps it from being busy, and the
   delay is offset from the panel sheen so the two never sweep together. */
.cta::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  /* The sheen slides as a background rather than a rotated box: an inset:0
     layer matches the button's exact rounded shape, so no corner is skipped.
     `both` keeps it parked off-screen during the delay instead of sitting
     visibly on the button. */
  background: linear-gradient(100deg, transparent 32%, rgba(255, 255, 255, .34) 50%, transparent 68%);
  background-size: 260% 100%;
  background-repeat: no-repeat;
  animation: cta-sweep 5.4s 1.1s ease-in-out infinite both;
}
@keyframes cta-sweep {
  0%        { background-position: -110% 0; }
  24%, 100% { background-position: 210% 0; }
}
.cta:hover {
  transform: translateY(-2px);
  filter: saturate(108%);
  box-shadow:
    0 1px 1px rgba(9, 44, 39, .22),
    0 16px 28px -10px rgba(15, 71, 63, .55),
    0 34px 56px -28px rgba(15, 71, 63, .52),
    inset 0 1px 0 rgba(255, 255, 255, .2);
}
.cta:active { transform: translateY(0) scale(.994); }

/* The chip is the Zalo logo itself, so the square and its colour come from the
   SVG rather than from a background here. */
.cta-mark {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 11px;
  box-shadow: 0 3px 8px -2px rgba(0, 60, 160, .45);
}
.cta-mark svg { display: block; width: 100%; height: 100%; }
.cta-text { text-align: left; }
.cta-arrow {
  display: grid;
  place-items: center;
  opacity: .72;
  transition: transform .3s var(--e), opacity .3s var(--e);
}
.cta:hover .cta-arrow { transform: translate(2px, -2px); opacity: 1; }

/* Secondary contacts */
.alt {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  /* Phone to the button's left edge, email to its right edge. */
  justify-content: space-between;
  margin: 0;
  color: var(--ink-400);
  font-size: 12px;
  font-weight: 500;
  animation: fade-up .8s .58s var(--e) both;
}
.alt > span[aria-hidden] { display: none; }
.alt a {
  border-radius: 4px;
  color: inherit;
  transition: color .22s var(--e);
}
.alt a:hover { color: var(--brand-700); }

/* --------------------------------------------------------------------------
   Company line — legal identity across the foot of the screen.
   -------------------------------------------------------------------------- */

.legal {
  position: relative;
  z-index: 6;
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding: 12px var(--gutter) max(12px, env(safe-area-inset-bottom));
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 4px 9px;
  color: var(--ink-400);
  font-size: 10.5px;
  line-height: 1.5;
  text-align: center;
  animation: fade-up .8s .72s var(--e) both;
}
.legal-name { font-weight: 600; letter-spacing: .01em; }
.legal-addr-short { display: none; }
.legal-place { display: inline-flex; align-items: center; gap: 6px; }

/* Flag flutters from its pole edge. Phones only — wider screens label the
   address with a word instead. */
.legal-flag {
  display: none;
  width: 15px;
  height: 11px;
  flex: 0 0 auto;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(14, 48, 43, .16);
  transform-origin: left center;
  animation: flag-wave 3.2s ease-in-out infinite;
}
@keyframes flag-wave {
  0%, 100% { transform: perspective(50px) rotateY(0deg) skewY(0deg); }
  25%      { transform: perspective(50px) rotateY(15deg) skewY(-1.8deg); }
  50%      { transform: perspective(50px) rotateY(0deg) skewY(0deg); }
  75%      { transform: perspective(50px) rotateY(-15deg) skewY(1.8deg); }
}
.legal-sep { opacity: .45; }
.legal-key,
.alt-key { color: var(--ink-500); font-weight: 620; }
/* Colon lives in CSS so the copy strings stay plain text. */
.legal-key::after,
.alt-key::after { content: ':'; }
.legal a { border-radius: 4px; transition: color .22s var(--e); }
.legal a:hover { color: var(--brand-700); }

@media (max-width: 620px) {
  .legal {
    padding: 10px 18px max(10px, env(safe-area-inset-bottom));
    gap: 3px 7px;
    font-size: 10px;
  }
  /* Only the tax number and the location survive here — the name, phone and
     email are all present in the panel above. */
  .legal {
    flex-wrap: nowrap;
    justify-content: space-between;
    gap: 10px;
  }
  .legal-name,
  .legal-sep,
  .legal-contact { display: none; }
  .legal-addr-full,
  .legal-addr-key { display: none; }
  .legal-addr-short { display: inline; }
  .legal-flag { display: block; }
}

/* --------------------------------------------------------------------------
   Lead capture — collapsed by default so the page stays one screen, and
   expanded on demand with a staggered reveal.
   -------------------------------------------------------------------------- */

.lead { margin-top: 0; }

/* A real secondary surface. The old dashed hairline read as cheap and was too
   faint to notice until hovered. */
.lead-toggle {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 10px 10px 15px;
  border: 1px solid rgba(14, 48, 43, .18);
  border-radius: 13px;
  background: linear-gradient(168deg, rgba(255, 255, 255, .95), rgba(255, 255, 255, .78));
  color: var(--ink-700);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 570;
  text-align: left;
  box-shadow:
    0 1px 2px rgba(16, 45, 41, .05),
    0 8px 18px -12px rgba(16, 45, 41, .3),
    inset 0 1px 0 rgba(255, 255, 255, .9);
  transition:
    border-color .26s var(--e),
    color .26s var(--e),
    transform .26s var(--e),
    box-shadow .26s var(--e);
  animation: fade-up .8s .64s var(--e) both;
}
.lead-toggle:hover {
  transform: translateY(-1px);
  border-color: var(--brand-600);
  color: var(--brand-900);
  box-shadow:
    0 1px 2px rgba(16, 45, 41, .05),
    0 12px 24px -12px rgba(15, 71, 63, .42),
    inset 0 1px 0 rgba(255, 255, 255, .9);
}
.lead-toggle:active { transform: translateY(0) scale(.995); }

.lead-toggle-chev {
  width: 26px;
  height: 26px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(23, 104, 93, .1);
  color: var(--brand-700);
  transition: transform .4s var(--e), background .26s var(--e);
}
.lead-toggle:hover .lead-toggle-chev { background: rgba(23, 104, 93, .17); }
.lead.is-open .lead-toggle { border-color: var(--brand-600); color: var(--brand-900); }
.lead.is-open .lead-toggle-chev {
  transform: rotate(180deg);
  background: var(--brand-700);
  color: #f2faf7;
}

/* 0fr -> 1fr animates to the content's own height with no magic numbers. */
.lead-reveal {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .48s var(--e);
}
.lead.is-open .lead-reveal { grid-template-rows: 1fr; }
.lead-reveal-inner { overflow: hidden; min-height: 0; }
.lead-reveal-inner.is-expanded { overflow: visible; }

.lead-form { display: flex; flex-direction: column; gap: 9px; padding-top: 12px; }
.lead-intro {
  margin: 0 0 2px;
  color: var(--ink-400);
  font-size: 11.5px;
  line-height: 1.5;
}
.lead.is-open .lead-intro { animation: fade-up .5s .02s var(--e) both; }

/* Standard fields: label above the control, no floating-label trickery. */
.field { display: flex; flex-direction: column; gap: 6px; }
.lead.is-open .field { animation: fade-up .55s var(--d, 0s) var(--e) both; }

.field > label {
  color: var(--ink-500);
  font-size: 9.5px;
  font-weight: 640;
  letter-spacing: .13em;
  line-height: 1;
  text-transform: uppercase;
}

.field input,
.field textarea {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--hairline-strong);
  border-radius: 11px;
  background: rgba(255, 255, 255, .78);
  color: var(--ink-800);
  font: inherit;
  font-size: 13.5px;
  line-height: 1.45;
  resize: none;
  transition: border-color .24s var(--e), box-shadow .24s var(--e), background .24s var(--e);
}
.field textarea { min-height: 60px; }
.field input::placeholder,
.field textarea::placeholder { color: var(--ink-300); }
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--brand-600);
  background: var(--white);
  box-shadow: 0 0 0 3px rgba(23, 104, 93, .13);
}

/* Phone field: country picker + national number, the usual arrangement. */
.field-phone { position: relative; z-index: 5; }
.tel {
  position: relative;
  display: flex;
  align-items: stretch;
  border: 1px solid var(--hairline-strong);
  border-radius: 11px;
  background: rgba(255, 255, 255, .78);
  transition: border-color .24s var(--e), box-shadow .24s var(--e), background .24s var(--e);
}
.tel:focus-within {
  border-color: var(--brand-600);
  background: var(--white);
  box-shadow: 0 0 0 3px rgba(23, 104, 93, .13);
}
.field.has-error .tel { border-color: var(--error); }
.field.has-error .tel:focus-within { box-shadow: 0 0 0 3px rgba(176, 74, 47, .14); }

.tel-country {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: 0 0 auto;
  padding: 0 10px 0 12px;
  border: 0;
  border-right: 1px solid var(--hairline-strong);
  border-radius: 11px 0 0 11px;
  background: transparent;
  color: var(--ink-700);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  transition: background .2s var(--e);
}
.tel-country:hover { background: rgba(23, 104, 93, .06); }
.tel-country svg:last-child { opacity: .55; transition: transform .28s var(--e); }
.tel-country[aria-expanded='true'] svg:last-child { transform: rotate(180deg); }
.cflag {
  display: block;
  flex: 0 0 auto;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(14, 48, 43, .16);
}

.tel-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 11px 13px;
  border: 0;
  background: transparent;
  color: var(--ink-800);
  font: inherit;
  font-size: 13.5px;
  letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
}
.tel-input:focus { outline: none; }
.tel-input::placeholder { color: var(--ink-300); letter-spacing: .02em; }

.tel-list {
  position: absolute;
  z-index: 30;
  top: calc(100% + 6px);
  left: 0;
  width: max(230px, 100%);
  max-height: 196px;
  margin: 0;
  padding: 5px;
  overflow-y: auto;
  list-style: none;
  border: 1px solid var(--hairline-strong);
  border-radius: 13px;
  background: var(--white);
  box-shadow:
    0 2px 6px rgba(16, 45, 41, .06),
    0 18px 40px -16px rgba(16, 45, 41, .34);
  animation: tel-open .22s var(--e) both;
}
@keyframes tel-open {
  from { opacity: 0; transform: translateY(-5px); }
  to   { opacity: 1; transform: translateY(0); }
}
.tel-option {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 9px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--ink-700);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  text-align: left;
}
.tel-option.is-active { background: rgba(23, 104, 93, .09); }
.tel-option[aria-selected='true'] { color: var(--brand-800); font-weight: 620; }
.tel-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tel-code { flex: 0 0 auto; color: var(--ink-400); font-variant-numeric: tabular-nums; }


.field.has-error input,
.field.has-error textarea { border-color: var(--error); }
.field.has-error input:focus,
.field.has-error textarea:focus { box-shadow: 0 0 0 3px rgba(176, 74, 47, .14); }
.field-err {
  display: block;
  color: var(--error);
  font-size: 11px;
  font-weight: 500;
  animation: err-in .3s var(--e) both;
}
@keyframes err-in {
  from { opacity: 0; transform: translateY(-3px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Pick-a-need chips: choosing is the fast path, typing stays optional. */
.chips-group {
  min-width: 0;
  margin: 2px 0 0;
  padding: 0;
  border: 0;
}
.lead.is-open .chips-group { animation: fade-up .55s var(--d, 0s) var(--e) both; }
.chips-group legend {
  padding: 0;
  margin-bottom: 8px;
  color: var(--ink-500);
  font-size: 9.5px;
  font-weight: 640;
  letter-spacing: .13em;
  text-transform: uppercase;
}
.chips {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.chips::-webkit-scrollbar { display: none; }
.chip {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  gap: 0;
  padding: 8px 11px;
  white-space: nowrap;
  border: 1px solid var(--hairline-strong);
  border-radius: 999px;
  background: rgba(255, 255, 255, .66);
  color: var(--ink-500);
  cursor: pointer;
  font: inherit;
  font-size: 11px;
  font-weight: 560;
  line-height: 1.15;
  transition:
    border-color .24s var(--e),
    background .24s var(--e),
    color .24s var(--e),
    box-shadow .24s var(--e),
    transform .24s var(--e);
}
.chip:hover { border-color: var(--brand-300); color: var(--brand-800); }
.chip:active { transform: scale(.97); }
/* The tick grows out of zero width, so the chip expands as it is chosen. */
.chip svg {
  width: 0;
  opacity: 0;
  overflow: visible;
  transition: width .26s var(--e), opacity .18s var(--e), margin-right .26s var(--e);
}
.chip.is-on {
  border-color: var(--brand-700);
  background: linear-gradient(168deg, var(--brand-600), var(--brand-800));
  color: #f2faf7;
  box-shadow: 0 5px 14px -6px rgba(15, 71, 63, .6);
}
.chip.is-on svg { width: 11px; margin-right: 6px; opacity: 1; }
.chips-group.has-error .chip { border-color: var(--error); }

.lead-submit {
  min-height: 46px;
  margin-top: 3px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 0 16px;
  border: 0;
  border-radius: 11px;
  background: linear-gradient(168deg, var(--brand-600), var(--brand-800));
  color: #f4fbf8;
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 620;
  box-shadow:
    0 1px 1px rgba(9, 44, 39, .2),
    0 8px 18px -9px rgba(15, 71, 63, .55),
    inset 0 1px 0 rgba(255, 255, 255, .14);
  transition: transform .26s var(--e), box-shadow .26s var(--e), opacity .26s var(--e);
}
.lead.is-open .lead-submit { animation: fade-up .55s var(--d, 0s) var(--e) both; }
.lead-submit:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow:
    0 1px 1px rgba(9, 44, 39, .2),
    0 13px 24px -10px rgba(15, 71, 63, .55),
    inset 0 1px 0 rgba(255, 255, 255, .18);
}
.lead-submit:active:not(:disabled) { transform: translateY(0) scale(.995); }
.lead-submit:disabled { cursor: default; opacity: .8; }

.spinner {
  width: 13px;
  height: 13px;
  border: 2px solid rgba(255, 255, 255, .35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Success */
/* Class selector thắng quy tắc [hidden] mặc định của trình duyệt, nên phải
   khai lại: thiếu dòng này thì khối cảm ơn hiện ngay khi form vừa mở, trơ mỗi
   dấu tick vì phần chữ còn rỗng. */
.lead-done[hidden] { display: none; }
.lead-done {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 4px 13px;
  padding: 16px 2px 4px;
}
.lead-done strong {
  display: block;
  color: var(--brand-900);
  font-size: 14px;
  font-weight: 620;
}
.lead-done p {
  margin: 4px 0 0;
  color: var(--ink-500);
  font-size: 12px;
  line-height: 1.55;
}
.lead-reset {
  grid-column: 2;
  justify-self: start;
  margin-top: 9px;
  padding: 7px 13px;
  border: 1px solid var(--hairline-strong);
  border-radius: 9px;
  background: transparent;
  color: var(--ink-500);
  cursor: pointer;
  font: inherit;
  font-size: 11.5px;
  font-weight: 550;
  transition: border-color .24s var(--e), color .24s var(--e);
}
.lead-reset:hover { border-color: var(--brand-300); color: var(--brand-800); }

.tick { grid-row: span 2; }
.tick-ring,
.tick-mark {
  fill: none;
  stroke: var(--brand-600);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.tick-ring {
  stroke-dasharray: 120;
  stroke-dashoffset: 120;
  animation: draw-ring .62s var(--e-out) forwards;
}
.tick-mark {
  stroke-width: 3;
  stroke-dasharray: 26;
  stroke-dashoffset: 26;
  animation: draw-tick .34s .42s var(--e-out) forwards;
}
@keyframes draw-ring { to { stroke-dashoffset: 0; } }
@keyframes draw-tick { to { stroke-dashoffset: 0; } }

/* Focus */
:where(a, button):focus-visible {
  outline: 2px solid var(--brand-700);
  outline-offset: 3px;
  border-radius: 8px;
}

/* --------------------------------------------------------------------------
   Entrance keyframes
   -------------------------------------------------------------------------- */

@keyframes fade-down {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fade-up {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes line-rise {
  from { transform: translateY(112%); }
  to   { transform: translateY(0); }
}
@keyframes art-arrive {
  from { opacity: 0; transform: translateY(18px) scale(.985); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes panel-arrive {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

/* Narrow desktop / large tablet landscape */
@media (max-width: 1180px) {
  .stage { grid-template-columns: minmax(0, 1fr) var(--panel); }
}

/* Landscape but squarish (1024x768, 1280x800). The artwork is width-bound at
   these proportions, so give it more bleed instead of leaving a tall void. */
@media (min-width: 901px) and (max-aspect-ratio: 3 / 2) {
  .stage {
    grid-template-columns: minmax(0, 1fr) var(--panel);
    gap: clamp(10px, 1.6vw, 26px);
  }
  .art { margin-left: calc(var(--gutter) * -1 - 6vw); }
}

/* Stack: tablet portrait and phones */
@media (max-width: 900px) {
  .stage {
    grid-template-columns: 1fr;
    grid-template-rows: minmax(0, 1fr) auto;
    align-content: stretch;
    gap: clamp(10px, 2vh, 24px);
    padding-bottom: max(clamp(16px, 2.5vh, 28px), env(safe-area-inset-bottom));
  }
  /* Bleed the group past the gutter and sit it directly above the panel, so the
     slack collects under the top bar instead of as a gap in the middle. */
  .art {
    margin: 0 calc(var(--gutter) * -1 - 5vw);
    align-self: stretch;
    /* Opening the enquiry form makes the panel tall enough to squash the
       artwork to a strip. Hold a floor and let the page scroll instead — the
       one-screen rule is about the landing state, not an expanded form. */
    min-height: 24svh;
  }
  /* Centred, so the space above and below the artwork stays even. */
  .art img { object-position: center center; }
  .panel { margin-bottom: 0; }
  .panel {
    padding: 26px 24px 24px;
    border-radius: 22px;
    /* Higher opacity: on mobile the panel sits closer to the artwork */
    background: linear-gradient(168deg, rgba(255, 255, 255, .90), rgba(255, 255, 255, .78));
    transform: none;
  }
  .lede { font-size: 13px; }
}

@media (max-width: 620px) {
  .topbar { padding: 16px 18px; }
  .brand-copy small { display: none; }
  .brand-mark { width: 38px; height: 38px; }
  .lang-btn { min-width: 58px; padding: 0 10px; }
  .panel { padding: 24px 20px 22px; }
  /* Keeps all three options on one row on a narrow phone. */
  .chip { padding: 7px 10px; font-size: 10.5px; }
  /* And keeps the longer English contact line on one row too. */
  .alt { font-size: 11.5px; }
  .lede { font-size: 12.5px; line-height: 1.6; }
  .panel { --panel-gap: 13px; }
}

/* Short and wide — phone in landscape. The old build clipped the CTA out of an
   unscrollable viewport here; keep two columns and compress instead. */
@media (max-height: 620px) and (min-width: 620px) {
  .topbar { padding-top: 12px; padding-bottom: 12px; }
  .stage {
    grid-template-columns: minmax(0, .95fr) var(--panel);
    align-items: center;
    padding-bottom: 0;
  }
  .panel { margin-bottom: clamp(8px, 1.6vh, 16px); }
  .panel { padding: 18px 20px; border-radius: 20px; }
  .panel { --panel-gap: 9px; }
  .headline { font-size: min(30px, 6.4cqi); }
  .lede { font-size: 12.5px; line-height: 1.5; }
  .cta { min-height: 48px; }
  .cta-mark { width: 32px; height: 32px; border-radius: 9px; }
}

/* Very short — drop the secondary line before anything important is squeezed */
@media (max-height: 470px) {
  .alt { display: none; }
  /* Only the tax number and the location survive here — the name, phone and
     email are all present in the panel above. */
  .legal {
    flex-wrap: nowrap;
    justify-content: space-between;
    gap: 10px;
  }
  .legal-name,
  .legal-sep,
  .legal-contact { display: none; }
  .legal-addr-full,
  .legal-addr-key { display: none; }
  .legal-addr-short { display: inline; }
  .legal-flag { display: block; }
  .legal { padding-top: 8px; padding-bottom: 8px; font-size: 10px; }
  .eyebrow { font-size: 9px; }
  .headline { font-size: min(26px, 6cqi); }
}

/* --------------------------------------------------------------------------
   Reduced motion — durations are collapsed rather than set to `none`, so the
   `both` fill still applies and nothing is left stuck in its start state.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  .aurora i { animation: none !important; }
  .art img, .panel { transform: none !important; }
  .art img { translate: none !important; }
  .panel::after, .cta::after { display: none !important; }
  .lead-reveal { transition: none !important; }
  .tick-ring, .tick-mark { stroke-dashoffset: 0 !important; }
}
