/* 對焦 — the studio as a calibration instrument.
   One hairline weight draws every frame, tick and leader; orange marks focus and the primary action. */

:root {
  --white: #f3f3f0;
  --ink: #0e0f10;
  --gray: #8a8b8c;      /* 18% gray: ticks and inactive marks */
  --focus: #ff4d1a;

  --sans: 'Noto Sans TC', 'PingFang TC', 'Microsoft JhengHei', sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Consolas, monospace;

  --gutter: clamp(16px, 4vw, 64px);
  --mast: 64px;
  --glass: calc(var(--mast) * 1.5); /* masthead glass overhang: content below the bar must clear this, not just --mast */
  --hair: 1px;
  --ease: cubic-bezier(.16, 1, .3, 1);
}

[data-theme="light"], :root {
  --bg: var(--white); --fg: var(--ink);
  --mute: #55575a;
  --line: #0e0f10;
  --faint: #c9cac6;
  --plate: #e4e4e0;
}
[data-theme="dark"] {
  --bg: var(--ink); --fg: var(--white);
  --mute: #a3a5a8;
  --line: #f3f3f0;
  --faint: #3a3c3f;
  --plate: #18191b;
}
[data-theme] { background: var(--bg); color: var(--fg); }

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: var(--glass); scrollbar-color: var(--ink) var(--white); }
body {
  margin: 0; background: var(--white); color: var(--ink);
  font-family: var(--sans); font-size: 16px; line-height: 1.8;
  font-kerning: normal; text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--focus); color: var(--ink); }
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, p, ol, ul, dl, dd, figure { margin: 0; }
ol, ul { padding: 0; list-style: none; }
button, input, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }
main:focus { outline: none; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip { position: fixed; left: 12px; top: -60px; z-index: 60; background: var(--ink); color: var(--white); padding: 10px 16px; }
.skip:focus { top: 12px; }
.page { width: 100%; max-width: 1600px; margin: 0 auto; padding-inline: var(--gutter); }
.mono { font-family: var(--mono); font-size: 12px; letter-spacing: .06em; font-variant-numeric: tabular-nums; }
.mute { color: var(--mute); }

/* ───── Masthead ───── */
.masthead {
  position: fixed; inset: 0 0 auto; z-index: 40; height: var(--mast);
  display: flex; align-items: center; gap: 24px; padding-inline: var(--gutter);
  border-bottom: var(--hair) solid var(--line);
  transition: background-color .4s var(--ease), color .4s var(--ease), border-color .4s var(--ease);
}
.imprint { display: block; margin-right: auto; }

/* ───── Atoms ───── */
.display { font-weight: 900; letter-spacing: -.015em; line-height: 1.1; }
.h2 { font-weight: 900; font-size: clamp(32px, 4.2vw, 64px); line-height: 1.25; letter-spacing: -.02em; text-wrap: balance; }
.lead { font-size: clamp(16px, 1.2vw, 19px); line-height: 1.85; max-width: 34em; }
.btn {
  display: inline-flex; align-items: center; justify-content: space-between; gap: 28px;
  min-height: 56px; padding: 14px 22px 14px 24px; border-radius: 999px;
  background: var(--focus); color: var(--ink); border: 0;
  font-weight: 700; font-size: 16px; letter-spacing: .1em; cursor: pointer;
  transition: background-color .25s, color .25s;
}
.btn:hover { background: var(--fg); color: var(--bg); }
.btn svg, .link svg { width: 16px; height: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; transition: transform .45s var(--ease); }
.btn:hover svg, .link:hover svg { transform: translate(3px, -3px); }
.btn.down:hover svg { transform: translateY(3px); }
.link {
  display: inline-flex; align-items: center; gap: 14px; min-height: 44px;
  font-weight: 500; letter-spacing: .08em;
  background: none; border: 0; padding: 0; cursor: pointer;
  background-image: linear-gradient(currentColor, currentColor); background-size: 100% 1px; background-position: 0 calc(100% - 8px); background-repeat: no-repeat;
  transition: background-size .45s var(--ease);
}
.link:hover { background-size: 0 1px; background-position: 100% calc(100% - 8px); }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 36px; }
.section { padding-block: clamp(96px, 11vw, 176px); }
.section-head { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 28px clamp(32px, 6vw, 112px); align-items: end; margin-bottom: clamp(56px, 7vw, 112px); }
.section-head p { color: var(--mute); max-width: 32em; }
.section-head .actions { margin-top: 20px; }

/* Corner brackets: the focus mark, drawn with four hairline corners. */
.bracket { position: relative; }
.bracket::before, .bracket::after {
  content: ''; position: absolute; inset: var(--b-inset, -14px); pointer-events: none;
  border: 2px solid var(--b-color, var(--focus));
  -webkit-mask: conic-gradient(at var(--b-len, 22px) var(--b-len, 22px), #0000 75%, #000 0) 0 0 / calc(100% - var(--b-len, 22px)) calc(100% - var(--b-len, 22px));
          mask: conic-gradient(at var(--b-len, 22px) var(--b-len, 22px), #0000 75%, #000 0) 0 0 / calc(100% - var(--b-len, 22px)) calc(100% - var(--b-len, 22px));
}
.bracket::after { display: none; }
.bracket::before { transform: scale(var(--bs, 1)); opacity: var(--bo, 1); }


/* The focus pull: each line resolves from blur, then the bracket locks. */
@media (prefers-reduced-motion: no-preference) {
}
/* GSAP takes over the entrance when it loads; the CSS keyframes stay as the no-library fallback. */
.has-smoother .contact-aside { position: static; }
.ch { will-change: transform, filter, opacity; }
@keyframes pull_unused {
  from { filter: blur(18px); opacity: .25; transform: scale(1.035); text-shadow: 6px 0 rgba(255, 77, 26, .7), -6px 0 rgba(60, 120, 255, .45); }
  60% { text-shadow: 1px 0 rgba(255, 77, 26, .4), -1px 0 rgba(60, 120, 255, .2); }
  to { filter: blur(0); opacity: 1; transform: none; text-shadow: none; }
}
@keyframes lock { from { opacity: 0; transform: scale(1.12); } 70% { opacity: 1; transform: scale(.985); } to { opacity: 1; transform: none; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* ───── Focus-distance scale (home, fixed) ───── */
.focus-scale {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 35; height: 40px;
  display: flex; align-items: stretch; padding-inline: var(--gutter);
  background: var(--bg); color: var(--fg); border-top: var(--hair) solid var(--line);
  transition: background-color .4s var(--ease), color .4s var(--ease);
}
.focus-scale[hidden] { display: none; }
.focus-scale-track { position: relative; flex: 1; display: flex; justify-content: space-between;
  background: linear-gradient(90deg, var(--gray) 1px, transparent 0) 0 0 / 16px 6px repeat-x; }
.focus-scale a { position: relative; display: flex; align-items: center; gap: 6px; padding-top: 6px; font-size: 12px; letter-spacing: .08em; color: var(--mute); transition: color .25s; }
.focus-scale a b { font-family: var(--mono); font-weight: 400; font-size: 11px; }
.focus-scale a.is-current, .focus-scale a:hover { color: var(--fg); }
.focus-scale-pointer { position: absolute; top: 0; left: 0; width: 2px; height: 14px; background: var(--focus); transform: translateX(calc(var(--p, 0) * (100cqw - 2px))); }
.focus-scale-track { container-type: inline-size; }

/* ───── Viewfinder (case plates) ───── */
.vf { position: relative; aspect-ratio: var(--ratio, 4 / 3); background: var(--plate); overflow: hidden; isolation: isolate; }
.vf-image { position: absolute; inset: 0; filter: blur(calc((1 - var(--f, 1)) * 10px)); transform: scale(calc(1 + (1 - var(--f, 1)) * .04)); transition: filter .2s linear; }
.vf-image img { width: 100%; height: 100%; object-fit: cover; }
.vf-empty { display: grid; grid-template-rows: minmax(0, 1fr) auto; place-items: center; gap: 10px; height: 100%; padding: 12% 12% 8%; color: var(--line); }
.vf-pending { font-size: 13px; letter-spacing: .08em; color: var(--mute); }
.vf-target { width: 100%; height: 100%; max-height: 100%; opacity: .78; }
.vf-lines { position: absolute; inset: clamp(12px, 2vw, 22px); pointer-events: none; z-index: 1; --b-color: var(--line); --b-inset: 0; --b-len: clamp(18px, 2.4vw, 34px); }
.vf-lines::before { border-width: 1px; }
.vf-center { position: absolute; left: 50%; top: 50%; width: 44px; height: 30px; margin: -15px 0 0 -22px; display: none; z-index: 1; pointer-events: none; --b-inset: 0; --b-len: 8px; --b-color: var(--focus); }
.vf-center::before { border-width: 1.5px; opacity: var(--f, 1); }
.vf-read { position: absolute; z-index: 2; color: var(--mute); }
.vf-read.tl { top: clamp(20px, 2.6vw, 34px); left: clamp(24px, 3vw, 40px); }
.vf-read.tr { top: clamp(20px, 2.6vw, 34px); right: clamp(24px, 3vw, 40px); }
.vf-read.bl { bottom: clamp(20px, 2.6vw, 34px); left: clamp(24px, 3vw, 40px); }
.vf-read.br { bottom: clamp(20px, 2.6vw, 34px); right: clamp(24px, 3vw, 40px); }

/* ───── Selected work (dark viewfinder chapter) ───── */
.feat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(72px, 8vw, 128px) clamp(20px, 2.4vw, 40px); }
.feat-more { justify-content: center; margin-top: clamp(64px, 7vw, 112px); }
.feat { display: grid; gap: 10px; transition: opacity .6s var(--ease); }
.feat-grid:has(.feat:hover) .feat:not(:hover) { opacity: .45; }
.vf-depth { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.vf.has-depth .vf-image > :not(.vf-depth) { visibility: hidden; }
/* Upside-down masthead glass: six stacked blur layers, each fading out lower than the last, so the blur is strongest at the
   bottom edge and clears upward; a mid-grey tint follows the same direction. */
.feat .vf-read.bl, .feat .vf-read.br { display: none; }
.feat .vf { border-radius: 14px; }
/* Featured work (home grid and the Work page): the card is square, but the pointer brackets lock on with the cover's rounded corners. */
.feat { --cursor-radius: 14px; }
/* One breath of light on hover: a warm, soft gradient swells and fades, then rests until the next visit. */
.feat-glow { position: absolute; inset: -10%; z-index: 2; pointer-events: none; opacity: 0; mix-blend-mode: screen;
  background:
    radial-gradient(60% 55% at 28% 22%, rgba(255, 246, 232, .22), transparent 70%),
    radial-gradient(55% 60% at 78% 82%, color-mix(in srgb, var(--focus) 26%, transparent), transparent 72%); }
.feat:hover .feat-glow, .feat:focus-visible .feat-glow { animation: feat-breathe 2.4s cubic-bezier(.45, 0, .55, 1) 1; }
@keyframes feat-breathe { 0% { opacity: 0; transform: scale(.96); } 45% { opacity: 1; transform: scale(1.02); } 100% { opacity: 0; transform: scale(1.05); } }
.feat-glass { position: absolute; left: 0; right: 0; bottom: 0; height: 44%; z-index: 2; pointer-events: none; }
.feat-glass i { position: absolute; inset: 0; -webkit-backdrop-filter: blur(2.4px); backdrop-filter: blur(2.4px); }
.feat-glass i:nth-child(1) { -webkit-mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 100%); mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 100%); }
.feat-glass i:nth-child(2) { -webkit-mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 90%); mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 90%); }
.feat-glass i:nth-child(3) { -webkit-mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 80%); mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 80%); }
.feat-glass i:nth-child(4) { -webkit-mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 70%); mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 70%); }
.feat-glass i:nth-child(5) { -webkit-mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 60%); mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 60%); }
.feat-glass i:nth-child(6) { -webkit-mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 50%); mask-image: linear-gradient(to top, #000 0%, #000 38%, transparent 50%); }
.feat-glass::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top,
    rgba(104, 105, 107, .74) 0%,
    rgba(104, 105, 107, .62) 20%,
    rgba(104, 105, 107, .42) 42%,
    rgba(104, 105, 107, .2) 64%,
    rgba(104, 105, 107, .06) 84%,
    transparent 100%);
}
@media (prefers-reduced-transparency: reduce) { .feat-glass i { display: none; } .feat-glass::after { background: linear-gradient(to top, rgba(60, 61, 63, .92), transparent); } }
.feat-title { position: absolute; z-index: 3; left: clamp(20px, 2.4vw, 36px); right: clamp(20px, 2.4vw, 36px); bottom: clamp(16px, 2vw, 30px); display: flex; align-items: center; overflow: hidden; color: #f3f3f0; font-weight: 900; font-size: clamp(26px, 2.6vw, 44px); line-height: 1.25; letter-spacing: -.02em; text-shadow: 0 1px 12px rgba(0, 0, 0, .18); }
.feat-arrow { position: absolute; left: 0; top: 50%; width: 1.1em; height: 1.1em; margin-top: -.55em; transform: translateX(-1.4em); transition: transform .7s var(--ease); }
.feat-arrow svg { width: 100%; height: 100%; display: block; fill: none; stroke: var(--focus); stroke-linecap: round; stroke-linejoin: round; }
.feat-arrow circle { stroke-width: 10; }
.feat-arrow path { stroke-width: 14; }
.feat-name { display: flex; height: 1.25em; overflow: hidden; transition: transform .7s var(--ease); }
.fc-col { display: flex; flex-direction: column; }
.fc-col > span { display: block; height: 1.25em; }
.fc-sp { width: .3em; }
.feat:hover .feat-arrow, .feat:focus-visible .feat-arrow { transform: none; }
.feat:hover .feat-name, .feat:focus-visible .feat-name { transform: translateX(1.5em); }
.feat-type { font: 600 clamp(14px, 1.05vw, 17px)/1.3 'Archivo', var(--sans); font-stretch: 100%; letter-spacing: .01em; color: var(--mute); }
.specs { border-top: var(--hair) solid var(--line); }
.specs > div { display: grid; grid-template-columns: 6.5em 1fr; gap: 16px; padding: 11px 0; border-bottom: var(--hair) solid var(--faint); font-size: 15px; }
.specs dt { color: var(--mute); letter-spacing: .1em; }
.specs dd ul { display: flex; flex-wrap: wrap; gap: 2px 14px; }

/* ───── Services: five focal lengths ───── */
.lenses { border-top: var(--hair) solid var(--line); }
.lens { display: block; border-bottom: var(--hair) solid var(--line); transition: opacity .5s var(--ease); }
.lenses:has(.lens:hover, .lens:focus-visible) .lens:not(:hover, :focus-visible) { opacity: .38; }
.lens-row {
  display: grid; grid-template-columns: 56px minmax(0, 1fr) minmax(0, 1.05fr) 24px; align-items: center; gap: 28px;
  padding: clamp(22px, 2.4vw, 34px) 0;
}
.fov { width: 48px; height: 48px; overflow: visible; }
.fov path { fill: none; stroke: currentColor; stroke-width: 1; }
.fov .fov-arc { stroke: var(--gray); stroke-dasharray: 2 3; }
.fov circle { fill: currentColor; transition: fill .3s; }
.lens:hover .fov circle, .lens:focus-visible .fov circle { fill: var(--focus); }
.lens-title { display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap; transition: transform .6s var(--ease); }
.lens-title b { font-weight: 900; font-size: clamp(30px, 3.6vw, 60px); line-height: 1.15; letter-spacing: -.015em; transition: color .3s; }
.lens-swap { display: grid; }
.lens-swap > * { grid-area: 1 / 1; align-self: center; transition: opacity .45s var(--ease), transform .6s var(--ease); }
.lens-swap p { color: var(--mute); max-width: 30em; }
.lens-swap ul { display: flex; flex-wrap: wrap; gap: 8px; opacity: 0; transform: translateY(6px); }
.lens-swap li { padding: 3px 12px; border: var(--hair) solid var(--line); font-size: 14px; }
.lens-row > svg:last-child { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.5; transition: transform .45s var(--ease); }
.lens:hover .lens-title, .lens:focus-visible .lens-title { transform: translateX(16px); }
[data-theme="dark"] .lens:hover .lens-title b, [data-theme="dark"] .lens:focus-visible .lens-title b { color: var(--focus); }
.lens:hover .lens-swap p, .lens:focus-visible .lens-swap p { opacity: 0; transform: translateY(-6px); }
.lens:hover .lens-swap ul, .lens:focus-visible .lens-swap ul { opacity: 1; transform: none; }
.lens:hover .lens-row > svg:last-child, .lens:focus-visible .lens-row > svg:last-child { transform: translate(3px, -3px); }
.lens:focus-visible { outline-offset: -2px; }
.lenses.compact .lens-row { grid-template-columns: 56px minmax(0, 1fr) 24px; }
.lens-legend { margin-top: 20px; font-size: 13px; color: var(--mute); }

/* ───── Process: the focus pull ─────
   Static = end state: every step open, target sharp. motion.js adds .is-live, pins the stage and drives --p (0–1) and .on. */
.proc-stage { --p: 1; display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); grid-template-areas: 'view list' 'ruler ruler';
  gap: 0 clamp(32px, 5vw, 96px); align-items: start; }
.proc-view { grid-area: view; position: relative; aspect-ratio: 4 / 3; background: var(--plate); overflow: hidden; isolation: isolate; }
.proc-plate { position: absolute; inset: 0; display: grid; place-items: center; padding: 11% 12% 9%; color: var(--line);
  filter: blur(calc((1 - var(--p)) * 18px)); transform: scale(calc(1 + (1 - var(--p)) * .08)); opacity: calc(.4 + var(--p) * .6); will-change: filter, transform; }
.proc-plate .vf-target { opacity: .82; }
.proc-lock { position: absolute; inset: 31% 37%; z-index: 1; pointer-events: none; --b-inset: 0; --b-len: 16px;
  opacity: 0; transform: scale(1.35); transition: opacity .35s var(--ease), transform .6s var(--ease); }
.proc-stage.is-focused .proc-lock { opacity: 1; transform: none; }
.proc-view [data-proc-s] { transition: color .3s; }
.proc-stage.is-focused [data-proc-s] { color: var(--fg); }
.proc-view b { font-weight: 500; color: var(--fg); }

.proc-list { grid-area: list; border-top: var(--hair) solid var(--line); counter-reset: none; }
.proc-step { border-bottom: var(--hair) solid var(--faint); transition: opacity .5s var(--ease); }
.proc-step h3 { font: inherit; }
.proc-btn { display: grid; grid-template-columns: 52px minmax(0, 1fr) auto; align-items: baseline; gap: 12px; width: 100%; padding: 20px 0 14px; margin: 0;
  background: none; border: 0; text-align: left; cursor: default; }
.proc-n, .proc-d { color: var(--mute); }
.proc-t { font-weight: 900; font-size: clamp(20px, 1.9vw, 30px); line-height: 1.35; letter-spacing: -.01em; transition: transform .6s var(--ease); }
.proc-t::before { content: ''; display: inline-block; width: 0; height: 9px; margin-right: 0; background: var(--focus); vertical-align: .22em;
  transform: scale(0); transition: transform .45s var(--ease), width .45s var(--ease), margin .45s var(--ease); }
.proc-stage.is-live .proc-step.on .proc-t::before { transform: scale(1); width: 9px; margin-right: 14px; }
.proc-body { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .6s var(--ease); }
.proc-body > div { min-height: 0; overflow: hidden; }
.proc-body p { padding: 0 0 22px 64px; color: var(--mute); font-size: 16px; line-height: 1.8; max-width: 30em; }

.proc-ruler { grid-area: ruler; position: relative; height: 64px; margin-top: clamp(40px, 5vw, 72px); border-top: var(--hair) solid var(--line);
  transform-origin: left center; transform: scaleX(var(--rule, 1));
  background: linear-gradient(90deg, var(--gray) 1px, transparent 0) 0 0 / calc(100% / 40) 7px repeat-x; }
.proc-stop { position: absolute; top: 0; left: calc(var(--x) * 100%); }
.proc-stop i { position: absolute; left: 0; top: 0; width: 1px; height: 16px; background: var(--line); }
.proc-stop b { position: absolute; top: 24px; left: 0; transform: translateX(calc(var(--x) * -100%)); font-weight: 400; color: var(--mute); white-space: nowrap; transition: color .3s; }
.proc-marker { position: absolute; top: -14px; left: 0; width: 2px; height: 30px; background: var(--focus); z-index: 1;
  translate: calc(var(--p) * (100cqw - 2px)) 0; }
.proc-ruler { container-type: inline-size; }

/* Live: pinned, one step open at a time */
.proc-stage.is-live { height: calc(100svh - var(--glass) - 76px); /* clears the fixed 40px focus-distance scale */ grid-template-rows: minmax(0, 1fr) auto; align-items: stretch; padding-top: 8px; }
.proc-stage.is-live .proc-view { aspect-ratio: auto; min-height: 0; }
.proc-stage.is-live .proc-list { align-self: center; }
.proc-stage.is-live .proc-btn { cursor: pointer; }
.proc-stage.is-live .proc-step:not(.on) { opacity: .34; }
.proc-stage.is-live .proc-step.past:not(.on) { opacity: .6; }
.proc-stage.is-live .proc-step:not(.on) .proc-body { grid-template-rows: 0fr; }
.proc-stage.is-live .proc-step:not(.on) .proc-btn:hover { opacity: 1; }
.proc-stage.is-live .proc-step:not(.on):hover { opacity: .8; }
.proc-stage.is-live .proc-step.on .proc-t { transform: translateX(2px); }
.proc-stage.is-live .proc-stop.past b { color: var(--fg); }
.proc-stage.is-live .proc-ruler { margin-top: 28px; }
.track-note { margin-top: 40px; color: var(--mute); font-size: 14px; }

/* ───── Process: the card stack (after Rise at Seven) ─────
   Six step cards in the services card material. Static: the heading holds the left and the cards stack by position: sticky.
   Live (motion.js, wide screens): the stage pins, the cards lie in one pile and the scroll deals them off the top. */
.pstack { --paper: color-mix(in srgb, white 55%, var(--white)); }
.ps-stage { --cw: min(460px, 100%); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: 0 clamp(32px, 6vw, 112px); align-items: start; }
.ps-side { position: sticky; top: calc(var(--glass) + 24px); display: grid; gap: 22px; align-content: start; }
.ps-lead { color: var(--mute); max-width: 30em; }
.ps-index { margin-top: 10px; max-width: 440px; border-top: var(--hair) solid var(--line); }
.ps-index li { border-bottom: var(--hair) solid var(--faint); }
.ps-index button { display: grid; grid-template-columns: 44px minmax(0, 1fr) 9px; align-items: center; width: 100%; padding: 11px 0; margin: 0;
  background: none; border: 0; font: inherit; font-weight: 700; text-align: left; color: var(--mute); cursor: pointer; transition: color .3s; }
.ps-index button::after { content: ''; width: 9px; height: 9px; background: var(--focus); transform: scale(0); transition: transform .45s var(--ease); }
.ps-index .mono { font-weight: 400; font-size: 12px; color: var(--mute); transition: color .3s; }
.ps-index button:hover { color: var(--fg); }
.ps-index li.on button { color: var(--fg); }
.ps-stage.is-live .ps-index li.on button::after { transform: none; }
.ps-stage.is-live .ps-index li.on .mono { color: var(--focus); }
.ps-note { color: var(--mute); font-size: 14px; }

.ps-pile { display: grid; justify-items: center; }
.ps-card { position: sticky; top: calc(var(--glass) + 24px + var(--i) * 14px); width: var(--cw); margin-bottom: 22vh; container-type: inline-size; }
.ps-card:last-child { margin-bottom: 0; }
.has-smoother .ps-card { margin-bottom: 32px; } /* sticky cannot hold inside the smoothed wrapper; the cards simply follow one another */
.ps-card:nth-child(odd) .ps-face { rotate: -1.4deg; }
.ps-card:nth-child(even) .ps-face { rotate: 1.2deg; }
.ps-card:last-child .ps-face { rotate: 0deg; }
.ps-face { position: relative; display: flex; flex-direction: column; aspect-ratio: 4 / 5; padding: 15cqi 9cqi 11cqi; border-radius: 5cqi; overflow: hidden;
  background: var(--paper); color: var(--ink);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 10%, transparent), 0 3cqi 9cqi color-mix(in srgb, var(--ink) 16%, transparent); }
.ps-frame { position: absolute; inset: 3.4cqi; border: 1px solid var(--focus); border-radius: 3.2cqi; pointer-events: none; }
.ps-no, .ps-of { position: absolute; top: 6.4cqi; font-size: max(11px, 2.9cqi); letter-spacing: .06em; }
.ps-no { left: 7cqi; color: var(--focus); }
.ps-of { right: 7cqi; color: var(--mute); }
.ps-no-r { top: auto; left: auto; right: 7cqi; bottom: 6.4cqi; rotate: 180deg; }
.ps-dial { flex: 1; align-self: center; width: 36cqi; min-height: 0; margin-bottom: 6cqi; overflow: visible; }
.ps-dial circle, .ps-dial line { fill: none; stroke: currentColor; vector-effect: non-scaling-stroke; }
.ps-dial-ring { opacity: .28; }
.ps-dial-inner { opacity: .2; stroke-dasharray: 2 4; }
.ps-dial circle:not([class]) { opacity: .45; }
.ps-dial .is-past { fill: currentColor; stroke: none; opacity: .7; }
.ps-dial .is-on { fill: var(--focus); stroke: none; }
.ps-dial-hand { stroke: var(--focus) !important; stroke-width: 1.5; }
.ps-dial-hub { fill: var(--focus) !important; stroke: none !important; }
.ps-t { font-weight: 900; font-size: 8.6cqi; line-height: 1.2; letter-spacing: -.01em; }
.ps-t::after { content: ''; display: block; width: 7cqi; height: max(2px, .9cqi); margin-top: 3.6cqi; background: var(--focus); }
.ps-d { margin-top: 3.6cqi; font-size: max(14px, 3.7cqi); line-height: 1.75; color: var(--mute); }

/* Ink cards are the service-card backs; the last card is the orange one. */
.ps-card[data-tone="ink"] .ps-face { background: radial-gradient(120% 80% at 50% 0%, #27292c, var(--ink) 72%); color: var(--white);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, white 10%, transparent), 0 3cqi 9cqi color-mix(in srgb, var(--ink) 26%, transparent); }
.ps-card[data-tone="ink"] .ps-frame { border-color: color-mix(in srgb, white 38%, transparent); }
.ps-card[data-tone="ink"] :is(.ps-of, .ps-d) { color: color-mix(in srgb, white 66%, transparent); }
.ps-card[data-tone="focus"] .ps-face { background: var(--focus); box-shadow: 0 3cqi 10cqi color-mix(in srgb, var(--focus) 30%, transparent); }
.ps-card[data-tone="focus"] .ps-frame { border-color: color-mix(in srgb, var(--ink) 45%, transparent); }
.ps-card[data-tone="focus"] :is(.ps-no, .ps-of, .ps-d) { color: color-mix(in srgb, var(--ink) 78%, transparent); }
.ps-card[data-tone="focus"] .ps-dial :is(.is-on, .ps-dial-hub) { fill: var(--ink) !important; }
.ps-card[data-tone="focus"] .ps-dial-hand { stroke: var(--ink) !important; }
.ps-card[data-tone="focus"] .ps-t::after { background: var(--ink); }

/* Live: one pile; motion.js writes each card's transform and the index follows the top card. */
.ps-stage.is-live { --cw: min(460px, 100%, calc((100svh - var(--glass) - 150px) * .8)); height: calc(100svh - var(--glass) - 76px); /* clears the fixed focus-distance scale */ align-items: center; }
.ps-stage.is-live .ps-side { position: static; }
.ps-stage.is-live .ps-pile { position: relative; height: 100%; }
.ps-stage.is-live .ps-card { position: absolute; left: 50%; top: 50%; margin: 0; translate: -50% -50%; z-index: calc(var(--n) - var(--i)); will-change: transform; }
.ps-stage.is-live .ps-face { rotate: none; }
@media (max-width: 1100px) {
  .ps-stage { grid-template-columns: minmax(0, 1fr); row-gap: 48px; }
  .ps-side { position: static; }
  .ps-index { display: none; }
  .ps-card { --cw: min(420px, 100%); top: calc(var(--glass) + 12px + var(--i) * 10px); margin-bottom: 16vh; }
}

/* ───── Principal / about teaser ───── */
.principal { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: 40px clamp(40px, 7vw, 140px); align-items: start; }
.principal-body { display: grid; gap: 28px; padding-top: 10px; }
.principal-body > p { font-size: clamp(17px, 1.3vw, 20px); line-height: 1.95; }
.signed { display: flex; align-items: center; gap: 14px; }
.signed::before { content: ''; width: 56px; border-top: var(--hair) dashed var(--line); }
.signed::after { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--focus); order: -1; }
.signed b { font-weight: 700; letter-spacing: .12em; }

/* Home: the principal at the centre of a focus chart, services at their own distances */
.principal-home { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; }
.principal-main { display: grid; gap: clamp(32px, 4vw, 56px); }
.principal-main .principal-body { padding-top: 0; max-width: 30em; }
.crew { position: relative; width: 100%; max-width: 760px; padding-right: clamp(80px, 9vw, 150px); justify-self: end; } /* room for right-hand labels */
.crew-field { position: relative; aspect-ratio: 1; }
.crew-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; fill: none; stroke: var(--line); }
.crew-svg * { vector-effect: non-scaling-stroke; stroke-width: 1px; }
.crew-ring { stroke: var(--gray); transform-box: view-box; transform-origin: 50% 50%; animation: crew-spin 140s linear infinite; }
@keyframes crew-spin { to { rotate: 360deg; } }
.crew-orbit { stroke: var(--faint); stroke-dasharray: 2 5; }
.crew-cross { stroke: var(--faint); }
.crew-core { fill: var(--bg); }
.crew-lead { transform-box: view-box; transform-origin: 50% 50%; transform: scale(var(--draw, 1)); transition: opacity .4s var(--ease); }
.crew-lead line { stroke-dasharray: 3 5; transition: stroke .3s; }
.crew[data-on] .crew-lead { opacity: .22; }
.crew[data-on="brand"] [data-k="brand"], .crew[data-on="web"] [data-k="web"], .crew[data-on="graphic"] [data-k="graphic"],
.crew[data-on="interface"] [data-k="interface"], .crew[data-on="illustration"] [data-k="illustration"] { opacity: 1; }
.crew[data-on="brand"] g[data-k="brand"] line, .crew[data-on="web"] g[data-k="web"] line, .crew[data-on="graphic"] g[data-k="graphic"] line,
.crew[data-on="interface"] g[data-k="interface"] line, .crew[data-on="illustration"] g[data-k="illustration"] line { stroke: var(--focus); stroke-dasharray: none; stroke-width: 2px; }
.crew-me { position: absolute; left: 50%; top: 50%; translate: -50% -50%; display: grid; justify-items: center; line-height: 1.3; pointer-events: none; }
.crew-me b { font-weight: 900; font-size: clamp(14px, 1.2vw, 17px); letter-spacing: .12em; }
.crew-me small { font-size: 9px; color: var(--mute); }
.crew-node { position: absolute; left: var(--x); top: var(--y); display: flex; align-items: center; gap: 14px; translate: -7px -50%;
  padding: 6px 0; transition: opacity .4s var(--ease); }
.crew-node.is-l { flex-direction: row-reverse; translate: calc(-100% + 7px) -50%; text-align: right; }
.crew-node i { flex: none; width: 14px; height: 14px; border-radius: 50%; border: var(--hair) solid var(--line); background: var(--bg); position: relative; transition: background-color .3s, border-color .3s, scale .45s var(--ease); }
.crew-node i::after { content: ''; position: absolute; inset: 4px; border-radius: 50%; background: var(--focus); transform: scale(0); transition: transform .4s var(--ease); }
.crew-node span { display: grid; line-height: 1.35; }
.crew-node b { font-weight: 900; font-size: clamp(15px, 1.25vw, 19px); white-space: nowrap; transition: color .3s; }
.crew-node small { font-size: 12px; font-weight: 500; letter-spacing: .02em; color: var(--mute); white-space: nowrap; }
.crew[data-on] .crew-node { opacity: .38; }
.crew-node:hover, .crew-node:focus-visible, .crew[data-on] .crew-node:hover, .crew[data-on] .crew-node:focus-visible { opacity: 1; }
.crew-node:hover i, .crew-node:focus-visible i { border-color: var(--focus); scale: 1.3; }
.crew-node:hover i::after, .crew-node:focus-visible i::after { transform: scale(1); }
.crew-read { position: absolute; left: 0; bottom: 0; width: 42%; display: grid; gap: 6px; font-size: 13px; line-height: 1.7; color: var(--mute); }
.crew-read .mono { color: var(--fg); }

/* ───── Inquiry band ───── */
.inquiry { padding-block: clamp(96px, 12vw, 192px); }
.inquiry-inner { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 40px clamp(40px, 6vw, 120px); align-items: end; }
.inquiry h2 { justify-self: start; --b-inset: -20px -28px; }
.inquiry h2 { font-weight: 900; font-size: clamp(38px, 5.6vw, 96px); line-height: 1.15; letter-spacing: -.015em; }
.inquiry-side { display: grid; gap: 28px; }
.inquiry-side p { color: var(--mute); }
.inquiry-side .inq-note { margin-top: -16px; font-size: 14px; }

/* ───── Inner page heads ───── */
.page-head { padding: calc(var(--glass) + clamp(64px, 9vw, 144px)) 0 clamp(56px, 7vw, 104px); border-bottom: var(--hair) solid var(--line); }
.page-head-grid { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(220px, .6fr); gap: 40px clamp(32px, 6vw, 112px); align-items: end; }
.page-head h1 { font-weight: 900; font-size: clamp(42px, 6.6vw, 116px); line-height: 1.12; letter-spacing: -.015em; text-wrap: balance; }
.page-head .lead { margin-top: clamp(24px, 3vw, 40px); }
.crumb { display: flex; gap: 10px; margin-bottom: 28px; font-size: 14px; color: var(--mute); }
.crumb a { color: var(--fg); background-image: linear-gradient(currentColor, currentColor); background-size: 100% 1px; background-position: 0 100%; background-repeat: no-repeat; }
.head-read { border-top: var(--hair) solid var(--line); padding-top: 12px; display: grid; gap: 4px; }
.head-read .mono { color: var(--mute); }
.head-read b { font-size: 17px; }
.head-read:has(.specs) { border-top: 0; padding-top: 0; }
/* The works page's head figure: a type case (hairline/sorter.js) in the empty upper right, larger than the column, reaching left. */
.head-side { display: grid; gap: clamp(8px, 1.6vw, 24px); align-self: stretch; align-content: end; }
.head-fig { --reach: clamp(0px, 16vw, 320px); position: relative; z-index: 1; width: calc(100% + var(--reach)); margin-left: calc(-1 * var(--reach)); aspect-ratio: 5 / 4; cursor: pointer; touch-action: pan-y; }
.head-fig .hl-slot {
  display: block; width: 100%; height: 100%;
  --hairline-plate: var(--bg); --hairline-hi: var(--focus);
  --hairline-edge: color-mix(in srgb, var(--fg) 52%, var(--bg)); --hairline-mid: color-mix(in srgb, var(--fg) 30%, var(--bg)); --hairline-lo: color-mix(in srgb, var(--fg) 14%, var(--bg));
}

/* ───── Works catalogue ───── */
/* The Work page lists every project with the home grid's cards, on a light page. */
.works-list { padding-top: clamp(48px, 6vw, 88px); }
/* Category index: words on a hairline, racked out of focus; the chosen one is sharp with an orange focus mark under it,
   and a faint ghost of the mark follows the pointer (studio.js placeFilterMark). */
.filters { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: end; gap: 12px clamp(28px, 4vw, 72px); margin-bottom: clamp(48px, 6vw, 88px); }
.flt-cap { display: grid; gap: 4px; padding-bottom: 20px; font-weight: 700; font-size: 13px; letter-spacing: .14em; }
.flt-cap span { font-family: var(--mono); font-weight: 400; font-size: 11px; letter-spacing: .08em; color: var(--mute); text-transform: uppercase; }
.flt-list { position: relative; display: flex; flex-wrap: wrap; gap: 0 clamp(22px, 3.4vw, 60px); border-bottom: var(--hair) solid var(--line); }
.filters button {
  display: grid; grid-template-columns: auto auto; grid-template-areas: "en en" "zh n"; justify-items: start; column-gap: 5px;
  padding: 10px 0 16px; background: none; border: 0; cursor: pointer; color: var(--mute); text-align: left;
}
.flt-en { grid-area: en; font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 6px; }
.flt-zh { grid-area: zh; font-weight: 900; font-size: clamp(24px, 2.5vw, 40px); line-height: 1.1; letter-spacing: .02em; transition: filter .7s var(--ease), color .35s; }
.filters sup { grid-area: n; align-self: start; font-family: var(--mono); font-size: 11px; line-height: 1; transition: color .35s; }
.filters button:hover, .filters button:focus-visible, .filters button[aria-pressed="true"] { color: var(--fg); }
.filters button[aria-pressed="true"] sup { color: var(--focus); }
.filters button.is-empty sup { opacity: .55; }
.flt-bar, .flt-ghost { position: absolute; left: 0; top: 0; height: 2px; margin-top: -1px; width: var(--w, 0px); translate: var(--x, 0px) var(--y, 0px); pointer-events: none;
  transition: translate .8s var(--ease), width .8s var(--ease), opacity .35s; }
.flt-bar { background: var(--focus); }
.flt-ghost { width: var(--gw, 0px); translate: var(--gx, 0px) var(--gy, 0px); background: var(--focus); opacity: 0; }
.flt-list.is-ghost .flt-ghost { opacity: .35; }
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .filters button:not(:hover, :focus-visible, [aria-pressed="true"]) .flt-zh { filter: blur(1.3px); }
}
/* Work page cards answer the pointer harder than the home grid: a sheen follows it across the plate, the rest of the
   grid racks out of focus, and pointing at a category previews which cards it would drop. */
.feat[hidden], .feat-grid[hidden], .empty[hidden] { display: none; }
.feat-sheen { display: none; }
.works-grid .feat-sheen { display: block; position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0; mix-blend-mode: soft-light;
  background: radial-gradient(circle at var(--mx, 50%) var(--my, 50%), rgba(255, 255, 255, .85), rgba(255, 255, 255, 0) 46%); transition: opacity .6s var(--ease); }
.works-grid .feat:hover .feat-sheen { opacity: 1; }
.works-grid .feat { transition: opacity .6s var(--ease), filter .6s var(--ease); }
.works-grid:has(.feat:hover) .feat:not(:hover), .works-grid .feat.is-off { opacity: .32; filter: blur(5px) grayscale(.7); }
.catalogue { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(56px, 6vw, 96px) clamp(24px, 3vw, 48px); }
.catalogue:has(.work:hover) .work:not(:hover) { opacity: .45; }
.work { display: grid; gap: 20px; transition: opacity .5s var(--ease); }
.work-title { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; padding-bottom: 14px; border-bottom: var(--hair) solid var(--line); }
.work-title h2 { font-weight: 900; font-size: clamp(26px, 2.6vw, 40px); letter-spacing: -.02em; line-height: 1.2; }
.work-title span { font-family: var(--mono); font-size: 12px; color: var(--mute); white-space: nowrap; }
.work p { color: var(--mute); font-size: 15px; }
[data-theme="dark"] .work:hover .work-title h2 { color: var(--focus); }
.empty { border: var(--hair) solid var(--line); padding: clamp(40px, 6vw, 96px); display: grid; gap: 20px; justify-items: start; }

/* ───── Case page: one rail ─────
   Default (narrow, or no motion): a vertical stack. .is-live (set by motion.js from 900px) pins the section to the
   viewport and turns it into a Cover Flow; see motion.js rail(). Latin text is Archivo, CJK falls through to Noto Sans TC. */
.case-rail { position: relative; padding: calc(var(--glass) + clamp(48px, 8vw, 112px)) 0 clamp(72px, 9vw, 128px); }
.rail-track { display: grid; gap: clamp(72px, 10vw, 128px); padding-inline: var(--gutter); }
.rail-intro { display: grid; align-content: start; }
.rail-title { width: fit-content; font-family: 'Archivo', var(--sans); font-weight: 900; font-size: clamp(48px, 5.8vw, 112px); line-height: 1.02; letter-spacing: -.02em; text-wrap: balance; }
.rail-en, .rail-type, .rail-next-type { font-family: 'Archivo', var(--sans); font-weight: 500; letter-spacing: .01em; color: var(--mute); }
/* The left column reads in three tiers: who (crumb, name, discipline), what (the summary, the loudest text after the
   name) and the facts (small labels over quiet values, below a hairline). 類別 is left to the English discipline line. */
.rail-intro .crumb { align-items: baseline; margin-bottom: clamp(18px, 2.4vh, 28px); font-size: 13px; }
.rail-intro .crumb .mono { color: var(--focus); }
.rail-en { margin-top: 18px; font-size: clamp(17px, 1.3vw, 20px); color: color-mix(in srgb, var(--fg) 88%, transparent); }
.rail-type { margin-top: 8px; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; }
.rail-body { display: grid; gap: clamp(28px, 3.6vh, 40px); margin-top: clamp(40px, 6vh, 72px); max-width: 520px; }
.rail-summary { font-size: clamp(17px, 1.3vw, 21px); line-height: 1.75; text-wrap: balance; word-break: keep-all; overflow-wrap: anywhere; }
.rail-body .note { margin-top: calc(-1 * clamp(12px, 2vh, 24px)); }
.rail-meta { display: grid; grid-template-columns: minmax(0, 1fr) fit-content(11em); gap: 20px clamp(28px, 3vw, 48px); padding-top: 20px; border-top: var(--hair) solid var(--faint); }
.rail-meta dt { margin-bottom: 10px; font-size: 12px; letter-spacing: .16em; color: var(--mute); }
.rail-meta dd { font-size: 14px; line-height: 1.5; }
.rail-meta ul { display: flex; flex-wrap: wrap; gap: 8px; }
.rail-meta li { padding: 4px 10px; border: var(--hair) solid var(--faint); }
.rail-status dd { display: flex; align-items: baseline; gap: 10px; padding-top: 5px; }
.rail-status dd::before { content: ''; flex: none; width: 7px; height: 7px; background: var(--focus); }
.rail-hint { display: none; }
.rail-card { display: grid; gap: 22px; margin: 0; }
/* Case plates keep the viewfinder frame, without its printed readouts: the picture speaks, the left column annotates. */
.rail-card .vf-read { display: none; }
.rail-cap { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 20px; align-items: baseline; max-width: 720px; }
.rail-cap .mono { color: var(--focus); }
.rail-cap h2 { font-weight: 900; font-size: clamp(20px, 1.7vw, 28px); line-height: 1.3; }
.rail-cap p { grid-column: 2; color: var(--mute); font-size: 15px; }
/* The next project: one block of focus orange with ink type, and the ring arrow from the featured-work titles. */
.rail-next { display: grid; gap: 14px; align-content: end; margin: clamp(72px, 10vw, 128px) 0 0; padding: clamp(48px, 8vw, 96px) var(--gutter); background: var(--focus); color: var(--ink); --cursor-radius: 0px; }
.rail-next-read { font-size: 15px; font-weight: 500; }
.rail-next-read .mono { font-size: 13px; }
.rail-next strong { font-family: 'Archivo', var(--sans); font-weight: 900; font-size: clamp(44px, 5.6vw, 112px); line-height: 1; letter-spacing: -.02em; }
.rail-next-type { font-size: 15px; color: color-mix(in srgb, var(--ink) 72%, transparent); }
.rail-next-arrow { display: block; width: clamp(48px, 4.4vw, 72px); height: clamp(48px, 4.4vw, 72px); margin-top: 16px; transition: transform .6s var(--ease); }
.rail-next-arrow svg { display: block; width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }
.rail-next-arrow circle { stroke-width: 8; }
.rail-next-arrow path { stroke-width: 11; }
.rail-next:hover .rail-next-arrow, .rail-next:focus-visible .rail-next-arrow { transform: translateX(14px); }
.rail-meter, .flow-cap { display: none; }

/* Cover Flow (from 900px). Two columns: a left column (--lw) that reads the front card (its FIG label, title and design
   note, top) and keeps the project name small at its foot; and the card stage, which takes all the width that is left
   (--cw) and centres the front card in it (--cx). Cards to come stack behind it on the right, cards already seen fade and
   blur away to the left. Each plate fits the stage box (--cw × --ch) at its own ratio. motion.js writes every transform,
   depth, opacity and focus (--f on the viewfinder); the CSS here only places things. */
.case-rail.is-live { --lw: clamp(300px, 26vw, 440px); --gap: clamp(32px, 3vw, 56px); --peek: 3vw; --ch: 64svh;
  --cw: calc(100vw - 2 * var(--gutter) - var(--lw) - var(--gap) - var(--peek)); --cx: calc(var(--gutter) + var(--lw) + var(--gap) + var(--cw) / 2); --cy: 50%;
  height: 100svh; padding: 0; overflow: hidden; }
.case-rail.is-live::before { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 40% 36% at var(--cx) var(--cy), color-mix(in srgb, var(--focus) 12%, transparent), transparent 70%); }
.is-live .rail-track { position: absolute; inset: 0; display: block; padding: 0; perspective: 1600px; perspective-origin: var(--cx) var(--cy); will-change: transform; }
.is-live .rail-intro { position: absolute; z-index: 3; left: var(--gutter); top: calc(var(--glass) + 16px); bottom: 72px; width: max(var(--lw), min(560px, 36vw)); align-content: safe center; }
.is-live .rail-intro > :not(.rail-name) { will-change: transform, opacity; }
.is-live .rail-title { transform-origin: left top; will-change: transform; }
.is-live .rail-name > p { will-change: transform; }
.is-live .rail-hint { display: flex; align-items: center; gap: 10px; margin-top: clamp(24px, 3.4vh, 44px); font: 500 13px/1 'Archivo', var(--sans); letter-spacing: .08em; text-transform: uppercase; color: var(--mute); }
.is-live .rail-hint svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.2; }
.is-live [data-flow] { position: absolute; z-index: 1; left: var(--cx); top: var(--cy); width: max-content; cursor: pointer; will-change: transform, opacity; backface-visibility: hidden; --cursor-radius: 16px; }

/* Clean glass (as on the Work page): the plate itself, rounded, with the glass told only at its edges — a bright rim
   top-left, a faint one bottom-right, a hairline all round. Static: nothing here repaints while the flow moves. */
.is-live .rail-card { gap: 0; }
.is-live .rail-card .vf { width: min(var(--cw), calc(var(--ch) * var(--ratio))); height: auto; border-radius: 16px; box-shadow: 0 40px 80px -36px rgba(0, 0, 0, .8); }
.is-live .rail-card::after { content: ''; position: absolute; inset: 0; z-index: 3; border-radius: 16px; pointer-events: none;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, white 12%, transparent), inset 1.5px 1.5px 0 color-mix(in srgb, white 50%, transparent),
    inset -1px -1px 0 color-mix(in srgb, white 16%, transparent), inset 0 0 24px color-mix(in srgb, white 6%, transparent); }
/* focus blur runs on the compositor; motion.js only steps --f in tenths */
.is-live .vf-image { will-change: filter; transition: filter .3s linear; }
.is-live .rail-cap { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* The next project (after Lusion): not a card but a whole panel that slides in from the right edge at the end. */
.is-live .rail-next { position: absolute; z-index: 150; top: 0; right: 0; bottom: 0; width: min(44vw, 720px); margin: 0; padding: calc(var(--glass) + 24px) var(--gutter) clamp(48px, 9vh, 96px) clamp(40px, 4vw, 72px);
  visibility: hidden; will-change: transform; }
/* Scroll charge (motion.js): past the last card the wheel fills a bar across the panel; at 100% the whole orange wipe
   plays from the panel (wipe.js). Without input the bar drains back. Only the bar moves; the panel stays put. */
.rail-next-charge { display: none; }
.is-live .rail-next-charge { display: flex; align-items: center; gap: 14px; margin-bottom: 18px; font-size: 12px; }
.rail-next-charge i { flex: 1; height: 3px; background: color-mix(in srgb, var(--ink) 20%, transparent); }
.rail-next-charge i::before { content: ''; display: block; height: 100%; background: var(--ink); transform-origin: left center; transform: scaleX(var(--c, 0)); }
.rail-next-charge b { font-weight: 500; min-width: 4ch; }
/* Case pages are one full-screen stage for now: no footer under them. */
.is-case .spec-footer, .is-about .spec-footer { display: none; }

/* The front card's note, in the left column: its top edge sits on the cards' top edge (motion.js sets top). */
.is-live .flow-cap { position: absolute; z-index: 2; left: var(--gutter); top: 30%; display: grid; align-content: start; gap: 14px; width: var(--lw); pointer-events: none; will-change: transform, opacity; }
.flow-cap .mono { color: var(--focus); font-size: 12px; }
.flow-cap strong { font-weight: 900; font-size: clamp(26px, 2.3vw, 40px); line-height: 1.25; letter-spacing: -.01em; text-wrap: balance; }
.flow-cap p { color: color-mix(in srgb, var(--fg) 72%, transparent); font-size: clamp(15px, 1.1vw, 17px); line-height: 1.9; }
.is-live .rail-meter { position: absolute; z-index: 2; left: var(--gutter); right: var(--gutter); bottom: 24px; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 16px; color: var(--mute); }
.rail-meter i { height: 1px; background: var(--line); }
.rail-meter i::before { content: ''; display: block; height: 100%; background: var(--focus); transform-origin: left center; transform: scaleX(var(--p, 0)); }

.note { font-size: 14px; color: var(--mute); }
.note::before { content: ''; display: inline-block; width: 7px; height: 7px; margin-right: 10px; background: var(--focus); vertical-align: .12em; }

/* ───── Service page ───── */
.service-head .en { display: block; margin-top: 20px; font-weight: 500; font-size: 17px; letter-spacing: .02em; color: var(--mute); }
.service-spec { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px clamp(40px, 6vw, 112px); }
.service-spec h2 { font-weight: 900; font-size: clamp(24px, 2.4vw, 36px); margin-bottom: 24px; }
.needs { border-top: var(--hair) solid var(--line); }
.needs li { display: grid; grid-template-columns: 3em 1fr; padding: 16px 0; border-bottom: var(--hair) solid var(--faint); font-size: 17px; }
.needs li span { font-family: var(--mono); font-size: 12px; color: var(--mute); padding-top: 5px; }
.deliverables { display: flex; flex-wrap: wrap; gap: 10px; }
.deliverables li { padding: 10px 18px; border: var(--hair) solid var(--line); font-weight: 500; font-size: 16px; }
.service-spec .note { margin-top: 28px; }

/* The services page is a card table with two states (deck.js). Spread: title on top, six cards floating in a row.
   Chosen: the card unfolds into a dossier, the rest are held as a hand at the bottom left, the title fades almost away.
   Cards are laid out at the spread size (--cw × --ch) and posed by --x/--y/--r/--s. */
.deck {
  --paper: color-mix(in srgb, white 55%, var(--white));
  position: relative; height: 100svh; min-height: 600px; padding-inline: var(--gutter);
  overflow: clip; /* clip, not hidden: focus must never scroll the table */
}
.deck-intro {
  position: absolute; left: var(--gutter); right: var(--gutter); top: calc(var(--glass) + 4px);
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, 380px); align-items: end; gap: 16px 48px;
  transition: opacity .6s var(--ease);
}
.deck-kicker { grid-column: 1 / -1; font-size: 12px; letter-spacing: .04em; color: var(--mute); }
.deck-intro h1 { font-weight: 900; font-size: clamp(32px, 4.4vw, 76px); line-height: 1.1; letter-spacing: -.015em; }
.deck-lead { color: var(--mute); }
.deck.has-play .deck-intro { opacity: .07; pointer-events: none; }

/* ── Cards ── */
.tcard {
  position: absolute; left: 0; top: 0; width: var(--cw, 180px); height: var(--ch, 272px);
  container-type: size; perspective: 1100px; transform-origin: 50% 50%;
  transform: translate(calc(var(--x, 0) * 1px), calc(var(--y, 0) * 1px + var(--deal, 0px))) rotate(calc(var(--r, 0) * var(--tilt, 1) * 1deg)) translateY(calc(var(--lift, 0) * -1px)) scale(calc(var(--s, 1) * var(--zoom, 1)));
  transition: transform .85s var(--ease), opacity .18s;
}
.tcard.in-hand { transition-duration: .55s, .18s; }
.deck.is-dealing .tcard { transition: none; }
.tcard.is-veiled { opacity: 0; pointer-events: none; }
@media (hover: hover) {
  .tcard:not(.face-up):hover { --lift: var(--up, 16); --zoom: 1.07; --tilt: 0; z-index: 120 !important; transition-duration: .5s; }
  .deck.has-play .tcard:not(.face-up):hover { --zoom: 1.12; }
}
.tcard:not(.face-up):has(.tc-back:focus-visible) { --lift: var(--up, 16); --zoom: 1.07; --tilt: 0; z-index: 120 !important; }

/* Floating: each card bobs on its own beat; the pointer leans it (--rx/--ry from deck.js). */
.tc-float {
  position: absolute; inset: 0; transform-style: preserve-3d;
  transform: rotateX(var(--ry, 0deg)) rotateY(var(--rx, 0deg)); transition: transform .35s var(--ease);
  animation: tc-bob calc(3.1s + var(--i) * .37s) ease-in-out calc(var(--i) * -.7s) infinite alternate;
}
.deck.has-play .tc-float { animation-play-state: paused; }
@keyframes tc-bob { from { translate: 0 0; } to { translate: 0 -9px; } }
.tc-inner { position: absolute; inset: 0; transform-style: preserve-3d; transform: rotateY(180deg); transition: transform .85s var(--ease) .05s; }
.tcard.face-up .tc-inner, .tc-proc .tc-inner { transform: none; }
.tc-face { position: absolute; inset: 0; display: block; border-radius: 6cqi; overflow: hidden; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
.tc-frame { position: absolute; inset: 3.4cqi; display: block; border: max(1px, calc(1px / var(--s, 1))) solid; border-radius: 4cqi; }
.tc-no { position: absolute; left: 5cqi; top: 4.6cqi; font-size: max(6cqi, calc(9px / var(--s, 1))); }
.tc-no-r { left: auto; top: auto; right: 5cqi; bottom: 4.6cqi; rotate: 180deg; }
.tc-emblem { position: absolute; left: 50%; top: 60%; translate: -50% -50%; display: grid; place-items: center; width: 50cqi; aspect-ratio: 1; border-radius: 50%; border: max(1px, calc(1px / var(--s, 1))) solid; transition: border-color .4s, box-shadow .4s; }
.tc-emblem .fov { width: 34cqi; height: 34cqi; translate: -4cqi 0; }
.tc-emblem .fov path { stroke-width: 1.4; transition: stroke .4s; }
.tc-emblem .fov circle { fill: var(--c); }

/* Hairline figures (hairline.js). The slot never takes the pointer: the card is its touchpad.
   Plates are filled with the face's own colour, so a near part hides a far one; the bright stroke is the card's colour. */
.hl-slot { pointer-events: none; }
.tc-emblem .hl-slot { position: absolute; left: 50%; top: 50%; width: 74cqi; aspect-ratio: 5 / 4; translate: -50% -50%; }
.tc-back .hl-slot, .ps-card[data-tone="ink"] .hl-slot {
  --hairline-plate: #101113; --hairline-hi: var(--c, var(--focus));
  --hairline-edge: color-mix(in srgb, white 50%, #101113); --hairline-mid: color-mix(in srgb, white 30%, #101113); --hairline-lo: color-mix(in srgb, white 15%, #101113);
}
.tc-front .hl-slot, .tc-proc .hl-slot, .ps-card:not([data-tone="ink"]):not([data-tone="focus"]) .hl-slot {
  --hairline-plate: var(--paper); --hairline-hi: color-mix(in srgb, var(--c, var(--focus)) 80%, var(--ink));
  --hairline-edge: color-mix(in srgb, var(--ink) 52%, var(--paper)); --hairline-mid: color-mix(in srgb, var(--ink) 30%, var(--paper)); --hairline-lo: color-mix(in srgb, var(--ink) 14%, var(--paper));
}
.ps-card[data-tone="focus"] .hl-slot {
  --hairline-plate: var(--focus); --hairline-hi: var(--ink);
  --hairline-edge: color-mix(in srgb, var(--ink) 62%, var(--focus)); --hairline-mid: color-mix(in srgb, var(--ink) 40%, var(--focus)); --hairline-lo: color-mix(in srgb, var(--ink) 22%, var(--focus));
}
.dp-stairs { position: absolute; left: 50%; top: 61%; width: 84cqi; aspect-ratio: 5 / 4; translate: -50% -50%; }
.ps-hl { flex: 1; align-self: stretch; min-height: 0; margin-bottom: 4cqi; aspect-ratio: auto; }

/* Back: ink, a white frame; the name sits top-left, the part a held hand leaves visible. */
.tc-back {
  transform: rotateY(180deg); padding: 0; border: 0; font: inherit; text-align: left; cursor: pointer;
  background: radial-gradient(120% 80% at 50% 0%, #27292c, var(--ink) 72%); color: var(--white);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, white 10%, transparent), 0 4cqi 10cqi color-mix(in srgb, var(--c) 16%, transparent), 0 3cqi 7cqi color-mix(in srgb, var(--ink) 26%, transparent);
  transition: box-shadow .45s var(--ease);
}
.tc-back .tc-frame { border-color: color-mix(in srgb, white 40%, transparent); transition: border-color .4s, box-shadow .4s; }
.tc-back .tc-no { color: color-mix(in srgb, white 70%, transparent); }
.tc-back .tc-emblem { border-color: color-mix(in srgb, white 20%, transparent); }
.tc-back .tc-emblem .fov .fov-arc { stroke: color-mix(in srgb, white 42%, transparent); }
.tc-name { position: absolute; left: 7cqi; right: 7cqi; top: 15cqi; display: grid; gap: 2cqi; }
.tc-name b { font-weight: 900; font-size: max(10.5cqi, calc(11px / var(--s, 1))); letter-spacing: .04em; line-height: 1.2; white-space: nowrap; }
.tc-name small { font-family: 'Archivo', var(--sans); font-weight: 500; font-size: max(5cqi, calc(7px / var(--s, 1))); letter-spacing: .02em; white-space: nowrap; color: color-mix(in srgb, white 58%, transparent); }
.tcard:not(.face-up) .tc-back:focus-visible { outline: 2px solid var(--c); outline-offset: -2px; }

/* Front: paper with the same frame; this is the cover the dossier unfolds from. */
.tc-front { background: var(--paper); color: var(--ink); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 10%, transparent), 0 4cqi 12cqi color-mix(in srgb, var(--ink) 18%, transparent); }
.tc-front .tc-frame { border-color: color-mix(in srgb, var(--c) 60%, var(--ink)); }
.tc-front .tc-no { color: var(--mute); }
.tc-front .tc-emblem { top: 40%; border-color: color-mix(in srgb, var(--c) 50%, transparent); }
.tc-cover { position: absolute; left: 0; right: 0; bottom: 14cqi; display: grid; gap: 2cqi; text-align: center; }
.tc-cover b { font-weight: 900; font-size: 11cqi; letter-spacing: .04em; }
.tc-cover small { font-family: 'Archivo', var(--sans); font-size: 5cqi; color: var(--mute); }

/* ── Magic: shared glow and a pointer-led light, then one form per card ── */
.tc-sheen, .tc-fx { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .45s var(--ease); }
.tc-sheen { background: radial-gradient(circle at var(--mx, 50%) var(--my, 35%), color-mix(in srgb, var(--c) 42%, transparent), transparent 58%); mix-blend-mode: screen; }
.tc-fx i { position: absolute; display: block; }
.tcard:not(.face-up):is(:hover, :has(:focus-visible)) :is(.tc-sheen, .tc-fx) { opacity: 1; }
.tcard:not(.face-up):is(:hover, :has(:focus-visible)) .tc-back {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c) 70%, transparent), 0 0 4cqi color-mix(in srgb, var(--c) 55%, transparent), 0 0 16cqi color-mix(in srgb, var(--c) 34%, transparent), 0 6cqi 14cqi color-mix(in srgb, var(--ink) 30%, transparent);
}
.tcard:not(.face-up):is(:hover, :has(:focus-visible)) .tc-back .tc-frame { border-color: var(--c); box-shadow: 0 0 3cqi color-mix(in srgb, var(--c) 60%, transparent), inset 0 0 3cqi color-mix(in srgb, var(--c) 40%, transparent); }
.tcard:not(.face-up):is(:hover, :has(:focus-visible)) .tc-back .tc-emblem { border-color: color-mix(in srgb, var(--c) 70%, transparent); box-shadow: 0 0 6cqi color-mix(in srgb, var(--c) 45%, transparent); }
.tcard:not(.face-up):is(:hover, :has(:focus-visible)) .tc-back .fov path:not(.fov-arc) { stroke: var(--c); }
/* centred on the emblem */
.tc-fx i { left: 50%; top: 60%; translate: -50% -50%; }

/* 品牌 — runes: two dashed rings turning against each other around the emblem. */
[data-fx="runes"] .tc-fx i:nth-child(-n+2) { width: 68cqi; aspect-ratio: 1; border-radius: 50%; background: repeating-conic-gradient(var(--c) 0 3deg, transparent 3deg 11deg); -webkit-mask: radial-gradient(closest-side, transparent 90%, #000 91% 97%, transparent 98%); mask: radial-gradient(closest-side, transparent 90%, #000 91% 97%, transparent 98%); animation: fx-spin 9s linear infinite; }
[data-fx="runes"] .tc-fx i:nth-child(2) { width: 82cqi; background: repeating-conic-gradient(var(--c) 0 14deg, transparent 14deg 22deg, var(--c) 22deg 24deg, transparent 24deg 40deg); opacity: .6; animation-duration: 14s; animation-direction: reverse; }
[data-fx="runes"] .tc-fx i:nth-child(3) { width: 40cqi; aspect-ratio: 1; border-radius: 50%; background: radial-gradient(closest-side, color-mix(in srgb, var(--c) 55%, transparent), transparent); animation: fx-breathe 2.4s ease-in-out infinite; }

/* 網站 — ripple: rings pushed out from the emblem, and a scan line passing down the card. */
[data-fx="ripple"] .tc-fx i:nth-child(-n+3) { width: 50cqi; aspect-ratio: 1; border-radius: 50%; border: 1px solid var(--c); box-shadow: 0 0 3cqi color-mix(in srgb, var(--c) 60%, transparent); animation: fx-ripple 2.4s cubic-bezier(.2, .6, .3, 1) infinite; }
[data-fx="ripple"] .tc-fx i:nth-child(2) { animation-delay: .8s; }
[data-fx="ripple"] .tc-fx i:nth-child(3) { animation-delay: 1.6s; }
[data-fx="ripple"] .tc-fx i:nth-child(4) { left: 4cqi; right: 4cqi; top: 0; translate: none; height: 18cqi; background: linear-gradient(transparent, color-mix(in srgb, var(--c) 30%, transparent) 85%, var(--c)); animation: fx-scan 2.8s linear infinite; }

/* 平面 — halftone: a band of dots sweeping across, offset like a misregistered print. */
[data-fx="halftone"] .tc-fx i:nth-child(-n+2) { inset: 0; translate: none; background: radial-gradient(var(--c) 32%, transparent 36%) 0 0 / 6cqi 6cqi; -webkit-mask: linear-gradient(115deg, transparent 35%, #000 50%, transparent 65%) 0 0 / 300% 100%; mask: linear-gradient(115deg, transparent 35%, #000 50%, transparent 65%) 0 0 / 300% 100%; animation: fx-sweep 2.6s ease-in-out infinite; }
[data-fx="halftone"] .tc-fx i:nth-child(2) { background: radial-gradient(#5be0ff 32%, transparent 36%) 1.6cqi 1.2cqi / 6cqi 6cqi; mix-blend-mode: screen; opacity: .7; animation-delay: .12s; }

/* 介面 — orbit: two points circling the emblem on tilted paths. */
[data-fx="orbit"] .tc-fx i:nth-child(-n+2) { width: 64cqi; aspect-ratio: 1; border-radius: 50%; border: 1px dashed color-mix(in srgb, var(--c) 55%, transparent); animation: fx-spin 3.2s linear infinite; }
[data-fx="orbit"] .tc-fx i:nth-child(2) { width: 84cqi; border-style: dotted; animation-duration: 5.4s; animation-direction: reverse; }
[data-fx="orbit"] .tc-fx i:nth-child(-n+2)::before { content: ''; position: absolute; left: 50%; top: -1.8cqi; width: 3.6cqi; aspect-ratio: 1; margin-left: -1.8cqi; border-radius: 50%; background: var(--c); box-shadow: 0 0 3cqi var(--c), 0 0 8cqi var(--c); }
[data-fx="orbit"] .tc-fx i:nth-child(3) { width: 30cqi; height: 1px; background: linear-gradient(90deg, transparent, var(--c), transparent); animation: fx-spin 1.6s linear infinite; }

/* 插畫 — sparkle: four-point stars blinking around the card. */
[data-fx="sparkle"] .tc-fx i { width: 7cqi; aspect-ratio: 1; background: var(--c); clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%); filter: drop-shadow(0 0 2cqi var(--c)); animation: fx-twinkle 1.8s ease-in-out infinite; }
[data-fx="sparkle"] .tc-fx i:nth-child(1) { left: 24%; top: 40%; }
[data-fx="sparkle"] .tc-fx i:nth-child(2) { left: 78%; top: 48%; width: 10cqi; animation-delay: .35s; }
[data-fx="sparkle"] .tc-fx i:nth-child(3) { left: 66%; top: 80%; width: 5cqi; animation-delay: .7s; }
[data-fx="sparkle"] .tc-fx i:nth-child(4) { left: 32%; top: 84%; width: 8cqi; animation-delay: 1.05s; }
[data-fx="sparkle"] .tc-fx i:nth-child(5) { left: 50%; top: 60%; width: 13cqi; animation-delay: 1.4s; }

/* 專案進程 — ember: sparks rising from the bar. */
[data-fx="ember"] .tc-fx i { top: auto; bottom: 22%; width: 2.6cqi; aspect-ratio: 1; border-radius: 50%; background: #ffb48a; box-shadow: 0 0 3cqi var(--focus), 0 0 6cqi var(--focus); animation: fx-rise 1.9s ease-out infinite; }
[data-fx="ember"] .tc-fx i:nth-child(1) { left: 22%; }
[data-fx="ember"] .tc-fx i:nth-child(2) { left: 41%; animation-delay: .5s; }
[data-fx="ember"] .tc-fx i:nth-child(3) { left: 58%; animation-delay: 1s; }
[data-fx="ember"] .tc-fx i:nth-child(4) { left: 76%; animation-delay: 1.4s; }
[data-fx="ember"] .tc-fx i:nth-child(5) { left: 33%; animation-delay: .8s; width: 1.8cqi; }

@keyframes fx-spin { to { rotate: 360deg; } }
@keyframes fx-breathe { 50% { scale: 1.3; opacity: .5; } }
@keyframes fx-ripple { from { scale: .5; opacity: 1; } to { scale: 1.9; opacity: 0; } }
@keyframes fx-scan { from { translate: 0 -20cqi; } to { translate: 0 calc(100cqb + 2cqi); } }
@keyframes fx-sweep { from { -webkit-mask-position: 100% 0; mask-position: 100% 0; } to { -webkit-mask-position: 0 0; mask-position: 0 0; } }
@keyframes fx-twinkle { 0%, 100% { scale: 0; rotate: 0deg; } 45% { scale: 1; rotate: 45deg; } 70% { scale: .4; } }
@keyframes fx-rise { from { translate: -50% 0; opacity: 0; } 15% { opacity: 1; } to { translate: -50% -55cqb; opacity: 0; } }

/* ── 專案進程: white with orange, face up, wherever the other cards are. Scrolling down charges it (--p from deck.js). ── */
.tc-proc .tc-face { transform: none; cursor: pointer; background: var(--paper); color: var(--ink); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 10%, transparent), 0 3cqi 8cqi color-mix(in srgb, var(--ink) 16%, transparent); }
.tc-proc .tc-frame { border-color: var(--focus); }
.tc-proc .tc-no { color: var(--focus); }
.tc-proc .tc-name small { color: var(--mute); }
.tc-proc .tc-name::after { content: ''; display: block; width: 9cqi; height: max(2px, 1.4cqi); margin-top: 3cqi; background: var(--focus); }
.dp-steps { position: absolute; left: 7cqi; right: 7cqi; top: 52%; display: flex; gap: 2.4cqi; }
.dp-steps i { flex: 1; height: 3cqi; min-height: 2px; border-radius: 2px; background: var(--focus); opacity: calc(.18 + .82 * clamp(0, var(--p, 0) * 6 - var(--k), 1)); }
.dp-bar { position: absolute; left: 7cqi; right: 7cqi; bottom: 17cqi; height: 4cqi; min-height: 3px; border-radius: 99px; background: color-mix(in srgb, var(--focus) 16%, transparent); overflow: hidden; }
.dp-bar i { display: block; height: 100%; background: repeating-linear-gradient(115deg, var(--focus) 0 4cqi, #ff7a4d 4cqi 8cqi); background-size: 200% 100%; transform-origin: left; transform: scaleX(var(--p, 0)); animation: fx-flow 1.2s linear infinite; }
@keyframes fx-flow { to { background-position: -11.3cqi 0; } }
.dp-read { position: absolute; left: 7cqi; right: 7cqi; bottom: 8cqi; display: flex; justify-content: space-between; gap: 4px; font-size: max(5.6cqi, calc(8px / var(--s, 1))); color: var(--mute); }
.dp-read span:first-child { color: var(--focus); font-weight: 700; }
.tc-proc .tc-sheen { mix-blend-mode: multiply; background: radial-gradient(circle at var(--mx, 50%) var(--my, 35%), color-mix(in srgb, var(--focus) 18%, transparent), transparent 60%); }
.tcard.tc-proc:not(:hover) :is(.tc-sheen, .tc-fx) { opacity: 0; }
.tcard.tc-proc:hover .tc-face { box-shadow: inset 0 0 0 1.5px var(--focus), 0 0 5cqi color-mix(in srgb, var(--focus) 50%, transparent), 0 6cqi 14cqi color-mix(in srgb, var(--ink) 20%, transparent); }
.deck.is-charging .tc-proc .tc-face { box-shadow: inset 0 0 0 1.5px var(--focus), 0 0 4cqi color-mix(in srgb, var(--focus) 55%, transparent), 0 0 18cqi color-mix(in srgb, var(--focus) 30%, transparent); }
.deck.is-charging .tc-proc .tc-fx { opacity: 1; }
@container (max-width: 110px) { .dp-read span:last-child { display: none; } }

/* ── Dossier: a large folder unfolding out of the chosen card. The held hand rests over its bottom-left corner, which
   the layout keeps empty (grid area "hand", --hv tall). ── */
.deck-dossiers { position: absolute; z-index: 40; left: var(--gutter); right: var(--gutter); top: calc(var(--glass) + 30px); bottom: 18px; pointer-events: none; }
.dossier {
  position: absolute; inset: 0; pointer-events: auto; outline: none;
  clip-path: inset(var(--ct, 45%) var(--cl, 45%) var(--ct, 45%) var(--cl, 45%) round var(--cr, 12px)); visibility: hidden;
  transition: clip-path .62s cubic-bezier(.6, 0, .3, 1), visibility 0s .62s;
}
.dossier.is-open { clip-path: inset(-60px -60px -60px -60px round 24px); visibility: visible; transition: clip-path .8s var(--ease), visibility 0s; }
.ds-paper {
  position: absolute; inset: 0; display: grid; gap: clamp(16px, 2.4vh, 28px) clamp(28px, 4vw, 72px);
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); grid-template-rows: auto minmax(0, 1fr) auto;
  grid-template-areas: "head head" "text refs" "hand foot";
  padding: clamp(26px, 3.4vw, 52px) clamp(26px, 3.6vw, 60px) clamp(20px, 2.6vw, 36px);
  background: var(--paper); color: var(--ink); border-radius: 22px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 10%, transparent), 0 30px 70px color-mix(in srgb, var(--ink) 16%, transparent), 0 0 0 1px color-mix(in srgb, var(--c) 30%, transparent);
}
.ds-paper::before { content: ''; position: absolute; inset: 12px; border: var(--hair) solid color-mix(in srgb, var(--c) 50%, var(--ink) 16%); border-radius: 14px; pointer-events: none; }
.ds-paper::after { content: ''; grid-area: hand; min-height: var(--hv, 140px); }
.ds-tab { position: absolute; left: 32px; bottom: 100%; padding: 8px 20px 6px; border-radius: 12px 12px 0 0; background: var(--paper); font-size: 12px; letter-spacing: .06em; color: var(--ink); box-shadow: 0 -1px 0 color-mix(in srgb, var(--ink) 10%, transparent); }
.ds-tab::before { content: ''; display: inline-block; width: 8px; height: 8px; margin-right: 10px; border-radius: 50%; background: var(--c); vertical-align: 1px; }
.dossier .ds-paper > * { opacity: 0; translate: 0 14px; transition: opacity .25s, translate .25s; }
.dossier.is-open .ds-paper > * { opacity: 1; translate: 0 0; transition: opacity .6s var(--ease), translate .8s var(--ease); }
.dossier.is-open .ds-tab { transition-delay: .2s; }
.dossier.is-open .ds-head { transition-delay: .3s; }
.dossier.is-open .ds-text { transition-delay: .4s; }
.dossier.is-open .ds-refs { transition-delay: .45s; }
.dossier.is-open .ds-foot { transition-delay: .55s; }
.ds-head { grid-area: head; position: relative; display: flex; justify-content: space-between; align-items: flex-start; gap: 20px; }
.ds-head h2 { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 18px; font-weight: 900; font-size: clamp(36px, 4.2vw, 72px); line-height: 1.05; letter-spacing: -.01em; }
.ds-head h2 span { font-family: 'Archivo', var(--sans); font-weight: 500; font-size: clamp(15px, 1.2vw, 19px); letter-spacing: 0; color: var(--mute); }
.ds-sub { margin-top: clamp(10px, 1.6vh, 18px); font-weight: 700; font-size: clamp(18px, 1.7vw, 26px); line-height: 1.4; }
.ds-close { flex: none; display: inline-flex; gap: 8px; align-items: center; padding: 9px 18px; border: var(--hair) solid color-mix(in srgb, var(--ink) 30%, transparent); border-radius: 999px; background: none; color: var(--ink); font: 500 14px/1 var(--sans); letter-spacing: .06em; cursor: pointer; transition: background-color .25s, color .25s, border-color .25s; }
.ds-close:hover, .ds-close:focus-visible { background: var(--ink); border-color: var(--ink); color: var(--white); }
.ds-text { grid-area: text; position: relative; display: flex; flex-direction: column; gap: clamp(16px, 2.4vh, 26px); min-height: 0; overflow: auto; scrollbar-width: none; }
.ds-text h3 { font-weight: 700; font-size: 15px; margin-bottom: 10px; }
.ds-desc { color: var(--mute); font-size: clamp(15px, 1.15vw, 17px); line-height: 1.7; }
.ds-needs li { position: relative; padding: 7px 0 7px 22px; font-size: clamp(15px, 1.15vw, 17px); line-height: 1.5; }
.ds-needs li::before { content: ''; position: absolute; left: 2px; top: calc(7px + .75em - 4px); width: 8px; height: 8px; border-radius: 50%; background: var(--c); }
.ds-items { display: flex; flex-wrap: wrap; gap: 8px; }
.ds-items li { padding: 6px 15px; border: var(--hair) solid color-mix(in srgb, var(--ink) 26%, transparent); border-radius: 999px; font-size: 15px; font-weight: 500; }
.ds-refs { grid-area: refs; position: relative; display: flex; min-height: 0; }
.ds-ref-grid { flex: 1; min-height: 0; display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1.6fr 1fr; gap: 12px; }
.ds-ref-grid > :first-child { grid-column: 1 / -1; }
.ds-ref-grid > :only-child { grid-row: 1 / -1; }
.ds-ref-grid:has(> :nth-child(2):last-child) > :nth-child(2) { grid-column: 1 / -1; }
.ds-ref { position: relative; display: block; min-height: 0; border-radius: 12px; overflow: hidden; background: var(--plate); }
.ds-img { position: absolute; inset: 0; display: grid; place-items: center; }
.ds-img img { width: 100%; height: 100%; object-fit: cover; transition: scale .8s var(--ease); }
.ds-img svg { width: min(42%, 170px); height: auto; opacity: .6; color: var(--ink); }
.ds-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 28px 16px 12px; background: linear-gradient(transparent, color-mix(in srgb, var(--ink) 58%, transparent)); color: var(--white); }
.ds-ref.is-empty .ds-cap { background: none; color: var(--mute); }
.ds-cap b { font-size: 16px; font-weight: 700; }
a.ds-ref:hover .ds-img img { scale: 1.05; }
.ds-foot { grid-area: foot; position: relative; display: flex; align-items: flex-end; justify-content: flex-end; }
@media (max-height: 820px) and (min-width: 900px) { .ds-desc { display: none; } .ds-head h2 { font-size: clamp(34px, 3.8vw, 60px); } .ds-needs li { padding-block: 5px; } }

@media (max-width: 899px) {
  .deck-intro { grid-template-columns: 1fr; gap: 12px; }
  .deck-intro h1 { font-size: clamp(28px, 7.4vw, 44px); }
  .deck-lead { font-size: 14px; }
  .deck-dossiers { top: calc(var(--glass) + 28px); bottom: calc(var(--hv, 80px) + 8px); }
  .ds-paper { display: flex; flex-direction: column; overflow: auto; scrollbar-width: none; padding: 26px 22px 22px; }
  .ds-paper::after { display: none; }
  .ds-text { overflow: visible; flex: none; }
  .ds-refs { flex: none; }
  .ds-ref-grid { grid-template-rows: none; grid-auto-rows: 160px; }
  .ds-foot { justify-content: stretch; }
  .ds-foot .btn { flex: 1; justify-content: center; }
  .ds-head h2 { font-size: clamp(32px, 9vw, 46px); }
}
@media (prefers-reduced-motion: reduce) {
  .tcard, .tc-inner, .tc-float, .dossier, .dossier .ds-paper > *, .deck-intro { transition: none !important; }
  .tc-float, .tc-fx i, .dp-bar i { animation: none !important; }
}

/* ───── About ───── */
.principles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-top: var(--hair) solid var(--line); margin-top: 16px; }
.principles > div { padding: 28px 28px 0 0; }
.principles > div + div { padding-left: 28px; border-left: var(--hair) solid var(--faint); }
.principles h3 { font-weight: 900; font-size: 22px; margin-bottom: 10px; }
.principles p { color: var(--mute); font-size: 15px; }

/* ───── Contact form ───── */
/* The form is the page: title top-left, notes bottom-left, the glass card fills the right at viewport height. */
.contact-page { padding: calc(var(--glass) + 16px) 0 clamp(72px, 9vw, 140px); overflow-x: clip; }
.contact { display: grid; grid-template-columns: minmax(280px, .78fr) minmax(0, 1.5fr); grid-template-areas: 'intro stage' 'notes stage' 'x status';
  grid-template-rows: auto 1fr; gap: 0 clamp(40px, 6vw, 120px); }
.contact-intro { grid-area: intro; padding-top: clamp(24px, 4vh, 56px); }
.contact-intro h1 { font-weight: 900; font-size: clamp(40px, 4.4vw, 84px); line-height: 1.1; letter-spacing: -.02em; }
.contact-intro .lead { margin-top: clamp(20px, 2.4vw, 32px); color: var(--mute); max-width: 26em; }
/* The notes are one line that rolls through three short readings, like the wordmark's destination sign; hover holds it. */
.contact-aside { grid-area: notes; align-self: end; padding-top: 48px; }
.contact-roll { position: relative; display: block; height: 3.4em; overflow: hidden; margin: 0; padding-left: 18px; border-top: var(--hair) solid var(--line); font-size: 14.5px; line-height: 3.4em; }
.contact-roll::before { content: ''; position: absolute; left: 0; top: 50%; width: 6px; height: 6px; translate: 0 -50%; background: var(--focus); }
.contact-roll-track { display: flex; flex-direction: column; animation: note-roll 12s linear infinite; }
.contact-roll-track > span { display: flex; align-items: center; gap: 14px; height: 3.4em; white-space: nowrap; }
.contact-roll-track b { min-width: 4.4em; font-weight: 400; color: var(--mute); }
.contact-roll:hover .contact-roll-track { animation-play-state: paused; }
@keyframes note-roll {
  0%, 28% { transform: translateY(0); animation-timing-function: cubic-bezier(.65, 0, .25, 1); }
  33%, 61% { transform: translateY(-25%); animation-timing-function: cubic-bezier(.65, 0, .25, 1); }
  66%, 94% { transform: translateY(-50%); animation-timing-function: cubic-bezier(.65, 0, .25, 1); }
  100% { transform: translateY(-75%); }
}
@media (prefers-reduced-motion: reduce) {
  .contact-roll { height: auto; line-height: 2.2; padding-block: 10px; }
  .contact-roll-track { animation: none; }
  .contact-roll-track > span { height: auto; white-space: normal; }
  .contact-roll-track > span:last-child { display: none; }
}

/* Glass card over a lit backdrop: a resolution target and a focus glow that drifts toward the pointer read through the frost. */
.q-stage { grid-area: stage; position: relative; isolation: isolate; min-width: 0; }
/* Everything stays under the glass: the clip sits 36px inside the card, more than the tilt + float ever moves its edge (~20px) */
.q-behind { position: absolute; inset: 36px; z-index: -1; pointer-events: none; overflow: hidden; border-radius: 12px; }
.q-behind .vf-target { position: absolute; right: -16%; top: 18%; width: 62%; height: auto; color: var(--ink); opacity: .5; rotate: -9deg; }
.q-behind .vf-target { transition: rotate 1.8s var(--ease), translate 1.8s var(--ease); rotate: calc(-9deg + var(--sx, 0) * 50deg); translate: calc(var(--sx, 0) * -90px) 0; }
.q-orb { position: absolute; left: 88%; top: 84%; width: clamp(220px, 24vw, 400px); aspect-ratio: 1; border-radius: 50%; opacity: .62;
  translate: calc(-50% + var(--dx, 0) * 70px - var(--sx, 0) * 140px) calc(-50% + var(--dy, 0) * 50px);
  background: radial-gradient(circle, var(--focus) 0 24%, color-mix(in srgb, var(--focus) 0%, transparent) 66%);
  transition: translate 1.8s var(--ease); }
.q-orb.is-b { left: 4%; top: 100%; width: clamp(120px, 11vw, 180px); opacity: .5; background: var(--ink); translate: -50% -50%; transition: none; }
.form { display: grid; gap: 34px; border-top: var(--hair) solid var(--line); padding-top: 34px; }
.row-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 34px 40px; }
.field { display: grid; gap: 6px; }
.field label, .field legend { display: flex; align-items: baseline; gap: 12px; padding: 0; font-weight: 700; font-size: 16px; letter-spacing: .06em; }
.field label .mono, .field legend .mono { color: var(--mute); font-weight: 400; }
.field label small, .field legend small { margin-left: auto; font-weight: 400; font-size: 12px; color: var(--mute); letter-spacing: .08em; }
.field input:not([type="checkbox"]), .field textarea {
  width: 100%; min-height: 50px; padding: 12px 0;
  background: transparent; border: 0; border-bottom: var(--hair) solid var(--line); border-radius: 0;
  font-size: 17px; caret-color: var(--focus); transition: border-color .2s, box-shadow .2s;
}
.field textarea { min-height: 160px; resize: vertical; line-height: 1.8; }
.field input::placeholder, .field textarea::placeholder { color: #626467; }
.field input:not([type="checkbox"]):focus, .field textarea:focus { outline: none; border-bottom-color: var(--focus); box-shadow: 0 1px 0 var(--focus); }
.field input:user-invalid, .field textarea:user-invalid { border-bottom-color: #c42b12; box-shadow: 0 1px 0 #c42b12; }
.field .is-missing:not(:focus) { border-bottom-color: #c42b12; box-shadow: 0 1px 0 #c42b12; }
.field .is-missing::placeholder { color: #c42b12; }
fieldset.field { border: 0; margin: 0; padding: 0; min-width: 0; }
.checks { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
.check { position: relative; display: inline-flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 16px 0 12px; border: var(--hair) solid var(--line); cursor: pointer; font-size: 15px; transition: background-color .2s, color .2s; }
.field .check { padding: 0 16px 0 12px; gap: 10px; font-weight: 500; font-size: 15px; letter-spacing: .04em; }
.check input { appearance: none; width: 14px; height: 14px; margin: 0; border: var(--hair) solid currentColor; cursor: pointer; display: grid; place-content: center; }
.check input::after { content: ''; width: 8px; height: 8px; background: var(--focus); transform: scale(0); transition: transform .2s var(--ease); }
.check input:checked::after { transform: scale(1); }
.check:has(input:checked) { background: var(--ink); color: var(--white); }
.check:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 3px; }
.check input:focus-visible { outline: none; }
.form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 16px 36px; }
.form-note { font-size: 14px; color: var(--mute); }
.form-status:not(:empty) { padding: 12px 16px; border: var(--hair) solid var(--line); font-size: 15px; }
/* Inquiry card: a page of one or two questions at a time under a progress rail; tiles fill from the press point */
.q-card { --edge: color-mix(in srgb, var(--fg) 16%, transparent);
  position: relative; display: grid; grid-template-rows: auto 1fr; min-height: calc(100svh - var(--glass) - 40px); border-radius: 24px; overflow: clip;
  background: linear-gradient(155deg, color-mix(in srgb, var(--bg) 66%, transparent), color-mix(in srgb, var(--bg) 46%, transparent));
  -webkit-backdrop-filter: blur(26px) saturate(1.45); backdrop-filter: blur(26px) saturate(1.45);
  box-shadow: inset 1.5px 1.5px 0 color-mix(in srgb, white 85%, transparent), inset -1px -1px 0 color-mix(in srgb, white 35%, transparent),
    inset 0 0 32px color-mix(in srgb, white 22%, transparent), 0 40px 80px -32px color-mix(in srgb, var(--ink) 30%, transparent), 0 2px 8px color-mix(in srgb, var(--ink) 6%, transparent); }
/* Step transition props */
.q-glare { position: absolute; top: -10%; bottom: -10%; left: 30%; width: 40%; z-index: 4; pointer-events: none; opacity: 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, white 55%, transparent) 50%, transparent); }
.q-lock { position: absolute; z-index: 4; pointer-events: none; opacity: 0; --b-inset: -10px -14px; --b-len: 12px; }
/* Review page: orange glass over the card's head, down to the rule under the heading; it wipes down on arrival */
.q-tint { position: absolute; left: 0; right: 0; top: 0; height: var(--tint, 0px); z-index: -1; pointer-events: none;
  background: linear-gradient(160deg, color-mix(in srgb, var(--focus) 84%, transparent), color-mix(in srgb, var(--focus) 60%, transparent));
  box-shadow: inset 1.5px 1.5px 0 color-mix(in srgb, white 55%, transparent), inset 0 -1px 0 color-mix(in srgb, white 25%, transparent);
  clip-path: inset(0 0 100% 0); transition: clip-path .9s var(--ease); }
.q-card.is-final .q-tint { clip-path: inset(0); }
.q-card.is-final .q-head { color: color-mix(in srgb, var(--ink) 70%, var(--focus)); }
.q-card.is-final .q-now .mono { color: color-mix(in srgb, var(--ink) 55%, var(--focus)); }
.q-card.is-final .q-rail .q-bar { background: color-mix(in srgb, var(--ink) 16%, transparent); }
.q-card.is-final .q-rail [data-state="current"] .q-bar i { background: var(--ink); }
/* Hover: the card floats (deeper shadow) and a soft specular light follows the pointer across the glass, under the content */
.q-card { transition: box-shadow .6s var(--ease); will-change: transform; }
.q-card::before { content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: 0; transition: opacity .5s var(--ease);
  background: radial-gradient(circle at var(--mx, 50%) var(--my, 30%), color-mix(in srgb, white 70%, transparent), transparent 42%); }
.q-card.is-tilt::before { opacity: .55; }
.q-card.is-tilt { box-shadow: inset 1.5px 1.5px 0 color-mix(in srgb, white 85%, transparent), inset -1px -1px 0 color-mix(in srgb, white 35%, transparent),
    inset 0 0 32px color-mix(in srgb, white 22%, transparent), 0 60px 110px -36px color-mix(in srgb, var(--ink) 38%, transparent), 0 4px 14px color-mix(in srgb, var(--ink) 8%, transparent); }
@media (prefers-reduced-transparency: reduce) { .q-card { background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; } }
@supports not (backdrop-filter: blur(1px)) { .q-card { background: color-mix(in srgb, var(--bg) 92%, transparent); } }
.q-anchor { position: absolute; top: calc(-1 * var(--glass) - 16px); }
/* Progress in one quiet line: "04 / 06  想法" on the left, six short segments on the right (each a button to a reached step) */
.q-top { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 22px clamp(20px, 3vw, 40px) 0; }
/* Step name leads; the count is a quiet Archivo figure beside it */
.q-now { display: flex; align-items: baseline; gap: 10px; margin: 0; }
.q-now [data-now-t] { order: -1; font-size: 15px; font-weight: 900; letter-spacing: .08em; }
.q-now .mono { font-family: 'Archivo', var(--sans); font-size: 13px; font-weight: 500; letter-spacing: .02em; font-variant-numeric: tabular-nums; color: color-mix(in srgb, var(--fg) 38%, transparent); }
.q-now .mono b { font-weight: 700; color: var(--fg); }
/* A loading bar: one continuous track that fills step by step, the current stretch in focus orange; hairline notches mark 01–06 */
/* Short, chunky loading bar: six 20×6 segments with 2px gaps, rounded ends; each segment is a button back to a reached step */
.q-rail { display: flex; gap: 2px; }
.q-rail li { position: relative; }
.q-rail button { display: grid; align-items: center; width: 20px; height: 24px; padding: 0; border: 0; background: none; cursor: pointer; }
.q-rail .q-bar { height: 6px; border-radius: 1.5px; background: color-mix(in srgb, var(--fg) 12%, transparent); }
.q-rail li:first-child .q-bar { border-radius: 3px 1.5px 1.5px 3px; }
.q-rail li:last-child .q-bar { border-radius: 1.5px 3px 3px 1.5px; }
.q-rail .q-bar i { height: 6px; margin: 0; background: var(--fg); }
.q-rail [data-state="current"] .q-bar i { height: 6px; background: var(--focus); }
.q-rail [data-state="done"] button:hover .q-bar i { background: var(--fg); }
.q-rail button:disabled { cursor: default; }
.q-rail [data-state="current"] button { color: var(--fg); }
.q-rail [data-state="current"] .mono { color: var(--mute); }
.q-rail [data-state="done"] button { color: var(--mute); }
.q-rail [data-state="done"] button:hover { color: var(--fg); }
/* Quiet rail: hairline track, passed steps in soft ink, only the current step in a 2px focus line */
.q-bar { display: block; height: 2px; overflow: hidden; background: linear-gradient(var(--edge, var(--faint)), var(--edge, var(--faint))) center / 100% 1px no-repeat; }
.q-bar i { display: block; height: 1px; margin-top: .5px; background: color-mix(in srgb, var(--fg) 45%, transparent); transform: scaleX(0); transform-origin: left center; transition: transform .7s var(--ease), background-color .25s; }
.q-rail [data-state="done"] button:hover .q-bar i { background: var(--fg); }
.q-rail [data-state="current"] .q-bar i { height: 2px; margin-top: 0; background: var(--focus); }
.q-rail [data-state="current"] button { font-weight: 700; }
.q-form { display: grid; grid-template-rows: 1fr auto; min-width: 0; }
.q-pages { overflow: hidden; min-width: 0; }
.q-step { display: grid; align-content: start; gap: clamp(40px, 4.5vw, 56px); padding: clamp(36px, 4.5vw, 60px) clamp(20px, 3vw, 40px) clamp(40px, 5vw, 64px); min-width: 0; }
.q-step[hidden] { display: none; }
.q { display: grid; gap: 24px; min-width: 0; margin: 0; padding: 0; border: 0; }
.q-head { float: left; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 .35em; width: 100%; padding: 0;
  color: var(--mute); font-size: clamp(26px, 2.4vw, 36px); font-weight: 700; line-height: 1.35; letter-spacing: -.01em; text-wrap: balance; }
.is-pair .q-head { font-size: clamp(20px, 1.7vw, 25px); }
.q-head:focus { outline: none; }
.q-head b { color: var(--fg); font-weight: 900; }
.q-head small { margin-left: auto; font-size: 12px; font-weight: 400; letter-spacing: .08em; }
.q > :not(legend) { clear: both; }

/* Tiles: name over a one-line hint; the number badge is the keyboard shortcut */
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, max(230px, var(--tw, 0px))), 1fr)); gap: 8px; }
.is-pair .tiles { grid-template-columns: repeat(auto-fill, minmax(min(100%, max(170px, var(--tw, 0px))), 1fr)); }
.tile { position: relative; isolation: isolate; overflow: hidden; display: flex; align-items: center; gap: 14px; min-height: 76px; padding: 14px 16px;
  border: var(--hair) solid var(--edge, var(--line)); border-radius: 14px; background: color-mix(in srgb, var(--bg) 52%, transparent); cursor: pointer; line-height: 1.45;
  transition: color .3s, transform .35s var(--ease), box-shadow .35s var(--ease); }
.tile.is-short { min-height: 58px; }
.tile input { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.tile::before { content: ''; position: absolute; inset: 0; z-index: -1; background: var(--ink); clip-path: circle(0 at var(--px, 50%) var(--py, 50%)); transition: clip-path .55s var(--ease); }
.tile-text { display: grid; gap: 3px; flex: 1; min-width: 0; }
.tile-text b { font-size: 16px; font-weight: 700; letter-spacing: .04em; }
.tile-text small { color: var(--mute); font-size: 13px; letter-spacing: .02em; transition: color .3s; }
.tile-key { display: grid; place-items: center; width: 22px; height: 22px; flex: none; border: var(--hair) solid var(--faint); color: var(--gray); font: 11px var(--mono); opacity: 0; transition: opacity .25s, border-color .25s, color .25s; }
.tile:hover { transform: translateY(-2px); border-color: color-mix(in srgb, var(--fg) 40%, transparent); box-shadow: 0 10px 22px -12px color-mix(in srgb, var(--ink) 30%, transparent); }
.tile:active { transform: scale(.98); box-shadow: none; transition-duration: .1s; }
.tile:has(input:checked) { color: var(--white); }
.tile:has(input:checked) .tile-text small { color: #a3a5a8; }
.tile:has(input:checked) .tile-key { border-color: #3a3c3f; color: #a3a5a8; }
.tile:has(input:checked)::before { clip-path: circle(150% at var(--px, 50%) var(--py, 50%)); }
.tile:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) { .q-card:hover .tile-key, .q-card:focus-within .tile-key { opacity: 1; } }
.tile-tick { width: 22px; height: 22px; flex: none; }
.tile-tick circle { fill: transparent; stroke: var(--gray); stroke-width: 1.2; transition: fill .3s var(--ease), stroke .3s; }
.tile-tick path { fill: none; stroke: var(--ink); stroke-width: 1.8; stroke-linecap: square; stroke-dasharray: 16; stroke-dashoffset: 16; transition: stroke-dashoffset .35s var(--ease) .08s; }
.tile:has(input:checked) .tile-tick { animation: tick-pop .45s var(--ease); }
.tile:has(input:checked) .tile-tick circle { fill: var(--focus); stroke: var(--focus); }
.tile:has(input:checked) .tile-tick path { stroke-dashoffset: 0; }
@keyframes tick-pop { 40% { transform: scale(1.2); } }

/* Description: grows with the text; prompts start a line for the visitor */
.q .field textarea { min-height: 140px; resize: none; overflow: hidden; transition: height .25s var(--ease); }
.q-prompts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.q-prompts > .mono { margin-right: 4px; color: var(--mute); }
.q-prompt { min-height: 36px; padding: 0 14px; border: var(--hair) solid var(--edge, var(--faint)); border-radius: 999px; background: color-mix(in srgb, var(--bg) 45%, transparent); font-size: 14px; letter-spacing: .04em; cursor: pointer; transition: border-color .25s, background-color .25s, color .25s, transform .35s var(--ease); }
.q-prompt::before { content: '+ '; color: var(--focus); }
.q-prompt:hover { border-color: var(--line); transform: translateY(-1px); }
.q-prompt.is-used { color: var(--mute); border-style: dashed; }
.q-prompt.is-used::before { content: '✓ '; }
.q-chars { margin-left: auto; color: var(--mute); }

/* Review */
.q-review { display: grid; border-top: var(--hair) solid var(--line); }
.q-review div { display: grid; grid-template-columns: 5em minmax(0, 1fr) auto; align-items: baseline; gap: 16px; padding: 16px 0; border-bottom: var(--hair) solid var(--faint); }
.q-review dt { color: var(--mute); font-size: 14px; }
.q-review dd { margin: 0; font-size: 16px; white-space: pre-line; overflow-wrap: anywhere; }
.q-review .is-empty dd { color: var(--gray); }
.q-edit { padding: 0; border: 0; background: none; color: var(--mute); font-size: 14px; text-decoration: underline; text-underline-offset: 4px; cursor: pointer; }
.q-edit:hover { color: var(--focus); }

/* Branching pages: choices and fields that only apply on some paths, a short note under the question, and the ways out */
.tile[hidden], .q .field[hidden] { display: none; }
/* Chinese breaks only where phrase() put a <wbr>; a word longer than the line may still break anywhere */
.contact .lead, .q-head span, .tile-text b, .tile-text small, .q-tip, .q-way span, .q-fields label span, .q-notice { word-break: keep-all; overflow-wrap: anywhere; }
.tile-text b, .tile-text small, .q-tip, .q-notice, .contact .lead { text-wrap: pretty; }
/* The notice that the path got longer: an orange speech bubble that pops out of the rail and hangs over the glass edge.
   It is fixed on <body> above the masthead (studio.js pins it to the rail), out of every layout, and bobs while it talks. */
.q-notice { --tail: 40px; position: fixed; z-index: 45; top: 0; left: 0; display: flex; align-items: center;
  max-width: min(340px, calc(100vw - 20px)); min-height: 46px; margin: 0; padding: 12px 18px;
  border-radius: 20px 20px 20px 20px; background: var(--focus); color: #fff; font-size: 14px; font-weight: 500; line-height: 1.7; letter-spacing: .03em;
  box-shadow: 0 18px 36px -16px color-mix(in srgb, var(--focus) 85%, black), inset 0 1px 0 color-mix(in srgb, white 35%, transparent);
  transform-origin: calc(100% - var(--tail)) -10px; cursor: pointer; animation: q-bob 3.2s ease-in-out .9s infinite; }
.q-notice[hidden] { display: none; }
body.menu-open .q-notice { visibility: hidden; }
.q-notice::before { content: ''; position: absolute; top: -9px; right: calc(var(--tail) - 8px); width: 18px; height: 11px; background: var(--focus); clip-path: polygon(50% 0, 100% 100%, 0 100%); border-radius: 2px; }
/* the little pop where it leaves the rail */
.q-notice::after { content: ''; position: absolute; top: -16px; right: calc(var(--tail) - 7px); width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--focus); opacity: 0; pointer-events: none; }
.q-notice.is-pop::after { animation: q-pop .6s cubic-bezier(.16,1,.3,1); }
.q-notice-typing { display: none; gap: 5px; align-items: center; height: 1.7em; padding-inline: 2px; }
.q-notice.is-typing .q-notice-typing { display: inline-flex; }
.q-notice.is-typing [data-notice] { display: none; }
.q-notice-typing i { width: 7px; height: 7px; border-radius: 50%; background: #fff; animation: q-typing 1s ease-in-out infinite; }
.q-notice-typing i:nth-child(2) { animation-delay: .15s; }
.q-notice-typing i:nth-child(3) { animation-delay: .3s; }
.q-notice [data-notice] { animation: q-say .45s cubic-bezier(.16,1,.3,1); }
@keyframes q-typing { 0%, 60%, 100% { transform: translateY(0); opacity: .55; } 30% { transform: translateY(-5px); opacity: 1; } }
@keyframes q-say { from { opacity: 0; transform: translateY(5px); } }
@keyframes q-bob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -4px; } }
@keyframes q-pop { 0% { opacity: .9; transform: scale(.3); } 100% { opacity: 0; transform: scale(2.4); } }
/* Rising out of the rail into the space above the card: the tail and the pop sit at the bottom */
.q-notice.is-up { max-width: min(440px, calc(100vw - 20px)); transform-origin: calc(100% - var(--tail)) calc(100% + 10px); }
.q-notice.is-up::before { top: auto; bottom: -9px; clip-path: polygon(0 0, 100% 0, 50% 100%); }
.q-notice.is-up::after { top: auto; bottom: -16px; }
.q-notice-ok { display: none; }
@media (prefers-reduced-motion: reduce) { .q-notice, .q-notice-typing i, .q-notice [data-notice], .q-notice.is-pop::after { animation: none; } }
@media (max-width: 600px) {
  .q-notice { flex-wrap: wrap; justify-content: flex-end; gap: 8px; max-width: calc(100vw - 20px); padding: 12px 14px 12px 16px; font-size: 13px; }
  .q-notice [data-notice] { flex: 1 1 100%; }
  /* Over the question on a phone, so it can be put away at once */
  .q-notice-ok { display: inline-flex; align-items: center; min-height: 36px; padding: 0 18px; border: 0; border-radius: 999px; background: #fff; color: var(--focus);
    font-size: 13px; font-weight: 700; letter-spacing: .08em; cursor: pointer; }
  .q-notice-ok:active { transform: scale(.96); }
  .q-notice.is-typing .q-notice-ok { display: none; }
}
.q-tip { margin: -8px 0 0; color: var(--mute); font-size: 14px; line-height: 1.7; }
.q-fields { display: grid; gap: 22px; }
.q-fields .field textarea, .q-other + .q-fields .field textarea { min-height: 96px; }
.q-fields .field:has(#f-idea) textarea { min-height: 140px; }
.q-fields input[type="number"] { max-width: 12em; }
.q-ways { display: flex; flex-wrap: wrap; gap: 8px 24px; margin-top: -12px; }
.q-way { display: inline-flex; align-items: center; gap: 8px; padding: 0; border: 0; background: none; color: var(--mute); font-size: 14px; letter-spacing: .04em; cursor: pointer; transition: color .25s; }
.q-way svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.6; transition: transform .45s var(--ease); }
.q-way:hover { color: var(--fg); }
.q-way:hover svg { transform: translateX(3px); }
.q-review dt small { display: block; margin-bottom: 2px; font-size: 11px; letter-spacing: .08em; color: var(--gray); }
.q-review div { grid-template-columns: 6.5em minmax(0, 1fr) auto; }
/* The rail grows and shrinks with the path, so its segments share the width instead of each taking 20px */
.q-top .q-rail { flex: 0 1 auto; min-width: 0; }
.q-rail li { flex: 1 1 20px; min-width: 5px; max-width: 20px; }
.q-rail button { width: 100%; }

/* Action bar */
.q-actions { position: sticky; bottom: 0; z-index: 2; display: flex; align-items: center; gap: 16px 24px; padding: 16px clamp(20px, 3vw, 40px);
  border-top: var(--hair) solid var(--edge, var(--line)); background: color-mix(in srgb, var(--bg) 40%, transparent); }
.has-smoother .q-actions { position: static; }
html:not(.has-smoother) .q-actions { background: color-mix(in srgb, var(--bg) 72%, transparent); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); }
.q-back { display: grid; place-items: center; width: 52px; height: 52px; flex: none; padding: 0; border: var(--hair) solid var(--edge, var(--line)); border-radius: 14px; background: color-mix(in srgb, var(--bg) 50%, transparent); cursor: pointer; transition: background-color .25s, color .25s, opacity .25s; }
.q-back:hover:not(:disabled) { background: var(--fg); color: var(--bg); }
.q-back:hover:not(:disabled) svg { transform: translateX(-3px); }
.q-back:disabled { opacity: .25; cursor: default; }
.q-back svg, .q-next svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; transition: transform .45s var(--ease); }
.q-next:hover svg { transform: translateX(3px); }
.q-next.down:hover svg { transform: translateY(3px); }
.q-tally { flex: 1; min-width: 0; overflow: hidden; color: var(--mute); font-size: 14px; white-space: nowrap; text-overflow: ellipsis; }
.q-actions .link[hidden] { display: none; }
/* 下一步 fills with the accent once the page is answered; a hairline runs along it while an answer moves on by itself */
.q-next { position: relative; overflow: hidden; min-height: 52px; border-radius: 14px; background: linear-gradient(var(--focus), var(--focus)) left / 0 100% no-repeat; box-shadow: inset 0 0 0 var(--hair) var(--line);
  transition: background-size .55s var(--ease), box-shadow .3s, color .25s; }
.q-next.is-ready { background-size: 100% 100%; box-shadow: inset 0 0 0 var(--hair) var(--focus); animation: q-nudge .7s var(--ease); }
.q-next:hover { background: var(--fg); color: var(--bg); box-shadow: none; }
@keyframes q-nudge { 35% { transform: translateX(6px); } }
.contact > .form-status { grid-area: status; margin-top: 16px; border-radius: 14px; }
@media (max-width: 1100px) {
  .contact { grid-template-columns: minmax(0, 1fr); grid-template-areas: 'intro' 'notes' 'stage' 'status'; grid-template-rows: none; }
  .contact-aside { align-self: start; padding-block: 32px 36px; max-width: 40em; }
  .contact-intro h1 { font-size: clamp(40px, 8vw, 72px); }
  .q-card { min-height: min(760px, calc(100svh - var(--glass) - 24px)); }
}
@media (max-width: 600px) {
  .q-card { border-radius: 20px; min-height: 0; }
  .q-behind { inset: 20px; }
  .q-behind .vf-target { width: 96%; right: -24%; top: 4%; }
  .q-top { padding: 12px 16px 0; }
  .q-rail button { font-size: 11px; letter-spacing: .02em; }
  .q-rail button .mono { display: none; }
  .q-step { padding: 28px 16px 40px; }
  .tiles, .is-pair .tiles { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .is-pair .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tile { gap: 12px; min-height: 64px; padding: 10px 14px; }
  .is-pair .tile { min-height: 56px; }
  .tile-text b { font-size: 15px; }
  .q-actions { flex-wrap: wrap; gap: 10px 12px; padding: 10px 16px 12px; }
  .q-tally { order: -1; width: 100%; flex: none; font-size: 13px; }
  .q-back { width: 48px; height: 48px; }
  .q-next { flex: 1; min-height: 48px; }
  .q-review div { grid-template-columns: 4em minmax(0, 1fr) auto; gap: 10px; }
}
@media (prefers-reduced-motion: reduce) {
  .tile, .tile::before, .tile-tick *, .q-bar i, .q-next { transition-duration: .01s; }
  .tile:hover { transform: none; }
  .tile:has(input:checked) .tile-tick, .q-next.is-ready { animation: none; }
}
.form-status:not(:empty)::before { content: ''; display: inline-block; width: 7px; height: 7px; margin-right: 10px; background: var(--focus); vertical-align: .12em; }

/* ───── Missing page ───── */
.missing { min-height: 86svh; display: grid; align-content: center; gap: 28px; padding: calc(var(--glass) + 48px) var(--gutter) 80px; }
.missing h1 { justify-self: start; font-weight: 900; font-size: clamp(44px, 7vw, 120px); line-height: 1.15; letter-spacing: -.015em; filter: blur(3px); transition: filter .8s var(--ease); --b-inset: -18px -24px; --b-color: var(--gray); }
.missing h1:hover { filter: none; }

/* ───── Footer spec sheet ───── */
/* Mark on top. Left: the invitation (headline → subhead → button). Right, behind a hairline: address, then contact rows.
   Columns sit on the 6-column grid lines: 4 + 2 on wide screens, 3 + 3 below 1200px, stacked below 860px.
   Spacing follows the Figma pass of 2026-10-14 (frame 「Footer — Desktop 1440 … TzenEdit」). */
.spec-footer { padding-block: clamp(40px, 4.1vw, 72px) 32px; }
.spec-footer-mark { display: inline-block; margin-bottom: clamp(48px, 5.35vw, 88px); }
.spec-footer-mark img { display: block; width: clamp(80px, 7.4vw, 120px); height: auto; }
.spec-footer-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); }
.spec-footer-invite { grid-column: 1 / 5; padding-right: clamp(32px, 4vw, 72px); }
.spec-footer-info { grid-column: 5 / 7; align-self: end; display: grid; gap: clamp(40px, 4vw, 56px); margin-left: clamp(24px, 2.65vw, 38px); padding-left: clamp(24px, 2.4vw, 40px); border-left: var(--hair) solid var(--line); }
.spec-footer-line { font-weight: 900; font-size: clamp(48px, 6.4vw, 112px); line-height: 1.08; letter-spacing: -.02em; }
.spec-footer-line > .bracket { display: inline-block; vertical-align: top; margin-inline: .12em .04em; --b-inset: -.04em -.1em; --b-len: 14px; }
/* The word inside the bracket rolls like the wordmark LED: hold, then roll up one word. Four words, the first repeated at the end so the loop is seamless. */
.word-roll { display: block; height: 1.08em; line-height: 1.08; clip-path: inset(0 -.2em); } /* matches the line's 1.08 so the word sits on the same baseline */
.word-track { display: flex; flex-direction: column; animation: word-roll 12s linear infinite; }
.word-track > span { display: block; height: 1.08em; white-space: nowrap; }
@keyframes word-roll {
  0%, 18% { transform: translateY(0); animation-timing-function: cubic-bezier(.65, 0, .25, 1); }
  25%, 43% { transform: translateY(-20%); animation-timing-function: cubic-bezier(.65, 0, .25, 1); }
  50%, 68% { transform: translateY(-40%); animation-timing-function: cubic-bezier(.65, 0, .25, 1); }
  75%, 93% { transform: translateY(-60%); animation-timing-function: cubic-bezier(.65, 0, .25, 1); }
  100% { transform: translateY(-80%); }
}
@media (prefers-reduced-motion: reduce) { .word-track { animation: none; } }
.spec-footer-sub { margin-top: clamp(36px, 3.6vw, 56px); font-weight: 700; font-size: clamp(20px, 1.7vw, 26px); line-height: 1.4; }
.spec-footer-invite .btn { margin-top: clamp(28px, 2.8vw, 40px); gap: 55px; }
.is-contact .spec-footer-invite .btn { display: none; } /* the contact page is the form itself */
.spec-footer-label { font-family: 'Archivo', var(--sans); font-size: 12px; line-height: 1.8; color: var(--mute); letter-spacing: .14em; font-weight: 400; margin-bottom: 16px; }
.spec-footer-address { font-family: 'Archivo', var(--sans); font-style: normal; font-size: clamp(16px, 1.2vw, 18px); line-height: 1.75; }
/* The footer's street (hairline.js): a small city block; the building under the pointer lifts its roof. It stands on the
   column's right. The block fills the middle 55% of its 5:4 stage, so on wide layouts the stage is pushed right by its
   empty margin to set the block's edge on the column's edge (the page gutter takes the empty part). */
.spec-footer-info { grid-template-columns: minmax(0, 1fr); } /* one fixed track, so the street below can never widen the column */
.spec-footer-tower { justify-self: end; width: clamp(280px, 26vw, 480px); max-width: 100%; aspect-ratio: 5 / 4; translate: 18% 0; cursor: default; }
.spec-footer-tower .hl-slot {
  display: block; width: 100%; height: 100%;
  --hairline-plate: var(--bg); --hairline-hi: var(--focus);
  --hairline-edge: color-mix(in srgb, var(--fg) 52%, var(--bg)); --hairline-mid: color-mix(in srgb, var(--fg) 30%, var(--bg)); --hairline-lo: color-mix(in srgb, var(--fg) 14%, var(--bg));
}
.spec-footer-bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 16px 32px; margin-top: 30px; padding-top: 24px; border-top: var(--hair) solid var(--faint); font-family: 'Archivo', var(--sans); font-size: 13px; color: var(--mute); }
.spec-footer-legal { display: flex; flex-wrap: wrap; gap: 4px 32px; }
@media (max-width: 1199px) {
  .spec-footer-invite { grid-column: 1 / 4; }
  .spec-footer-info { grid-column: 4 / 7; }
}
@media (max-width: 860px) {
  .spec-footer-grid { grid-template-columns: minmax(0, 1fr); }
  .spec-footer-invite, .spec-footer-info { grid-column: 1 / -1; padding-inline: 0; }
  .spec-footer-info { margin: 64px 0 0; padding-top: 40px; border-left: 0; border-top: var(--hair) solid var(--line); }
  .spec-footer-tower { width: min(320px, 86vw); translate: none; }
}
.spec-footer-bottom a { color: var(--fg); }
.spec-footer-bottom a:hover { text-decoration: underline; text-underline-offset: .3em; }
body.has-scale .spec-footer { padding-bottom: 72px; }

/* ───── Pointer focus bracket ───── */
.cursor { position: fixed; inset: 0; z-index: 70; pointer-events: none; opacity: 0; transition: opacity .3s; }
.cursor.on { opacity: 1; }
.cursor i { position: absolute; left: 0; top: 0; width: 10px; height: 10px; border: 0 solid var(--focus); will-change: transform; }
.cursor .c-tl { border-width: 2px 0 0 2px; }
.cursor .c-tr { border-width: 2px 2px 0 0; }
.cursor .c-br { border-width: 0 2px 2px 0; }
.cursor .c-bl { border-width: 0 0 2px 2px; }
/* Size, offset and corner radius are set per frame in studio.js so the brackets fit rounded targets. */
.cursor b { position: absolute; left: 0; top: 0; width: 6px; height: 6px; margin: -3px 0 0 -3px; background: var(--focus); transition: width .3s var(--ease), height .3s var(--ease), margin .3s var(--ease); }
.cursor.locked b { width: 4px; height: 4px; margin: -2px 0 0 -2px; }
.cursor .c-tag { position: absolute; left: 0; top: 0; display: flex; align-items: center; gap: 8px; padding: 8px 12px 8px 10px; border-radius: 999px;
  background: var(--ink); color: var(--white); font-weight: 700; font-size: 12px; line-height: 1; letter-spacing: .12em; white-space: nowrap;
  opacity: 0; scale: .5; transform-origin: 0 0; transition: opacity .25s, scale .5s var(--ease); }
.cursor .c-tag .c-no { font-family: var(--mono); font-weight: 400; font-size: 11px; letter-spacing: .04em; color: var(--focus); }
.cursor .c-tag svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.cursor.tagged .c-tag { opacity: 1; scale: 1; }
.has-cursor, .has-cursor a, .has-cursor button, .has-cursor label { cursor: none; }
.has-cursor input, .has-cursor textarea { cursor: text; }
.btn, .nav-cta, .link, .chip, #main-nav a, .menu-toggle, .imprint, .filters button, label.check, .focus-scale a, .spec-footer-bottom a, .crumb a { transition-property: background-color, color, background-size, background-position, padding, translate; translate: 0 0; }
.btn, .nav-cta, .link, .chip, #main-nav a, .menu-toggle, .imprint, .filters button, label.check, .focus-scale a, .spec-footer-bottom a, .crumb a { transition-duration: .25s, .25s, .45s, .45s, .35s, .9s; transition-timing-function: ease, ease, var(--ease), var(--ease), var(--ease), var(--ease); }
.is-magnet { transition-duration: .25s, .25s, .45s, .45s, .35s, .3s !important; }


/* ───── Visible column grid: the page's own measure, drawn once over everything ───── */
.grid-lines { position: fixed; inset: 0; z-index: 30; pointer-events: none; }
.grid-lines > div { height: 100%; max-width: 1600px; margin: 0 auto; padding-inline: var(--gutter); display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); }
.grid-lines i { border-left: var(--hair) solid rgba(128, 129, 128, .16); }
.grid-lines i:last-child { border-right: var(--hair) solid rgba(128, 129, 128, .16); }

/* ───── Keyword blocks in the hero copy ───── */
.chip {
  display: inline-block; margin: 0 .06em; padding: 0 .34em; line-height: 1.55;
  background: var(--ink); color: var(--white); font-weight: 700;
  transition: background-color .25s, color .25s;
}
.chip:hover { background: var(--focus); color: var(--ink); }
.chip:focus-visible { outline-offset: 2px; }

/* ───── Seam ticker: the line where the white page turns black ─────
   Three flat bands cross at different angles on the seam: the orange main band on top, two support bands under it.
   Support bands and every stripe blend by difference, so they flip ink/paper as they cross the seam.
   Each band's geometry lives in --h / --y / --rot; its stripe layer shares the same box. Sized from --m (main band height). */
.ticker {
  --m: clamp(64px, 6.8vw, 112px); --u: calc(var(--m) / 40);
  position: relative; overflow: hidden; isolation: isolate; height: calc(var(--m) * 4); font-family: 'Archivo', var(--sans);
  background: linear-gradient(var(--white) 50%, var(--ink) 50%);
}
.tk, .tk-lines {
  position: absolute; left: -15%; width: 130%; top: 50%; height: var(--h);
  transform: translateY(calc(-50% + var(--y))) rotate(var(--rot));
}
.tk-main { --h: var(--m); --y: 0px; --rot: -3deg; }
.tk-a { --h: calc(var(--m) * .56); --y: calc(var(--m) * -.62); --rot: 4.5deg; }
.tk-b { --h: calc(var(--m) * .56); --y: calc(var(--m) * .66); --rot: -7.5deg; }
.tk { overflow: hidden; display: flex; align-items: center; white-space: nowrap; }
.tk.tk-main { z-index: 4; background: var(--focus); color: var(--ink); font-size: calc(var(--m) * .5); }
.tk.tk-a, .tk.tk-b { z-index: 2; background: var(--white); color: var(--ink); font-size: calc(var(--m) * .27); mix-blend-mode: difference; }
.tk-lines { z-index: 1; pointer-events: none; mix-blend-mode: difference; }
.tk-lines.tk-main { z-index: 3; }

.ticker-track { display: flex; align-items: center; width: max-content; will-change: transform; }
.ticker-unit { display: flex; align-items: center; gap: .9em; padding-right: .9em; line-height: 1; }
.tk-main .ticker-unit b { font-weight: 900; letter-spacing: -.015em; }
/* A weight ripple runs through the main band's Latin letters. Each letter sits in a fixed cell (motion.js measures it most of the way
   toward its heaviest weight) and overflows it evenly when heavier, so the ripple never moves a neighbour or leaves gaps. */
.tk-wave { display: flex; letter-spacing: -.01em; }
.tk-wave span { display: inline-flex; justify-content: center; font-variation-settings: 'wdth' 112, 'wght' 500; }
.tk-wave.is-cells span { contain: layout style; animation: tk-wave 2.6s cubic-bezier(.45, 0, .55, 1) calc(var(--i) * -.12s) infinite; }
@keyframes tk-wave {
  0%, 100% { font-variation-settings: 'wdth' 112, 'wght' 300; }
  50% { font-variation-settings: 'wdth' 112, 'wght' 900; }
}
.tk-a .ticker-unit > span, .tk-b .ticker-unit > span, .tk-a .lcd, .tk-b .lcd { font-variation-settings: 'wdth' 62, 'wght' 620; letter-spacing: .05em; text-transform: uppercase; }
.ticker-unit svg { flex: none; width: 1em; height: 1em; fill: none; stroke: currentColor; stroke-width: 3; }
.tk-dot { flex: none; width: .3em; height: .3em; border-radius: 50%; background: currentColor; }

/* LED cell: a bare window whose lines roll vertically (same idea as the header wordmark) */
.lcd { flex: none; display: block; overflow: hidden; height: 1.3em; line-height: 1.3; }
.lcd-track { display: flex; flex-direction: column; align-items: flex-start; will-change: transform; }
.lcd-track > span { display: block; height: 1.3em; white-space: nowrap; text-transform: none; }
.tk-main .lcd { font-size: .62em; line-height: 1.5; height: 1.5em; font-variation-settings: 'wdth' 112, 'wght' 700; letter-spacing: .01em; }
.tk-main .lcd-track > span { height: 1.5em; }

/* Route strip: the lit stop swaps ink and paper (colour only, so nothing reflows) */
.stops { display: flex; align-items: center; gap: .35em; }
.stop { padding: .2em .45em; transition: background-color .35s var(--ease), color .35s var(--ease); }
.stop.on { background: var(--ink); color: var(--white); }
.stop-sep { font-style: normal; opacity: .45; }

/* Racing stripes: a heavy rule with a hairline along the main band, a checker that runs toward the band's left along each support band */
.ln { position: absolute; left: 0; right: 0; --c: var(--white); }
.ln-top { bottom: calc(100% + var(--u) * 1.4); }
.ln-bottom { top: calc(100% + var(--u) * 1.4); }
.ln-double { height: calc(var(--u) * 4.4); }
.ln-double.ln-top { background: linear-gradient(to bottom, var(--c) 0 calc(var(--u) * .6), transparent 0 calc(var(--u) * 2), var(--c) 0); }
.ln-double.ln-bottom { background: linear-gradient(to top, var(--c) 0 calc(var(--u) * .6), transparent 0 calc(var(--u) * 2), var(--c) 0); }
.ln-check { height: calc(var(--u) * 3.2); background: conic-gradient(var(--c) 25%, transparent 0 50%, var(--c) 0 75%, transparent 0) 0 0 / calc(var(--u) * 3.2) calc(var(--u) * 3.2); animation: tk-run-check 2.4s linear infinite; }
@keyframes tk-run-check { to { background-position-x: calc(var(--u) * -6.4); } }
@media (prefers-reduced-motion: reduce) { .ln-check, .tk-wave span { animation: none; } }

/* ───── Responsive ───── */
.vf:has(img) .vf-center { display: block; }
@media (max-width: 1100px) {
  .lens-row { grid-template-columns: 56px minmax(0, 1fr) 24px; row-gap: 10px; }
  .lens-swap { grid-column: 2; grid-row: 2; }
  .lens-row > svg:last-child { grid-column: 3; grid-row: 1; }
  .proc-stage { grid-template-columns: minmax(0, 1fr); grid-template-areas: 'view' 'list'; row-gap: 40px; }
  .proc-view { aspect-ratio: 16 / 10; }
  .proc-ruler { display: none; }
  .principal-home { grid-template-columns: minmax(0, 1fr); }
  .crew { justify-self: center; margin-top: 24px; }
}

@media (max-width: 860px) {
  :root { --mast: 56px; }
  .led { font-size: 19px; }

  .grid-lines > div { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-lines i:nth-child(n+3) { display: none; }
  .grid-lines i:nth-child(2) { border-right: var(--hair) solid rgba(128, 129, 128, .16); }
  .focus-scale { display: none !important; }
  body.has-scale .spec-footer { padding-bottom: 32px; }

  .section-head, .principal, .inquiry-inner, .page-head-grid, .service-spec, .contact { grid-template-columns: minmax(0, 1fr); }
  .head-fig { --reach: 0px; width: min(100%, 560px); justify-self: end; }
  .vf-read { font-size: 10px; }
  .vf-read.tr, .vf-read.bl { display: none; }
  .vf-empty { padding: 32px 20px; }
  .lens-row { grid-template-columns: 40px minmax(0, 1fr) 20px; gap: 6px 14px; }
  .fov { width: 36px; height: 36px; }
  .lens-swap p { font-size: 14px; }
  .lens-swap ul { display: none; }
  .lens:hover .lens-swap p { opacity: 1; transform: none; }
  .lens:hover .lens-title { transform: none; }
  .inquiry h2 { --b-inset: -10px -12px; }
  .lenses:has(.lens:hover) .lens:not(:hover) { opacity: 1; }
  .proc-btn { grid-template-columns: 40px minmax(0, 1fr) auto; }
  .proc-body p { padding-left: 52px; font-size: 15px; }
  .crew { width: calc(100% - 120px); padding-right: 0; }
  .crew-node b { font-size: 14px; }
  .crew-me b { font-size: 11px; letter-spacing: .06em; }
  .crew-me small { display: none; }
  .crew-node small { display: none; }
  .crew-read { position: static; width: auto; margin-top: 28px; }
  .catalogue { grid-template-columns: minmax(0, 1fr); }
  .catalogue:has(.work:hover) .work:not(:hover), .feat-grid:has(.feat:hover) .feat:not(:hover) { opacity: 1; }
  .feat-grid { grid-template-columns: minmax(0, 1fr); }
  .filters { grid-template-columns: minmax(0, 1fr); }
  .flt-cap { display: none; }
  .flt-list { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .flt-list::-webkit-scrollbar { display: none; }
  .filters button { flex: none; }
  .principles { grid-template-columns: minmax(0, 1fr); }
  .principles > div + div { padding-left: 0; border-left: 0; border-top: var(--hair) solid var(--faint); }
  .row-2 { grid-template-columns: minmax(0, 1fr); }
  .btn { min-height: 52px; }
}

@media (hover: none), (pointer: coarse) { .cursor { display: none; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
  .vf-image { filter: none; transform: none; }
  .proc-plate { filter: none; transform: none; opacity: 1; }
  .cursor { display: none; }
}

/* Rotunda embed */
.rotunda { position: relative; aspect-ratio: 16 / 9; min-height: 420px; background: #05060a; border: var(--hair) solid var(--line); overflow: hidden; }
.rotunda-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }
.rotunda-skip { position: absolute; left: 12px; bottom: 12px; font: 500 12px var(--mono); color: var(--fg); background: var(--bg); padding: 6px 10px; transform: translateY(160%); }
.rotunda-skip:focus-visible { transform: none; }
.rotunda-page { padding: 0; }
.rotunda-full { aspect-ratio: auto; height: 100svh; min-height: 560px; border: 0; }
@media (max-width: 720px) { .rotunda { aspect-ratio: 3 / 4; } }

/* Minimal masthead: wordmark + menu toggle at every width; the four-page menu opens as an overlay */

/* Glass masthead: continuous progressive blur. Six equal layers stack (blur accumulates), each switching on a little lower than the last,
   so blur grows smoothly from 0 at the top edge, holds, then every layer fades out together so the glass dissolves into the page. */
.masthead { background: transparent; border-bottom: 0; }
.glass { position: absolute; left: 0; right: 0; top: 0; height: var(--glass); z-index: -1; pointer-events: none; }
.glass i { position: absolute; inset: 0; -webkit-backdrop-filter: blur(1.8px); backdrop-filter: blur(1.8px); }
.glass::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--bg) 62%, transparent) 0%,
    color-mix(in srgb, var(--bg) 54%, transparent) 20%,
    color-mix(in srgb, var(--bg) 38%, transparent) 40%,
    color-mix(in srgb, var(--bg) 20%, transparent) 60%,
    color-mix(in srgb, var(--bg) 6%, transparent) 80%,
    transparent 100%);
}
.glass i:nth-child(1) { -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 62%, transparent 100%); mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 62%, transparent 100%); }
.glass i:nth-child(2) { -webkit-mask-image: linear-gradient(to bottom, transparent 8%, #000 30%, #000 62%, transparent 100%); mask-image: linear-gradient(to bottom, transparent 8%, #000 30%, #000 62%, transparent 100%); }
.glass i:nth-child(3) { -webkit-mask-image: linear-gradient(to bottom, transparent 16%, #000 38%, #000 62%, transparent 100%); mask-image: linear-gradient(to bottom, transparent 16%, #000 38%, #000 62%, transparent 100%); }
.glass i:nth-child(4) { -webkit-mask-image: linear-gradient(to bottom, transparent 24%, #000 46%, #000 62%, transparent 100%); mask-image: linear-gradient(to bottom, transparent 24%, #000 46%, #000 62%, transparent 100%); }
.glass i:nth-child(5) { -webkit-mask-image: linear-gradient(to bottom, transparent 32%, #000 54%, #000 62%, transparent 100%); mask-image: linear-gradient(to bottom, transparent 32%, #000 54%, #000 62%, transparent 100%); }
.glass i:nth-child(6) { -webkit-mask-image: linear-gradient(to bottom, transparent 40%, #000 62%, #000 62%, transparent 100%); mask-image: linear-gradient(to bottom, transparent 40%, #000 62%, #000 62%, transparent 100%); }
@media (prefers-reduced-transparency: reduce) { .glass i { display: none; } .glass::after { background: color-mix(in srgb, var(--bg) 92%, transparent); } }
@supports not (backdrop-filter: blur(1px)) { .glass::after { background: color-mix(in srgb, var(--bg) 88%, transparent); } }

/* Dispersion: RGB channel split strongest at the top edge, fading out well before the glass ends */
.glass i.disp { -webkit-backdrop-filter: none; }
.glass i.disp-a { backdrop-filter: url(#disp-a); -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 18%, transparent 62%); mask-image: linear-gradient(to bottom, #000 0%, #000 18%, transparent 62%); }
.glass i.disp-b { backdrop-filter: url(#disp-b); -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 38%); mask-image: linear-gradient(to bottom, #000 0%, transparent 38%); }
@media (prefers-reduced-transparency: reduce) { .glass i.disp { display: none; } }

/* Hero viewfinder field: behind the headline, never intercepts input */
.focus-field { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
@media (hover: none), (pointer: coarse) { .focus-field { opacity: .8; } }



/* ───── Cover: one vertical interactive block that settles on scroll (two states; GSAP scrubs between them) ───── */
.chart { --u: min(1vw, calc(100svh * 1440 / 850 / 100)); position: relative; height: 100svh; min-height: 560px; background: var(--bg); }
.chart > * { position: absolute; margin: 0; }
.chart-window { left: 0; top: 0; width: 60.42%; height: 100%; overflow: hidden; background: var(--plate); border-radius: 0; z-index: 0; }
.focus-field { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.cw-read { position: absolute; z-index: 1; font: 500 11px var(--mono); letter-spacing: .06em; color: var(--mute); pointer-events: none; }
.cw-read.tl { left: 12px; top: 74px; } .cw-read.bl { left: 12px; bottom: 12px; }
.c-kicker { left: 63%; top: 36.7%; z-index: 1; font-weight: 500; font-size: max(calc(var(--u) * 1.2), 13px); line-height: 1.8; }
.chart-title { left: 63%; top: 44%; z-index: 1; }
.chart-title h1 { font-weight: 800; font-size: max(calc(var(--u) * 4.9), 38px); line-height: 1.2; letter-spacing: -.01em; }
.chart-title h1 span { display: block; white-space: nowrap; }
.chart-title h1 span:nth-child(2) { transform: translate(calc(3em * var(--t, 0)), calc(-1.2em * var(--t, 0))); } /* second line slides up beside the first; em follows the live font size */
.c-tag { left: 63%; top: 66%; z-index: 1; font: 500 max(calc(var(--u) * 1.75), 15px)/1.3 'Archivo', var(--sans); }
.c-side { z-index: 1; opacity: 0; writing-mode: vertical-rl; transform: translate(-50%, -50%) rotate(180deg); white-space: nowrap; font: 500 max(calc(var(--u) * 1.27), 12px)/1 'Archivo', var(--sans); letter-spacing: .04em; left: 2.85%; }
.c-side-t { top: 38.6%; } .c-side-b { top: 84.2%; }
/* end state, used directly when motion is reduced and as the pre-scroll fallback */
.chart.is-end .chart-window { left: 10.42%; top: 4.82%; width: 39.58%; height: 86.5%; border-radius: calc(var(--u) * 1.32); }
.chart.is-end .c-kicker { opacity: 0; }
.chart.is-end .chart-title { left: 51.8%; top: 20%; opacity: 0; visibility: hidden; }
.chart.is-end .chart-title h1 { --t: 1; font-size: max(calc(var(--u) * 3.1), 26px); }
.chart.is-end .c-tag { left: 51.8%; top: 33%; font-size: max(calc(var(--u) * 1.5), 14px); }
.chart.is-end .c-side { opacity: 1; }
@media (max-width: 860px) {
  .chart { height: auto; min-height: 0; display: flex; flex-direction: column; gap: 18px; padding: calc(var(--glass) + 8px) 20px 44px; }
  .chart > * { position: static; transform: none !important; opacity: 1 !important; width: auto !important; }
  .chart-window { order: 2; height: clamp(320px, 52svh, 460px); border-radius: 19px; margin-top: 8px; }
  .chart > .chart-window { position: relative; } /* the scene's canvas fills the window, not the whole cover */
  .cw-read.tl { top: 10px; }
  .c-kicker { order: 0; font-size: 15px; }
  .chart-title { order: 1; } .chart-title h1 { font-size: clamp(34px, 9.6vw, 52px); }
  .chart-title h1 span:nth-child(2) { transform: none !important; }
  .c-tag { order: 3; font-size: 17px; }
  .c-side { display: none; }
}
@media (hover: none), (pointer: coarse) { .cw-read.bl { display: none; } }

/* Introduction under the cover */
.intro { padding-block: clamp(72px, 9vw, 150px); }

/* Logo mark: the 森 glyph, centred in the masthead; follows the header theme through currentColor */
.mark { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: grid; place-items: center; height: 30px; color: inherit; }
.mark-svg { height: 100%; width: auto; display: block; }

/* Wordmark as a destination sign: a fixed little panel that alternates 森鑒閣 / 4rest floor, rolling up smoothly. */
.led { display: block; width: max-content; height: 1.3em; overflow: hidden; font-size: 21px; line-height: 1.3; }
.led-track { display: flex; flex-direction: column; animation: led-roll 9s linear infinite; }
.led-i { display: block; height: 1.3em; white-space: nowrap; }
.led-i.zh, .c-kicker, .c-side-t { font-family: 'Chiron Sung HK', 'Noto Serif TC', 'PMingLiU', serif; }
.led-i.zh { font-weight: 500; letter-spacing: .1em; }
.led-i.en { font-family: 'Archivo', var(--sans); font-weight: 500; letter-spacing: .01em; }
@keyframes led-roll {
  0%, 40% { transform: translateY(0); animation-timing-function: cubic-bezier(.65, 0, .25, 1); }
  47%, 90% { transform: translateY(-33.3333%); animation-timing-function: cubic-bezier(.65, 0, .25, 1); }
  97%, 100% { transform: translateY(-66.6667%); }
}
@media (prefers-reduced-motion: reduce) { .led-track { animation: none; } }


/* ───── Menu: four cards that grow out of the 森 mark ───── */
.menu-toggle { display: inline-flex; align-items: center; gap: 12px; height: 44px; padding: 0; background: none; border: 0; color: inherit; font: 500 14px/1 var(--sans); letter-spacing: .12em; cursor: pointer; }
.menu-toggle i { position: relative; width: 22px; height: 9px; border-block: 1.5px solid currentColor; transition: transform .35s var(--ease); }
.menu-toggle[aria-expanded="true"] i { transform: scaleY(.15); }
.tled { display: block; }
.tled-idle { display: block; width: 3.6em; height: 1.3em; overflow: hidden; line-height: 1.3; }
.tled-track { display: flex; flex-direction: column; animation: led-roll 9s linear -4.5s infinite; } /* half a cycle behind the wordmark */
.tled-track span { display: block; height: 1.3em; text-align: right; }
.tled-open { display: none; text-align: right; line-height: 1.3; }
.menu-toggle[aria-expanded="true"] .tled-idle { display: none; }
.menu-toggle[aria-expanded="true"] .tled-open { display: block; }
@media (prefers-reduced-motion: reduce) { .tled-track { animation: none; } }

#main-nav {
  --bg: var(--white); --fg: var(--ink); --line: var(--ink); --mute: #55575a; --faint: #c9cac6;
  position: fixed; z-index: 2; left: 50%; top: calc(var(--mast) + 14px); transform: translateX(-50%);
  width: min(1000px, calc(100vw - 2 * var(--gutter)));
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(8px, 1.2vw, 16px);
  visibility: hidden; pointer-events: none; counter-reset: card; color: var(--ink);
}
#main-nav.is-open { visibility: visible; pointer-events: auto; }
#main-nav a {
  position: relative; display: flex; flex-direction: column; justify-content: space-between; gap: 20px;
  min-height: clamp(150px, 24vh, 240px); padding: 16px 16px 14px;
  background: var(--white); color: var(--ink); border: var(--hair) solid var(--ink);
  font-weight: 900; font-size: clamp(22px, 2.4vw, 34px); line-height: 1.15; letter-spacing: .04em;
  will-change: transform; transition: border-color .25s, background-color .25s, color .25s, transform .4s var(--ease);
}
#main-nav a::before { counter-increment: card; content: counter(card, decimal-leading-zero); font: 500 11px/1 var(--mono); letter-spacing: .06em; color: var(--mute); }
#main-nav a small { font: 500 12px/1 'Archivo', var(--sans); letter-spacing: .02em; color: var(--mute); }
#main-nav a:hover, #main-nav a:focus-visible { border-color: var(--focus); transform: translateY(-4px); }
#main-nav a[aria-current="page"]::after { content: ''; position: absolute; top: 16px; right: 16px; width: 7px; height: 7px; border-radius: 50%; background: var(--focus); }
#main-nav .nav-cta { background: var(--focus); border-color: var(--focus); }
#main-nav .nav-cta::before, #main-nav .nav-cta small { color: var(--ink); }
#main-nav .nav-cta:hover, #main-nav .nav-cta:focus-visible { background: var(--ink); border-color: var(--ink); color: var(--white); }
#main-nav .nav-cta:hover::before, #main-nav .nav-cta:hover small { color: var(--white); }
.menu-scrim { position: fixed; inset: 0; z-index: 39; background: color-mix(in srgb, var(--ink) 20%, transparent); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); opacity: 0; pointer-events: none; transition: opacity .5s var(--ease); }
body.menu-open .menu-scrim { opacity: 1; pointer-events: auto; }
@media (max-width: 700px) {
  #main-nav { grid-template-columns: repeat(2, minmax(0, 1fr)); top: calc(var(--mast) + 10px); }
  #main-nav a { min-height: clamp(110px, 17vh, 150px); font-size: 24px; }
}
@media (prefers-reduced-motion: reduce) { .menu-scrim { transition: none; } }

/* Everything that comes out of the header is glass, with the same dispersion as the bar:
   translucent tint over a blurred, RGB-split backdrop, a lit top edge, and a soft shadow. */
#main-nav { --bg: inherit; --fg: inherit; --line: inherit; --mute: inherit; --faint: inherit; color: var(--fg); }
#main-nav a {
  background: linear-gradient(160deg, color-mix(in srgb, var(--bg) 62%, transparent), color-mix(in srgb, var(--bg) 40%, transparent));
  color: var(--fg);
  border: var(--hair) solid color-mix(in srgb, var(--fg) 24%, transparent);
  -webkit-backdrop-filter: blur(5px) saturate(1.25); backdrop-filter: blur(5px) saturate(1.25) url(#disp-b);
  box-shadow: inset 0 1px 0 color-mix(in srgb, white 65%, transparent), inset 0 0 0 1px color-mix(in srgb, white 12%, transparent), 0 14px 34px color-mix(in srgb, var(--ink) 16%, transparent);
}
#main-nav a:hover, #main-nav a:focus-visible { background: linear-gradient(160deg, color-mix(in srgb, var(--bg) 46%, transparent), color-mix(in srgb, var(--bg) 24%, transparent)); border-color: var(--focus); }
#main-nav a::before, #main-nav a small { color: var(--mute); }
#main-nav .nav-cta { background: linear-gradient(160deg, color-mix(in srgb, var(--focus) 82%, transparent), color-mix(in srgb, var(--focus) 56%, transparent)); border-color: color-mix(in srgb, var(--focus) 70%, white); color: var(--ink); }
#main-nav .nav-cta::before, #main-nav .nav-cta small { color: color-mix(in srgb, var(--ink) 80%, transparent); }
#main-nav .nav-cta:hover, #main-nav .nav-cta:focus-visible { background: linear-gradient(160deg, color-mix(in srgb, var(--ink) 78%, transparent), color-mix(in srgb, var(--ink) 58%, transparent)); border-color: var(--ink); color: var(--white); }
.menu-scrim { background: color-mix(in srgb, var(--ink) 12%, transparent); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
@media (prefers-reduced-transparency: reduce) { #main-nav a { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--bg); } #main-nav .nav-cta { background: var(--focus); } }

/* Card labels are swapping marquees: state 1 = Chinese title / English caption, state 2 = English title / Chinese caption.
   Both rows roll together; the loop only runs while the menu is open, so every opening starts on state 1. */
#main-nav a > .sw { display: block; overflow: hidden; height: 1.3em; line-height: 1.3; }
#main-nav a > .sw.big { font-size: clamp(22px, 2.4vw, 34px); font-weight: 900; letter-spacing: .04em; }
#main-nav a > .sw.small { font-size: 12px; font-weight: 500; letter-spacing: .02em; color: var(--mute); }
.sw-t { display: flex; flex-direction: column; }
.sw-t > span { display: block; height: 1.3em; white-space: nowrap; }
.sw-t > .en { font-family: 'Archivo', var(--sans); font-weight: 500; letter-spacing: 0; }
#main-nav .nav-cta > .sw.small { color: color-mix(in srgb, var(--ink) 80%, transparent); }
#main-nav .nav-cta:hover > .sw.small { color: var(--white); }
#main-nav.is-open .sw-t { animation: led-roll 9s linear calc(var(--i, 0) * .14s) infinite; }
@media (prefers-reduced-motion: reduce) { #main-nav.is-open .sw-t { animation: none; } }

/* The frosted card does the blurring, so the page behind is barely touched; title and caption sit together at the card's foot. */
.menu-scrim { background: color-mix(in srgb, var(--ink) 3%, transparent); -webkit-backdrop-filter: none; backdrop-filter: none; }
#main-nav a { gap: 3px; -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3) url(#disp-b); }
#main-nav a::before { margin-bottom: auto; }
@media (prefers-reduced-transparency: reduce) { #main-nav a { backdrop-filter: none; -webkit-backdrop-filter: none; } }

/* Clearer glass: much less tint so it reads as transparent rather than white; larger captions. */
#main-nav a { background: linear-gradient(160deg, color-mix(in srgb, var(--bg) 24%, transparent), color-mix(in srgb, var(--bg) 8%, transparent)); }
#main-nav a:hover, #main-nav a:focus-visible { background: linear-gradient(160deg, color-mix(in srgb, var(--bg) 14%, transparent), color-mix(in srgb, var(--bg) 3%, transparent)); }
#main-nav .nav-cta { background: linear-gradient(160deg, color-mix(in srgb, var(--focus) 62%, transparent), color-mix(in srgb, var(--focus) 34%, transparent)); }
#main-nav a > .sw.small { font-size: clamp(14px, 1.25vw, 18px); }
#main-nav a::before { font-size: 12px; }

/* Glass dispersion for the cards: the layer underneath is refracted per colour channel, strongest at the card edges,
   with only a light frost so the split stays readable. (Chromium; elsewhere the cards fall back to plain frosted glass.) */
#main-nav a { -webkit-backdrop-filter: blur(6px) saturate(1.3); backdrop-filter: url(#refract) blur(6px) saturate(1.3); }
@media (prefers-reduced-transparency: reduce) { #main-nav a { backdrop-filter: none; -webkit-backdrop-filter: none; } }

/* Glass rim light: bright upper-left edge, softer lower-right edge, faint inner glow. */
#main-nav a {
  border-color: color-mix(in srgb, white 38%, transparent);
  box-shadow:
    inset 1.5px 1.5px 0 color-mix(in srgb, white 78%, transparent),
    inset -1px -1px 0 color-mix(in srgb, white 30%, transparent),
    inset 0 0 18px color-mix(in srgb, white 14%, transparent),
    0 14px 34px color-mix(in srgb, var(--ink) 16%, transparent);
}
#main-nav a:hover, #main-nav a:focus-visible { border-color: var(--focus); }
#main-nav .nav-cta { border-color: color-mix(in srgb, white 55%, var(--focus)); }

/* Slightly rounded glass cards */
#main-nav a { border-radius: 12px; }

/* Five cards: the cards shrink, the type does not. Services is the dark glass card, Contact keeps the orange one. */
#main-nav a { min-height: clamp(120px, 18vh, 180px); padding: 14px 14px 12px; }
@media (min-width: 701px) { #main-nav { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: clamp(8px, 1vw, 12px); } }
#main-nav .nav-dark {
  background: linear-gradient(160deg, color-mix(in srgb, var(--ink) 90%, transparent), color-mix(in srgb, var(--ink) 74%, transparent));
  color: var(--white); border-color: color-mix(in srgb, white 24%, transparent);
}
#main-nav .nav-dark::before, #main-nav .nav-dark > .sw.small { color: color-mix(in srgb, var(--white) 64%, transparent); }
#main-nav .nav-dark:hover, #main-nav .nav-dark:focus-visible { background: linear-gradient(160deg, color-mix(in srgb, var(--ink) 96%, transparent), color-mix(in srgb, var(--ink) 86%, transparent)); border-color: var(--focus); }
#main-nav .nav-dark[aria-current="page"]::after { background: var(--focus); }
@media (max-width: 700px) {
  #main-nav a { min-height: clamp(96px, 14vh, 124px); }
  #main-nav .nav-cta { grid-column: 1 / -1; }
}
@media (prefers-reduced-transparency: reduce) { #main-nav .nav-dark { background: var(--ink); } }

/* Frosted glass after all: no per-channel refraction, a heavy frost with a milky tint, so the page behind reads only as soft colour. */
#main-nav a { -webkit-backdrop-filter: blur(22px) saturate(1.4); backdrop-filter: blur(22px) saturate(1.4); }
#main-nav a:not(.nav-dark, .nav-cta) { background: linear-gradient(160deg, color-mix(in srgb, var(--bg) 52%, transparent), color-mix(in srgb, var(--bg) 30%, transparent)); }
#main-nav a:not(.nav-dark, .nav-cta):is(:hover, :focus-visible) { background: linear-gradient(160deg, color-mix(in srgb, var(--bg) 66%, transparent), color-mix(in srgb, var(--bg) 44%, transparent)); }
#main-nav .nav-cta { background: linear-gradient(160deg, color-mix(in srgb, var(--focus) 74%, transparent), color-mix(in srgb, var(--focus) 52%, transparent)); }
#main-nav .nav-dark { background: linear-gradient(160deg, color-mix(in srgb, var(--ink) 80%, transparent), color-mix(in srgb, var(--ink) 62%, transparent)); }
@media (prefers-reduced-transparency: reduce) { #main-nav a { backdrop-filter: none; -webkit-backdrop-filter: none; } }

/* Second state of the cover: the invitation and the five services, where the sentence used to be */
.c-act { left: 51.8%; top: 43%; width: 40%; z-index: 2; visibility: hidden; }
.c-act { top: 41%; width: min(40%, calc(var(--u) * 40)); }
.c-svc { display: grid; grid-template-columns: repeat(3, 1fr); gap: max(calc(var(--u) * .8), 8px); container-type: inline-size; }
/* Same glass as the menu cards: translucent tint over a blurred, RGB-split backdrop, a lit top edge, a soft shadow. */
.c-svc li a { position: relative; display: flex; flex-direction: column; justify-content: space-between; aspect-ratio: 1; align-self: start; overflow: hidden; padding: 3cqi; border-radius: 12px;
  background: linear-gradient(160deg, color-mix(in srgb, var(--bg) 62%, transparent), color-mix(in srgb, var(--bg) 40%, transparent)); color: var(--fg);
  border: var(--hair) solid color-mix(in srgb, var(--fg) 24%, transparent);
  -webkit-backdrop-filter: blur(5px) saturate(1.25); backdrop-filter: blur(5px) saturate(1.25);
  box-shadow: inset 0 1px 0 color-mix(in srgb, white 65%, transparent), inset 0 0 0 1px color-mix(in srgb, white 12%, transparent), 0 14px 34px color-mix(in srgb, var(--ink) 16%, transparent);
  transition: border-color .25s, background-color .25s; will-change: transform; }
.c-svc li a::after { content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity .3s;
  background: radial-gradient(circle at var(--mx, 50%) var(--my, 30%), color-mix(in srgb, white 55%, transparent), transparent 55%); }
.c-svc li a.is-tilt::after { opacity: .5; }
.c-svc li a:hover, .c-svc li a:focus-visible { border-color: var(--focus); }
.sv-no { font: 500 max(2.1cqi, 11px)/1 var(--mono); letter-spacing: .06em; color: var(--mute); }
.sv-go { position: absolute; right: 3cqi; top: 3cqi; width: max(3.4cqi, 14px); height: max(3.4cqi, 14px); fill: none; stroke: currentColor; stroke-width: 1.6; }
/* Labels are swapping marquees like the menu: title zh -> en, caption en -> zh, rolling together. */
.sv-body { display: grid; gap: .6cqi; }
.c-svc .sw { display: block; overflow: hidden; line-height: 1.2; }
.c-svc .sw.big { height: 2.5em; font-size: max(3.7cqi, 16px); font-weight: 900; letter-spacing: .02em; }
.c-svc .sw.small { height: 2.6em; font-size: max(2.3cqi, 11px); font-weight: 500; letter-spacing: .02em; color: var(--mute); }
.c-svc .sw-t { display: flex; flex-direction: column; animation: led-roll 9s linear calc(var(--i, 0) * .14s) infinite; }
.c-svc .sw.big .sw-t > span { display: flex; align-items: flex-end; height: 2.5em; }
.c-svc .sw.small .sw-t > span { display: block; height: 2.6em; }
/* wraps to a second line when the English runs long (higher specificity than the row rule above) */
.c-svc .sw.big .sw-t > .en { white-space: normal; font-family: 'Archivo', var(--sans); font-weight: 800; font-stretch: 106%; font-size: .62em; height: calc(2.5em / .62); letter-spacing: 0; line-height: 1.12; hyphens: auto; overflow-wrap: anywhere; }
.c-svc .sw.small .sw-t > span { white-space: normal; }
.c-svc .sw.small .en { font-family: 'Archivo', var(--sans); font-weight: 500; font-stretch: 100%; letter-spacing: 0; line-height: 1.3; overflow-wrap: anywhere; }
/* The sixth slot is an open frame: and more. */
.c-svc .c-more a { background: none; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; border: var(--hair) dashed color-mix(in srgb, var(--fg) 22%, transparent); color: var(--mute); }
.c-svc .c-more a:hover, .c-svc .c-more a:focus-visible { border-style: solid; border-color: var(--focus); background: color-mix(in srgb, var(--focus) 8%, transparent); }
.c-svc .c-more .sv-no { font-size: max(3cqi, 14px); color: var(--mute); }
.c-svc .c-more .sw.big { font-weight: 500; opacity: .62; }
.c-svc .c-more .sw.big .sw-t > .en { font-weight: 500; }
.c-svc .c-more .sw.small { opacity: .6; }
.c-svc .c-more .sv-go { opacity: .5; }
.c-svc .c-more a:hover .sw, .c-svc .c-more a:hover .sv-go { opacity: 1; }
.c-svc .c-more a:hover { color: var(--fg); }
@media (prefers-reduced-motion: reduce) { .c-svc .sw-t { animation: none; } }
@media (prefers-reduced-transparency: reduce) { .c-svc li a { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--bg); } }
@container (max-width: 440px) { .sv-body .sw.small { display: none; } }
.chart.is-end .c-act { visibility: visible; }
/* Second state: heroDescription in two lines where the headline stood (the headline fades out as it settles); the services roll inside
   the bracket (keyframes c-roll-y / c-roll-w come from coverLead()). */
.c-lead { left: 51.8%; top: 17.5%; z-index: 1; visibility: hidden; font-weight: 800; font-size: max(calc(var(--u) * 3.1), 26px); line-height: 1.2; letter-spacing: -.01em; }
.c-lead > span { display: block; white-space: nowrap; }
.c-lead > span:first-child { margin-bottom: .45em; font-size: .48em; font-weight: 700; line-height: 1.5; letter-spacing: 0; } /* the lead-in; the second line, the services, is the point */
.c-lead .bracket { display: inline-block; vertical-align: top; margin-inline: .2em .12em; --b-inset: .06em -.1em .02em; --b-len: max(calc(var(--u) * .9), 10px); }
.c-lead .word-roll { height: 1.2em; line-height: 1.2; clip-path: inset(0 -.3em); animation: c-roll-w var(--roll, 12s) linear infinite; }
.c-lead .word-track { animation: c-roll-y var(--roll, 12s) linear infinite; }
.c-lead .word-track > span { height: 1.2em; }
.chart.is-end .c-lead { visibility: visible; }
@media (prefers-reduced-motion: reduce) { .c-lead .word-roll, .c-lead .word-track { animation: none; } }
@media (max-width: 860px) { .c-lead { visibility: visible; order: 4; font-size: clamp(26px, 7.4vw, 44px); } .c-lead > span:first-child { white-space: normal; font-size: max(.48em, 16px); } }
@media (max-width: 860px) { .c-act { visibility: visible; order: 4; width: auto; } .c-svc { grid-template-columns: repeat(2, 1fr); } }

/* Introduction statement under the cover */
.intro { padding-block: clamp(80px, 10vw, 170px); }
.intro-lead { font-weight: 500; font-size: clamp(22px, 2.8vw, 46px); line-height: 1.7; max-width: 26em; text-wrap: balance; }
.intro-lead .ul { text-decoration: underline; text-underline-offset: .22em; text-decoration-thickness: 1px; }
.intro-lead .ul:hover { color: var(--focus); }

/* The 3D window is a mid-grey box on the light page */
.chart-window.is-tone { background: #7b7874; }
.chart-window.is-tone .cw-read { color: rgba(14, 15, 16, .62); }
.chart-window.is-tone.is-sheet { background: #121212; }
.chart-window.is-sheet .cw-read { color: rgba(255, 255, 255, .5); }

/* Header items that sit on the dark cover window turn white (set from studio.js while they overlap it) */
.masthead .on-dark { color: #f3f3f0; }
.imprint, .mark, .menu-toggle { transition: color .3s var(--ease); }

/* ───────── "Let's Chat" pointer: the Figma button that replaces the cursor over the lower right of the cover ───────── */
.talk { position: fixed; left: 0; top: 0; z-index: 71; width: 0; height: 0; pointer-events: none; will-change: transform; }
.talk-pop { position: absolute; left: -84px; top: -84px; width: 168px; height: 168px; transform: scale(0); opacity: 0;
  transition: transform .3s cubic-bezier(.5, 0, .75, 0), opacity .2s linear; }
.talk.is-on .talk-pop { transform: scale(1); opacity: 1; transition: transform .45s var(--ease), opacity .15s linear; }
.talk-body { position: absolute; inset: 0; }
.talk-ring { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; transition: scale .5s var(--ease); }
.talk-ring text { font: 700 19px var(--sans); letter-spacing: .04em; fill: var(--focus); }
.talk-disc { position: absolute; left: 31px; top: 31px; width: 106px; height: 106px; border-radius: 50%; background: var(--focus);
  box-shadow: 0 2.4px 4.6px rgba(0, 0, 0, .25); transition: scale .25s var(--ease), box-shadow .3s var(--ease); }
.talk-glass, .talk-arrow { position: absolute; inset: 0; }
.talk-glass { width: 100%; height: 100%; transition: scale .25s var(--ease); }
.talk-arrow { display: block; overflow: hidden; border-radius: 50%; }
.talk-arrow svg { width: 100%; height: 100%; display: block; }
.talk-arrow.go svg { animation: talk-arrow .75s cubic-bezier(.65, 0, .25, 1); }
@keyframes talk-arrow { 0% { transform: translateX(0); } 45% { transform: translateX(62%); opacity: 0; } 46% { transform: translateX(-62%); opacity: 0; } 100% { transform: translateX(0); opacity: 1; } }
.talk.is-press .talk-disc { scale: .9; box-shadow: 0 1px 2px rgba(0, 0, 0, .3); }
.talk.is-press .talk-glass { scale: .88; }
.talk.is-press .talk-ring { scale: .94; }
html.talk-on .cursor { opacity: 0; }
html.talk-on.has-cursor, html.talk-on.has-cursor * { cursor: none; }
@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) { .talk { display: none; } }
.talk-wave { position: fixed; z-index: 90; border-radius: 50%; background: var(--focus); transform: scale(0); will-change: transform; pointer-events: all; }
@property --talk-r { syntax: '<length>'; inherits: false; initial-value: 0px; }
.talk-veil { position: fixed; inset: 0; z-index: 90; background: var(--focus); pointer-events: none; --talk-r: 0px;
  -webkit-mask: radial-gradient(circle at var(--x) var(--y), transparent var(--talk-r), #000 calc(var(--talk-r) + 1.5px));
  mask: radial-gradient(circle at var(--x) var(--y), transparent var(--talk-r), #000 calc(var(--talk-r) + 1.5px)); }
/* Next-project wipe (wipe.js): the orange panel widens over the viewport, then leaves in six grid columns. */
.wipe-cover { position: fixed; inset: 0; z-index: 90; background: var(--focus); transform-origin: 0 0; will-change: transform; pointer-events: all; }
.wipe-cols { position: fixed; inset: 0; z-index: 90; pointer-events: none; }
.wipe-cols i { position: absolute; top: 0; bottom: 0; background: var(--focus); transform-origin: left center; will-change: transform; }

/* ───── Punch line (home, last frame): one line pulled into focus, then the frame locks ───── */
.finale { position: relative; }
.finale-stage { position: relative; height: 100vh; height: 100svh; min-height: 560px; display: grid; place-content: center; justify-items: center; padding: var(--glass) var(--gutter) 64px; overflow: hidden; text-align: center; }
.finale-type { margin: 0; display: grid; justify-items: center; font-weight: 900; font-size: clamp(56px, 11.5vw, 208px); line-height: 1.02; letter-spacing: -.04em; }
.finale-type span { display: block; will-change: filter, transform, opacity; }
.finale-type span:last-child { color: var(--focus); }
/* The making well (well.js) renders behind the frame; once it shows, the band carries the line and the HTML type steps back (still read by screen readers). */
.finale-gl { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.finale-gl canvas { display: block; width: 100%; height: 100%; opacity: 0; transition: opacity 1.2s var(--ease); }
.finale-gl.is-live canvas { opacity: 1; }
/* Moonlit corners: the clock tower's frame falls away to indigo dark at its edges. */
.finale-gl::after { content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 1.2s var(--ease);
  background: radial-gradient(ellipse 72% 68% at 50% 46%, transparent 48%, rgba(5, 7, 24, .5) 82%, rgba(2, 3, 14, .86) 100%); }
.finale-gl.is-live::after { opacity: 1; }
.finale-stage > :not(.finale-gl) { position: relative; z-index: 1; }
.finale-stage > .finale-frame { position: absolute; }
.finale-copy { display: grid; justify-items: center; }
.finale-en { margin: clamp(20px, 2.4vw, 36px) 0 0; font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: var(--mute); }
/* 認識我們: a small orange card after the case pages' next-project panel (.rail-next), arrow and all. */
.finale-next { display: grid; gap: 8px; justify-items: start; width: min(100%, 300px); margin-top: clamp(32px, 4vw, 56px); padding: 22px 24px 20px; background: var(--focus); color: var(--ink); text-align: left; --cursor-radius: 0px; }
.finale-next-read { font-size: 13px; font-weight: 500; }
.finale-next-read .mono { font-size: 12px; }
.finale-next strong { font-weight: 900; font-size: clamp(30px, 2.6vw, 44px); line-height: 1.05; letter-spacing: -.02em; }
.finale-next-type { font-family: 'Archivo', var(--sans); font-weight: 500; font-size: 13px; letter-spacing: .01em; color: color-mix(in srgb, var(--ink) 72%, transparent); }
.finale-next-arrow { display: block; width: 44px; height: 44px; margin-top: 10px; transition: transform .6s var(--ease); }
.finale-next-arrow svg { display: block; width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }
.finale-next-arrow circle { stroke-width: 8; }
.finale-next-arrow path { stroke-width: 11; }
.finale-next:hover .finale-next-arrow, .finale-next:focus-visible .finale-next-arrow { transform: translateX(10px); }
/* With the clock tower the scene is the picture: no line (it stays for screen readers), no focus frame, and the card sits
   at the lower right, away from the next section's headline on the left. */
.finale.has-gl .finale-frame { display: none; }
.finale.has-gl .finale-copy { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.finale-stage > .finale-next { justify-self: center; }
.finale.has-gl .finale-stage > .finale-next { position: absolute; right: var(--gutter); bottom: clamp(56px, 9vh, 104px); margin: 0; }
.finale-frame { position: absolute; inset: calc(var(--glass) + 20px) clamp(16px, 6vw, 112px) clamp(96px, 13vh, 140px); pointer-events: none; }
.finale-frame i { position: absolute; width: clamp(28px, 4vw, 64px); aspect-ratio: 1; border: 2px solid var(--focus); }
.finale-frame i:nth-child(1) { left: 0; top: 0; border-width: 2px 0 0 2px; }
.finale-frame i:nth-child(2) { right: 0; top: 0; border-width: 2px 2px 0 0; }
.finale-frame i:nth-child(3) { left: 0; bottom: 0; border-width: 0 0 2px 2px; }
.finale-frame i:nth-child(4) { right: 0; bottom: 0; border-width: 0 2px 2px 0; }
@media (max-width: 860px) {
  .finale-stage { min-height: 480px; }
  .finale-type { font-size: 17.5vw; }
}

/* About opening: the rotunda fills the screen; the brand, then the story, the mission and a closing line hand their shared pieces on over it
   (stage pinned by motion.js aboutStage). 森鑒閣 is Chiron Sung HK on its weight axis: the larger it is set, the lighter it is drawn.
   Without motion the panels simply follow one another over a dark band. */
.about-stage { position: relative; background: #0b0a08; color: #f4edde; }
.about-pin { position: relative; height: 100vh; height: 100svh; min-height: 560px; overflow: hidden; }
.about-rotunda { position: absolute; inset: 0; aspect-ratio: auto; min-height: 0; border: 0; background: #706c57; }
.about-scrim { position: absolute; inset: 0; pointer-events: none; background: linear-gradient(180deg, rgba(10, 9, 7, .5), transparent 24%), linear-gradient(0deg, rgba(10, 9, 7, .55), transparent 46%); }
.about-panel { position: absolute; inset: 0; pointer-events: none; }
.about-ch { display: inline-block; transform-origin: 50% 50%; }
.about-roll { display: inline-grid; }
.about-roll i { grid-area: 1 / 1; font-style: normal; }
.about-ln { display: block; white-space: nowrap; }
.about-panel > * { position: absolute; margin: 0; }
.about-mark { width: 92px; aspect-ratio: 92 / 52; background: currentColor; -webkit-mask: url(logo.svg) center / contain no-repeat; mask: url(logo.svg) center / contain no-repeat; }
.about-zh, .about-en { text-shadow: 0 1px 18px rgba(0, 0, 0, .5); }
.is-brand .about-mark { left: 50%; bottom: 26%; width: clamp(150px, 15.8vw, 240px); transform: translateX(-50%); }
.is-brand .about-zh { left: 0; right: 0; bottom: 17%; text-align: center; font: 500 clamp(19px, 1.67vw, 24px)/1.2 'Chiron Sung HK', 'Noto Serif TC', serif; letter-spacing: .4em; padding-left: .4em; }
.is-brand .about-en { left: 0; right: 0; bottom: 13.5%; text-align: center; font: 500 clamp(13px, 1.18vw, 17px) 'Archivo', var(--sans); letter-spacing: .24em; padding-left: .24em; }
.about-cue { left: 0; right: 0; bottom: 28px; text-align: center; font: 500 10px var(--mono); letter-spacing: .3em; opacity: .7; }
.about-label { display: grid; gap: .95em; font-size: clamp(14px, 1.18vw, 17px); letter-spacing: .24em; text-shadow: 0 1px 18px rgba(0, 0, 0, .5); }
.about-label b { font-weight: 600; }
.about-label span { font-family: 'Archivo', var(--sans); font-weight: 500; }
.about-big { font-family: 'Chiron Sung HK', 'Noto Serif TC', 'PMingLiU', serif; font-weight: 400; line-height: 1; color: #f4edde; text-shadow: 0 2px 40px rgba(0, 0, 0, .35); }
.about-text, .about-side { font-size: clamp(14px, 1.18vw, 17px); line-height: 1.76; letter-spacing: .08em; text-shadow: 0 1px 16px rgba(0, 0, 0, .6); }
.about-text { left: 58.8%; width: min(28.5vw, 440px); }
/* story: mark top-left, label mid-left, 森鑒閣 huge and cropped at the lower left, text lower right */
.is-story .about-mark { left: var(--gutter); top: 19%; width: 92px; }
.is-story .about-label { left: var(--gutter); top: 46%; }
.is-story .about-big { left: -.08em; bottom: 6%; font-size: clamp(96px, 12.9vw, 250px); font-weight: 260; letter-spacing: -.1em; white-space: nowrap; }
.is-story .about-text { bottom: 13.5%; }
/* mission: 森鑒閣 stacked down the left edge and cut by it, label beside it; mark and text share the story's right-hand column */
.is-mission .about-big { left: -.2em; top: 49%; width: 1.3em; font-size: clamp(96px, 12.9vw, 250px); font-weight: 260; line-height: .885; letter-spacing: .12em; word-break: break-all; }
.is-mission .about-label { left: 19.2%; top: 72%; }
.is-mission .about-mark { left: 58.8%; top: 50%; width: 92px; }
.is-mission .about-text { top: 71%; }
/* close: 森鑒閣 small and open-spaced down the centre, a phrase either side of 鑒 */
.is-close .about-big { left: 50%; top: 50%; width: 1.3em; margin: -2.985em 0 0 -.5em; font-size: clamp(44px, 4.27vw, 80px); line-height: 1.99; letter-spacing: .12em; word-break: break-all; }
.is-close .about-side { top: 50%; margin-top: -.88em; white-space: nowrap; }
.is-close .about-side.is-l { right: calc(50% + 7.4vw); }
.is-close .about-side.is-r { left: calc(50% + 7.4vw); }
.about-stage:not(.is-live) .about-pin { height: auto; }
.about-stage:not(.is-live) .about-rotunda { position: relative; height: 100svh; }
.about-stage:not(.is-live) .about-panel { position: relative; height: 100svh; background: #0b0a08; }
.about-stage:not(.is-live) .about-cue { display: none; }
@media (max-width: 720px) {
  .is-brand .about-mark { width: 150px; }
  .is-story .about-label { top: 38%; }
  .is-story .about-big { font-size: 34vw; bottom: 30%; }
  .is-story .about-text { left: var(--gutter); right: var(--gutter); width: auto; bottom: 6%; }
  .is-mission .about-big { top: 24%; font-size: 30vw; }
  .is-mission .about-mark { left: 34%; top: 24%; }
  .is-mission .about-label { left: 34%; top: 36%; }
  .is-mission .about-text { left: 34%; right: var(--gutter); width: auto; top: calc(36% + 84px); }
  .is-close .about-big { font-size: 13vw; }
  .is-close .about-side { left: 0; right: 0; margin: 0; text-align: center; }
  .is-close .about-side.is-l { right: 0; top: 17%; }
  .is-close .about-side.is-r { left: 0; top: auto; bottom: 17%; }
}

/* ───── Touch (touch.js) ─────
   No hover on a phone: the card crossing the middle of the screen takes the hover look (.is-near), a press sinks and
   leans what is under the finger, and a tap on an image draws the camera's AF square. html.is-touch is set by touch.js. */
.is-touch :is(a, button, [role="button"], label) { -webkit-tap-highlight-color: transparent; }
@media (hover: none) {
  /* a tap leaves :hover stuck on the last card; nothing dims its neighbours on a phone */
  .feat-grid:has(.feat:hover) .feat:not(:hover), .catalogue:has(.work:hover) .work:not(:hover),
  .lenses:has(.lens:hover, .lens:focus-visible) .lens:not(:hover, :focus-visible) { opacity: 1; }
  /* press: a small sink under the finger (the individual scale property, so it rides on any transform already there);
     the most used ones also ease back up */
  .btn, .filters button { transition: background-color .25s, color .25s, scale .25s var(--ease); }
  .tile { transition: color .3s, transform .35s var(--ease), box-shadow .35s var(--ease), scale .25s var(--ease); }
  .lens { transition: opacity .5s var(--ease), scale .3s var(--ease); }
  #main-nav a { transition: border-color .25s, background-color .25s, color .25s, transform .4s var(--ease), scale .25s var(--ease); }
  :is(.btn, .link, .chip, .q-next, .q-back, .filters button, .ds-close, .ps-index button, .menu-toggle, .to-top):active { scale: .96; transition-duration: .08s; }
  :is(.tile, .q-prompt, #main-nav a, .lens, .work, a.ds-ref):active { scale: .98; transition-duration: .08s; }
}

/* In focus while scrolling */
.is-touch .feat.is-near .feat-arrow { transform: none; }
.is-touch .feat.is-near .feat-name { transform: translateX(1.5em); }
.is-touch .feat.is-near .feat-glow { animation: feat-breathe 2.4s cubic-bezier(.45, 0, .55, 1) 1; }
.is-touch .lens .lens-title b, .is-touch .lens .fov circle { transition: color .4s, fill .4s; }
.is-touch .lens.is-near .fov circle { fill: var(--focus); }
.is-touch .lens.is-near .lens-row > svg:last-child { transform: translate(3px, -3px); }
.is-touch [data-theme="dark"] .lens.is-near .lens-title b, .is-touch .lens.is-near .lens-title b { color: var(--focus); }
.is-touch .work.is-near .work-title h2 { color: var(--focus); }
/* the case images stacked on a phone: the one in the middle is sharp, the others sit a little back and soft, like the Cover Flow */
.is-touch .case-rail:not(.is-live) .rail-card .vf { transition: filter .6s var(--ease), opacity .6s var(--ease), scale .6s var(--ease); }
.is-touch .case-rail:not(.is-live) .rail-card:not(.is-near) .vf { filter: blur(3px); opacity: .62; scale: .96; }
@media (prefers-reduced-motion: reduce) {
  .is-touch .case-rail:not(.is-live) .rail-card:not(.is-near) .vf { filter: none; opacity: 1; scale: 1; }
  .is-touch .feat.is-near .feat-glow { animation: none; }
}

/* Press on the services cards: they lift as on hover, and the card's own light gathers under the finger */
.tcard.is-press:not(.face-up) { --lift: var(--up, 16); --zoom: 1.05; --tilt: 0; z-index: 120 !important; transition-duration: .3s; }
.tcard.is-press:not(.face-up) :is(.tc-sheen, .tc-fx) { opacity: 1; }
.tcard.is-press:not(.face-up) .tc-back .tc-frame { border-color: var(--c); }
/* the panels that lean under a press keep a little light at the press point */
.finale-next.is-press, .rail-next.is-press { box-shadow: inset 0 0 0 1.5px var(--ink); }

/* The cover sheet on touch: its hint shows again, and a long press is the AF lock, not a text selection or callout */
.chart-window.is-touch .cw-read.bl { display: block; }
.chart-window.is-touch { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }

/* Tap-to-focus: the AF square closes on the finger, blinks once and goes */
.af-mark { position: fixed; z-index: 10000; width: 68px; height: 68px; margin: -34px 0 0 -34px; pointer-events: none;
  animation: af-in 1.1s cubic-bezier(.2, .7, .2, 1) both; }
.af-mark i { position: absolute; width: 14px; height: 14px; border: 0 solid var(--focus); filter: drop-shadow(0 0 4px rgba(0, 0, 0, .35)); }
.af-mark i:nth-child(1) { left: 0; top: 0; border-width: 2px 0 0 2px; }
.af-mark i:nth-child(2) { right: 0; top: 0; border-width: 2px 2px 0 0; }
.af-mark i:nth-child(3) { right: 0; bottom: 0; border-width: 0 2px 2px 0; }
.af-mark i:nth-child(4) { left: 0; bottom: 0; border-width: 0 0 2px 2px; }
.af-mark::after { content: ''; position: absolute; left: 50%; top: 50%; width: 4px; height: 4px; margin: -2px; background: var(--focus); }
.af-mark.is-gone { animation: af-out .18s ease-out both; }
@keyframes af-in {
  0% { opacity: 0; transform: scale(1.7); }
  22% { opacity: 1; transform: scale(1); }
  40% { opacity: 1; } 47% { opacity: .25; } 54% { opacity: 1; }
  78% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(.92); }
}
@keyframes af-out { to { opacity: 0; transform: scale(.85); } }

/* ───────── About, after the rotunda stage: how we work, who, the name, the bridge ───────── */
.about-name-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr); gap: 40px clamp(40px, 7vw, 140px); align-items: start; }
.entries { border-top: var(--hair) solid var(--line); }
.entry { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.6fr); gap: 10px 32px; padding: 30px 0; border-bottom: var(--hair) solid var(--faint); }
.entry dt { font-weight: 900; font-size: clamp(26px, 2.5vw, 40px); line-height: 1.15; letter-spacing: .02em; }
.entry dt[lang="en"] { font-family: 'Archivo', var(--sans); letter-spacing: -.01em; }
.entry dd { display: grid; gap: 10px; padding-top: 6px; }
.entry dd .mono { color: var(--mute); }
.entry dd p { font-size: clamp(16px, 1.2vw, 19px); line-height: 1.9; text-wrap: pretty; }

.about-principal { padding-top: clamp(56px, 6vw, 96px); }
.about-principal .principal { grid-template-columns: minmax(0, .85fr) minmax(0, 1fr); }
.principal-photo { position: sticky; top: calc(var(--glass) + 24px); }
.about-principal .principal-body { padding-top: 0; gap: 24px; }
.about-principal .principal-body .h2 { margin-bottom: 12px; }
.about-principal .specs { margin-top: 12px; }

.ways { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-top: var(--hair) solid var(--line); counter-reset: none; }
.ways li { display: grid; align-content: start; gap: 12px; padding: 28px clamp(18px, 2vw, 32px) 0 0; }
.ways li + li { padding-left: clamp(18px, 2vw, 32px); border-left: var(--hair) solid var(--faint); }
.ways .mono { color: var(--focus); }
.ways h3 { font-weight: 900; font-size: clamp(30px, 2.8vw, 46px); line-height: 1.15; }
.ways b { font-weight: 700; font-size: 17px; }
.ways p { color: var(--mute); font-size: 15px; line-height: 1.85; }

.about-vision .page { display: grid; gap: 28px; max-width: 1180px; }
.about-vision-label { color: var(--mute); display: flex; align-items: center; gap: 12px; }
.about-vision-label::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--focus); }
.about-vision .h2 { max-width: 20em; }
.about-vision-next { color: var(--mute); font-size: clamp(17px, 1.3vw, 20px); line-height: 1.9; max-width: 34em; text-wrap: pretty; }


.about-bridge { padding-block: clamp(56px, 7vw, 112px) 0; }
.about-bridge .h2 { max-width: 14em; }

.about-ways { position: relative; overflow: hidden; }
.about-ways > .page { position: relative; }
.ways-field { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.way-hl { display: block; width: 100%; max-width: 260px; aspect-ratio: 5 / 4; margin: 0 0 8px -10px; }
.way-hl svg { display: block; width: 100%; height: 100%; }
.ways-more { margin-top: clamp(40px, 5vw, 72px); }

.about-who { padding-block: clamp(72px, 8vw, 128px); }
.who { display: grid; gap: clamp(24px, 2.6vw, 40px); max-width: 1180px; }
/* The sentence leads; the line above it is a quiet label and the cards are the facts under it. */
.who-kicker { color: var(--mute); font-size: clamp(15px, 1.1vw, 17px); font-weight: 700; letter-spacing: .06em; display: flex; align-items: center; gap: 12px; }
.who-kicker::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--focus); }
.who-scrub { font-size: clamp(26px, 3.1vw, 50px); line-height: 1.6; font-weight: 900; max-width: 22em; text-wrap: pretty; margin-bottom: clamp(8px, 2vw, 32px); }
.who-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(12px, 1.4vw, 20px); }
.who-cards li { container-type: inline-size; display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); align-items: center; gap: clamp(8px, 1vw, 16px); padding: clamp(12px, 1.2vw, 18px) clamp(16px, 1.6vw, 24px) clamp(12px, 1.2vw, 18px) clamp(6px, .8vw, 12px); border: var(--hair) solid var(--line); border-radius: 18px; }
.who-hl { display: block; width: 100%; aspect-ratio: 5 / 4; }
.who-hl svg { display: block; width: 100%; height: 100%; }
.who-card-text { display: grid; gap: 6px; min-width: 0; }
.who-cards .mono { color: var(--mute); }
.who-cards b { font-weight: 900; font-size: clamp(22px, 7cqi, 40px); line-height: 1.15; letter-spacing: .01em; word-break: keep-all; overflow-wrap: anywhere; } /* sized by the card, so 線下 × 線上 stays inside it */
.who-cards p { color: var(--mute); font-size: clamp(13px, 3.2cqi, 16px); line-height: 1.7; text-wrap: pretty; word-break: keep-all; overflow-wrap: anywhere; } /* breaks at the comma, not inside 網頁 */

@media (max-width: 1100px) {
  .who-cards { grid-template-columns: minmax(0, 1fr); max-width: 560px; }
  .who-cards li { grid-template-columns: 180px minmax(0, 1fr); }
  .ways { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ways li:nth-child(3) { padding-left: 0; border-left: 0; }
  .ways li:nth-child(n + 3) { margin-top: 28px; border-top: var(--hair) solid var(--faint); }
}
@media (max-width: 860px) {
  .about-name-grid, .about-principal .principal { grid-template-columns: minmax(0, 1fr); }
  .entry { grid-template-columns: minmax(0, 1fr); }
  .principal-photo { position: static; max-width: 420px; }
}
@media (max-width: 600px) {
  .ways { grid-template-columns: minmax(0, 1fr); }
  .ways li, .ways li + li { padding-left: 0; border-left: 0; }
  .ways li + li { margin-top: 28px; border-top: var(--hair) solid var(--faint); }
}

/* ───── Languages (i18n.js sets html[data-lang]) ─────
   English sets in Archivo, the Latin face the Chinese pages already use for their English, with Noto Sans TC behind it for the
   Chinese second labels. Japanese sets in Noto Sans JP and breaks by phrase (word-break: auto-phrase reads lang="ja"),
   where the Chinese pages hold words together with keep-all and <wbr>. */
:root[data-lang="en"] { --sans: 'Archivo', 'Noto Sans TC', 'PingFang TC', 'Microsoft JhengHei', sans-serif; }
:root[data-lang="ja"] { --sans: 'Noto Sans JP', 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', 'Yu Gothic', 'Noto Sans TC', sans-serif; }
:root[data-lang="ja"] body { line-break: strict; }
:root[data-lang="ja"] :is(h1, h2, h3, .lead, .about-text, .about-side, .contact .lead, .q-head span, .tile-text b, .tile-text small, .q-tip, .q-way span, .q-fields label span, .q-notice) { word-break: auto-phrase; }
:root[data-lang="en"] :is(h1, h2, .h2) { hyphens: manual; }

/* The switch: three short codes, the open one in ink with an orange focus dot under it. */
.lang-switch { display: flex; align-items: center; gap: 2px; font: 500 11px/1 var(--mono); letter-spacing: .06em; }
.lang-switch a { position: relative; display: grid; place-items: center; min-width: 28px; height: 28px; padding: 0 4px; color: inherit; opacity: .48; text-decoration: none; transition: opacity .25s var(--ease); }
.lang-switch a:hover, .lang-switch a:focus-visible { opacity: 1; }
.lang-switch a[aria-current] { opacity: 1; }
.lang-switch a[aria-current]::after { content: ''; position: absolute; left: 50%; bottom: 2px; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--focus); }
.lang-switch .lang-short { font-family: var(--mono); }
.lang-switch a[lang="zh-Hant"] .lang-short, .lang-switch a[lang="ja"] .lang-short { font-family: var(--sans); font-size: 12px; letter-spacing: 0; }
.lang-top { margin-right: -8px; }
/* Sound toggle (sound.js): four hairline bars beside the language switch, lying low while off and breathing while on. */
.sound-toggle { flex: none; display: grid; place-items: center; width: 32px; height: 32px; margin-left: auto; margin-right: -12px; padding: 0; background: none; border: 0; color: inherit; cursor: pointer; opacity: .48; transition: opacity .25s var(--ease); }
.sound-toggle:hover, .sound-toggle:focus-visible, .sound-toggle[aria-pressed="true"] { opacity: 1; }
.sound-bars { display: flex; align-items: center; gap: 2px; height: 12px; }
.sound-bars i { width: 1.5px; height: 100%; background: currentColor; transform: scaleY(.16); transition: transform .5s var(--ease); }
.sound-toggle.is-on .sound-bars i { animation: sound-bar 1.1s ease-in-out infinite alternate; }
.sound-toggle.is-on .sound-bars i:nth-child(2) { animation-duration: .8s; animation-delay: -.3s; }
.sound-toggle.is-on .sound-bars i:nth-child(3) { animation-duration: 1.3s; animation-delay: -.6s; }
.sound-toggle.is-on .sound-bars i:nth-child(4) { animation-duration: .95s; animation-delay: -.2s; }
@keyframes sound-bar { from { transform: scaleY(.25); } to { transform: scaleY(1); } }
@media (prefers-reduced-motion: reduce) { .sound-toggle.is-on .sound-bars i { animation: none; transform: scaleY(.7); } }
.spec-footer-bottom .lang-foot a { color: var(--fg); }
.spec-footer-bottom .lang-foot a:hover { text-decoration: none; }
/* The menu label's roll box was sized for 選單 / Menu; メニュー needs a wider one or it runs into the switch beside it. */
:root[data-lang="ja"] .tled-idle { width: 4.9em; }
/* Phones have no room beside the mark: the switch waits in the open menu, as a glass pill at the foot of the screen. */
@media (max-width: 600px) {
  .lang-top { display: none; }
  body.menu-open .lang-top {
    display: flex; position: fixed; left: 50%; bottom: calc(20px + env(safe-area-inset-bottom, 0px)); margin: 0; transform: translateX(-50%);
    gap: 4px; padding: 4px; border-radius: 999px; color: var(--ink);
    background: color-mix(in srgb, var(--white) 72%, transparent); -webkit-backdrop-filter: blur(14px) saturate(1.3); backdrop-filter: blur(14px) saturate(1.3);
    box-shadow: inset 1px 1px 0 color-mix(in srgb, white 70%, transparent), 0 10px 30px color-mix(in srgb, var(--ink) 18%, transparent);
    animation: lang-pill .5s var(--ease) .25s both;
  }
  body.menu-open .lang-top a { min-width: 52px; height: 40px; border-radius: 999px; font-size: 13px; }
  body.menu-open .lang-top a[aria-current] { background: var(--ink); color: var(--white); }
  body.menu-open .lang-top a[aria-current]::after { bottom: 5px; }
  body.menu-open .lang-top a[lang="zh-Hant"] .lang-short, body.menu-open .lang-top a[lang="ja"] .lang-short { font-size: 14px; }
}
@keyframes lang-pill { from { opacity: 0; translate: 0 12px; } }
@media (prefers-reduced-motion: reduce) { body.menu-open .lang-top { animation: none; } }
/* The cover's headline and lead were measured for a few CJK glyphs a line; English runs about twice as wide. */
:root[data-lang="en"] .chart-title h1 { font-size: max(calc(var(--u) * 3.3), 30px); letter-spacing: -.02em; }
:root[data-lang="en"] .chart.is-end .chart-title h1 { font-size: max(calc(var(--u) * 2.2), 22px); }
:root:not([data-lang="zh"]) .c-lead > span:first-child { white-space: normal; max-width: 30em; }
:root[data-lang="ja"] .c-lead { font-size: max(calc(var(--u) * 2.8), 24px); }
/* Japanese service names run longer than the Chinese: on the cover cards they wrap by phrase at a smaller size. */
:root[data-lang="ja"] .c-svc .sw.big .sw-t > .zh { white-space: normal; font-size: .74em; height: calc(2.5em / .74); line-height: 1.15; letter-spacing: 0; word-break: auto-phrase; }
/* The finale's punch line (shown when the clock tower has no WebGL) was sized for four or five glyphs a line. */
:root[data-lang="en"] .finale-type { font-size: clamp(40px, 6.6vw, 124px); letter-spacing: -.03em; }
:root[data-lang="ja"] .finale-type { font-size: clamp(36px, 7.2vw, 136px); letter-spacing: -.02em; }
@media (max-width: 600px) { :root[data-lang="en"] .finale-type { font-size: 11vw; } :root[data-lang="ja"] .finale-type { font-size: 7.6vw; } }
/* Tarot cards on the services table: the names were set on one line for four or five CJK glyphs. */
:root[data-lang="en"] .tc-name b { white-space: normal; font-size: max(8.6cqi, calc(9px / var(--s, 1))); letter-spacing: -.01em; line-height: 1.06; }
:root[data-lang="en"] .tc-cover b { font-size: 8.6cqi; letter-spacing: -.01em; line-height: 1.06; padding-inline: 8cqi; }
:root[data-lang="ja"] .tc-name b { white-space: normal; font-size: max(9cqi, calc(9px / var(--s, 1))); letter-spacing: 0; line-height: 1.15; word-break: auto-phrase; }
:root[data-lang="ja"] .tc-cover b { font-size: 9cqi; letter-spacing: 0; padding-inline: 6cqi; word-break: auto-phrase; }
:root[data-lang="ja"] :is(.c-lead > span, .ds-sub, .ways b, .ways h3, .finale-next strong, .spec-footer-sub, .deck-lead, .ps-lead, .ps-t, .inq-note, .about-vision-next, .entry p) { word-break: auto-phrase; }
@media (max-width: 600px) { :root[data-lang="ja"] .c-lead { font-size: 21px; } }

/* ───── Visual guidance (2026-10-19) ─────
   Scroll cue: a hairline under a first screen with a focus-orange tick running down it; it leaves once the page has moved.
   Try hint: a pulsing focus dot and one line beside things that answer the pointer.
   About meter: the pinned stage's four layouts as a vertical index on the right, the current one lit. */
.scroll-cue { display: inline-flex; align-items: center; gap: 12px; margin-top: clamp(28px, 3.6vw, 52px); font-size: 12px; letter-spacing: .14em; color: var(--mute); transition: opacity .5s var(--ease), translate .5s var(--ease); }
.scroll-cue i { position: relative; width: 1px; height: 44px; background: var(--line); overflow: hidden; }
.scroll-cue i::after { content: ''; position: absolute; left: 0; top: 0; width: 1px; height: 14px; background: var(--focus); animation: cue-fall 1.8s var(--ease) infinite; }
@keyframes cue-fall { from { translate: 0 -14px; } to { translate: 0 44px; } }
.is-scrolled .scroll-cue { opacity: 0; translate: 0 10px; pointer-events: none; }
.chart > .scroll-cue { position: absolute; left: 63%; bottom: 72px; margin: 0; z-index: 2; }

.try-hint { display: inline-flex; align-items: center; gap: 10px; margin-top: 18px; font-size: 13px; letter-spacing: .04em; color: var(--mute); }
.try-hint b { position: relative; width: 7px; height: 7px; border-radius: 50%; background: var(--focus); flex: none; }
.try-hint b::after { content: ''; position: absolute; inset: 0; border-radius: 50%; border: 1px solid var(--focus); animation: hint-ping 2s ease-out infinite; }
@keyframes hint-ping { from { scale: 1; opacity: .9; } to { scale: 3.2; opacity: 0; } }
.section-head > .try-hint { justify-self: end; margin: 0; }
.who > .try-hint { margin: clamp(28px, 3vw, 44px) 0 0; }

.about-meter { display: none; }
.about-stage.is-live .about-meter { position: absolute; right: var(--gutter); top: 50%; translate: 0 -50%; z-index: 4; display: grid; gap: 14px; list-style: none; margin: 0; padding: 0 0 0 14px; border-left: 1px solid rgba(244, 237, 222, .18); pointer-events: none; }
.about-meter li { position: relative; display: flex; align-items: baseline; gap: 8px; font-size: 12px; letter-spacing: .1em; color: rgba(244, 237, 222, .38); transition: color .4s var(--ease); }
.about-meter li .mono { font-size: 10px; }
.about-meter li::before { content: ''; position: absolute; left: -15px; top: 0; bottom: 0; width: 1px; background: var(--focus); scale: 1 0; transition: scale .4s var(--ease); }
.about-meter li.is-on { color: #f4edde; }
.about-meter li.is-on::before { scale: 1 1; }

@media (prefers-reduced-motion: reduce) {
  .scroll-cue i::after, .try-hint b::after { animation: none; }
}
@media (max-width: 760px) {
  .chart > .scroll-cue { display: none; }
  .section-head > .try-hint { justify-self: start; }
  .about-stage.is-live .about-meter { right: 14px; gap: 10px; }
  .about-meter li { font-size: 0; }
  .about-meter li .mono { font-size: 10px; }
}

/* ───── Cover as one screen (2026-10-19) ─────
   The lead that used to replace the headline in the second state now sits under it; the right column reads
   森鑒閣 / headline / tagline / lead, then the scroll cue. The is-end rules above are no longer reached. */
@media (min-width: 861px) {
  .c-kicker { top: 22%; }
  .chart-title { top: 28%; }
  .c-tag { top: 51%; }
  .c-lead { left: 63%; top: 61%; visibility: visible; font-size: max(calc(var(--u) * 2.3), 22px); }
}
.c-lead > span:first-child { color: var(--mute); }
@media (min-width: 861px) { .c-lead > span:first-child { font-size: max(.5em, 14px); } }

/* Footer: the service cards under 想法，在這裡對焦。 */
.spec-footer-svc { margin-top: clamp(32px, 3.2vw, 48px); max-width: 720px; }
body:not(.is-home) .spec-footer-svc { display: none; } /* other pages keep the footer as it was */
.spec-footer-svc .c-svc li { list-style: none; }
.spec-footer-svc .c-svc { margin: 0; padding: 0; }
@media (max-width: 860px) { .spec-footer-svc .c-svc { grid-template-columns: repeat(2, 1fr); } }

/* ───── Side scroll rail (2026-10-19, replaces the focus-distance scale) ─────
   A hairline track on the right edge, filled in focus orange as far as the page has gone; .is-nudge rolls a small wheel and
   says 往下捲動 beside it now and then. Takes the theme of the section under its middle (studio.js frame()). */
.scroll-rail { position: fixed; right: 14px; top: 50%; translate: 0 -50%; z-index: 36; height: min(34vh, 280px); width: 2px; pointer-events: none; color: var(--fg); --rail-line: color-mix(in srgb, currentColor 18%, transparent); }
.scroll-rail[hidden] { display: none; }
.scroll-rail[data-theme="dark"] { color: #f3f3f0; }
.scroll-rail[data-theme="light"] { color: #0e0f10; }
.sr-track { position: absolute; inset: 0; border-radius: 2px; background: var(--rail-line); overflow: hidden; }
.sr-track b { position: absolute; inset: 0; background: var(--focus); transform-origin: 50% 0; scale: 1 var(--p, 0); }
.sr-nudge { position: absolute; right: 14px; top: calc(var(--p, 0) * 100%); translate: 8px -50%; display: flex; align-items: center; gap: 10px; flex-direction: row-reverse;
  font-size: 12px; letter-spacing: .12em; white-space: nowrap; opacity: 0; transition: opacity .45s var(--ease), translate .45s var(--ease); }
.scroll-rail.is-nudge .sr-nudge { opacity: 1; translate: 0 -50%; }
.sr-wheel { position: relative; width: 16px; height: 25px; border: 1.2px solid currentColor; border-radius: 9px; flex: none; }
.sr-wheel i { position: absolute; left: 50%; top: 5px; width: 2px; height: 5px; margin-left: -1px; border-radius: 1px; background: var(--focus); }
.scroll-rail.is-nudge .sr-wheel i { animation: sr-roll 1.1s var(--ease) infinite; }
@keyframes sr-roll { 0% { translate: 0 0; opacity: 1; } 70% { translate: 0 8px; opacity: 0; } 100% { translate: 0 0; opacity: 0; } }
.scroll-rail.is-nudge .sr-track b { animation: sr-glow 1.1s ease-in-out 3; }
@keyframes sr-glow { 50% { filter: brightness(1.35); } }
.menu-open .scroll-rail { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .scroll-rail.is-nudge .sr-wheel i, .scroll-rail.is-nudge .sr-track b { animation: none; } }
@media (max-width: 760px) {
  .scroll-rail { right: 6px; height: min(26vh, 200px); }
  .sr-say { display: none; }
  .about-stage.is-live .about-meter { right: 24px; }
}

/* Case pages: the rail hint is a clear call — a rolling wheel, one line, an arrow nudging right, in a pill. (2026-10-19) */
.is-live .rail-hint { width: fit-content; gap: 12px; padding: 10px 16px 10px 12px; border: 1px solid color-mix(in srgb, var(--focus) 55%, transparent); border-radius: 999px;
  font: 600 14px/1.2 var(--sans); letter-spacing: .06em; text-transform: none; color: var(--fg); background: color-mix(in srgb, var(--focus) 10%, transparent); }
.rail-hint .sr-wheel i { animation: sr-roll 1.1s var(--ease) infinite; }
.rail-hint .rh-arrow { display: flex; color: var(--focus); animation: rh-nudge 1.1s var(--ease) infinite; }
.is-live .rail-hint .rh-arrow svg { stroke-width: 1.8; }
@keyframes rh-nudge { 0%, 100% { translate: 0 0; } 50% { translate: 6px 0; } }
@media (prefers-reduced-motion: reduce) { .rail-hint .sr-wheel i, .rail-hint .rh-arrow { animation: none; } }

/* About: the stage's 01–04 index is off for now — the scroll itself carries the four layouts. (2026-10-19) */
.about-stage .about-meter { display: none !important; }

/* Ticker off screen: its CSS loops (letter weights, edge stripes) stop with the GSAP ones (motion.js ticker). */
.ticker.is-off, .ticker.is-off * { animation-play-state: paused !important; }

/* Clock tower loading bar (2026-10-19): while well.js builds the tower, the finale says so in the About loader's style.
   well.js writes --load (0–1) and the percentage, and adds .is-built once the first frame is up. */
.finale-load { display: none; }
.finale.has-gl .finale-load { position: absolute; left: 50%; top: 50%; translate: -50% -50%; z-index: 2; display: grid; gap: 12px; justify-items: center; width: 168px;
  font: 500 11px var(--mono); letter-spacing: .3em; color: #f4edde; pointer-events: none; transition: opacity .6s var(--ease); }
.finale-load span { padding-left: .3em; opacity: .75; white-space: nowrap; }
.finale-load i { display: block; width: 100%; height: 1px; background: rgba(244, 237, 222, .16); }
.finale-load b { display: block; height: 100%; background: var(--focus); transform-origin: left; transform: scaleX(var(--load, 0)); transition: transform .3s var(--ease); }
.finale-load em { font-style: normal; font-variant-numeric: tabular-nums; opacity: .6; }
.finale.is-built .finale-load { opacity: 0; }
