/* ==========================================================================
   Humble Crew Auto Spa — design tokens
   Style: Vexon (GetLayers) — pure black ground, accent is EMISSIVE LIGHT,
   never a painted surface. Brand ramp sampled from the client's own logo.
   Contrast figures are measured, not estimated (WCAG 2.1 vs #000000).
   ========================================================================== */
:root{
  /* — ground ————————————————————————————————— */
  --bg:            #000000;
  --bg-alt:        #060407;   /* faint warm-violet lift, never a visible band */
  --surface:       #0b070d;
  --surface-raised:#130c16;

  /* — ink ladder (measured on #000) ——————————— */
  --ink:           #ffffff;   /* 21.00:1 */
  --ink-muted:     #ffffff;   /* 21:1 */
  --ink-subtle:    #ffffff;   /* 21:1 — no off-whites anywhere */
  --ink-faint:     #ffffff;   /* 21:1 — hierarchy is size + tracking, never grey */

  /* — brand ramp, lifted from the logo badge ——— */
  --brand-red:     #ff0000;
  --brand-red-deep:#ed0017;
  --brand-magenta: #a20086;
  --brand-violet:  #8a00b0;

  /* The gradient is LIGHT. It may glow, sweep and bloom.
     It may never be a flat fill behind text.                              */
  --brand-sweep: linear-gradient(120deg,
                  var(--brand-red) 0%,
                  #d1004b 34%,
                  var(--brand-magenta) 66%,
                  var(--brand-violet) 100%);
  --brand-sweep-v: linear-gradient(180deg,
                  var(--brand-red) 0%,
                  var(--brand-magenta) 55%,
                  var(--brand-violet) 100%);

  /* The sweep as a FILL THAT CARRIES WHITE TYPE. --brand-sweep opens on pure
     #ff0000, which is only 4.00:1 against white — measured 3.69:1 on the
     "Get a custom quote" button and 3.72:1 on a checked service chip, both
     below AA. Every stop here is the same hue at 86% value, which lifts the
     worst point (the red end) to 5.23:1 and leaves the rest at 7.0–9.4:1,
     while staying visibly the same ramp.
     Use --brand-sweep for LIGHT (glows, hairlines, focus rules) and
     --brand-sweep-fill for any surface that has white text sitting on it.
     NOTE: .btn::before still paints --brand-sweep, so every solid button on
     the other 44 pages is still at 3.69:1. One-line fix, not made here
     because it is outside this section's brief. */
  --brand-sweep-fill: linear-gradient(120deg,
                  #db0000 0%,
                  #b30040 34%,
                  #8b0073 66%,
                  #770097 100%);

  /* Readable accent — sits ON the brand ramp but passes AA on black.
     #a20086 (2.88:1) and #8a00b0 (2.71:1) FAIL as text and are barred
     from any type role: they exist only as glow.                          */
  --accent:        #ff0080;   /*  5.56:1 ✓ links, labels, small UI */
  --accent-ink:    #ffffff;
  --accent-quiet:  #ff4da3;   /*  6.84:1 ✓ hover / focus lift  */

  /* Emphasis ramp — the brand sweep lifted into the readable band so it can
     carry TYPE. Every stop measured on #000: 5.99 / 5.56 / 7.81. The real
     ramp's #a20086 (2.88) and #8a00b0 (2.71) fail as text and stay light.  */
  --brand-type: linear-gradient(96deg,#ff3d3d 0%,#ff0080 52%,#c77dff 100%);

  /* — light & line ——————————————————————————— */
  --glow:          rgba(255, 0, 128, .55);
  --glow-violet:   rgba(138, 0, 176, .45);
  --line:          rgba(255,255,255,.10);
  --line-strong:   rgba(255,255,255,.22);
  --line-accent:   rgba(255, 0, 128, .38);

  /* — type ——————————————————————————————————— */
  --font-display: "Epic Pro", "Arial Narrow", Impact, ui-sans-serif, system-ui, sans-serif;
  --font-body:    "Figtree", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-mono:    "Rajdhani", ui-sans-serif, system-ui, sans-serif;
  --tracking-display: .04em;   /* Syncopate is already wide — restrain it */
  --tracking-label:   .16em;

  /* — 宽屏等比例缩放 ————————————————————————
     >1860px 时整站按 --z 放大(见文件末尾的断点)。视口**高度**单位必须
     除以 --z 才不会被二次缩放,所以 CSS 里所有 svh/vh/vmax 都写成
     calc(Nsvh / var(--z))。这个默认值 1 是它们的兜底,别删。 */
  --z: 1;

  /* — space (density 4/10 — marketing, generous) ——— */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px; --sp-8: 64px;
  --sp-9: 96px; --sp-10:128px;

  /* — form ——————————————————————————————————— */
  --radius: 2px;         /* near-square: automotive, not app-store */
  --radius-lg: 4px;
  --border: 1px;

  /* — motion ————————————————————————————————— */
  --dur-fast: 160ms;
  --dur:      280ms;
  --dur-slow: 720ms;
  --ease:      cubic-bezier(.22,1,.36,1);   /* out-expo-ish */
  --ease-in-out: cubic-bezier(.65,0,.35,1);
}

@media (prefers-reduced-motion: reduce){
  :root{ --dur-fast:1ms; --dur:1ms; --dur-slow:1ms; }
}

/* ── 首帧防闪 ────────────────────────────────────────────
   js/curtain.js 在 <head> 里同步挂上 .hc-preveal,把入场动画的元素
   在第一帧就摆成不可见,免得访客先看见一屏字、再看它被 GSAP 抹掉重放。
   site.js / landing.js 一设好 from-state 就会把这个类摘掉(而且必须在
   任何 gsap.from 之前摘,否则 from 会把「隐藏」当成元素的终值)。
   prefers-reduced-motion 下这个类根本不会挂上去。                  */
.hc-preveal [data-rv],
.hc-preveal [data-rv2],
.hc-preveal #heroH1,
.hc-preveal #lheroH1,
.hc-preveal .svc__grid .card{opacity:0}

/* 横向平移的兜底 —— body 上的 overflow-x:hidden 只挡住了桌面 Chrome 的
   scrollWidth,iOS Safari 照样能把整页往左右拖(Jason 2026-09-10 在真机上看到的)。
   放到根元素上,并且用 clip 不用 hidden:hidden 会让 <html> 变成滚动容器,
   把 position:sticky 的 hero / 服务堆叠全打坏。
   注意:这条会让"横向溢出"在检查里变得不可见 —— 所以验收脚本量的是元素矩形
   (right > innerWidth),不是 scrollWidth。 */
html{overflow-x:clip}

/* ── 宽屏:等比例放大 ────────────────────────────────────
   2026-09-09,Jason 要的"等比例拓展"。1920 以上原来什么都不长:内容栏钉在
   1560px、H1 钉在 72px、正文钉在 21px —— 2560 上内容只占 61%,3440 上只占 45%,
   两边全是死黑。

   做法是给根元素上 zoom:版式一个像素都不改,整站按视口比例放大,
   2560 看到的就是 1440 上的同一版设计、只是更大。

   为什么是离散断点而不是连续值:`zoom` 的语法只收数字/百分比,
   `zoom:calc(100vw/1688)` 和 `zoom:min(...)` 都解析失败(实测 Chrome 153)。
   用 JS 设又会在首帧闪一下尺寸 —— 这个站刚把闪回修掉,不能再引进来一个。
   五档、每档约 7%,肉眼看不出跳变。

   断点值不是随便取的:设计的自然宽度是 1560 内容栏 + 2×64 边距 = 1688。
   缩放后的可用宽度 = 视口 / z,必须 ≥ 1688,否则内容栏反而会被压窄。
   所以每一档的起点都 ≥ 1688 × z。1.4 是 Jason 定的封顶。 */
@media (min-width:1860px){ :root{ --z:1.100; zoom:1.100 } }
@media (min-width:1990px){ :root{ --z:1.175; zoom:1.175 } }
@media (min-width:2120px){ :root{ --z:1.250; zoom:1.250 } }
@media (min-width:2250px){ :root{ --z:1.325; zoom:1.325 } }
@media (min-width:2380px){ :root{ --z:1.400; zoom:1.400 } }
