/* ============================================================
   base.css — INTENTIONALLY NEAR-EMPTY.
   The template ships no visual identity. 100% of visual tokens + components
   are generated FRESH per project in Phase 0, AFTER the Anti-clone gate is approved
   (see CLAUDE.md + PAST-PROJECTS.md). Tokens must stay in sync with assets/js/tailwind.config.js.

   ⚠️ NEVER copy components/CSS from past projects into this file (including retyping from memory).
   Past projects' visual signatures are listed in PAST-PROJECTS.md — a match fails QA.

   Everything below is pure mechanics (reset + reveal contract), zero styling.
   ============================================================ */

/* mechanical reset */
html{ -webkit-text-size-adjust:100%; -webkit-tap-highlight-color:transparent; }
body{ -webkit-font-smoothing:antialiased; }

/* Reveal-on-scroll contract (base.js adds .in on viewport entry; ?revealall shows everything — screenshot.mjs relies on it).
   Hidden only when JS runs: every page must have an inline <head> script adding the `js` class to <html> early.
   No JS → no html.js → everything is visible; blank sections can never ship.
   The reveal's transition/transform/easing is defined by EACH PROJECT per its approved motion direction. */
html.js .reveal{ opacity:0; }
html.js .reveal.in{ opacity:1; }

/* ============================================================
   LogiWork tokens + shared components: direction A "Ops Desk" (Swiss flat).
   Locked 2026-07-05 (PROJECT-BRIEF.md §12 + DESIGN.md). Sync with assets/js/tailwind.config.js.
   Flat system: no gradients, no shadows (only the .btn offset hairline), radius 2/4px.
   ============================================================ */
:root{
  --bg:#FFFFFF;
  --surface:#F6F5F8;
  --surface-2:#EEECF2;
  --line:#E4E1EA;
  --line-strong:#CFC9D9;
  --ink:#0A0414;
  --muted:#57506A;
  --pink:#FF3C9D;
  --magenta:#D42BB2;
  --purple:#6E0ABE;
  --violet:#8B5CF6;
  --indigo:#240A46;
  --indigo-muted:rgba(255,255,255,.72);
  --coral:#FF6B6B;
  --font-display:"Space Grotesk",sans-serif;
  --font-body:"Be Vietnam Pro",sans-serif;
  --font-mono:"JetBrains Mono",monospace;
  --radius-ctl:2px;
  --radius-card:4px;
  --ease-out:cubic-bezier(0.22,1,0.36,1);
  --section-pad:clamp(4rem,9vw,7.5rem);
  /* z-scale */
  --z-nav:30; --z-menu:40;
}

body{
  font-family:var(--font-body);
  color:var(--ink);
  background:var(--bg);
  line-height:1.7;
  font-size:1rem;
}

h1,h2,h3,h4{
  font-family:var(--font-display);
  font-weight:700;
  line-height:1.15;
  letter-spacing:-0.02em;
  text-wrap:balance;
}
/* font-weight also set on the CLASSES (not just the h1-h4 element rule) so Tailwind Preflight's
   runtime-injected `h1{font-weight:inherit}` can't win by source order and drop headings to 400
   (they currently only look bold because Space Grotesk is loaded at weight 700 only). */
.display, .h2, .h3{ font-weight:700; }
.display{ font-size:clamp(2.25rem,5.5vw,4rem); line-height:1.1; letter-spacing:-0.03em; }
.h2{ font-size:clamp(1.625rem,3.5vw,2.5rem); }
.h3{ font-size:clamp(1.1875rem,2vw,1.5rem); line-height:1.3; }
p{ max-width:70ch; text-wrap:pretty; }

.mono-label{
  font-family:var(--font-mono);
  font-size:.8125rem;
  line-height:1.4;
  letter-spacing:.05em;
  font-weight:500;
}

/* layout */
.wrap{ max-width:72rem; margin-inline:auto; padding-inline:clamp(1rem,3vw,2rem); }
.section{ padding-block:var(--section-pad); }

/* reveal motion (direction A: near-static fade/slide) */
html.js .reveal{ transform:translateY(12px); transition:opacity .24s var(--ease-out),transform .24s var(--ease-out); }
html.js .reveal.in{ transform:translateY(0); }

/* links on light backgrounds */
.link{ color:var(--purple); text-decoration:underline; text-underline-offset:3px; text-decoration-thickness:1px; }
.link:hover{ color:var(--magenta); }

/* active nav item (aria-current contract, every page) */
nav a[aria-current="page"]{ text-decoration:underline; text-decoration-color:var(--pink); text-decoration-thickness:2px; text-underline-offset:6px; }

/* buttons: squared, solid ink, pink offset block ALWAYS visible; hover presses halfway, active presses flat
   (signature; NOT pills, NOT gradients) */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:.5rem;
  font-family:var(--font-body); font-weight:600; font-size:1rem;
  min-height:48px; padding:.75rem 1.5rem;
  border-radius:var(--radius-ctl);
  background:var(--ink); color:#fff;
  border:1px solid var(--ink);
  box-shadow:4px 4px 0 var(--pink);
  cursor:pointer; text-decoration:none;
  transition:background-color .15s var(--ease-out),box-shadow .15s var(--ease-out),transform .15s var(--ease-out);
}
.btn:hover{ box-shadow:2px 2px 0 var(--pink); transform:translate(2px,2px); }
.btn:active{ box-shadow:0 0 0 var(--pink); transform:translate(4px,4px); }
/* ghost = secondary: stays flat so the 3D block reads as "primary" */
.btn--ghost{ background:transparent; color:var(--ink); border:1px solid var(--ink); box-shadow:none; }
.btn--ghost:hover{ background:var(--surface); box-shadow:none; transform:none; }
.btn--ghost:active{ box-shadow:none; transform:none; }
/* on dark indigo bands: white solid, same pink block */
.btn--inverse{ background:#fff; color:var(--ink); border-color:#fff; }
.btn--inverse:hover{ background:#fff; }
.btn--ghost-inverse{ background:transparent; color:#fff; border:1px solid #fff; box-shadow:none; }
.btn--ghost-inverse:hover{ background:rgba(255,255,255,.1); box-shadow:none; transform:none; }
.btn--ghost-inverse:active{ box-shadow:none; transform:none; }
@media (hover:none){
  .btn:hover{ box-shadow:4px 4px 0 var(--pink); transform:none; }
  .btn:active{ box-shadow:0 0 0 var(--pink); transform:translate(4px,4px); }
  .btn--ghost:hover,.btn--ghost:active,
  .btn--ghost-inverse:hover,.btn--ghost-inverse:active{ box-shadow:none; transform:none; }
}
:focus-visible{ outline:2px solid var(--pink); outline-offset:2px; }

/* hairline card */
.card{ background:var(--bg); border:1px solid var(--line); border-radius:var(--radius-card); }

/* JD ticket (signature): hairline card + mono code row + perforation notches */
.ticket{ position:relative; background:var(--bg); border:1px solid var(--line-strong); border-radius:var(--radius-card); }
.ticket__code{
  display:flex; align-items:center; justify-content:space-between;
  padding:.625rem 1rem; border-bottom:1px dashed var(--line-strong);
  font-family:var(--font-mono); font-size:.8125rem; letter-spacing:.05em; color:var(--muted);
}
.ticket::before,.ticket::after{
  content:""; position:absolute; width:12px; height:12px; border-radius:50%;
  background:var(--bg); border:1px solid var(--line-strong);
  top:34px;
}
.ticket::before{ left:-7px; clip-path:inset(0 0 0 50%); border-left-color:transparent; }
.ticket::after{ right:-7px; clip-path:inset(0 50% 0 0); border-right-color:transparent; }

/* process rows 01-05 (the one deliberate numbered sequence of the site) */
.step-row{ display:grid; grid-template-columns:auto 1fr; gap:1rem 1.5rem; padding-block:1.5rem; border-top:1px solid var(--line); }
.step-row:last-child{ border-bottom:1px solid var(--line); }
/* 24px keeps the pink number ≥ WCAG large-text threshold (mono is loaded at weight 500 only, so it can't rely on bold) */
.step-row__no{ font-family:var(--font-mono); font-weight:500; font-size:1.5rem; color:var(--pink); }

/* spec-sheet comparison table (signature) */
.spec{ width:100%; border:1px solid var(--line-strong); border-radius:var(--radius-card); border-collapse:separate; border-spacing:0; overflow:hidden; }
.spec th{ background:var(--surface-2); font-family:var(--font-mono); font-weight:500; font-size:.8125rem; letter-spacing:.05em; text-align:left; padding:.75rem 1rem; }
.spec td{ padding:.75rem 1rem; border-top:1px solid var(--line); vertical-align:top; overflow-wrap:break-word; }
/* 2-column term/definition spec tables (position pages, pricing): keep the first-column header on one line so it doesn't wrap when the terms are short (was breaking "NGHIỆP VỤ" on vi-tri-chung-tu). Not applied to .spec--compare, whose narrow fixed columns need wrapping. */
.spec:not(.spec--compare) th:first-child{ white-space:nowrap; }

/* multi-column comparison variant: even columns, never overflows (see index/vi-sao) */
.spec--compare{ table-layout:fixed; }
.spec--compare th:first-child, .spec--compare td:first-child{ width:20%; }

/* comparison table → stacked cards on mobile (no horizontal scroll) */
@media (max-width:720px){
  .spec--compare{ border:0; border-radius:0; }
  .spec--compare thead{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
  .spec--compare tbody, .spec--compare tr, .spec--compare td{ display:block; width:auto; }
  .spec--compare tr{ border:1px solid var(--line-strong); border-radius:var(--radius-card); margin-bottom:1rem; overflow:hidden; background:var(--bg); }
  .spec--compare td{ border-top:1px solid var(--line); }
  .spec--compare td:first-child{ width:auto; font-weight:600; font-size:1.0625rem; border-top:0; padding-bottom:.5rem; border-bottom:1px solid var(--line-strong); }
  .spec--compare td[data-label]::before{ content:attr(data-label); display:block; font-family:var(--font-mono); font-size:.6875rem; letter-spacing:.05em; text-transform:uppercase; color:var(--muted); margin-bottom:.2rem; }
  .spec--compare td[data-label="LogiWork"]{ border-left:2px solid var(--pink); background:rgba(255,60,157,.06); }
}

/* duel treatment: elevated LOGIWORK column + verdict icons (homepage teaser + vi-sao full table) */
.spec--duel th:nth-child(2),
.spec--duel td:nth-child(2){
  background:rgba(255,60,157,.05);
  border-left:2px solid var(--pink);
  border-right:2px solid var(--pink);
}
.spec--duel thead th:nth-child(2){ border-top:2px solid var(--pink); background:rgba(255,60,157,.1); }
.spec--duel tbody tr:last-child td:nth-child(2){ border-bottom:2px solid var(--pink); }
.spec--duel td:nth-child(2){ font-weight:600; }
/* on mobile the duel table becomes stacked cards (spec--compare); keep only the pink LEFT accent on the LogiWork cell, drop the column's right/last-child framing so it doesn't fight the card layout */
@media (max-width:720px){
  .spec--duel td:nth-child(2){ border-right:0; border-top:1px solid var(--line); background:rgba(255,60,157,.06); }
  .spec--duel tbody tr:last-child td:nth-child(2){ border-bottom:0; }
}
.spec__ic{
  width:16px; height:16px;
  display:inline-block; vertical-align:-2px; margin-right:.4rem;
  color:var(--line-strong);
}
td .spec__ic.text-pink{ color:var(--pink); }

/* hub role photos on tablet (640-1023, single-column stack): cap image HEIGHT so the full-width photos become short bands instead of towering blocks (was making the hub ~5900px tall). object-cover crops. Released below 640 (phones, full photo fine) and at lg (grid controls size). */
@media (min-width:640px) and (max-width:1023px){
  .role-figure img{ aspect-ratio:3/1; }
}

/* photo frame with mono caption (signature) */
.frame{ border:1px solid var(--line-strong); border-radius:var(--radius-card); overflow:hidden; background:var(--bg); }
.frame img{ display:block; width:100%; height:auto; }
.frame--fill img{ height:100%; object-fit:cover; }
.frame__caption{
  display:flex; justify-content:space-between; gap:1rem;
  padding:.5rem .75rem; border-top:1px solid var(--line-strong);
  font-family:var(--font-mono); font-size:.75rem; letter-spacing:.04em; color:var(--muted);
}

/* form fields */
/* FAQ accordion: hover affordance on the full-width question row (desktop) */
[data-acc]{ transition:color .15s var(--ease-out); }
[data-acc]:hover{ color:var(--purple); }

.field{ display:flex; flex-direction:column; gap:.375rem; }
.field label{ font-weight:600; font-size:.875rem; }
.field input,.field select,.field textarea{
  font-family:var(--font-body); font-size:1rem; color:var(--ink);
  min-height:48px; padding:.625rem .875rem;
  background:var(--bg); border:1px solid var(--line-strong); border-radius:var(--radius-ctl);
  transition:border-color .15s var(--ease-out);
}
.field textarea{ min-height:7rem; resize:vertical; }
.field input:focus,.field select:focus,.field textarea:focus{ border-color:var(--pink); outline:2px solid var(--pink); outline-offset:0; }
.field__hint{ font-family:var(--font-mono); font-size:.75rem; color:var(--muted); }
.field__error{ display:none; align-items:center; gap:.375rem; font-size:.875rem; color:#C0392B; }
.field.is-invalid input,.field.is-invalid select,.field.is-invalid textarea{ border-color:var(--coral); }
.field.is-invalid .field__error{ display:flex; }
/* styled file input: hide the native control, use a square ghost-button label (matches Ops Desk; also removes the native control's intrinsic min-width so it can't overflow on narrow mobile) */
.field input[type="file"]{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); border:0; }
.file-trigger{
  display:inline-flex; align-items:center; gap:.5rem; align-self:flex-start; max-width:100%;
  min-height:44px; padding:.5rem 1rem;
  font-family:var(--font-body); font-weight:600; font-size:.875rem;
  background:transparent; color:var(--ink); border:1px solid var(--ink); border-radius:var(--radius-ctl);
  cursor:pointer;
}
.file-trigger:hover{ background:var(--surface); }
.field input[type="file"]:focus-visible + .file-trigger{ outline:2px solid var(--pink); outline-offset:2px; }

/* MOCK transparency label (client-facing mock content) */
.mock-tag{
  display:inline-block; font-family:var(--font-mono); font-size:.6875rem; letter-spacing:.05em;
  color:var(--muted); border:1px dashed var(--line-strong); border-radius:var(--radius-ctl);
  padding:.125rem .5rem; background:var(--surface);
}

/* monogram tile for mock client logos */
.monogram{
  display:flex; align-items:center; justify-content:center;
  font-family:var(--font-mono); font-weight:500; letter-spacing:.05em; color:var(--muted);
  background:transparent; border:1px solid var(--line); border-radius:var(--radius-card);
  min-height:64px;
  transition:color .15s var(--ease-out),border-color .15s var(--ease-out);
}
.monogram:hover{ color:var(--ink); border-color:var(--line-strong); }

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *{ animation:none !important; transition-duration:.001ms !important; }
  .reveal{ opacity:1 !important; transform:none !important; }
}
