/* DiffPixel shared foundation: tokens, fonts, instrument-grid, signature components. */

:root {
  color-scheme: dark;
  --bg: #080910;
  --surface: #11131d;
  --surface-2: #191c29;
  --line: #2b3042;
  --line-strong: #454c66;
  --text: #f4f6fb;
  --muted: #a7afc4;
  --quiet: #737d98;
  --cyan: #00d7ff;
  --cyan-soft: #123342;
  --pink: #ff456d;
  --ink: #031319;
  --display: "Syne", system-ui, sans-serif;
  --mono: "JetBrains Mono", "SFMono-Regular", Consolas, monospace;
  /* Unlike --display, this never switches to Noto Sans JP under html[lang="ja"]:
     the footer wordmark spells the Latin brand name "DiffPixel" in every
     locale, so it keeps a single fixed typeface rather than reflowing into a
     CJK font whose Latin glyphs weren't drawn for this kind of display use. */
  --brand-font: "Syne", system-ui, sans-serif;
  --body: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Sans", "Yu Gothic UI", Meiryo, sans-serif;
  --fs-hero: clamp(4rem, 7.6vw, 8rem);
  --fs-h2: clamp(3.5rem, 8vw, 7.875rem);
  --fs-h3: clamp(2.75rem, 5vw, 4.875rem);
  --fs-lead: clamp(1.0625rem, 1.4vw, 1.3125rem);
  --lh-display: .86;
  --lh-h2: .88;
  --lh-body: 1.7;
  --ls-display: -.06em;
  --ls-h2: -.055em;
  --ease-snap: cubic-bezier(.16, 1, .3, 1);
  --ease-out: cubic-bezier(.25, .8, .3, 1);
  --dur-fast: .15s;
  --dur-base: .6s;
  --dur-slow: .9s;
  --radius: 0px;
  --border-w: 1px;
  --shadow-panel: 0 24px 80px rgba(0, 0, 0, .5);
  --shell: min(1440px, calc(100% - 64px));
  --header-h: 82px;
  --tick: 72px;
}

html[lang="ja"] {
  --display: "Noto Sans JP", system-ui, sans-serif;
  --mono: "Noto Sans JP", system-ui, sans-serif;
  --body: "Noto Sans JP", system-ui, sans-serif;
}

@font-face {
  font-family: "Syne";
  font-style: normal;
  font-weight: 700 800;
  font-display: swap;
  src: url("fonts/syne-variable.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/jetbrains-mono-variable.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215;
}

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

html {
  background: var(--bg);
  overflow-x: clip;
  overscroll-behavior-y: none;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 24px);
}

body {
  margin: 0;
  overflow-x: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: var(--body);
  font-size: 16px;
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

/* Film grain: static SVG turbulence tile above everything, non-interactive. */
body::after {
  position: fixed;
  inset: 0;
  z-index: 2000;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.6'/%3E%3C/svg%3E");
  background-size: 160px 160px;
  content: "";
  opacity: .05;
  pointer-events: none;
}

html[lang="ja"] body {
  font-feature-settings: "palt" 1;
  font-kerning: normal;
}

html[lang="ja"] .site-nav a,
html[lang="ja"] .btn,
html[lang="ja"] .eyebrow,
html[lang="ja"] .hero-meta,
html[lang="ja"] .hud-meta,
html[lang="ja"] .chapter-nav,
html[lang="ja"] .footer-meta,
html[lang="ja"] .diff-comparison figcaption,
html[lang="ja"] .step-number {
  letter-spacing: .035em;
}

img { display: block; max-width: 100%; }
a { color: inherit; }
button, input { font: inherit; }
button, a { -webkit-tap-highlight-color: transparent; }
h1, h2, h3, p { margin-top: 0; }
h1, h2, h3 { font-family: var(--display); font-weight: 800; }

.shell {
  width: var(--shell);
  margin-inline: auto;
}

[data-lang-panel][hidden] { display: none !important; }

/* ---------- Skip link ---------- */

.skip-link {
  position: fixed;
  z-index: 200;
  top: 12px;
  left: 12px;
  padding: 12px 18px;
  transform: translateY(-140%);
  background: var(--cyan);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .04em;
  text-decoration: none;
  text-transform: uppercase;
  transition: transform .15s ease;
}

.skip-link:focus-visible {
  transform: translateY(0);
  outline: 3px solid var(--text);
  outline-offset: 4px;
}

#main-content:focus {
  outline: none;
}

#main-content:focus-visible {
  outline: none;
}

/* ---------- Instrument canvas (measurement grid) ---------- */

body::before {
  position: fixed;
  inset: 0;
  z-index: -2;
  background:
    linear-gradient(rgba(0, 215, 255, .022) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 215, 255, .022) 1px, transparent 1px);
  background-size: var(--tick) var(--tick);
  content: "";
  pointer-events: none;
}

.ruler {
  position: fixed;
  z-index: -1;
  pointer-events: none;
}

.ruler-top {
  inset: 0 0 auto 0;
  height: 6px;
  background-image: repeating-linear-gradient(90deg, rgba(0, 215, 255, .16) 0 1px, transparent 1px var(--tick));
}

.ruler-left {
  inset: 0 auto 0 0;
  width: 6px;
  background-image: repeating-linear-gradient(0deg, rgba(0, 215, 255, .16) 0 1px, transparent 1px var(--tick));
}

/* ---------- Header ---------- */

.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  border-bottom: 1px solid transparent;
  background: linear-gradient(to bottom, rgba(8, 9, 16, .92), rgba(8, 9, 16, 0));
  transition: background-color .2s ease, border-color .2s ease, backdrop-filter .2s ease;
}

.site-header.scrolled {
  border-color: var(--line);
  background: rgba(8, 9, 16, .92);
  backdrop-filter: blur(18px);
}

.header-inner {
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  gap: 28px;
}

.brand {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--text);
  font-family: var(--display);
  font-weight: 800;
  text-decoration: none;
  white-space: nowrap;
}

.brand img { width: 28px; height: 28px; }

.site-nav {
  display: flex;
  gap: 28px;
  margin-left: auto;
}

.site-nav a,
.footer-links a {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .05em;
  text-decoration: none;
  text-transform: uppercase;
  transition: color var(--dur-fast) ease;
}

/* Underline draw: wipes in from the left, retracts to the right. */
.site-nav a::after,
.footer-links a::after {
  position: absolute;
  right: 0;
  bottom: 9px;
  left: 0;
  height: 1px;
  background: currentColor;
  content: "";
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform .3s var(--ease-snap);
}

.site-nav a:hover::after,
.site-nav a:focus-visible::after,
.footer-links a:hover::after,
.footer-links a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.site-nav a:hover,
.site-nav a:focus-visible,
.site-nav a[aria-current="page"],
.footer-links a:hover,
.footer-links a:focus-visible { color: var(--cyan); }

.header-actions {
  display: flex;
  align-items: center;
  gap: 14px;
}

.lang-switch {
  display: inline-flex;
  border: 1px solid var(--line);
  background: var(--surface);
}

.lang-switch button {
  min-width: 44px;
  min-height: 44px;
  padding: 0 10px;
  border: 0;
  background: transparent;
  color: var(--quiet);
  cursor: pointer;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
}

.lang-switch button { transition: color var(--dur-fast) ease; }
.lang-switch button:hover,
.lang-switch button:focus-visible { color: var(--text); }
.lang-switch button[aria-pressed="true"] { background: var(--cyan); color: var(--ink); }

/* ---------- Buttons ---------- */

.btn {
  position: relative;
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 0 18px;
  border: var(--border-w) solid var(--cyan);
  border-radius: var(--radius);
  background: var(--cyan);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .04em;
  text-decoration: none;
  text-transform: uppercase;
  overflow: hidden;
  isolation: isolate;
  transition: border-color var(--dur-fast) ease, color .25s ease;
}

/* Sweep fill: a second surface wipes across on hover/focus (transform only). */
.btn::before {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--text);
  content: "";
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform .35s var(--ease-snap);
}

.btn:hover::before,
.btn:focus-visible::before {
  transform: scaleX(1);
  transform-origin: left center;
}

.btn:hover,
.btn:focus-visible { border-color: var(--text); }

.btn > span {
  display: inline-block;
  transition: transform .3s var(--ease-snap);
}

.btn:hover > span,
.btn:focus-visible > span { transform: translate(2px, -2px); }

.btn-secondary {
  border-color: var(--line-strong);
  background: transparent;
  color: var(--text);
}

.btn-secondary:hover,
.btn-secondary:focus-visible { border-color: var(--text); color: var(--ink); }

.btn-lg { min-height: 58px; padding-inline: 26px; font-size: 12px; }

.text-link {
  position: relative;
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  gap: 12px;
  color: var(--cyan);
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .07em;
  text-decoration: none;
  text-transform: uppercase;
  transition: color var(--dur-fast) ease;
}

.text-link::after {
  position: absolute;
  right: 0;
  bottom: 9px;
  left: 0;
  height: 1px;
  background: currentColor;
  content: "";
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform .3s var(--ease-snap);
}

.text-link:hover::after,
.text-link:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.text-link:hover,
.text-link:focus-visible { color: var(--text); }

.text-link > span {
  transition: transform .3s var(--ease-snap);
}

.text-link:hover > span,
.text-link:focus-visible > span { transform: translate(2px, -2px); }

/* ---------- Eyebrow / meta typography ---------- */

.eyebrow,
.hero-meta,
.hud-meta,
.diff-comparison figcaption,
.step-number,
.chapter-index,
.chapter-nav {
  font-family: var(--mono);
  text-transform: uppercase;
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 24px;
  color: var(--cyan);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
}

.eyebrow::before { width: 38px; height: 2px; background: currentColor; content: ""; }

/* ---------- HUD meta strip (decorative coordinate readout) ---------- */

.hud-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  color: var(--quiet);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .12em;
}

.hud-meta span { display: inline-flex; align-items: center; gap: 8px; }
.hud-meta span::before { width: 5px; height: 5px; background: var(--cyan); content: ""; }

/* ---------- Diff seam: section divider motif ---------- */

.diff-seam {
  position: relative;
  border-top: 1px solid var(--line);
}

.diff-seam::before {
  position: absolute;
  top: -1px;
  left: 0;
  width: 56px;
  height: 2px;
  background: var(--cyan);
  content: "";
}

.diff-seam[data-seam]::after {
  position: absolute;
  top: 14px;
  left: 0;
  color: var(--quiet);
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .14em;
  content: attr(data-seam);
}

/* ---------- Drift title: ghost layer that snaps into register ---------- */

.drift-title {
  position: relative;
  isolation: isolate;
}

.drift-title::before {
  position: absolute;
  inset: 0;
  z-index: -1;
  color: transparent;
  -webkit-text-stroke: 1px var(--cyan);
  content: attr(data-drift-text);
  opacity: .5;
  transform: translate(7px, -7px);
  transition: transform .9s cubic-bezier(.16, 1, .3, 1), opacity .7s ease;
  pointer-events: none;
}

.drift-title.is-snapped::before { transform: translate(0, 0); opacity: 0; }

/* ---------- Footer ---------- */

/* The wordmark is sized off the footer shell's own measured width (via
   container query units), not the viewport — a fixed vw-based clamp was
   overflowing badly (the "DiffPixel" glyphs at the old clamp max render far
   wider than any shell width, clipped mid-letter by body's overflow-x:hidden).
   Sizing from the container guarantees the full word always fits, regardless
   of which page's --shell formula or breakpoint is active. */
.site-footer .shell { container-type: inline-size; }

.footer-wordmark {
  position: relative;
  z-index: 0;
  width: 100%;
  max-width: 100%;
  margin: 0;
  overflow: visible;
  font-family: var(--brand-font);
  font-size: clamp(2.5rem, 15vw, 260px); /* fallback for browsers without container query units */
  font-weight: 800;
  line-height: .78;
  letter-spacing: -.075em;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
  transform: translateY(8%);
  transform-origin: center bottom;
}

@supports (width: 1cqw) {
  .footer-wordmark { font-size: clamp(2.5rem, 14cqw, 320px); }
}

.footer-meta {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: space-between;
  gap: 28px;
  margin-bottom: 56px;
  padding-bottom: 22px;
  border-bottom: 1px solid var(--line);
  color: var(--quiet);
  font-family: var(--mono);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
}

.footer-links,
.footer-info { display: flex; flex-wrap: wrap; gap: 18px 26px; }

/* ---------- Motion system pre-states ----------
   Content is fully visible by default (no-JS, reduced-motion, script failure).
   motion.js adds html.has-motion ONLY when motion is allowed, and removes it
   again if the animation stack fails to load. */

/* nowrap keeps chars from soft-wrapping inside a word (inline-block chars
   are otherwise treated as individual break opportunities). */
.split-heading .word { display: inline-block; white-space: nowrap; }
.split-heading .char { display: inline-block; }

html.has-motion .split-heading .char {
  opacity: 0;
  transform: translate(.12em, .38em);
}

html.has-motion .split-heading.chars-in .char {
  opacity: 1;
  transform: none;
}

html.has-motion [data-reveal] {
  opacity: 0;
  transform: translateY(26px);
}

html.has-motion [data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* Cross-document fade between Home / Manual / Privacy (progressive). */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root),
  ::view-transition-new(root) { animation-duration: .3s; }
}

/* ---------- Focus & motion baseline ---------- */

:focus-visible { outline: 3px solid var(--cyan); outline-offset: 4px; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
  .drift-title::before { transform: translate(0, 0); opacity: 0; }
  /* Belt and braces: even if has-motion is present, nothing may stay hidden. */
  html.has-motion .split-heading .char,
  html.has-motion [data-reveal] { opacity: 1; transform: none; }
}

@media (max-width: 700px) {
  :root { --header-h: 68px; --tick: 56px; }
  .ruler { display: none; }
}
