/* ==========================================================================
   ULC — Dragon Gate
   Night ink: a warm black ground with hairline rules. Geist for type, Geist
   Mono for UI. Public-domain Chinese and Japanese ink paintings, dithered live
   into soft bone-coloured dots (ink.js), tell the carp that leaps the Dragon
   Gate: two dragons behind the headline (only they turn green), carp → waves
   → dragon over the three steps, plum blossom above booking, bamboo beside the
   FAQs, an old pine at the foot of every page. One brush stroke (brush.js)
   runs behind Selected work and How it works. Green is the accent only, as in
   the mark: the third of three.
   ========================================================================== */

:root {
  --page: #090908;        /* warm ink-black */
  --panel: #10100e;
  --bar: #141412;
  --bar-hover: #1b1a17;
  --ink: #f3f3ed;
  --ink-2: #aaa9a1;
  --line: rgba(236, 228, 210, 0.1);
  --media: #090908;
  --green: #a2d88d;       /* brand green — marks and indicators only, never text.
                             Like the mark (two white strokes, one green), it is
                             the accent: the third of three, the brightest ink. */
  --bone: #d8d0bc;        /* the ink of the paintings and brush strokes */
  --on-ink: #0a0a09;
  --ink-hover: #dcdcd5;
  --top-glass: rgba(9, 9, 8, 0.86);
  --dialog-glass: rgba(9, 9, 8, 0.95);
  --dialog-shadow: rgba(0, 0, 0, 0.58);

  --frame: min(calc(100% - 32px), 1120px);
  --top: 64px;
  --r: 3px;
  --inset: 20px;          /* inner padding of every tile and bar */

  --ease: cubic-bezier(0.25, 0.8, 0.25, 1);
  --sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

html { background: var(--page); scrollbar-gutter: stable; scroll-behavior: smooth; scroll-padding-top: calc(var(--top) + 16px); -webkit-text-size-adjust: 100%; }
html.has-dialog { overflow: hidden; }

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, ol, ul { margin: 0; }
/* No single word left alone on a last line. */
h2, h3, p { text-wrap: pretty; }
ol, ul { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
img, video, canvas, svg { display: block; }
[hidden] { display: none !important; }

::selection { background: rgba(162, 216, 141, 0.5); }
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

.skip {
  position: fixed; z-index: 100; top: 10px; left: 10px;
  padding: 9px 14px;
  border-radius: var(--r);
  background: var(--ink); color: var(--on-ink);
  font-family: var(--mono); font-size: 12px;
  transform: translateY(-160%);
}
.skip:focus { transform: none; }

.frame { position: relative; width: var(--frame); margin-inline: auto; }
.noscript { padding: 48px 24px; color: var(--ink-2); text-align: center; }

.mark { width: 100%; height: auto; }
.mark__ink { fill: var(--ink); }
.mark__green { fill: var(--green); }

/* --------------------------------------------------------------------------
   Buttons — primary typeface, sentence case, nearly square
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 42px; padding: 0 18px;
  border-radius: var(--r);
  font-family: var(--sans); font-size: 14px; font-weight: 500; letter-spacing: -0.01em;
  transition: background-color 180ms var(--ease), box-shadow 180ms var(--ease);
}
.btn--ink { background: var(--ink); color: var(--on-ink); }
.btn--ink:hover { background: var(--ink-hover); }
.btn--line { background: var(--panel); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line); }
.btn--line:hover { box-shadow: inset 0 0 0 1px var(--ink); }
.btn--small { min-height: 36px; padding: 0 14px; }

/* Touch screens get 44px targets without changing the design at desktop. */
@media (pointer: coarse) {
  .btn, .btn--small { min-height: 44px; }
}

/* --------------------------------------------------------------------------
   Top bar
   -------------------------------------------------------------------------- */

.top {
  position: sticky; top: 0; z-index: 20;
  transition: background-color 220ms var(--ease);
}
.top.is-stuck {
  background: var(--top-glass);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
}

.top__inner {
  display: flex; align-items: center; justify-content: space-between;
  height: var(--top);
}

/* One logo lockup, used in the top bar and the footer. */
.brand,
.footer__logo {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 44px;
  font-size: 20px; font-weight: 600; letter-spacing: -0.045em;
}
.brand .mark,
.footer__logo .mark { width: 38px; }

.brand { transition: opacity 160ms var(--ease); }
.brand:hover { opacity: 0.66; }

/* --------------------------------------------------------------------------
   Hero — the headline over Two Dragons in Clouds, held quiet behind the words
   -------------------------------------------------------------------------- */

.hero { position: relative; touch-action: pan-y pinch-zoom; }

/* The painting bleeds edge to edge and up under the top bar. */
.hero > .hero__ink { position: absolute; inset: calc(-1 * var(--top)) 0 0; }

.hero__inner {
  position: relative;
  display: grid; justify-items: center; align-content: center; text-align: center;
  min-height: min(calc(100svh - var(--top)), 860px);
  padding-block: clamp(72px, 10vw, 140px);
}
.hero__headline { justify-self: stretch; }

.hero__title {
  font-size: clamp(42px, 5.9vw, 84px);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.05em;
}
/* One line each where they fit; on narrow screens the first breaks evenly
   ("Make your / next launch") instead of orphaning "launch". */
.hero__title span { display: block; text-wrap: balance; }

.hero__sub {
  margin-top: 20px;
  color: var(--ink-2);
  font-size: 18px;
  letter-spacing: -0.01em;
}

.hero__actions {
  display: flex; flex-wrap: nowrap; justify-content: center; gap: 8px;
  margin-top: 30px;
}
.hero__actions .btn { min-width: 124px; }

/* Client logos, quiet and monochrome, pinned to the foot of the hero so
   showing or hiding them (CMS: sections → clients) never shifts the page. */
.clients {
  position: absolute; bottom: clamp(20px, 3.5vw, 44px); left: 50%;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 14px clamp(28px, 4vw, 56px);
  width: max-content; max-width: 100%;
  transform: translateX(-50%);
}
.clients:empty { display: none; }
.clients__item img {
  display: block; width: auto; height: 20px;
  filter: brightness(0) invert(0.85);
  opacity: 0.5;
  transition: opacity 200ms var(--ease);
}
.clients__item img:hover { opacity: 0.85; }
.clients__item img.is-dark-plate { filter: grayscale(1) brightness(0.95); mix-blend-mode: screen; }
.clients__item img.is-light-plate { filter: grayscale(1) invert(1) brightness(0.95); mix-blend-mode: screen; }
@media (max-width: 520px) { .clients__item img { height: 16px; } }

/* --------------------------------------------------------------------------
   Ink (ink.js) — every painting is a canvas, shown once it is drawn
   -------------------------------------------------------------------------- */

.ink { position: relative; display: block; overflow: hidden; }
.ink__canvas {
  display: block;
  opacity: 0;
  /* ink.js draws one pixel per 3px dot; scaled up crisp, then masked into
     soft round dots. */
  image-rendering: pixelated;
  -webkit-mask: radial-gradient(circle, #000 0.7px, rgba(0, 0, 0, 0.55) 1.15px, transparent 1.6px) 0 0 / 3px 3px;
  mask: radial-gradient(circle, #000 0.7px, rgba(0, 0, 0, 0.55) 1.15px, transparent 1.6px) 0 0 / 3px 3px;
}
.is-live > .ink__canvas { opacity: 1; }


/* --------------------------------------------------------------------------
   The brush stroke and section heads
   -------------------------------------------------------------------------- */

/* The stroke (brush.js): one calligraphic stroke behind Selected work and
   How it works, on one continuous rice-paper grain that fades in and out over
   long soft edges — no section boundary ever shows. Grain and stroke are
   dimmed together, so both sections sit a shade darker than the page around
   them. It sits behind all content; the body is its stacking context. Placed
   and sized by JS. */
body.has-stroke { position: relative; z-index: 0; }
.stroke { position: absolute; left: 0; z-index: -1; overflow: hidden; opacity: 0.4; pointer-events: none; }
.stroke__paper {
  position: absolute; inset: 0;
  background: url("/assets/ink/paper.webp?v=20260929f") 0 0 / 256px 256px;
  -webkit-mask: linear-gradient(transparent, #000 380px, #000 calc(100% - 380px), transparent);
  mask: linear-gradient(transparent, #000 380px, #000 calc(100% - 380px), transparent);
}
.stroke__ink {
  position: absolute; top: 0; left: 0;
  image-rendering: pixelated;
  -webkit-mask: radial-gradient(circle, #000 0.7px, rgba(0, 0, 0, 0.55) 1.15px, transparent 1.6px) 0 0 / 3px 3px;
  mask: radial-gradient(circle, #000 0.7px, rgba(0, 0, 0, 0.55) 1.15px, transparent 1.6px) 0 0 / 3px 3px;
}

.section__head {
  padding: clamp(88px, 10.5vw, 148px) 0 clamp(32px, 3.6vw, 44px);
  text-align: center;
}

.section__title {
  font-size: clamp(32px, 3.3vw, 46px);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.045em;
}

.section__note { max-width: 42ch; margin: 12px auto 0; color: var(--ink-2); font-size: 15px; }

/* Centred lines break into even halves when they wrap. */
.section__title, .section__note { text-wrap: balance; }

/* --------------------------------------------------------------------------
   Selected work — film tiles
   -------------------------------------------------------------------------- */

.work {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.work__media {
  position: relative;
  display: block; width: 100%;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  border-radius: var(--r);
  background: var(--media);
  text-align: left;
}

.preview-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 1;
}

/* A dark foot so the caption holds on any frame, including white ones. */
.work__media::after {
  content: "";
  position: absolute; right: 0; bottom: 0; left: 0; z-index: 1;
  height: 40%;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0));
  pointer-events: none;
}

/* A faint inner edge, so a tile showing a white frame doesn't dissolve into
   the page. Drawn over the video, under the caption. */
.work__media::before {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(10, 10, 10, 0.07);
  pointer-events: none;
}

.work__caption {
  position: absolute; right: 0; bottom: 0; left: 0; z-index: 2;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
  padding: var(--inset);
  color: #fff;
  line-height: 1.2; /* no extra leading under the name, so the bottom inset matches the sides */
}
.work__name { font-size: 15px; font-weight: 500; letter-spacing: -0.015em; }
.work__arrow { font-family: var(--mono); font-size: 15px; transition: transform 200ms var(--ease); }
.work__media:hover .work__arrow { transform: translate(2px, -2px); }

@media (max-width: 700px) { .work { grid-template-columns: minmax(0, 1fr); } }

/* --------------------------------------------------------------------------
   How it works — three tiles
   -------------------------------------------------------------------------- */

.steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.step { display: flex; flex-direction: column; min-height: 240px; padding: var(--inset); border-radius: var(--r); background: var(--bar); }

/* The Dragon Gate: carp, waves, dragon — one painting on top of each step.
   Wide, each panel and its step read as one tile; narrow, the three sit as a
   small triptych above the stacked steps. */
.gate {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}
/* One canvas paints all three panels (ink.js [data-ink-group]). */
.gate > .ink__canvas { position: absolute; top: 0; left: 0; z-index: 1; pointer-events: none; }
.gate__panel { aspect-ratio: 4 / 3; border-radius: var(--r) var(--r) 0 0; background: var(--bar); }
.gate + .steps .step { border-radius: 0 0 var(--r) var(--r); }

/* The small mono label with a green square: step numbers here, eyebrows and
   form group numbers on the brief pages. */
.step__index, .label {
  /* A block-level flex box, so a label sitting directly in running text gets
     no line-box strut above it and lines up with labels elsewhere. */
  display: flex; align-items: center; gap: 8px;
  width: fit-content;
  color: var(--ink-2);
  font-family: var(--mono); font-size: 12px;
}
.step__index::before, .label::before { content: ""; width: 7px; height: 7px; background: var(--green); }

/* A fixed offset rather than margin:auto — auto pushed each title down by its
   own copy length, so titles with shorter copy sat lower than their neighbours. */
.step__title {
  margin: clamp(56px, 6vw, 84px) 0 10px;
  font-size: 24px;
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.035em;
}
.step__copy { max-width: 34ch; color: var(--ink-2); font-size: 15px; }

@media (max-width: 780px) {
  .gate { margin-bottom: 8px; }
  .gate__panel { aspect-ratio: 1; border-radius: var(--r); }
  .gate + .steps .step { border-radius: var(--r); }
  .steps { grid-template-columns: minmax(0, 1fr); }
  .step { min-height: 0; }
  .step__title { margin-top: 36px; }
}

/* --------------------------------------------------------------------------
   FAQs — title on the left, bars on the right
   -------------------------------------------------------------------------- */

.faq {
  display: grid;
  grid-template-columns: minmax(0, 0.42fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 64px);
  padding-top: clamp(88px, 10.5vw, 148px);
}

/* The title, then a hanging scroll of bamboo beside the questions. Its size
   is fixed, so opening an answer never resizes it. */
.faq__side { display: flex; flex-direction: column; gap: 24px; align-self: start; }
.faq__title { text-align: left; }
.faq__scroll { width: 100%; aspect-ratio: 5 / 6; }

.faq__list { display: grid; gap: 8px; }

.faq__item { border-radius: var(--r); background: var(--bar); transition: background-color 180ms var(--ease); }
.faq__item:hover { background: var(--bar-hover); }

.faq__button {
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  width: 100%; min-height: 56px; padding: 16px var(--inset);
  font-size: 15px; font-weight: 500; letter-spacing: -0.015em;
  text-align: left;
}
.faq__sign { flex: none; width: 14px; color: var(--ink-2); font-family: var(--mono); font-size: 15px; text-align: center; }
.faq__sign::before { content: "+"; }

.faq__panel { height: 0; overflow: hidden; transition: height 320ms var(--ease); }
.faq__panel p { max-width: 62ch; padding: 0 54px var(--inset) var(--inset); color: var(--ink-2); font-size: 15px; }
.faq__panel a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

details.faq__item > summary.faq__button { list-style: none; cursor: pointer; }
details.faq__item > summary.faq__button::-webkit-details-marker { display: none; }
details.faq__item > .faq__panel { height: auto; overflow: visible; }
details.faq__item[open] .faq__sign::before { content: "\2212"; }

/* Answers open and close smoothly where the browser can animate to auto. */
@supports (interpolate-size: allow-keywords) {
  .faq__item { interpolate-size: allow-keywords; }
  .faq__item::details-content {
    height: 0; overflow: clip;
    transition: height 320ms var(--ease), content-visibility 320ms allow-discrete;
  }
  .faq__item[open]::details-content { height: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .faq__panel { transition: none; }
  .faq__item::details-content { transition: none; }
}

@media (max-width: 780px) {
  .faq { grid-template-columns: minmax(0, 1fr); }
  .faq__scroll { display: none; }
}

/* --------------------------------------------------------------------------
   Booking — one quiet conversion section, using the same frame and type scale
   -------------------------------------------------------------------------- */

/* A dithered landscape in the band around the heading: it spans the page's
   width, reaches up through the section's top padding and dissolves by the
   end of the heading, quiet behind the words and gone before the calendar,
   which sits straight on the page. */
.booking { position: relative; isolation: isolate; overflow-x: clip; }
.booking__head { position: relative; }
.booking__ink {
  position: absolute; z-index: -1;
  top: calc(-1 * clamp(112px, 12vw, 168px)); bottom: 0; left: 50%;
  width: 100vw; transform: translateX(-50%);
}

.booking__inner { padding-top: clamp(112px, 12vw, 168px); }
.booking__head { max-width: 640px; margin-inline: auto; text-align: center; }
.booking__sub { max-width: 42ch; margin: 16px auto 0; color: var(--ink-2); font-size: 15px; text-wrap: balance; }
.booking__sub a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }

.booking__shell {
  position: relative;
  width: 100%; min-width: 0;
  margin-top: clamp(36px, 5vw, 56px);
  overflow: hidden;
  border-radius: var(--r);
  background: var(--page);
}
.booking__embed { width: 100%; min-width: 0; overflow: hidden; }
.booking__shell.is-loading .booking__embed { min-height: 680px; }
.booking__embed iframe,
.booking__embed > :not(style) { display: block; width: 100% !important; max-width: 100% !important; min-width: 0 !important; border: 0 !important; }
.booking__loading {
  position: absolute; z-index: 1; inset: 0;
  display: grid; place-items: center;
  color: var(--ink-2);
  font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em; text-transform: uppercase;
}
.booking__loading[hidden], .booking__fallback[hidden] { display: none; }
.booking__fallback { padding: 24px; color: var(--ink-2); text-align: center; }
.booking__fallback a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.booking__shell.has-failed { padding-block: 16px; }

@media (max-width: 520px) {
  .booking__shell { margin-inline: -8px; width: calc(100% + 16px); }
  .booking__shell.is-loading .booking__embed { min-height: 760px; }
}

/* --------------------------------------------------------------------------
   Footer — brand, line, links, then the old pine dissolving into the page,
   with the mark at its centre
   -------------------------------------------------------------------------- */

.footer { padding-top: clamp(112px, 12vw, 168px); overflow: hidden; }
.footer__scene { position: relative; margin-top: clamp(48px, 6vw, 88px); }
.footer__ink { height: clamp(180px, 24vw, 340px); touch-action: pan-y pinch-zoom; }
.footer__seal {
  position: absolute; top: 56%; left: 50%;
  width: clamp(60px, 6.5vw, 96px);
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.footer__seal .mark { position: relative; }

/* A green glow behind the mark's third stroke, in the same soft dots as the
   paintings, breathing slowly. */
.footer__glow {
  position: absolute; top: 52%; left: 80%;
  width: 120%; aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(162, 216, 141, 0.6), rgba(162, 216, 141, 0.22) 45%, rgba(162, 216, 141, 0) 100%);
  -webkit-mask: radial-gradient(circle, #000 0.7px, rgba(0, 0, 0, 0.55) 1.15px, transparent 1.6px) 0 0 / 3px 3px;
  mask: radial-gradient(circle, #000 0.7px, rgba(0, 0, 0, 0.55) 1.15px, transparent 1.6px) 0 0 / 3px 3px;
  animation: seal-glow 5s var(--ease) infinite alternate;
}
@keyframes seal-glow {
  from { opacity: 0.7; transform: translate(-50%, -50%) scale(0.9); }
  to { opacity: 1; transform: translate(-50%, -50%) scale(1.05); }
}
@media (prefers-reduced-motion: reduce) { .footer__glow { animation: none; } }

.footer__inner {
  display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between;
  gap: 40px;
}

.footer__line { margin: 12px 0 14px; font-size: 15px; font-weight: 500; letter-spacing: -0.015em; }

/* Links sit together on the logo's line. */
.footer__links { display: flex; flex-wrap: wrap; align-items: center; gap: 0 24px; min-height: 44px; }

.footer__link {
  display: inline-flex; align-items: center;
  min-height: 32px;
  color: var(--ink-2);
  font-family: var(--sans); font-size: 14px;
  transition: color 160ms var(--ease);
}
.footer__link:hover { color: var(--ink); }

@media (pointer: coarse) {
  .footer__link { min-width: 44px; min-height: 44px; }
}

@media (max-width: 700px) {
  .footer__inner { flex-direction: column; gap: 24px; }
  .footer__links { width: 100%; gap: 0 24px; }
}

/* --------------------------------------------------------------------------
   Film dialog
   -------------------------------------------------------------------------- */

.film { width: min(92vw, 1100px); max-width: none; padding: 0; border: 0; background: transparent; overflow: visible; }
.film::backdrop { background: var(--dialog-glass); }
.film__inner { overflow: hidden; border-radius: var(--r); background: var(--panel); box-shadow: 0 0 0 1px var(--line), 0 24px 64px -24px var(--dialog-shadow); }
.film__bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 8px 8px 8px 16px; }
.film__title { font-size: 15px; font-weight: 500; letter-spacing: -0.015em; }
.film__close {
  min-height: 36px; padding: 0 14px;
  border-radius: var(--r);
  box-shadow: inset 0 0 0 1px var(--line);
  font-family: var(--mono); font-size: 12px; font-weight: 500; letter-spacing: 0.04em; text-transform: uppercase;
  transition: box-shadow 180ms var(--ease);
}
.film__close:hover { box-shadow: inset 0 0 0 1px var(--ink); }
@media (pointer: coarse) { .film__close { min-height: 44px; } }
.film__video { width: 100%; max-height: 78vh; aspect-ratio: 16 / 9; object-fit: contain; background: #000; }
