/* -------------------------------------------------------------
   Tokens — warm ink, paper, temple red
--------------------------------------------------------------*/
:root {
  --ink:        #0f0d0a;
  --ink-elev:   #16130f;
  --stone:      #1e1a15;
  --stone-hi:   #2a251f;
  --paper:      #ede4d3;
  --paper-mute: #a89f8f;
  --paper-dim:  #736b5f;
  --line:       #26221c;
  --line-hi:    #3a352d;
  --timber:     #8f6c47;
  --red-deep:   #9b1c1f;   /* logo-match; used for decorative marks and primary button */
  --red:        #c8383f;   /* accessible for text on ink */
  --red-hi:     #e04a52;

  --font-sans:    'Inter', system-ui, -apple-system, Segoe UI, sans-serif;
  --font-display: 'Noto Serif TC', 'Times New Roman', Georgia, serif;
  --font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --page-pad: clamp(1.25rem, 4vw, 3rem);
  --max-w:    1200px;

  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

/* -------------------------------------------------------------
   Reset
--------------------------------------------------------------*/
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body, h1, h2, h3, p, ul, ol, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; }

html { background: var(--ink); }
body {
  background: transparent;
  color: var(--paper);
  font-family: var(--font-sans);
  font-weight: 400;
  line-height: 1.6;
  min-height: 100dvh;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Hero-anchored animated scene, sits behind content and scrolls away with the page. */
.scene-bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  z-index: -1;
  pointer-events: none;
  display: block;
  /* Fade the lower edge so it doesn't hard-cut into the About section */
  mask-image: linear-gradient(to bottom, #000 0%, #000 65%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 65%, transparent 100%);
}

/* Animation pause/play toggle — icon-only, anchored to the top-right of the
   .hero section so it scrolls with the hero content. The background scene it
   controls only exists in the first viewport, so once the hero is scrolled
   past there is nothing left to pause and the button can leave the screen.
   Meets WCAG 2.5.8 target size (40×40 > 24×24 CSS px), 1.4.11 non-text contrast.
   Fades in 2s after load so it doesn't announce itself immediately. */
.anim-toggle {
  position: absolute;
  top: 1.25rem;
  right: 1.25rem;
  z-index: 20;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: rgba(15, 13, 10, 0.82);
  border: 1px solid var(--line-hi);
  border-radius: 999px;
  color: var(--paper-mute);
  cursor: pointer;
  opacity: 0;
  animation: anim-toggle-in 500ms var(--ease-out) 2000ms forwards;
  transition: color 180ms var(--ease-out),
              border-color 180ms var(--ease-out),
              background 180ms var(--ease-out);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
@keyframes anim-toggle-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.anim-toggle:hover,
.anim-toggle:focus-visible {
  color: var(--paper);
  border-color: var(--red);
  background: rgba(20, 17, 15, 0.92);
}
.anim-toggle:focus-visible {
  outline: 2px solid var(--red-hi);
  outline-offset: 2px;
}
.anim-toggle-icon {
  display: block;
  color: currentColor;
}
.anim-toggle[aria-pressed="false"] .icon-play { display: none; }
.anim-toggle[aria-pressed="true"]  .icon-pause { display: none; }

@media (prefers-reduced-motion: reduce) {
  .anim-toggle {
    animation: none;
    opacity: 1;
  }
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* Focus */
:where(a, button, [tabindex]):focus { outline: none; }
:where(a, button, [tabindex]):focus-visible {
  outline: 1px solid var(--red);
  outline-offset: 3px;
}

.skip-link {
  position: absolute;
  top: 0; left: 0;
  padding: 0.75rem 1rem;
  background: var(--red-deep);
  color: #fff;
  font-weight: 500;
  transform: translateY(-120%);
  z-index: 100;
}
.skip-link:focus { transform: translateY(0); }

/* -------------------------------------------------------------
   Load cascade — above-fold elements fade in on page load using
   an inline --fade-order index and one keyframe.
--------------------------------------------------------------*/
[data-fade] {
  opacity: 0;
  animation: fade-up 700ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
  animation-delay: calc(var(--fade-order, 0) * 110ms);
}

/* Scroll-triggered reveal — below-fold sections stay hidden until their
   parent [data-reveal-group] enters the viewport, then their children
   cascade in using the same fade-up + --fade-order pattern. Scoped under
   html.js so no-JS users see content immediately. */
html.js [data-reveal] {
  opacity: 0;
}
html.js [data-reveal-group].is-visible [data-reveal] {
  animation: fade-up 700ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
  animation-delay: calc(var(--fade-order, 0) * 110ms);
}

/* Word-by-word title reveal — each word carries a --word-index set by JS.
   Base delay comes from the h2's --fade-order; per-word stagger adds 80ms
   between words. Words stay in the natural text flow (inline-block). */
html.js [data-reveal-words] .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(8px);
}
html.js [data-reveal-group].is-visible [data-reveal-words] .word {
  animation: fade-up 600ms var(--ease-out) forwards;
  animation-delay: calc(
    var(--fade-order, 0) * 110ms +
    var(--word-index, 0) * 80ms
  );
}
@media (prefers-reduced-motion: reduce) {
  html.js [data-reveal-words] .word,
  html.js [data-reveal-group].is-visible [data-reveal-words] .word {
    opacity: 1;
    transform: none;
    animation: none;
  }
}

/* Letter-by-letter title reveal — each letter carries a --letter-index set
   by JS. Base delay comes from the h2's --fade-order; per-letter stagger
   adds a short beat between letters. Spaces stay as plain text nodes so
   the line still wraps naturally. */
html.js [data-reveal-letters] .letter {
  display: inline-block;
  opacity: 0;
  transform: translateY(6px);
}
html.js [data-reveal-group].is-visible [data-reveal-letters] .letter {
  animation: fade-up 500ms var(--ease-out) forwards;
  animation-delay: calc(
    var(--fade-order, 0) * 110ms +
    var(--letter-index, 0) * 35ms
  );
}
@media (prefers-reduced-motion: reduce) {
  html.js [data-reveal-letters] .letter,
  html.js [data-reveal-group].is-visible [data-reveal-letters] .letter {
    opacity: 1;
    transform: none;
    animation: none;
  }
}

@keyframes fade-up {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  [data-fade],
  html.js [data-reveal] { opacity: 1; transform: none; animation: none; }
}

/* Static grain — texture only, no motion */
.grain {
  position: fixed; inset: 0;
  pointer-events: none;
  opacity: 0.04;
  z-index: 1;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  mix-blend-mode: overlay;
}

/* -------------------------------------------------------------
   Ornaments (SVG architectural motifs)
--------------------------------------------------------------*/
.ornament { color: var(--line-hi); pointer-events: none; }

/* Lattice divider bands between sections */
.divider {
  max-width: var(--max-w);
  margin: 0 auto;
  padding-inline: var(--page-pad);
  position: relative;
  z-index: 2;
}
.mountains {
  width: 100%;
  height: 40px;
  color: var(--line-hi);
}

/* Moon-gate (月門) marker on capability cards — circle bisected by a hairline,
   with a temple-red pin at center. */
.moongate {
  width: 34px; height: 34px;
  color: var(--paper-mute);
  margin-bottom: 1.25rem;
  overflow: visible;
}

/* Draw-in animation. Only apply the pre-animation state under html.js so that
   no-JS users always see the icon fully rendered. IntersectionObserver adds
   .is-drawn to each card when it enters the viewport. */
html.js .capabilities .moon-ring {
  stroke-dasharray: 82;              /* circumference of r=13 ring ≈ 81.68 */
  stroke-dashoffset: 82;
}
html.js .capabilities .moon-line {
  stroke-dasharray: 5;
  stroke-dashoffset: 5;
}
html.js .capabilities .moon-pin {
  opacity: 0;
  transform: scale(0);
  transform-origin: center;
  transform-box: fill-box;
}

/* Moongate draw-in triggers when the parent reveal-group becomes visible.
   Per-card timing derives from the li's --fade-order (inherited via CSS
   custom property), so it stays in sync with the card's own fade-up. */
html.js [data-reveal-group].is-visible .moon-ring {
  animation: moongate-ring 900ms var(--ease-out) calc(var(--fade-order, 0) * 110ms + 500ms) forwards;
}
html.js [data-reveal-group].is-visible .moon-line--l {
  animation: moongate-line 380ms var(--ease-out) calc(var(--fade-order, 0) * 110ms + 1200ms) forwards;
}
html.js [data-reveal-group].is-visible .moon-line--r {
  animation: moongate-line 380ms var(--ease-out) calc(var(--fade-order, 0) * 110ms + 1260ms) forwards;
}
html.js [data-reveal-group].is-visible .moon-pin {
  animation: moongate-pin 400ms var(--ease-out) calc(var(--fade-order, 0) * 110ms + 1400ms) forwards;
}

@keyframes moongate-ring { to { stroke-dashoffset: 0; } }
@keyframes moongate-line { to { stroke-dashoffset: 0; } }
@keyframes moongate-pin  { to { opacity: 1; transform: scale(1); } }

@media (prefers-reduced-motion: reduce) {
  html.js .moon-ring,
  html.js .moon-line {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }
  html.js .moon-pin {
    opacity: 1;
    transform: none;
  }
  html.js [data-reveal-group].is-visible .moon-ring,
  html.js [data-reveal-group].is-visible .moon-line,
  html.js [data-reveal-group].is-visible .moon-pin {
    animation: none;
  }
}

/* Moon-gate mark in footer — echoes the About-card icons */
.footer-mark {
  width: 100%;
  max-width: 200px;
  height: 24px;
  margin: 0 auto 1.5rem;
  color: var(--line-hi);
  opacity: 0.85;
}

/* -------------------------------------------------------------
   Layout containers
--------------------------------------------------------------*/
.site-header,
main > .section,
.footer-inner,
.hero-inner {
  max-width: var(--max-w);
  margin-inline: auto;
  padding-inline: var(--page-pad);
  position: relative;
  z-index: 2;
}

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  color: var(--paper);
  font-family: var(--font-mono);
  font-weight: 500;
  letter-spacing: 0.02em;
  font-size: 0.95rem;
}
.brand-mark {
  display: inline-flex;
  width: 42px; height: 42px;
  align-items: center; justify-content: center;
}
.brand-mark svg { display: block; width: 100%; height: 100%; }

.nav {
  display: flex;
  gap: 2rem;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--paper-mute);
}
.nav a {
  position: relative;
  padding: 0.25rem 0;
  transition: color 200ms var(--ease-out);
}
.nav a:hover, .nav a:focus-visible { color: var(--paper); }
.nav a::after {
  content: '';
  position: absolute;
  left: 0; bottom: -3px;
  width: 100%; height: 1px;
  background: var(--red);
  transform-origin: left;
  transform: scaleX(0);
  transition: transform 260ms var(--ease-out);
}
.nav a:hover::after, .nav a:focus-visible::after { transform: scaleX(1); }
@media (max-width: 540px) {
  .nav { gap: 1.1rem; }
}

/* -------------------------------------------------------------
   Hero — centered, symmetric, architectural
--------------------------------------------------------------*/
.hero {
  padding-top: clamp(2rem, 6vh, 5rem);
  padding-bottom: clamp(4rem, 10vh, 8rem);
  text-align: center;
  /* Anchor for the absolutely-positioned pause toggle. */
  position: relative;
}
.hero-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--paper-mute);
  margin-bottom: 2rem;
}
.eyebrow .tick {
  display: inline-block;
  width: 24px; height: 1px;
  background: var(--red-deep);
}

.hero-title {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(2.75rem, 8.5vw, 6rem);
  line-height: 1.05;
  letter-spacing: -0.01em;
  max-width: 14ch;
  margin-bottom: 1.75rem;
}
.hero-title em {
  color: var(--red);
  font-style: italic;
  font-weight: 400;
}

.hero-sub {
  font-size: clamp(1rem, 1.4vw, 1.15rem);
  color: var(--paper-mute);
  max-width: 46ch;
  margin-bottom: 2.5rem;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
}

/* -------------------------------------------------------------
   Buttons (sharp, architectural rectangles)
--------------------------------------------------------------*/
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.95rem 1.4rem;
  border: 1px solid transparent;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition:
    background 200ms var(--ease-out),
    color 200ms var(--ease-out),
    border-color 200ms var(--ease-out);
}
.btn-primary {
  background: var(--red-deep);
  color: #fff;
}
.btn-primary:hover, .btn-primary:focus-visible {
  background: var(--paper);
  color: var(--ink);
}
.btn-ghost {
  color: var(--paper);
  border-color: var(--line-hi);
  background: transparent;
}
.btn-ghost:hover, .btn-ghost:focus-visible {
  border-color: var(--paper);
}

/* -------------------------------------------------------------
   Sections
--------------------------------------------------------------*/
.section {
  padding-block: clamp(3.5rem, 10vh, 7rem);
}

.section-head {
  display: grid;
  grid-template-columns: 10rem 1fr;
  gap: 1.5rem 3rem;
  align-items: baseline;
  margin-bottom: 3.5rem;
}
.section-index {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--paper-dim);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding-top: 0.5rem;
}
.section-head h2 {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(1.85rem, 4vw, 2.75rem);
  letter-spacing: -0.01em;
  line-height: 1.15;
  max-width: 22ch;
}

.section-body {
  display: grid;
  gap: 3rem;
  padding-left: calc(10rem + 3rem);
}
.section-lede {
  max-width: 60ch;
  font-size: 1.05rem;
  color: var(--paper-mute);
}
@media (max-width: 720px) {
  .section-head { grid-template-columns: 1fr; gap: 0.5rem; }
  .section-body { padding-left: 0; }
}

/* Capabilities — three panels in a plank grid */
.capabilities {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  border: 1px solid var(--line);
  background: rgba(30, 26, 21, 0.4);
}
.capabilities li {
  padding: 2rem 1.75rem;
  border-right: 1px solid var(--line);
  transition: background 220ms var(--ease-out);
}
.capabilities li:last-child { border-right: none; }
.capabilities li:hover { background: rgba(155, 28, 31, 0.05); }
.capabilities h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.2rem;
  margin-bottom: 0.5rem;
  color: var(--paper);
}
.capabilities p {
  color: var(--paper-mute);
  font-size: 0.95rem;
  line-height: 1.6;
}
@media (max-width: 720px) {
  .capabilities li { border-right: none; border-bottom: 1px solid var(--line); }
  .capabilities li:last-child { border-bottom: none; }
}

/* Steps — horizontal beams */
.steps {
  display: grid;
  border: 1px solid var(--line);
  background: rgba(30, 26, 21, 0.4);
}
.steps li {
  display: grid;
  grid-template-columns: 4rem 1fr;
  gap: 1.5rem;
  padding: 1.85rem 1.75rem;
  border-bottom: 1px solid var(--line);
  transition: background 220ms var(--ease-out);
}
.steps li:last-child { border-bottom: none; }
.steps li:hover { background: rgba(155, 28, 31, 0.05); }
.step-num {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--red-deep);
  letter-spacing: 0.1em;
  padding-top: 0.35rem;
}
.steps h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.2rem;
  margin-bottom: 0.35rem;
}
.steps p {
  color: var(--paper-mute);
  font-size: 0.95rem;
  max-width: 60ch;
  line-height: 1.6;
}

/* Contact — plank grid */
.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  border: 1px solid var(--line);
  background: rgba(30, 26, 21, 0.4);
}
.contact-card {
  display: grid;
  gap: 0.5rem;
  padding: 2rem 1.75rem;
  border-right: 1px solid var(--line);
  transition: background 220ms var(--ease-out), color 220ms var(--ease-out);
}
.contact-card:last-child { border-right: none; }
.contact-card:hover, .contact-card:focus-visible { background: rgba(155, 28, 31, 0.05); }
.contact-label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--paper-dim);
}
.contact-value {
  font-size: 1.1rem;
  color: var(--paper);
}
@media (max-width: 720px) {
  .contact-card { border-right: none; border-bottom: 1px solid var(--line); }
  .contact-card:last-child { border-bottom: none; }
}

/* -------------------------------------------------------------
   Footer
--------------------------------------------------------------*/
.site-footer {
  border-top: 1px solid var(--line);
  padding-block: 3rem 2rem;
  margin-top: 2rem;
  position: relative;
  z-index: 2;
  text-align: center;
}
.footer-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  align-items: center;
  color: var(--paper-mute);
  font-family: var(--font-mono);
  font-size: 0.78rem;
}
@media (max-width: 540px) {
  .footer-inner { flex-direction: column; }
}
.footer-links {
  display: flex;
  gap: 1.5rem;
}
.footer-links a { transition: color 200ms var(--ease-out); }
.footer-links a:hover, .footer-links a:focus-visible { color: var(--paper); }

/* -------------------------------------------------------------
   Forced-colors fallback
--------------------------------------------------------------*/
@media (forced-colors: active) {
  .grain, .ornament { display: none; }
  .capabilities, .steps, .contact-grid,
  .capabilities li, .steps li, .contact-card { border-color: CanvasText; }
  .btn-primary { background: Highlight; color: HighlightText; }
}
